剑指offer第二版-56.2.数组中唯一只出现一次的数字

本系列导航:剑指offer(第二版)java实现导航帖

面试题56.2:数组中唯一只出现一次的数字

题目要求:
在一个整数数组中除了一个数字只出现一次外,其他数字都出现三次。找出那个出现一次的数字。

解题思路:
如果题目中的“三次”换成“两次”,这道题目将非常简单,因此两个相同的数字异或,每一位都会变成0,其实亦或也可以看成两个数字的每一个二进制位对应进行加法后对2取模后的结果。按照这种思路,对于出现三次的数字,改成对3取模即可。举个例子说明下(10,4,5,5,4,4,5):

相关数字对应二进制表示:10 = 1010      4 = 0100     5 = 0101
1)申请一个长度为32(因为int占32bit)的int型数组bitsum,用于记录整型数字每一位出现1的次数。
bitsum = 00000000 00000000 00000000 00000000

2)将每个数字计入到bitsum[]中
10-> 00000000 00000000 00000000 00001010
4 -> 00000000 00000000 00000000 00001110
5 -> 00000000 00000000 00000000 00001211
5 -> 00000000 00000000 00000000 00001312
4 -> 00000000 00000000 00000000 00001412
4 -> 00000000 00000000 00000000 00001512
5 -> 00000000 00000000 00000000 00001613

3)bitsum的每一个元素对3取模:
bitsum = 00000000 00000000 00000000 00001010

4)将bitsum作为一个32bit的整数:
result = 00000000 00000000 00000000 00001010 = 10

代码实现:

package chapter6;

/**
 * Created with IntelliJ IDEA
 * Author: ryder
 * Date  : 2017/8/17
 * Time  : 11:54
 * Description:数组中唯一只出现一次的数字
 * 一个数字出现一次,其他的都出现三次,找到那一个数字
 **/
public class P278_NumberAppearOnce {
    public static int findNumberAppearOnce(int[] data){
        if(data==null ||data.length<3)
            return 0; //为了方便返回0,但其实并不能区分异常
        // 存储一个int(长度32bit)的每个bit的状态
        int[] bitSum = new int[32];
        int k = 3;
        for(int i=0;i<data.length;i++){
            int indexOfBit1 = 1;
            for(int j=31;j>=0;j--){
                if((data[i]&indexOfBit1)!=0)
                    bitSum[j] += 1;
                indexOfBit1<<=1;
            }
        }
        int result = 0;
        for(int i=0;i<32;i++){
            result<<=1; //先移位
            result+=bitSum[i]%k;
        }
        return result;
    }
  
    public static void main(String[] args){
        int[] data1 = new int[]{10,4,5,3,5,4,3,3,4,5};
        int[] data2 = new int[]{0,-4,5,3,5,-4,3,3,-4,5};
        int[] data3 = new int[]{-10,-4,5,3,5,-4,3,3,-4,5};
        System.out.println(findNumberAppearOnce(data1));
        System.out.println(findNumberAppearOnce(data2));
        System.out.println(findNumberAppearOnce(data3));
    }
}

运行结果:

10
0
-10
    原文作者:ryderchan
    原文地址: https://www.jianshu.com/p/258785bdf416#comments
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞