判断数组元素是否有重复

这个问题看起来很简单,很容易想到以下三种解法:

解法时间空间
两重循环 n 2 n^2 n21
先排序,再遍历 n log ⁡ n n\log n nlogn1
哈希表nn

但如果继续问,还有没有更高效的算法呢?

比如时间复杂度是 O ( n ) O(n) O(n), 空间复杂度为 O ( 1 ) O(1) O(1) 的算法?

😏😏😏

还真有!!

但是对 数组 有几个要求:

  1. 数组元素都是正数
  2. 数组是可写的
  3. 数组元素的最大值小于数组的长度

满足了以上三点。我们就可以使用下面这个算法了

def CheckDuplicates(A):
	for i in range(0, len(A)):
		if(A[abs(A[i])] < 0):
			return abs(A[i])
		else:
			A[abs(A[i])] *= -1
	return None

A = [3, 2, 1, 4, 2, 3]
print(CheckDuplicates(A))  # 2

咱们来看看具体的过程:

循环数组状态
原始 [ 3 , 2 , 1 , 4 , 2 , 3 ] [3, 2, 1, 4, 2, 3] [3,2,1,4,2,3]
i=0把第 A [ 0 ] A[0] A[0]个元素取负, A = [ 3 , 2 , 1 , − 4 , 2 , 3 ] A= [3, 2, 1, -4, 2, 3] A=[3,2,1,4,2,3]
i=1把第 A [ 1 ] A[1] A[1]个元素取负, A = [ 3 , 2 , − 1 , − 4 , 2 , 3 ] A= [3, 2, -1, -4, 2, 3] A=[3,2,1,4,2,3]
i=2把第 A [ 2 ] A[2] A[2]个元素取负, A = [ 3 , − 2 , − 1 , − 4 , 2 , 3 ] A= [3, -2, -1, -4, 2, 3] A=[3,2,1,4,2,3]
i=3把第 A [ 3 ] A[3] A[3]个元素取负, A = [ 3 , − 2 , − 1 , − 4 , − 2 , 3 ] A= [3, -2, -1, -4, -2, 3] A=[3,2,1,4,2,3]
i=4发现第 A [ 4 ] A[4] A[4]个元素已经是负数,说明之前有元素和 A [ 4 ] A[4] A[4] 相同,所以找到了重复元素

上述算法的本质是把原始数组用作计数器,节省了额外的空间,但是要求元素的取值范围在数组的长度范围之内,否则就没法对它计数了。

上述算法实现了时间复杂度是 O ( n ) O(n) O(n), 空间复杂度为 O ( 1 ) O(1) O(1) 的算法,还是非常巧妙滴 🤓

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值