题目:

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. Javascript软键盘设计

    国内大多数网站的密码在网络传输过程中都是明文的,我们目前正在做的产品也是这样的情形,这正常吗? 大家都偷懒?不重视安全?各人持有观点,有人认为明文传输并不是想象中的那么可怕,事实上正常情况下这些报文你 ...

  2. 1455.Solitaire(bfs状态混摇)

    Solitaire Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total ...

  3. Mac OS 中的 Python(和 NumPy)开发环境设置

    http://www.python()tab.com/html/2013/pythonjichu_1010/582.html ()需要删除

  4. JAVA设计模式 之 观察者模式(JDK内置实现)

    简介:使用JAVA内置的帮你搞定观察者模式. 1. 先把类图放在这里: (1). Observable类追踪所有的观察者,并通知他们. (2). Observer这个接口看起来很熟悉,它和我们之前写的 ...

  5. HTML 5 <input> placeholder 属性

    原文链接:http://www.w3school.com.cn/html5/att_input_placeholder.asp HTML 5 <input> placeholder 属性 ...

  6. Linux搭建一个FTP服务器

    1.安装vsftp 2.配置vsftpd.conf, vim /etc/vsftpd.conf 下面说说里面比较重要的选项 1 anonymous_enable=NO #不允许匿名用户 2 3 loc ...

  7. HDU 2855 斐波那契+矩阵快速幂

    http://acm.hdu.edu.cn/showproblem.php?pid=2855 化简这个公式,多写出几组就会发现规律 d[n]=F[2*n] 后面的任务就是矩阵快速幂拍一个斐波那契模板出 ...

  8. Python自动化之sqlalchemy复合外键

    复合外键用法 metadata = MetaData(engine) classedu = Table('classedu', metadata, # Column('qq', BigInteger, ...

  9. Python自动化之pickle和面向对象初级篇

    pickle模块扩展 1 pickle之文件操作 示例1 with open("test", 'rb') as f: lines = f.readlines() print(pic ...

  10. 《Head First Servlet JSP》学习笔记一