題目
Given an array of numbers 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?
中文大意
給定一個數組nums,該數組中只有兩個元素只出現一次,其他元素都是出現兩次的,找出只出現一次的這兩個元素。
分析
(1)在沒有看到大神們的解答之前,我們一般會想到的常規方法就是使用Map類型,其中key爲元素值,value爲元素的個數,但是這樣的效率很低,下面來看看大神的解法。
(2)主要分爲兩步:
a.將數組中的所有元素進行XOR運算,結果爲res,XOR的特性是相同爲0,相異爲1,所以res實際爲數組中那兩個不相同的元素的異或結果,而這個res的二進制中某位值爲“1”,也就意味着這兩個元素的二進制對應位上的值是不同的;
b.雖然得到了兩個不相同元素的異或結果,但是還沒有將這兩個元素徹底區分開,所以我們可以將所有的元素分爲兩組,而分組的標準(這個方法的核心重點)是:先使用res &= -res獲得的res對應二進制中最右邊的“1”的位置,即res &= -res操作完成後,會使res中在原res上最後一個“1”的位置上的值爲1,而其他的全部爲0。res再和nums數組中的所有元素進行“&”操作,nums[i] & res == 0 的爲一組,其他情況爲另一組,然後將兩組數據分別進行異或運算,得到的就是兩個所要求的元素。
java代碼實現
class Solution {
public int[] singleNumber(int[] nums) {
int res = 0;
for(int i = 0; i < nums.length;i++){
res ^= nums[i];
}
res &= -res;
int[] ans = new int[2];
for(int j = 0;j<nums.length;j++){
if((res & nums[j]) == 0){
ans[0] ^= nums[j];
}else{
ans[1] ^= nums[j];
}
}
return ans;
}
}