今天开始每日一道LeetCode,从AC率最高的开始刷吧,相信几个月下来自己的Algorithm能力会提高不少。
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!于是换了一个思路:
后面就在想相同和不同有什么区别?本科学数电的时候经常这样背到:相同为零不同为一。不同的那个为一,于是我想到了异或,但是一开始的想法是转换成二进制,在一个个异或,最后返回的肯定是那个不同的数字。百度一下异或的基本用法
记得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 有更详细的讨论