题目:

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. 认识ATL窗口

    这是一个相当于“Hello world!”的任务,作为认识ATL,考查了其运作流程与机制. 环境:VS2008 创建:新建-项目-Win32项目-添加公用头文件用于(选择ATL). PS:注意新建项目 ...

  2. jQuery框架分析第一章: 第一个匿名函数

    我的jQuery版本为1.7* 这个版本代码比之前的版本优化了很多,结构也清晰了不少,就用最新的吧. 打开jQuery源代码 首先你能看到所有代码被一个 (function(window,undefi ...

  3. Android手机如何通过USB共享网络给Mac?

    最近网络挂了,mac不能上网查资料,心情非常毛躁,急切寻求用mac蹭WiFi的方法. 没有找到电脑端破解WiFi密码的软件,手头的Android手机没有root,也无法查看WiFi密码--->破 ...

  4. Flash相册-------3D旋转应用

    1.图层一,图片1,转换为元件 2.3D旋转工具,变形--->y->180

  5. nginx反向代理proxy模块相关参数

    http_proxy_module Proxy_pass proxy_pass指令属于ngx_http_proxy_module模块,此模块可以将请求转发到另一台服务器:官方说明:http://ngi ...

  6. Code First03---CodeFirst根据配置同步到数据库的三种方式

    上一节我们说到使用Fluent API对实体的配置,但是有一个问题了,在业务中我们可以用到的实体很多,那是不是每个都需要这样去配置,这样就造成我们重写的OnModelCreating方法很庞大了.所以 ...

  7. 原生态js,鼠标按下后,经过了那些单元格

    本来是要判断那些单元格被选中,结果发现行不通,只能判断鼠标按下后,经过了那些单元格 之所以发出来,是觉得案例还有很多有意思的地方 onmouseover  的持续触发,导致了很多重复元素 由于将事件绑 ...

  8. ii7安装php

    http://www.jb51.net/article/22372.htm 我们知道php配置有几种: 1.CGI方式加载PHP环境,通常就是IIS里面配置解释器为php.exe,早期比较常见,目前使 ...

  9. JAVA序列化的作用

    所谓的Serializable,就是java提供的通用数据保存和读取的接口.至于从什么地方读出来和保存到哪里去都被隐藏在函数参数的背后了.这样子,任何类型只要实现了Serializable接口,就可以 ...

  10. Android--多线程之Handler

    前言 Android的消息传递机制是另外一种形式的“事件处理”,这种机制主要是为了解决Android应用中多线程的问题,在Android中不允许Activity新启动的线程访问该Activity里的U ...