1.題目大意
Given an array of integers, every element appears twice except for one. Find that single one.
Note:
Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory?
給定一個數組的整數,數組中的每個元素都出現了兩次。例外地,有一個元素只出現了一次。找出那個只出現了一次的元素。
要求:算法的時間復雜度應是線性的,不需要額外的存儲空間。
2.思路
縱觀全題,我的第一想法是先排序,然后開始一加一減,最后取絕對值。當然,第一想法都比較幼稚。互相握手的想法就更加不現實了。
第二想法是,先排序,然后相鄰元素對比,例如這樣的思路:
class Solution { public: int singleNumber(vector<int>& nums) { sort(nums.begin(),nums.end()); for(int i=0;i<nums.size();i+=2) if(nums[i]!=nums[i+1]) return nums[i]; return 0; } };
當然,這個思路是可以AC的,但是要考慮到sort()的時間復雜性在C++里面是$O(nlogn)$。雖然在之后的篩查中復雜度是$O(n)$,但在sort()這一步,顯然不算線性了。LeetCode似乎很多時候判的比較松。
這題剛好我是跟另一題一起看的,看完題我就出去吃飯了,另一題剛好用到位運算,…… 呃好像要扯遠了,反正另一種方法就是位運算中的xor。稍微解釋一下的話,就是相同位不同則為1,相同位相同則為0。符號是 ^
比如 11101 ^ 10110 = 01011
在11101和10110中:
第一位都是1,相同位相同,因此結果的第一位為0;
第二位分別是1和0,相同位不同,因此結果的第二位為1。
以此類推。
用這種方法實現的代碼是:
class Solution { public: int singleNumber(vector<int>& nums) { int result=0; for (int i=0;i<nums.size();i++) result= result ^ nums[i]; return result; } };
3.應當注意的地方
這題主要要注意的地方還是出現在第一種實現方法里的。
首先是vector的特性,要用sort()的時候的用法跟一般數組使用的時候不大一樣(具體參見代碼)。
第二點是如果漏了最后一行
return 0;
就會提示warning: control reaches end of non-void function,詳細原因大部分老師應該都提過,就不贅述了。