document.write('
方法一:字典法
 对于本题而言,定义一个字典,把数组元素的值作为key,遍历整个数组,如果key值不存在,则将
value设为1,如果key值已经存在,则翻转该值(如果为0,则翻转为1;如果为1,则翻转为0),在完成
数组遍历后,字典中value为1的就是出现奇数次的数。
 例如:给定数组=[3,5,6,6,5,7,2,2];
 首先遍历3,字典中的元素为:{3:1};
 遍历5,字典中的元素为:{3:1,5:1};
 遍历6,字典中的元素为:{3:1,5:1,6:1};
 遍历6,字典中的元素为:{3:1,5:1,6:0};
 遍历5,字典中的元素为:{3:1,5:0,6:0};
 遍历7,字典中的元素为:{3:1,5:0,6:0,7:1};
 遍历2,字典中的元素为:{3:1,5:0,6:0,7:1,2:1};
 遍历2,字典中的元素为:{3:1,5:0,6:0,7:1,2:0};
 显然,出现1次的数组元素为3和7。
 实现代码如下:
 def get2Num(arr):
 if arr==None or len(arr)<1:
 print "参数不合理"
 return
 dic=dict()
 i=0
 while i<len(arr):
 #dic中没有这个数字, 说明第一次出现, value赋值为1
 if arr[i] notin dic:
 dic[arr[i]]=1
 #当前遍历的值在dic中存在,说明前面出现过,value赋值为0
 else:
 dic[arr[i]]=0
 i+=1
 for k,v in dic.items():
 if v==1:
 print int(k)
 if __name__=="__main__":
 arr=[3,5,6,6,5,7,2,2]
 get2Num(arr)
 程序输出为:
 3
 7
 性能分析:
 这种方法对数组进行了一次遍历,时间复杂度为O(n)。但是申请了额外的存储过程来记录数据出现的
情况,因此,空间复杂度为O(n)。
 方法二:异或法
 根据异或运算的性质不难发现,任何一个数字异或它自己其结果都等于0。所以,对于本题中的数组
元素而言,如果从头到尾依次异或每一个元素,那么异或运算的结果自然也就是那个只出现奇数次的数
字,因为出现偶数次的数字会通过异或运算全部消掉。
 但是通过异或运算,也仅仅只是消除掉了所有出现偶数次数的数字,最后异或运算的结果肯定是那两
个出现了奇数次的数异或运算的结果。假设这两个出现奇数次的数分别为a与b,根据异或运算的性
质,将二者异或运算的结果记为c,由于a与b不相等,所以,c的值自然也不会为0,此时只需知道c对
应的二进制数中某一个位为1的位数N,例如,十进制数44可以由二进制0010 1100表示,此时可取
N=2或者3,或者5,然后将c与数组中第N位为1的数进行异或,异或结果就是a,b中一个,然后用c异
或其中一个数,就可以求出另外一个数了。
 通过上述方法为什么就能得到问题的解呢?其实很简单,因为c中第N位为1表示a或b中有一个数的第
N位也为1,假设该数为a,那么,当将c与数组中第N位为1的数进行异或时,也就是将x与a外加上其他
第N位为1的出现过偶数次的数进行异或,化简即为x与a异或,结果即为b。
 示例代码如下:
 def get2Num(arr):
 if arr==None or len(arr)<1:
 print "参数不合理"
 return
 result=0
 position=0
 #计算数组中所有数字异或的结果
 i=0
 while i<len(arr):
 result=result^arr[i]
 i+=1
 tmpResult=result #临时保存异或结果
 #找出异或结果中其中一个位值为1的位数(如1100,位值为1位数为2和3)
 i=result
 while i&1=0:
 position+=1
 i=i>>1
 i=1
 while i<len(arr):
 #异或的结果与所有第position位为1的数异或,结果一定是出现一次的两个数中其中一个
 if ((arr[i]>>position)&1)==1:
 result=result^arr[i]
 i+=1
 print result,
 #得到另外一个出现一次的数
 print result^tmpResult
 
 if __name__="__main__":
 arr[3,5,6,6,5,7,2,2]
 get2Num(arr)
 程序的运行结果为:
 3 7
 算法性能分析:
 这种方法首先对数组进行了一次遍历,其时间复杂度为O(N),接着找result对应二进制数中位值为1的位数,时间复杂度为O(1),接着又遍历了一次数组,时间复杂度为O(N),因此,这种方法整体的时间复杂度为O(N)。

 

');