您的位置:首页 > 编程语言 > Python开发

python练习

2015-08-25 14:42 615 查看
题目1:一个正整数数组,有2个数只出现了一次,其他的数都出现了2次,求出这2个只出现了一次的数。要求算法复杂度为O(n),空间复杂度为O(1)

思路:所有数相异或,出现2次的数消掉了,剩下的是出现1次的2个数相异或的结果,结果的为1的位表示这2个数的差异位。

比如list_t=[1,2,3,8,4,4,3,1,5,5],所有数相与的结果为‘0b1010’,2与8在第二位和第4位是不相同的。

将数组分成2部分,所有第4位为1的为一组,为0的在另一组。那么那2个只出现一次的数必然分开在了2边,而且相同的2个数也必然在同一边。

那么每一边都只会出现一个单独的数,对两边分别求异或,就可以得出单独的数。

#一个数组,有2个数只出现了一次,其他数都出现了2次,求出这2个数
import math

def findone(list_t,first_num,second_num):
r=list_t[0]
for i in list_t[1:len(list_t)]:    #这样求出了只出现一次的2个数之间的差异
r=r^i
#接下来要找到这2个数其中一个差异位
str_r=bin(r)[2:len(bin(r))]      #把r转换为二进制形式。bin()将十进制整数转换为二进制字符串,前面有0b.
r=int(math.pow(2,len(str_r)-1))
m=0                              #用于分成两类的指针
n=len(list_t)-1
while(m<n):                      #把数组中的数分成2类。一类是所有的数在位b上为1,另一类是不为1.这两个不同的数一定分开在这两边了
while(list_t
&r!=0):
n=n-1
temp=list_t
#第一个b位为1的数,存储在temp中
while(m<n and list_t[m]&r==0):
m=m+1
list_t
=list_t[m]          #第一个b为不为1的数,移到前面,把temp中的数移到后面
list_t[m]=temp
print m                           #m表示的是最后一个b位不为1的数
print list_t
first=list_t[0]
second=list_t[m+1]
for i in list_t[1:m+1]:              #两个相同的数一定会在同一边,只分别出现一次的数一定分开在了两边。对这两边分别相与,可以得出出现一次的数
first^=i
for i in list_t[m+2:len(list_t)]:
second^=i
return first,second

first_num=0
second_num=0
list_t=[1,2,3,8,4,4,3,1,5,5,8,7]
first_num,second_num=findone(list_t,first_num,second_num)   #注意python可以一次返回多个值,多次赋值。python中的引用概念不强
print "first_num:%d" %first_num
print "second_num:%d" %second_num

#for i in range(1,len(str_r)):  #提取r的首位为1,其他为0。表示这两个数在某一个位b上不相同
#str_r[i]='0'     #字符串不支持按位幅值
#r=int(str_r,2)


几个注意的python语法:

1.bin(x) 将整数转换为二进制字符串,前面有0b字符,要去掉
2.math.pow(x,y)求x的y次幂
3.for i in range(1,len(str_r)):  注意range的写法
4.字符串不支持按位幅值
5.注意python可以一次返回多个值,调用时可采用多参数赋值。python中的引用概念不强
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: