[LeetCode] 137. Single Number II (位操作)
Description
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?
思路
题意:给定一个数组,其中有一个数出现一次,其他数出现三次,要求在时间复杂度为O(n)空间复杂度为O(1)的条件下,找出这个出现一次的数。
题解:
方法一:因为除了一个数外,其他每个数都出现三次,因此枚举每一位二进制位,统计每一位上这些数为1的数总共有多少个,然后与3相模,如果余1,证明这个出现一次的数的二进制在这位上为1。(此法是通用方法,适用于除一个数外,其他数出现k次,那么只需模k即可)
class Solution {
public:
//12ms
int singleNumber(vector<int>& nums) {
int res = 0;
for (int i = 0;i < 32;i++){
int cnt = 0;
int mask = 1 << i;
for (int j = 0;j < nums.size();j++){
if (nums[j] & mask){
cnt++;
}
}
if (cnt % 3){
res |= mask;
}
}
return res;
}
};
方法二:用两个变量记录所有数二进制位中哪些位为1出现一次,哪些二进制位为1出现两次,之所以只需两个,是因为同一个数最多只出现三次,因此我们可以选定状态 00 -> 01 -> 10来记录,那么我们用ones表示哪些位为1出现一次(模3后出现一次),用twos表示哪些位为1出现两次(模3后出现一次),当ones和twos某一二进制位上同时为1说明这位为1出现了三次,那么我们此时将ones和twos的这位二进制位清0,最后ones就是答案。
class Solution {
public:
//9ms
int singleNumber(vector<int>& nums) {
int ones = 0,twos = 0,threes = 0;
for (unsigned int i = 0;i < nums.size();i++){
//以下两句代码不能颠倒次序,如若颠倒,则一个数先记录于ones,
//然后twos的值依赖于ones及这个数,那么这个数就被统计了两次
twos |= (nums[i] & ones); //记录有哪些二进制位为1且出现两次存于twos
ones ^= nums[i]; //记录有哪些二进制位为1且出现一次存于ones
//以下三句是清零操作
threes = ones & twos;
ones &= ~threes;
twos &= ~threes;
}
return ones;
}
};
另外,方法二代码可精简如下:ones与twos的含义与上述相同。
class Solution {
public:
//9ms
int singleNumber(vector<int>& nums) {
int ones = 0,twos = 0;
for (unsigned int i = 0;i < nums.size();i++){
//ones&~twos以及twos&~ones都是为了清零操作,两者二进制位都为1时清零
ones = (ones ^ nums[i]) & (~twos);
twos = (twos ^ nums[i]) & (~ones);
}
return ones;
}
};
┆ 凉 ┆ 暖 ┆ 降 ┆ 等 ┆ 幸 ┆ 我 ┆ 我 ┆ 里 ┆ 将 ┆ ┆ 可 ┆ 有 ┆ 谦 ┆ 戮 ┆ 那 ┆ ┆ 大 ┆ ┆ 始 ┆ 然 ┆
┆ 薄 ┆ 一 ┆ 临 ┆ 你 ┆ 的 ┆ 还 ┆ 没 ┆ ┆ 来 ┆ ┆ 是 ┆ 来 ┆ 逊 ┆ 没 ┆ 些 ┆ ┆ 雁 ┆ ┆ 终 ┆ 而 ┆
┆ ┆ 暖 ┆ ┆ 如 ┆ 地 ┆ 站 ┆ 有 ┆ ┆ 也 ┆ ┆ 我 ┆ ┆ 的 ┆ 有 ┆ 精 ┆ ┆ 也 ┆ ┆ 没 ┆ 你 ┆
┆ ┆ 这 ┆ ┆ 试 ┆ 方 ┆ 在 ┆ 逃 ┆ ┆ 会 ┆ ┆ 在 ┆ ┆ 清 ┆ 来 ┆ 准 ┆ ┆ 没 ┆ ┆ 有 ┆ 没 ┆
┆ ┆ 生 ┆ ┆ 探 ┆ ┆ 最 ┆ 避 ┆ ┆ 在 ┆ ┆ 这 ┆ ┆ 晨 ┆ ┆ 的 ┆ ┆ 有 ┆ ┆ 来 ┆ 有 ┆
┆ ┆ 之 ┆ ┆ 般 ┆ ┆ 不 ┆ ┆ ┆ 这 ┆ ┆ 里 ┆ ┆ 没 ┆ ┆ 杀 ┆ ┆ 来 ┆ ┆ ┆ 来 ┆

浙公网安备 33010602011771号