分列如下:
- 268.Missing Number
- 136.Single Number
- 389.Find the Difference
- 137.Single Number II
- 260.Single Number III
268. Missing Number
https://leetcode.com/problems/missing-number/description/
题目大意
给出[0,n]
中的n-1
个数,让你找出缺失的那一个。
思路
只要用[0:n]跟上面的n-1个数XOR就可以了。
因为两个相同的数XOR会抵消,不影响其他结果。并且XOR满足交换律,与n-1个数的出现顺序无关,因此不需要排序,也没有整形溢出的问题,而且位运算速度还很快。
参考代码
class Solution {
public:
int missingNumber(vector<int>& nums) {
int result = nums.size();
int i=0;
for(int num:nums){
result ^= num;
result ^= i;
i++;
}
return result;
}
};
136. Single Number
https://leetcode.com/problems/single-number/description/
题目大意
给出一个数列,所有的数字都出现两次,只有一个是出现一次的。找出只出现一次的数字
思路
跟上面的MissingNumber一样。
参考代码
class Solution {
public:
int singleNumber(vector<int>& nums) {
int ans = 0;
for(auto num: nums)
ans ^= num;
return ans;
}
};
389. Find the Difference
https://leetcode.com/problems/find-the-difference/description/
题意
与上两题类似,不过是寻找多出的那一个char,而非数字。
参考代码
class Solution {
public:
char findTheDifference(string s, string t) {
char ans = 0;
for(auto c: s)
ans ^= c;
for(auto c: t)
ans ^= c;
return ans;
}
};
137. Single Number II
https://leetcode.com/problems/single-number-ii/description/
题意
给出很多数字,所有都是出现三次,除了有一个只出现一次。
思路
这是Single Number问题的推广。
首先我们必须看到,计算机中,整数是通过二进制来存储的。对于某一个数,如果出现了三次,那么每一个位出现的次数必然是三的倍数。对于某一个位i,计算在所有的数字中出现的次数,取余,就得到这个位在singleNumber的值。
例如,给出3,3,3,2,写成二进制分别是,11,11,11,10。
对于最低位,累加,1+1+1+0=3,在取余得3%3=0,余3是因为这个题目要求从出现3次的数字中寻找出现一次的数字。如果是要求从出现k次的数字中寻找出现一次的,则余k。因此说,这个方法可以推广到任意次数中寻找出现一次的数。
对于最高位,1+1+1+1=4, 4%3=1,因而最高位是1。
从而我们找到了SingleNumber,10,即2。
代码
class Solution {
public:
int singleNumber(vector<int>& nums) {
int count[32] = {0};
for(int i = 0; i < 32; i++){
for(auto num: nums) {
count[i] += (num >> i)&1;
}
count[i] %=3;
count[i] <<=i;
}
int ans = 0;
for(int i = 0; i < 32; i++){
ans |= count[i];
}
return ans;
}
};
260. Single Number III
题意
给出很多数字,所有数字都出现三次,除了两个不相同的数字只出现了一次。找出只出现了一次的两个数字。
解析
关键在于区分出这两个只出现一次的数。
下面这个链接解释得很好。
https://segmentfault.com/a/1190000004886431