Single Number II位运算解析

本题最机巧的O(n)解法最早由1337c0d3r于2013.11.26发布在leetcode。之后看到类似的,都系转载、引用或抄袭。(原文:https://oj.leetcode.com/discuss/857/constant-space-solution)

大多数转载都写得语焉不详,有的甚至据为己有。本帖旨在全面解析该算法。

如下:

int singleNumber(int A[], int n) {
    int ones = 0, twos = 0, threes = 0;
    for (int i = 0; i < n; i++) {
        twos |= ones & A[i];
        ones ^= A[i];
        threes = ones & twos;
        ones &= ~threes;
        twos &= ~threes;
    }
    return ones;
}

只看这几行代码,很难得其要领,如很多人的转载。原文解释如下:

  1. ones as a bitmask to represent the ith bit
    had appeared once.
  2. twos as a bitmask to represent the ith bit
    had appeared twice.
  3. threes as a bitmask to represent the ith bit
    had appeared three times.

When the ith bit had appeared for the third time, clear the ith bit
of both ones and twos to
0. The final answer will be the value of ones.

three计算完之后,要清零ones和twos,这和二进制加法相同。可能还有人觉得难以理解,尤其是第一句:

twos |= ones & A[i]; // ones代表1出现一次的位元,如果A[i]对应位是1则&后为1代表出现两次了,否则为0;结果就是twos中为1的位,表示该位出现两次1

第二句:

ones ^= A[i]; // 出现偶数则为0,出现奇数则为1,本题没有出现偶数的情况,所有ones代表出现1,3,5,……等位;但后面的语句会将其它情况去掉

第三句:

threes = ones & twos;// 相当与三进制加法。

第四、五句:

ones &= ~threes;  //加完之后要清理,如果three为1则ones和twos对应位清0;如果为0,则ones twos和1相与保持不变。
twos &= ~threes;  //这两句处理第二句中Ones其它奇数次情况,即ones如果为大于1的奇数,则此处必然被清0

如果你还不明白该算法,没关系下面还有一段等价的python代码:

class Solution:
# @param A, a list of integer
# @return an integer
def singleNumber(self, A):
    ones=0
    twos=0
    threes=0
    for i in A:
        #(threes&(~i)):if a bit we get three times and it occured in new element, then clear it. (twos&i): if a bit we get twice and it occured again, add to threes.
        threes=(threes&(~i))|(twos&i)

        #the same with threes
        twos=(twos&(~i))|(ones&i) 

        #if a bit occured in odd times and it not in threes, we can sure it occured once
        ones=(ones^i)&(~threes) 

    return ones | twos

解释的很清楚,当然最后一句可以改成return ones,没有任何问题。

位运算的形式大多很简洁,但内涵很丰富,需要字斟句酌方能得其真意。所有的算法必然都是简单的,如果你觉得难以理解,只能说你还没有理解,或者它本身就一堆垃圾。

时间: 2024-10-02 11:34:03

Single Number II位运算解析的相关文章

[LeetCode] Single Number II 位运算

Given an array of integers, every element appears three times except for one. Find that single one. Note:Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory? Hide Tags Bit Manipulation 数组中的数均出现3次,

[LeetCode][JavaScript]Single Number II

Single Number II Given an array of integers, every element appears three times except for one. Find that single one. Note:Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory? https://leetcode.com/

leetCode: Single Number II [137]

[题目] Given an array of integers, every element appears three times except for one. Find that single one. Note: Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory? [题意] 给定一个整数以外,其中除了一个整数只出现一次以外,其他

【leetcode78】Single Number II

题目描述: 给定一个数组,里面除了一个数字,其他的都出现三次.求出这个数字 原文描述: Given an array of integers, every element appears three times except for one. Find that single one. Note: Your algorithm should have a linear runtime complexity. Could you implement it without using extra m

leetcode 刷题之路 84 Single Number II

Given an array of integers, every element appears three times except for one. Find that single one. 给定一个包含n个整数的数组,除了一个数出现一次外所有的整数均出现三次,找出这个只出现一次的整数. 思路,根据数组构成的特点可知,数组中所有数的某一位上1的个数总和为3*n或者3*n+1. 当只出现一次的整数该位为0时,总和为3*n,当只出现一次的整数该位为1时,总和为3*n+1. 因此我们可以计算数

Leetcode 137 Single Number II 仅出现一次的数字

原题地址https://leetcode.com/problems/single-number-ii/ 题目描述Given an array of integers, every element appears three times except for one. Find that single one. 给出一个整数数组,除了某个元素外所有元素都出现三次.找出仅出现一次的数字. Note: 注意: Your algorithm should have a linear runtime co

LeetCode136 Single Number, LeetCode137 Single Number II, LeetCode260 Single Number III

136. Single Number Given an array of integers, every element appears twice except for one. Find that single one. (Easy) Note:Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory? 分析: 第一问属于技巧题,做过就会,

Single Number II ——位操作

题意: 给定两个32位的整数 N 和 M,以及表示比特位置的 i 与 j .编写一个方法,将 M 插入 N,使得 M 从 N 的第 j 位开始,到第 i 位结束.假定从 j 位到 i 位足以容纳M. 输入:N = 10000101000,M = 10011,i = 2, j = 6 输出:N = 10001001100 解题思路 :  根据题意,我们将问题解决分为三个步骤: (1)将 N 中从 j 到 i 之间的位清零: (2)对 M 进行移位操作,M << i (3)合并 M 与 N . 为

LeetCode 137:Single Number II

Given an array of integers, every element appears three times except for one. Find that single one. Note: Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory? Single Number II 比Single Number要复杂的多,