zoukankan      html  css  js  c++  java
  • LeetCode 137. Single Number II

    Given a non-empty 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?

    Example 1:

    Input: [2,2,3,2]
    Output: 3
    

    Example 2:

    Input: [0,1,0,1,0,1,99]
    Output: 99
     
    题目很简单就是数组中所有的数字都出现三次,只有一个数字出现一次,在O(n)的时间复杂度和O(1)的空间复杂度找出这个唯一出现一次的数。
     
    其实我的第一反应是用一个数组记录每一个二进制位出现1的个数,如果不能被3整除,证明所求的数字在该二进制位为1。
     
    思路没问题,但是…………
     & 

    去!你!妹!哦!

     
    相信大家都做过一道面试题,数组中所有的数字都出现两次,只有一个数字出现一次,在O(n)的时间复杂度和O(1)的空间复杂度找出这个唯一出现一次的数。
     
    答案很简单,利用异或的性质,求所有的数字异或和,就是答案。
     
     
    二进制有两个状态,0 和 1 ,刚好可以对应该二进制位 1 出现的次数 % 2 ,如果 %2 = 1 就是我们要求的。
     
    那如果是出现三次,我们想知道的是一位出现 1 的次数 %3 = 1 的位置。而 %3 为出现 0 1 2 很明显一个二进制位是不够用的,只要用两个二进制位就好了。假设这两个数是 a 和 b
     
    ab
    00 -->  0
    01  -->  1
    10  -->  2
     
    a 表示 第二位 b 表示第一位
     
    但是,这样肯定不能简单通过异或来计算了。我们假设有一种运算为@
     
    这样呢 我们只需要
    for x: nums
        ab = ab @ x

    就可以啦~

    至于 @ 这个符号具体该怎么计算啊=。=要通过位运算实现啊(硬凑还是能凑出来的。。。可意会不可言传。。。咳。。。

    [a, b] = [a ^ ((a | b) & x), (~a) & (b ^ x)]

    完整代码:

    var singleNumber = function(nums) {
        let a = 0, b = 0;
        for (let x of nums) {
            [a, b] = [a ^ ((a | b) & x), (~a) & (b ^ x)];
        }
        return b;
    };
  • 相关阅读:
    POJ 2068 Nim#双人dp博弈
    POJ 1678 I Love this Game!#dp博弈
    HDU 3404&POJ 3533 Nim积(二维&三维)
    POJ 3537 Crosses and Crosses(SG/还未想完全通的一道SG)
    POJ 2311 Cutting Game(SG+记忆化)
    POJ 2484 A Funny Game(找规律)
    POJ 2505 A multiplication game(找规律博弈/贪心)
    POJ 2975 Nim(普通nim)
    POJ 2368 Buttons(巴什博弈变形)
    POJ 1704 Georgia and Bob(阶梯博弈+证明)
  • 原文地址:https://www.cnblogs.com/wenruo/p/11020613.html
Copyright © 2011-2022 走看看