1、题目
给你一个数组 nums ,数组中的数字 要么 出现一次,要么 出现两次。
请你返回数组中所有出现两次数字的按位 XOR 值,如果没有数字出现过两次,返回 0 。
示例 1:
输入:nums = [1,2,1,3]
输出:1
解释:
nums 中唯一出现过两次的数字是 1 。
示例 2:
输入:nums = [1,2,3]
输出:0
解释:
nums 中没有数字出现两次。
示例 3:
输入:nums = [1,2,2,1]
输出:3
解释:
数字 1 和 2 出现过两次。1 XOR 2 == 3 。
提示:
1 <= nums.length <= 50
1 <= nums[i] <= 50
nums 中每个数字要么出现过一次,要么出现过两次。
2、解
笨方法:统计每个数字出现次数;再将出现2次的数字进行XOR计算得到结果
int duplicateNumbersXOR(vector<int> &nums){int result = 0;unordered_map<int, int> numTimes;for(int &num : nums){numTimes[num]++;}for(auto &[num, time] : numTimes){if(2 == time){result = result ^ num;}}return result;}
进阶
优化版:题目有说1 <= nums[i] <= 50,就可以通过数组索引来表示数字,对应存储的数字表示出现次数节省空间。
int duplicateNumbersXORA(vector<int> &nums){int result = 0;int temp[52] = {0};for(int &num : nums){temp[num]++;}for(int i = 0; i < 52; i++){if(2 == temp[i]){result ^= i;}}return result;}
更优解题思路:位运算。(待仔细学习版)
int duplicateNumbersXORB(vector<int> &nums){int ans = 0;long long vis = 0;for (int x : nums) {if (vis >> x & 1) {ans ^= x;} else {vis |= 1LL << x;}}return ans;}