今天开始每日一道LeetCode,从AC率最高的开始刷吧,相信几个月下来自己的Algorithm能力会提高不少。

LeetCode ----Single Number 找出与众不同的数_LeetCode

Single Number

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

Note:

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


题意:给出一个×××数组,里面每个数字都出现了两次,只有一个出现了一次,找出这个数字。


一开始没注意Note,当时的想法是建一个bitmap数组,memset全部置0,然后从让第一个数与后面的所有的数遍历,相同的话,这一位就置1,然后开始试验第二个数,O(N^2)后为0的bimap组员就是那不同的数字。


class Solution {
public:
    int singleNumber(int A[], int n) {
        int i,j;
        bool bitmap[n];
        memset(bitmap,0,sizeof(bitmap));
        for(i=0;i<n;i++)
            for(j=i+1;j<n;j++)
                if(A[i] == A[j])
                    bitmap[i]=bitmap[j]=1;//相同的数,位图数组中置1
        for(i=0;i<n;i++)
            if(0 == bitmap[i]) //位图数组中为0的就是那个与众不同的数字
            return A[i];      
    }
};


结果显而易见,LTE!于是换了一个思路:

后面就在想相同和不同有什么区别?本科学数电的时候经常这样背到:相同为零不同为一。不同的那个为一,于是我想到了异或,但是一开始的想法是转换成二进制,在一个个异或,最后返回的肯定是那个不同的数字。百度一下异或的基本用法LeetCode ----Single Number 找出与众不同的数_LeetCode_02

记得CCASP (深入理解计算机系统)第二章还是第三章,里面有对异或的精妙解释,大家有机会可以去翻翻。


后面写好后,想到不需要转换为二进制,直接异或就可以了,因为系统会内部进行0,1的与运算或运算。

好了 后面贴代码,非常小巧。

class Solution {
public:
    int singleNumber(int A[], int n) {
       int one,i;
       for(one=0,i=0;i<n;i++)
            one ^= A[i];//最后one的值肯定是那个与众不同的数字
        return one;
    }
};


PS:知乎。http://www.zhihu.com/question/19659409 有更详细的讨论