Single Number II

https://oj.leetcode.com/problems/single-number-ii/

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?

解题思路:

这道题和Single Number很相像,Single Number是从一堆数字中,找出只出现一次的数字,其他数字都出现两次。根据XOR的性质,A^A = 0,0^A=A,A^B^A=A^A^B=B;从头到尾XOR一次就能找出那个出现一次的数字。

不过这次其他数字都出现三次,就不能用这个方法了。

同样可以考虑用hashmap计数,需要时间复杂度O(n),不过空间复杂度也达到了O(n)。

这里利用XOR的另一个性质。N个数字按位XOR可以看作是,把他们按位十进制相加后,取2的模。那么同样,这个题目就是按位十进制相加后,取3的模。那么出现3次的位就会变为0,即清空了,仅仅剩下出现1次的位数。然后再把他十进制复原出来即可。

以上结论具体可以参见网页:http://www.cs.umd.edu/class/sum2003/cmsc311/Notes/BitOp/xor.html

public class Solution {

    public int singleNumber(int[] A) {

        int[] array = new int[32];

        int signal = 0;

        

        for(int i = 0; i < A.length; i++){

            int temp = A[i] > 0 ? A[i] : -A[i];

            if(A[i] < 0){

                signal = (signal + 1) % 3;

            }

            int j = 0;

            do{

                array[j] += temp % 2;

                temp = temp /2;

                j++;

            }while(temp > 0);

        }

        

        for(int i = 0; i < 32; i++){

            array[i] = array[i] % 3;

        }

        

        int result = 0;

        

        for(int i = array.length - 1; i >= 0 ; i--){

            result = result * 2 + array[i];    

        }

        

        if(signal == 1){

            result = 0 - result;

        }

        return result;

    }

}

 上述的解法没有用到位移的运算,采用/2取余数的方法,在针对都是正数的情况下可以得出结果。对于负数,需要区别对待。那么对于Integer.MIN_VALUE,拿掉符号变成正数就越界了,很难处理。

带着符号的按位右移,可以比较好的解决这个问题,将正负数一起解决了。

public class Solution {

    public int singleNumber(int[] A) {

        int[] array = new int[32];

        int signal = 0;

        

        for(int i = 0; i < A.length; i++){

            //int temp = A[i];

            //int j = 0;

            //do{

              //  array[j] += temp & 1;

                //temp = temp >> 1;

                //if(temp == 0){

                  //  break;

                //}

                //j++;

            //}while(temp > 0);

             for(int j = 0; j < 32; ++j)

             {

                 int rotated = A[i]>>j;

                 if(rotated == 0) 

                    break;

                 array[j] += rotated & 1;

             }

        }

        

        for(int i = 0; i < 32; i++){

            array[i] = array[i] % 3;

        }

        

        int result = 0;

        

        for(int i = 0; i <32 ; i++){

            result += array[i] << i;    

        }

        return result;

    }

}

 

你可能感兴趣的:(number)