zoukankan      html  css  js  c++  java
  • leetcode------Single Number II

    标题: Single Number II
    正确率: 34%
    难度: 中等

    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?

     如有疑问请联系我:e-mail:yanghg@pku.edu.cn

    看这题之前还是先看下 Single NumberSingle Number还是好理解的,但是到了升级版就变得很难理解了,这个也反映对了对位操作的薄弱,还是先复习下位操作,

    1、“ & ”  按位与操作。应用场景:清除某些位,或者是取某些位的值,

    2、“ | ” 按位与操作,应用场景:合并数据

    3、“ ^ ”按位异或操作,应用场景:是特定位值取反,示例:a=tmp1,b=tmp2 交换两个值且不引入第三变量,则可以这样处理,a=tmp2^tmp1^tmp1 b=tmp1^tmp2^tmp2,看完3的介绍。 Single Number就感觉它弱爆了。

    回到这个题,对于这个题我其实也是一点想法都没有!我感觉如果把这个题目解决了!那我们对于数列中有只会出现两种类型数:1、出现n个2、只有一个数出现m个。也是能解决的。看我的分析

    假如说现在有一个数组A={3,5,3,3}转换成二进制A’={011,101,011,011}所有可以找到一些规律,同时出现三个数中每一位的1的个数一定是三个,单独的那个一定是一个,那么就用三个变量来存储每1的个数,也就是说,如果发现了一个位上的1到了三个那么就应该进行清零,循环比较一遍后剩下的那个统计1为一个的变量便是要得到的解。

    循环遍历数组每一个位置,“位操作的相加”,迭代操作。

    设定变量:a,b,c=0,0,0;

    a便是统计每一位1的个数,b便是统计出现两个1,c便是统计出现三个,以下为每一次迭代的步骤;

    1、b|=(a&A[i]);

    2、a^=A[i];

    3、c=~(a&b);

    4、a&=c;

    5、b&=c;

     解释:

    1、先处理出现两个1的问题,用a与A[i]进行与操作,用原来是1个1的情况判断该位是否还有1,如果出现A[i]对应的位也是1,则说明该位是个两个1,该位为0,则是一个1,不去处理,最后的结果与b进行或操作,将该位为两个1的情况进行统计。(b的二进制表示:1,则表示该位有两个1,0:则表示该位没有两个1)

    2、用a统计出现该位一个1的数量,(1代表有一个1,0代表没有1,如:a的第一位本身就是1,A[i]的第一位也是一,则不去统计,因为这是b要考虑的事情,两个1的问题),a,A[i]对应位同时为1,则表示有两个1,要进行进位,任何一个为1则要进行置1操作,其他情况为0,刚好符合 异或操作,

    3、统计1出现三次的情况,如果该位已经是现在该位对应的a是1,b是1,则说明该位已经有3个1了,那么A[i]的该位也是1,则需要进行a、b的清零操作,分别用a b与c的取反进行与操作。

    1、用b去统计

    如果看不懂,我来以上述那个A数组为例子进行解释

    A’={011,101,011,011},a=0,b=0c=0

    1、A[0]=011、b=000,a=011,c=000

    2、A[1]=101、b=001,a=110,c=000

    3、A[2]=011、b=011,a=101 出现了ab有相同位为1的情况,c=110

    4、A[2]=011,b=010,a=100,c=110

    5、A[3]=011 b=010 a=111出现了ab有相同位为1的情况,c=101

    6、A[4]=011 b=000 a=101 c=101

    最后发现剩下的a刚好是A'中的单独出现过的那个数字。

    具体看代码:

     1 public class Solution {
     2     public int singleNumber(int[] A) {
     3         int a=0,b=0,c=0;
     4         for(int i=0;i<A.length;i++){
     5             b |= (a & A[i]);
     6             a ^=A[i];
     7             c=~(a&b);
     8             a&=c;
     9             b&=c;
    10         }
    11         return a;
    12     }
    13 }
  • 相关阅读:
    数据仓库的直白概述
    Google准实时数据仓库Mesa(一)
    活动预告丨易盾CTO朱浩齐将出席2018 AIIA大会,分享《人工智能在内容安全的应用实践》
    3招搞定APP注册作弊
    【0门槛】PR稿的自我修养
    Hive中文注释乱码解决方案(2)
    Hive中文注释乱码解决方案
    网易考拉Android客户端网络模块设计
    有运气摇号来不及挑选?网易有数帮你科学选房
    selenium下拉框踩坑埋坑
  • 原文地址:https://www.cnblogs.com/pkuYang/p/4158612.html
Copyright © 2011-2022 走看看