题目:

Given an array of integers, every element appears three times except for one. Find that single one.

Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory?

代码:

这个题目就一句话,看到后肯定会想到很多解决办法,但是:不能用更多的存储空间;还提示要用bit操作。

首先,我尝试了一下一般人都能想到的办法,就是排序之后挑出来前后都不一样的:

public int singleNumber_old(int[] nums) {       
        if (nums==null) {
            return 0;
        }
        if (nums.length==1) {
            return nums[0];
        }
        sort_bubbling(nums);
        if (nums[0] != nums[1]) {
            return nums[0];
        }
         if (nums[nums.length-1] != nums[nums.length-2]) {
            return nums[nums.length-1];
        }
        for (int i = 1; i < nums.length-1; i++) {
            if(nums[i]!=nums[i-1]&&nums[i]!=nums[i+1]) {
                return nums[i];
            }
        }
        return 0;
    }
    public void sort_bubbling(int[] nums) {
        for(int i = 0; i < nums.length; i++) {
            for(int j = 0; j < nums.length-i-1; j++) {
                if(nums[j]>nums[j+1]) {
                    int temp = nums[j];
                    nums[j] = nums[j+1];
                    nums[j+1] = temp;
                }
            }
        }
    }

放进去后,不出所料的超时了,系统用了一串复制都复制不下的数字去测试~哎...

数了下,居然用了20002个这种大数字在测试~~~太暴力了!

有点懵逼啊!bit操作一直有点晕,百度了一下,原来这个算法很成熟了:

  这串int型的数字,变成二级制就是16位的0和1。

  由于每个数字都有三个,所以在每一个bit位上面无论是0还是1,都是3的倍数个,如果不是,说明这一位就是那个单个数字产生的。

  当然,我们只要看他产生的1在哪些位置上面,剩下的自然就是0的位置,然后就可以得出这儿数字。

  3个0或3个1相加之后对3取余都应该为0,因此取余不为1的位数组合起来就是那个 “Single Number”。

一个直接的实现就是用大小为 32的数组来记录所有 位上的和:

public int singleNumber(int[] nums) {       
        int[] count = new int[32];
        int result = 0;
        for (int i = 0; i < 32; i++) {
            for (int j = 0; j < nums.length; j++) {
                if (((nums[j] >> i) & 1)>0) {
                    count[i]++;
                }
            }
            result |= ((count[i] % 3) << i);
        }
        System.out.println(Integer.toBinaryString(result));
        return result;
    }

这个算法还不是最好了,百度到还有大神用掩码变量,我这里拷贝过来,供我们一起学习:)

这个算法是有改进的空间的,可以使用掩码变量:

  1. ones   代表第ith 位只出现一次的掩码变量
  2. twos  代表第ith 位只出现两次次的掩码变量
  3. threes  代表第ith 位只出现三次的掩码变量

假设在数组的开头连续出现3次5,则变化如下:

ones = 101
twos = 0
threes = 0
--------------
ones = 0
twos = 101
threes = 0
--------------
ones = 0
twos = 0
threes = 101
--------------

当第 ith 位出现3次时,我们就 ones  和 twos  的第 ith 位设置为0. 最终的答案就是 ones。

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];// 异或3次 和 异或 1次的结果是一样的
       //对于ones 和 twos 把出现了3次的位置设置为0 (取反之后1的位置为0)
        threes = ones & twos;
        ones &= ~threes;
        twos &= ~threes;
    }
    return ones;
}

参考:http://oj.leetcode.com/discuss/857/constant-space-solution

Single Number II的更多相关文章

  1. 【leetcode】Single Number && Single Number II(ORZ 位运算)

    题目描述: Single Number Given an array of integers, every element appears twice except for one. Find tha ...

  2. 【题解】【位操作】【Leetcode】Single Number II

    Given an array of integers, every element appears three times except for one. Find that single one. ...

  3. [OJ] Single Number II

    LintCode 83. Single Number II (Medium) LeetCode 137. Single Number II (Medium) 以下算法的复杂度都是: 时间复杂度: O( ...

  4. Single Number,Single Number II

    Single Number Total Accepted: 103745 Total Submissions: 218647 Difficulty: Medium Given an array of ...

  5. leetcode 之 Single Number II

    问题来源:Single Number II 问题描述:给定一个整数数组,除了一个整数出现一次之外,其余的每一个整数均出现三次,请找出这个出现一次的整数. 大家可能很熟悉另一个题目(Single Num ...

  6. 【leetcode78】Single Number II

    题目描述: 给定一个数组,里面除了一个数字,其他的都出现三次.求出这个数字 原文描述: Given an array of integers, every element appears three ...

  7. leetcode 136. Single Number 、 137. Single Number II 、 260. Single Number III(剑指offer40 数组中只出现一次的数字)

    136. Single Number 除了一个数字,其他数字都出现了两遍. 用亦或解决,亦或的特点:1.相同的数结果为0,不同的数结果为1 2.与自己亦或为0,与0亦或为原来的数 class Solu ...

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

    原题地址https://leetcode.com/problems/single-number-ii/ 题目描述Given an array of integers, every element ap ...

  9. 【LeetCode】137. Single Number II (3 solutions)

    Single Number II Given an array of integers, every element appears threetimes except for one. Find t ...

  10. LeetCode 137. Single Number II(只出现一次的数字 II)

    LeetCode 137. Single Number II(只出现一次的数字 II)

随机推荐

  1. 将json返回的日期格式转换

    <script>         function ChangeDateFormat(cellval) {             var date = new Date(parseInt ...

  2. mysql-mysql优化

    mysql数据库优化1.查询优化 (1)避免where 子句中对字段进行 null 值判断 (2)避免在 where 子句中使用 or 来连接条件 (3)少使用like,如果要用可以考虑全文检索 (4 ...

  3. C/C++多种方法获取文件大小(转)

    源码下载:点击下载 源码如下: #include <iostream> #include <io.h> #include <sys\stat.h> #include ...

  4. sass兼容IE8透明度方法

    你可以轻松的利用 {Sass::Script::Functions#ie_hex_str ie_hex_str} 函数对其做转换.$translucent-red: rgba(, , , 0.5); ...

  5. JavaScript判断图片是否加载完成的三种方式

    JavaScript判断图片是否加载完成的三种方式 有时需要获取图片的尺寸,这需要在图片加载完成以后才可以.有三种方式实现,下面一一介绍. 一.load事件 1 2 3 4 5 6 7 8 9 10 ...

  6. 高性能Java网络框架 MINA

    Apache MINA(Multipurpose Infrastructure for Network Applications) 是 Apache 组织一个较新的项目,它为开发高性能和高可用性的网络 ...

  7. HDU 5014 Number Sequence(位运算)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5014 解题报告:西安网赛的题,当时想到一半,只想到从大的开始匹配,做异或运算得到对应的b[i],但是少 ...

  8. nhibernat4.0.0.4000 bug

    //类 NHibernate.Loader.Loader 中 protected virtual string[] ResultRowAliases { get { return null; } } ...

  9. Linus爱GPL 但不喜欢GPL诉讼

    导读 在上周多伦多举行的LinuxCon NA会议上,Linus Torvalds 和 VMware 副总裁 Dirk Hohndel讨论了 GNU GPL 在 Linux 成功上所起的作用.Hohn ...

  10. Google在三大系统上停止对Chrome Apps的支持

    近年来凭借着低廉的价格和易于管理和追踪的特性,Chrome OS设备逐渐获得了市场的肯定.只是相比较Windows和macOS桌面系统来说,Chrome OS在应用方面依然存在劣势,为此三年前Goog ...