nums
, in which exactly two
elements appear only once and all the other elements appear exactly
twice. Find the two elements that appear only once.
For example:
Given
nums = [1, 2, 1, 3, 2, 5]
, return [3, 5]
.
Note:
- The order of the result is not important. So in the above example,
[5, 3]
is also correct. - Your algorithm should run in linear runtime complexity. Could you implement it using only constant space complexity?
我想說用quick sort去跑 再去找哪個沒重複的
但是他quick sort出來是錯的.....
測資:[1403617094,-490450406,-1756388866,-967931676,1878401007,1878401007,-74743538,1403617094,-1756388866,-74743538,-490450406,-1895772685]
但是我自己測試這個側資可以 網路上不給過....
而且這版本沒有線性
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | /** * Return an array of size *returnSize. * Note: The returned array must be malloced, assume caller calls free(). */ int cmp(const void* s1, const void* s2){ return *(int*)s2 - *(int*)s1; } int* singleNumber(int* nums, int numsSize, int* returnSize) { //if(nums==NULL)return NULL; int *ans=(int *)malloc(2*sizeof(int)); qsort(nums,numsSize,sizeof(int),cmp); for(int i=0;i<numsSize;i++){ printf("%d ",nums[i]); } int index=0; for(int i=0;i<numsSize;){ if(i==numsSize-1){ ans[index++]=nums[i]; ++i; }else if(nums[i]==nums[i+1]){ i+=2; } else{ ans[index++]=nums[i]; ++i; } if (index ==2)break; } *returnSize=2; return ans; } |
---------------
我知道位甚麼上面的quick會錯了
因為那個側資 數值很大 直接用相減會容易overflow
所要改判斷式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | /** * Return an array of size *returnSize. * Note: The returned array must be malloced, assume caller calls free(). */ int cmp(const void* s1, const void* s2){ int c = *(int *)s1; int d = *(int *)s2; if(c < d) {return -1;} //傳回 -1 代表 s1 < s2 else if (c == d) {return 0;} //傳回 0 代表 s1 = s2 else return 1; //傳回 1 代表 s1>s2 } int* singleNumber(int* nums, int numsSize, int* returnSize) { //if(nums==NULL)return NULL; int *ans=(int *)malloc(2*sizeof(int)); qsort(nums,numsSize,sizeof(int),cmp); for(int i=0;i<numsSize;i++){ printf("%d ",nums[i]); } int index=0; for(int i=0;i<numsSize;){ if(i==numsSize-1){ ans[index++]=nums[i]; ++i; }else if(nums[i]==nums[i+1]){ i+=2; } else{ ans[index++]=nums[i]; ++i; } if (index ==2)break; } *returnSize=2; return ans; } |
-------------------
天才解法!!!!
https://leetcode.com/discuss/52369/c-o-n-time-o-1-space-7-line-solution-with-detail-explanation
https://leetcode.com/discuss/68750/why-diff%26-diff-1-can-pick-one-bit-that-is-one
因為所有數列全部XOR起來 X^=every element
最後只會有X=A^B (A!=B)
因為A跟B不同,所以在X會有一個bit是1
問題就是怎麼找到X裡面出現的1bit位置
笨方法就是用for去找
但是有更快的!!
方法:
X & -X
假設X=01100,那-X=10100
可以發現兩者and起來 會找到右邊第一個出現1bit的位置
或是X=01101 -X=10011
因為-X 會是X的complement+1 造成會有這樣的現象
於是我們可以找到出現1的位置
而這個1 只會屬於A或B其中一個
於是我們把這個1當作是條件再把全部內容作XOR
會得到A或B的某一個數值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | /** * Return an array of size *returnSize. * Note: The returned array must be malloced, assume caller calls free(). */ int* singleNumber(int* nums, int numsSize, int* returnSize) { int *ans=(int *)malloc(2*sizeof(int)); int allxor=0,ANS1=0,ANS2=0; for(int i=0;i<numsSize;i++){ allxor^=nums[i]; } //after for loop, the allxor will have ANS1 XOR ANS2 int flag = allxor & -allxor; for(int i=0;i<numsSize;i++){ if(nums[i]&flag)ANS1^=nums[i]; } ANS2=ANS1^allxor; // becase the ans1 has the anser, ans[0]=ANS1; ans[1]=ANS2; *returnSize=2; return ans; } |
沒有留言:
張貼留言