《剑指offer》01&02、数组中的重复数

数组中的重复数

题目要求是输入一个长度为n的数组,含有1至n-1的整数,找出其中的重复数,如果对python熟悉的话,首先就会想到一个重要的函数sorted:

sorted(data, cmp=None, key=None, reverse=False) 

其中,data是待排序数据,可以使List或者iterator, cmp和key都是函数,这两个函数作用与data的元素上产生一个结果,sorted方法根据这个结果来排序。
cmp(e1, e2) 是带两个参数的比较函数, 返回值: 负数: e1 < e2, 0: e1 == e2, 正数: e1 > e2. 默认为 None, 即用内建的比较函数.
key 是带一个参数的函数, 用来为每个元素提取比较值. 默认为 None, 即直接比较每个元素.
通常, key 和 reverse 比 cmp 快很多, 因为对每个元素它们只处理一次; 而 cmp 会处理多次.
一个简单的例子是:

students = [('john', 'A', 15), ('jane', 'B', 12), ('dave', 'B', 10),]  
print(sorted(students, key=lambda student : student[2]))   # sort by age 

>>> [('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]  

在排序完成的前提下,有两个方法可以找出重复数。1是对比前后两个数,直到找到两个相同的数;2是直接对比数与其下标,第一个下标与数字相同的数就是重复数。一开始我没想到后面的方法,因此写得又多又杂……

# offer01-solution 1
def Find_repeat_num(num)
	num = sorted(num)
	p = 0
	for i in range(0, len(num)-1, 1): # 一次遍历找出重复数
    	if num[i+1]-num[i] == 0: 
        	p = 1
    	if num[i+1]-num[i] != 0 and p == 1:
        	print(num[i])
        	p = 0
	if num[len(num)-1] == num[len(num)-2]:
    	print(num[len(num)-1])
    return

num = [int(n) for n in input().split()]
Find_repeat_num(num)

时间复杂度为O(nlogn),空间复杂度是O(1)
如果用下标法就会简洁很多。

# offer01-solution 2
def Find_repeat_num(num)
	num = sorted(num)
	for i in range(0, len(num)-1, 1)
	if num[i] == i:
		print(num[i])
		break
	return
	
num = [int(n) for n in input().split()]
Find_repeat_num(num)

原地修改数组中的重复数

题目要求是原地修改,没有要求不能借助额外的空间,所以只要考虑空间复杂度为O(n)的方法就完事。

# offer02-solution
import numpy as np

def Find_repeat_num2(num)
	p = 0
	pnum = [0 for _ in range(len(num))]
	for i in range(0, len(num)-1, 1):
    	for j in range(i+1, len(num), 1):
        	if num[i] == num[j] and num[i] not in pnum:
            	pnum[p] = num[i]
            	p += 1
            	break
	pnum = np.array(pnum)
	pnum = pnum[(pnum>0)==1]
	print(pnum)

num = [int(n) for n in input().split()]
Find_repeat_num2(num)

讲真写完就不知道自己写了啥,但是代码还是能跑的,而且这里没有sorted。
这里我的时间复杂度是O(n^2),空间复杂度O(n);实际上最优时间复杂度O(n),对应空间复杂度O(n);最优空间复杂度O(1),对应时间复杂度O(nlogn)

参考

numpy中的sorted方法说明

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值