136. Single Number
Given an array of integers, every element appears twice except for one. Find that single one. (Easy)
Note:
Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory?
分析:
第一问属于技巧题,做过就会,没做过很难想。考虑异或操作,相同数异或之后为0, 0与一个数异或还是这个数本身,且异或操作满足交换律和结合律。
所以这个题将所有的数异或起来,就能得到那个落单的数。
代码:
class Solution {
public:
int singleNumber(vector<int>& nums) {
int result = ;
for (int i = ; i < nums.size(); ++i) {
result ^= nums[i];
}
return result;
}
};
137. Single Number II
Given an array of integers, every element appears three times except for one. Find that single one. (Medium)
Note:
Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory?
分析:
除了“单身狗”以外其他元素均出现了三次,考虑上一题中的异或的思想(不进位加法,两个1之后就变成0),推广到三个数,就是有一位1如果出现三遍,就应该抵消为0;
所以可以考虑建立一个32个元素数组表示int的各个位置,然后把每个数的每一位对应加进去,mod 3后的结果恢复成一个数即为结果。
代码:
class Solution {
public:
int singleNumber(vector<int>& nums) {
int bitArray[];
memset(bitArray, , sizeof(bitArray));
int result = ;
for (int i = ; i < ; ++i) {
for (int j = ; j < nums.size(); ++j) {
bitArray[i] += (nums[j] >> i & );
}
bitArray[i] %= ;
result |= (bitArray[i] << i);
}
return result;
}
};
260. Single Number III
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. (Medium)
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?
分析:
有两个单身狗,其他都是出现两次。考虑怎么把这个问题转化为single number1的问题。
利用1中的思路,先把所有的数异或,最后可以得到一个数。可以知道这个数(xorResult)是那两个单身狗异或的结果,但是我们无法从这个数恢复两个数本身。
但是我们可以xorResult中第一个1出现的位置,这个位置是1说明之前两个数在这一位不同(一个0,一个1);
于是我们可以把原数组中的元素这一位是0还是1分为两个数组,这两个数组便都是single number1的问题,最后把两个结果添加到vector返回。
代码:
class Solution {
public:
vector<int> singleNumber(vector<int>& nums) {
int xorResult = ;
for (int i = ; i < nums.size(); ++i) {
xorResult ^= nums[i];
}
int lastBitofOne = xorResult - (xorResult & (xorResult - ) );
int result1 = , result2 = ;
for (int i = ; i < nums.size(); ++i) {
if ( (nums[i] & lastBitofOne) == ) {
result1 ^= nums[i];
}
else {
result2 ^= nums[i];
}
}
vector<int> result{result1, result2};
return result;
}
};