mirror of
https://github.com/ShusenTang/LeetCode.git
synced 2024-09-02 14:20:01 +00:00
70 lines
2.3 KiB
Markdown
70 lines
2.3 KiB
Markdown
![]() |
# [137. Single Number II](https://leetcode.com/problems/single-number-ii/)
|
|||
|
# 思路
|
|||
|
这道题是 [136. Single Number](https://leetcode.com/problems/single-number/)的拓展,136的解法就是利用计算机按位储存数字的特性来做的,
|
|||
|
这道题就是除了一个单独的数字之外,数组中其他的数字都出现了三次,由于需要线性复杂度,所以还是要利用位操作。
|
|||
|
|
|||
|
## 思路一
|
|||
|
我们可以建立一个32位的数字,来统计每一位上1出现的个数,我们知道如果某一位上为1的话,
|
|||
|
那么如果该整数出现了三次,对3去余为0,我们把每个数的对应位都加起来对3取余,最终剩下来的那个数就是单独的数字。
|
|||
|
|
|||
|
## 思路二
|
|||
|
将思路一的计数过程也改成位操作将会更简洁。我们用整数one表示出现了1次,two表示出现了2次,当出现3次的时候清零。
|
|||
|
可以列出状态转换表(《数字电路》课程里面貌似叫做真值表)如下:
|
|||
|
|
|||
|
|编号| input | one | two| new_one |new_two| 备注|
|
|||
|
|--| ---| --- | -- |------ |----- | ---|
|
|||
|
|1| 0 | 0 | 0 | 0| 0| |
|
|||
|
|2| 0 | 0 | 1 | 0| 1| |
|
|||
|
|3| 0 | 1 | 0 | 1| 0| |
|
|||
|
|4| 1 | 0 | 0 | 1| 0| |
|
|||
|
|5| 1 | 0 | 1 | 0| 0| 三个1,清零 |
|
|||
|
|6| 1 | 1 | 0 | 0| 1| |
|
|||
|
|
|||
|
注意上表中不可能出现one和two都为1的情况。根据上表我们可以写出状态表达式:
|
|||
|
```
|
|||
|
根据表格第3、4行:
|
|||
|
new_one = [(~input) & one & (~two)] | [input & (~one) & (~two)] = (input ^ one) & (~two)
|
|||
|
|
|||
|
同理根据第2、6行:
|
|||
|
new_two = [(~input) & two & (~new_one)] | [input & (~two) & (~new_one)] = (input ^ two) & (~new_one)
|
|||
|
```
|
|||
|
(学过《数字电路》的同学可能更好理解上述化简过程)
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
# C++
|
|||
|
## 思路一
|
|||
|
``` C++
|
|||
|
class Solution {
|
|||
|
public:
|
|||
|
int singleNumber(vector<int>& nums) {
|
|||
|
int res = 0;
|
|||
|
for(int i = 0; i < 32; i++){
|
|||
|
int count = 0;
|
|||
|
for(int j = 0; j < nums.size(); j++){
|
|||
|
count += ((nums[j] >> i) & 1);
|
|||
|
}
|
|||
|
count %= 3;
|
|||
|
res |= count * (1 << i);
|
|||
|
}
|
|||
|
return res;
|
|||
|
}
|
|||
|
};
|
|||
|
```
|
|||
|
|
|||
|
## 思路二
|
|||
|
``` C++
|
|||
|
class Solution {
|
|||
|
public:
|
|||
|
int singleNumber(vector<int>& nums) {
|
|||
|
int one = 0, two = 0;
|
|||
|
for(auto &num: nums){
|
|||
|
one = (~two) & (one ^ num);
|
|||
|
two = (~one) & (two ^ num);
|
|||
|
}
|
|||
|
return one;
|
|||
|
}
|
|||
|
};
|
|||
|
```
|