给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
说明:
你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?
示例 1:
输入: [2,2,1] 输出: 1
示例 2:
输入: [4,1,2,1,2] 输出: 4
方法1:泛型算法暴力解决
代码:
class Solution1 { public: int singleNumber(vector<int> &nums) { for (auto it = nums.begin(); it != nums.end(); it++) if (count(nums.begin(), nums.end(), *it) == 1) //使用泛型算法的count return *it; return 0; } };
方法2:循环暴力解决
代码:
class Solution2 { public: int singleNumber(vector<int> &nums) { int i, j, cur; int len = nums.size(); for (i = 0; i < len; i++) { cur = nums[i]; for (j = 0; j < len; j++) //寻找数组后面是否存在相同数字 { if (j == i) continue; if (cur == nums[j]) break; } if (j == len) return cur; } return -1; } };
以上两种方法是常规做法,很容易想到,但不满足题目的线性时间复杂度
方法3:位异或运算符
异或:相同的二进制位进行位异或之后结为0,不同的二进制位进行位异或后结果为1
1. a ⊕ a = 0
2. a ⊕ b = b ⊕ a
3. a ⊕b ⊕ c = a ⊕ (b ⊕ c) = (a ⊕ b) ⊕ c;
4. d = a ⊕ b ⊕ c 可以推出 a = d ⊕ b ⊕ c.
5. a ⊕ b ⊕ a = b.
a⊕0=a,
a⊕a=0,
a⊕b⊕a=(a⊕a)⊕b=0⊕b=b
因此可以将每个数都进行位异或运算,最后得到的数就是只出现一次的数
class Solution3{ public: int singleNumber(vector<int> &nums){ int num=0; for(int i=0;i<nums.size();i++) num^=nums[i]; return num; } };
时间复杂度为O(n),只需要遍历一次数组,空间复杂度为O(1)
浙公网安备 33010602011771号