136. Single Number
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?
Subscribe to see which companies asked this question.
题意解析:
给一组数,除了一个数字外,每个数字都出现两次,求其中只出现了一次的数字。
解题思路:
- 原本考虑简单的按照数字的值建立哈希表,但用了一下超过内存限制,应该还是使用map,按照value,count的方式去存储,然后遍历map,获得count为1的那个value。
- 又想到除了一个数字外,每个数字都出现两次,那么可以用一个集合,维护当前只出现一次的数字,当发现再次遇到这个数字,就从集合里面删掉这个数字,这样遍历一边就只剩下那个只出现了一次的数字了,不过这样也需要使用O(n)大小的内存。
- 最后查看参考答案,原来对每个元素使用XOR操作即可解决问题。每个数字和自己做XOR得到0,而0和一个数字XOR得到该数字。又因为XOR操作满足算术中的交换律和结合律,所以计算的顺序可以不用考虑。
//维护一个当前只出现了一次的集合
class Solution {
public:
int singleNumber(vector<int>& nums) {
set<int> current;
for(int i = 0; i < nums.size();i++) {
if(current.count(nums[i])!=1) {
current.insert(nums[i]);
}else{
current.erase(nums[i]);
}
}
return *current.begin();
}
};//异或
class Solution {
public:
int singleNumber(vector<int>& nums) {
int number = 0;
for(int i = 0; i < nums.size();i ++) {
number = number xor nums[i];
}
return number;
}
};137. Single Number II
Given an array of integers, every element appears three times except for one, which appears exactly once. Find that single one.
Note:
Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory?
题意解析:
给一组数,除了一个数字外,每个数字都出现三次,求其中只出现了一次的数字。
解题思路:
- 类似上题思路,改成保存出现了一次和出现了两次的两个集合。
- 一个int类型为32位二进制数,那么对于每一位上的数进行求和,如果出现了三次则可以模除3,那么正好得到了只出现了一次的数字。
//出现了一次once和出现了两次twice的两个集合。
class Solution {
public:
int singleNumber(vector<int>& nums) {
set<int> twice;
set<int> once;
for(int i = 0; i<nums.size(); i++) {
int a = nums[i];
if(twice.count(a)== 1) {
twice.erase(a);
} else if(once.count(a)==1) {
twice.insert(a);
once.erase(a);
} else {
once.insert(a);
cout<<a;
}
}
return *once.begin();
}
};//使用位运算
class Solution {
public:
int singleNumber(vector<int>& nums) {
vector<int> bits(32);
int result = 0;
for(int i = 0; i<32; i++) {
for(int j = 0; j < nums.size(); j++) {
if((nums[j]>>i) & 1) {
bits[i]++;
}
}
result |= ((bits[i]%3) << i);
}
return result;
}
};Bit Manipulation(位运算):
一共五种运算:与,或,异或,左移,右移。
常用技巧:
- n & (n-1)能够消灭n中最右侧的一个1。
- 右移:除以2, 左移:乘以2。
- 异或性质:交换律,0^a=a, a^a=0;
- 将常用字符、数字等均转为按位运算,可以节约空间。
版权声明:本文为u013775900原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。