Day 1.21
只出现一次的数字(Ⅱ)
题目
思路(1)
同(Ⅰ)遍历后查找,代码完全不变
思路(2)(位运算答案)
引入运算符:
&
按位与运算符:参与运算的两个值,如果两个相应位都为1,则该位的结果为1,否则为0 ;
~
按位取反运算符:将参与运算的数每位取反,1变0,0变1;
定义变量:
seen_once
: 保存出现一次的元素,确保所有三个的元素作用的结果对只出现一次的元素无影响
seen_twice
:保存出现两次的元素
定义运算规则:
seen_once = ~seen_twice & (seen_once ^ x);
seen_twice = ~seen_once & (seen_twice ^ x);
对每一个元素x:
- 第一次出现时,
seen_once
为 0,seen_twice
为 0,导致seen_once
被更新为 x,seen_twice
依旧是 0; - 第二次出现时,
seen_once
被更新为 0,seen_twice
更新为 x; - 第三次出现时,
seen_once
保持为 0,seen_twice
更新为 0;
因此,所有出现三次的元素都不会改变 seen_once
、seen_twice
的值,而仅出现一次的元素x会使得 seen_once
会被更新为x,对 seen_twice
则无影响。所以最终 seen_once
中存储的就是只出现一次的元素。
代码
class Solution {
public int singleNumber(int[] nums) {
int seen_once = 0, seen_twice = 0;
for(int i: nums) {
seen_once = ~seen_twice & (seen_once ^ i);
seen_twice = ~seen_once & (seen_twice ^ i);
}
return seen_once;
}
}