我的解法
第一次的錯誤解法
public class Solution {
public List<Integer> findDisappearedNumbers(int[] nums) {
List<Integer> v = new ArrayList<>();
Arrays.sort(nums);
for(int i=1;i<nums.length;i++){
if(i!=nums[i-1]){
v.add(i);
}
}
return v;
}
}
很zz,對不對。。。如果第一次出現缺的數字。後面也就一緻對不上。是以,我們可以這麼改進一下。
第二次的錯誤解法:
大概思路就是,先進行排序,如果中間有什麼空下的數字,那麼好,我w++,如果還是對不上數組中下一位數字,那麼我一直v.add(w),直至對上數組中的下一位。我覺得這個思路很正确,值得一試。可惜還是失敗了。消耗時間有點長了,不劃算。直接discuss
public class Solution {
public List<Integer> findDisappearedNumbers(int[] nums) {
List<Integer> v = new ArrayList<>();
Arrays.sort(nums);
int w=1;
for(int i=0;i<nums.length;i++,w++){
while(w!=nums[i])
{
v.add(w);
w++;
}
}
return v;
}
}
discuss
from:mnv.koundinya
public List<Integer> findDisappearedNumbers(int[] nums) {
List<Integer> ret = new ArrayList<Integer>();
for(int i = 0; i < nums.length; i++) {
int val = Math.abs(nums[i]) - 1;
if(nums[val] > 0) {
nums[val] = -nums[val];
}
}
for(int i = 0; i < nums.length; i++) {
if(nums[i] > 0) {
ret.add(i+1);
}
}
return ret;
}
大緻思路:就是第一遍周遊,給見過的做一個标記。可是這是一堆數字,怎麼給數字做标記呢?我們就把它置為負數就好啦。——這個想法,感覺和boolean異曲同工?大哥腦洞奇清。。。
記住讀題:Given an array of integers where 1 ≤ a[i] ≤ n (n = size of array) 要沒這句話,他這樣搞就會搞出事情的。。。。
from:hu19
同樣是腦洞奇清。。。這是trick,不是程式設計???
public List<Integer> findDisappearedNumbers(int[] nums) {
List<Integer> res = new ArrayList<>();
int n = nums.length;
for (int i = 0; i < nums.length; i ++) nums[(nums[i]-1) % n] += n;
for (int i = 0; i < nums.length; i ++) if (nums[i] <= n) res.add(i+1);
return res;
}
如果nums裡面沒出現過的數字,他是不會+n的。。。是以所有比n小的,都是沒出現過的。。。
總結一下:
上面倆種答案,居然都做到了O(n),他們是通過“标記”的方法,實作O(n)的。我在想,這種“标記”是不是一定程度上的散列,隻不過散列成兩個部分而已。
以後遇見數字分類的題目,最好能借鑒一下這種“标記”的思想,但是我覺得實際上還是散列了。。。。