array专题4
674 Longest Continuous Increasing Subsequence
問題:比較簡單,直接看代碼。問題是速度更快的代碼是什么樣子?
代碼
665 Non-decreasing Array
思路:非降序數(shù)組,能有一次修改的機會。那就是查找 array[i+1]<array[i]array[i+1]<array[i],這個時候,修改idx+1,就不能達到目的(因為nums[idx+1]>=4并且nums[idx+1]<=3nums[idx+1]>=4并且nums[idx+1]<=3是做不到的)。而修改nums[idx]就可以達到目的(nus[i]<=2即可nus[i]<=2即可)。但是例如[3,4,2,3] ,當idx=1的時候nums[idx+1]<nums[idx]nums[idx+1]<nums[idx],這個時候修改nums[idx+1],要求的范圍是[4,3],沒有數(shù)據(jù);修改nums[idx],要求的范圍是[3,2]還是沒有數(shù)據(jù)。所以不能滿足要求。
進一步分析:[4,2,3] ,idx=0的時候,nums[idx+1]<nums[idx]nums[idx+1]<nums[idx],這個時候應(yīng)該修改nums[idx]=nums[idx+1]=2。因為nums[idx+1]越大,對后面形成非降數(shù)組越不利。
[3,4,2,3] ,當idx=1的時候nums[idx+1]<nums[idx]nums[idx+1]<nums[idx],因為nums[idx-1]>nums[idx+1],所以就不能修改nums[idx],只能修改nums[idx+1]=nums[idx]=4。在后面的判斷,會繼續(xù)出現(xiàn)第二次錯誤,最終返回false。
代碼
661 Image Smoother
思路:這種查找二維數(shù)組周圍的題目,一定要用到數(shù)組new int[]{-1,0,1}。
代碼
189 Rotate Array
思路:For example, with n = 7 and k = 3, the array [1,2,3,4,5,6,7] is rotated to [5,6,7,1,2,3,4].首先我的思路是循環(huán)隊列,一次移動一個位置,移動k次:分別為[7,1,2,3,4,5,6] [6,7,1,2,3,4,5] [5,6,7,1,2,3,4],接著查找規(guī)律一次移動k個,需要借助長度為k的數(shù)組。
學(xué)習(xí):題目要求O(1)的額外空間完成。學(xué)習(xí)到了倒轉(zhuǎn)的思路。倒轉(zhuǎn)數(shù)組。例如a= [1,2,3,4,5,6,7],首選倒轉(zhuǎn)整個數(shù)組得到[7,6,5,4,3,2,1];接著倒轉(zhuǎn)0到k-1前半部分數(shù)組得到[5,6,7,4,3,2,1];最后倒轉(zhuǎn)k到末尾數(shù)組得到:[5,6,7,1,2,3,4]。為什么有效,沒有找到答案。
代碼
219 Contains Duplicate II
思路:把每個值對應(yīng)的下標存起來,遇到相同的比較一下是不是最多相差k
學(xué)習(xí):另外一種思路是,當前判斷nums[i],那集合中只保留i-k,i-k+1,…i-1范圍內(nèi)的nums值,其他值去掉
代碼
268 Missing Number
思路一:可以計算0,1,2,…n的和,然后再減去數(shù)組中的值,留下的就是丟失的數(shù)據(jù)。
思路二:將nums數(shù)組排序,二分查找的left值就是丟失的數(shù)據(jù)。
思路三:將0,1,2,…n異或的值與nums數(shù)組中每個值異或,最后的結(jié)果就是丟失的數(shù)據(jù)。
66 Plus One
思路:從低位開始加,如果不發(fā)生進位,則加法結(jié)束。如果發(fā)生進位,則前進到前一位做加1操作。最后判斷,如果digits[0]=0則說明存在進位,需要擴展數(shù)組。
學(xué)習(xí):思路跟上面差不多。不同之處是:加法結(jié)束直接返回;如果所有位數(shù)遍歷完,還沒有返回,則說明是 999+1,則需要擴展數(shù)組,將首位修改為1。這樣速度更快。
代碼
283 Move Zeroes
思路:idx記錄不等于0的數(shù)組的存放下標,從左向右遍歷。之后把idx到n之間的值填充為0。
532 K-diff Pairs in an Array
思路:每處理一個nums[i],需要判斷j從i+1到n的數(shù)組值,是否符合|nums[i]-nums[j]|=k。去重部分使用set。例如nums[i]=2,k=3,則需要找到數(shù)值5,-1。當需要處理nums[i]=5的時候,因為2已經(jīng)匹配過了,所以需要找到數(shù)值8。
public int findPairs(int[] nums, int k) {if (k < 0)return 0;int count = 0;Set<Integer> set = new HashSet<Integer>();// 存放已經(jīng)計算過的數(shù)值for (int i = 0; i < nums.length; i++) {if (!set.contains(nums[i])) {Set<Integer> list = new HashSet<Integer>();if (!set.contains(nums[i] - k)) {list.add(nums[i] - k);}if (!set.contains(nums[i] + k)) {list.add(nums[i] + k);}for (int j = i + 1; j < nums.length && !list.isEmpty(); j++) {if (list.contains(nums[j])) {count++;list.remove((Integer) (nums[j]));}}set.add(nums[i]);}}return count;}思路二:處理數(shù)組。首先因為需要去重,那就把數(shù)組排序,并且去掉重復(fù)的數(shù)據(jù)。還是依據(jù)上述的思路,只是不再考慮去重。這里要注意的是當k=0的時候,需要知道有多少數(shù)據(jù)重復(fù)。
public int findPairsV2(int[] nums, int k) {if (k < 0)return 0;Arrays.sort(nums);int idx = 0;// 新的長度int sameMatcherCount = 0;for (int i = 0; i < nums.length; i++) {nums[idx++] = nums[i];if (i + 1 < nums.length && nums[i + 1] == nums[i]) {sameMatcherCount++;}while (i + 1 < nums.length && nums[i + 1] == nums[i]) {i++;}}if (k == 0)return sameMatcherCount;int newLength = idx;int count = 0;for (int i = 0; i < newLength; i++) {for (int j = i + 1; j < newLength; j++) {if (Math.abs(nums[i] - nums[j]) == k) {count++;}}}return count;}學(xué)習(xí)到的:統(tǒng)計每個數(shù)值出現(xiàn)次數(shù)。在處理某個數(shù)值n的時候,判斷map的key值中是否存在n+k。時間復(fù)雜度降到了O(n)。
public int findPairsV3(int[] nums, int k) {if (nums == null || nums.length == 0 || k < 0)return 0;Map<Integer, Integer> map = new HashMap<>();int count = 0;for (int num : nums) {map.put(num, map.get(num) != null ? map.get(num) + 1 : 1);}for (Map.Entry<Integer, Integer> entry : map.entrySet()) {if (k == 0) {if (entry.getValue() >= 2) {count++;}} else {// 只判斷entry.getKey()+k,避免重復(fù)if (map.keySet().contains(entry.getKey() + k)) {count++;}}}return count;}代碼
總結(jié)
- 上一篇: 软件工程之知识架构
- 下一篇: 【数据结构与算法】【算法思想】拓扑排序