leetCode 137. 只出现一次的数字 II 有其他的题解可看我的往期文章:
关于 leetCode 137. 只出现一次的数字 II,参考灵神的解法做的思路分析:
cpp
0->1->2->0->1->2->...
(0,0)->(0,1)->(1,0)->(0,0)->(0,1)->(1,0)->...
>>分析
其中有大量 0 和 1 之间的转换,可以用异或运算实现
① a=a^1
② b=b^1
方式1:「同时计算」
a = a^x & a|b
b = b^x & (~a)
方式2:「分别计算」
先计算b,再计算a(思路:b在同时计算的时候式子比较简洁,可用新b来参与计算a)
b = b^x & (~a)
a = a^x & (~b)
>>思路和过程分析
(0,0)->(0,1)->(1,0)
(1)先算b:b = b^x & (~a),可得
(0,1)->(0,0)->(1,0)
(2)再算a
(0,1)->(0,0)->(1,0)
// 1.调换位置
(1,0)->(0,0)->(0,1)
// 2.调整画法
(0,0)->(0,1)->(1,0)
// 计算b前的状态转换图
(0,0)->(0,1)->(1,0)
//最后的得到的状态转换图与计算b前的状态转换图是等价的,即若使用计算后的新b,则可以通过相同的公式计算a
a = a^x & (~b)
1.方式1:
cpp
class Solution {
public:
// 模3加法 方法2:用位运算实现
int singleNumber(vector<int>& nums) {
int a=0,b=0;
for(const int& x:nums) {
int tmp_a = a;
a = (a^x) & (a|b);
b = (b^x) & (~tmp_a);
}
return b;
}
};
2.方式2:
cpp
class Solution {
public:
// 模3加法 方法2:用位运算实现
int singleNumber(vector<int>& nums) {
int a=0,b=0;
for(const int& x:nums) {
b = (b^x) & (~a);
a = (a^x) & (~b);
}
return b;
}
};
【灵茶山艾府出的思考题】(137. 只出现一次的数字 II - 力扣(LeetCode)):
- 如果把转换规则改成 0→2→1→0→2→1→⋯ ,对应的代码应该如何修改呢?
- 如果改成除了一个数字出现一次,其余数字均出现 5 次呢?
(1)第一题解法:
cpp
这个是我的解题思路:
// 第一种方法
0 → 2 → 1 → 0 → 2 → 1 → ⋯
(0,0) -> (1,0) -> (0,1) -> (0,0) -> ...
>>分析
其中有大量 0 和 1 之间的转换,可以用异或运算实现
① a=a^1
② b=b^1
(1)先算a,a = a^x & (~b);可得
(1,0) -> (0,0) -> (0,1) -> (1,0) -> ...
(2)再算b
(1,0) -> (0,0) -> (0,1)
// 1.调换位置
(0,1) -> (0,0) -> (1,0)
// 2.调整画法
(0,0)->(1,0)->(0,1)
// 计算a前的状态转换图
(0,0)->(1,0)->(0,1)
// 最后的得到的状态转换图与计算a前的状态转换图是等价的,即若使用计算后的新a,则可以通过相同的公式计算b
b = b^x & (~a);
// 第二种方法
0->1->2->0->1->2->...
(0,0)->(0,1)->(1,0)->(0,0)->(0,1)->(1,0)->...
0 → 2 → 1 → 0 → 2 → 1 → ⋯
(0,0) -> (1,0) -> (0,1) -> (0,0) -> ...
仔细观察这个区别,其实就是a和b调换了,所以可以先计算a,再计算b
a = a^x & (~b);
b = b^x & (~a);
(2)第二题解法:
1.「同时计算」
![](https://file.jishuzhan.net/article/1719792086481375234/7886b3bda40e6568f2e00c06907c8125.webp)
![](https://file.jishuzhan.net/article/1719792086481375234/fba4714be0b6feaa3e55c2c111d03660.webp)
![](https://file.jishuzhan.net/article/1719792086481375234/823ed6c2d50e29f351ca4c0b19013eae.webp)
![](https://file.jishuzhan.net/article/1719792086481375234/e0d96e96f45089f6eb57e4c543fb4821.webp)
化简 b 和 c:
![](https://file.jishuzhan.net/article/1719792086481375234/823ed6c2d50e29f351ca4c0b19013eae.webp)
![](https://file.jishuzhan.net/article/1719792086481375234/ab442db36959efc4c0be708070c2854f.webp)
![](https://file.jishuzhan.net/article/1719792086481375234/74c6aab6a451d08af973df28b6a275ff.webp)
![](https://file.jishuzhan.net/article/1719792086481375234/ca700a0de5c2b57c78e25013dc752410.webp)
![](https://file.jishuzhan.net/article/1719792086481375234/2bcb561139acd3f3f8fa7444127a36e9.webp)
![](https://file.jishuzhan.net/article/1719792086481375234/e0d96e96f45089f6eb57e4c543fb4821.webp)
![](https://file.jishuzhan.net/article/1719792086481375234/f3beb512901aa4ec1e8e62cb81b6e7f2.webp)
![](https://file.jishuzhan.net/article/1719792086481375234/ac5e195161609187ef65c1891c8193c8.webp)
![](https://file.jishuzhan.net/article/1719792086481375234/e010fc2754ed3ae7a21d1b4f013c2192.webp)
![](https://file.jishuzhan.net/article/1719792086481375234/3398bf8ab5d76526d21c911c06332125.webp)
![](https://file.jishuzhan.net/article/1719792086481375234/f73872685de8b37828be29267dfc228b.webp)
cpp
#include <iostream>
#include <vector>
using namespace std;
int singleNumber(vector<int> nums) {
int i, a, b, c, tmpa, tmpb, tmpc;
a = 0;
b = 0;
c = 0;
for (const int& x : nums) {
// 第一种
tmpa = a;
tmpb = b;
tmpc = c;
a = a & ~tmpb & ~tmpc & ~x | ~a & tmpb & tmpc & x;
b = ~tmpa & b & (~tmpc | tmpc) | ~tmpa & x & (b ^ tmpc);
c = ~tmpa & (c ^ x);
}
return c;
}
int main() {
vector<int> nums{3,3,3,3,3,2,2,2,2,2,6,6,6,6,6,4,4,4,10,4,4 };
cout<<"打印结果:"<<singleNumber(nums) << endl;
return 0;
}
2.「分别计算」
发现上面化简 c 后,式子很简洁:
![](https://file.jishuzhan.net/article/1719792086481375234/8f46a77664dabe64ac5b8d6ee02f2278.webp)
![](https://file.jishuzhan.net/article/1719792086481375234/a743aac05d2a64e6404581a6decdc190.webp)
![](https://file.jishuzhan.net/article/1719792086481375234/748d9d12614f9d83f4ecce9995592019.webp)
![](https://file.jishuzhan.net/article/1719792086481375234/d529315cc7c81c549412432571d372f1.webp)
![](https://file.jishuzhan.net/article/1719792086481375234/3f6e1c3f4445dede7f73d4ad481b9d68.webp)
![](https://file.jishuzhan.net/article/1719792086481375234/45fef0323d18675c992f6f3318344d3d.webp)
![](https://file.jishuzhan.net/article/1719792086481375234/4d0e19ab90d5b8b4a1febdd859cd4fef.webp)
![](https://file.jishuzhan.net/article/1719792086481375234/f4d9dcdddcdbfecd5dc61ddf057559c9.webp)
![](https://file.jishuzhan.net/article/1719792086481375234/81ab3892a9d8bfdeb7caf50457ca61ce.webp)
cpp
#include <iostream>
#include <vector>
using namespace std;
int singleNumber(vector<int> nums) {
int i, a, b, c, tmpa, tmpb, tmpc;
a = 0;
b = 0;
c = 0;
for (const int& x : nums) {
// 第二种
c = ~a & (c ^ x);
b = ~a & ~c & (b ^ x) | ~a & b & c;
a = ~b & ~c & (a ^ x);
}
return c;
}
int main() {
vector<int> nums{3,3,3,3,3,2,2,2,2,2,6,6,6,6,6,4,4,4,10,4,4 };
cout<<"打印结果:"<<singleNumber(nums) << endl;
return 0;
}
![](https://file.jishuzhan.net/article/1719792086481375234/d462af42f7ced17b072699e0bd184d0c.webp)
我的解法,不知道是否正确,仅供参考!