如何用O(nlogn)或O(n)的时间复杂度在python中解决对和问题?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何用O(nlogn)或O(n)的时间复杂度在python中解决对和问题?相关的知识,希望对你有一定的参考价值。
阵列中的对和给定一个随机整数数组A和一个数字x。查找并打印数组中总计为x的一对元素。数组A可以包含重复的元素。打印一对时,请先打印较小的元素。也就是说,如果有效对为(6,5),则打印“ 5 6”。没有限制,必须在第一行中打印出5对。您可以按任何顺序打印对,只需注意成对元素的顺序即可。
输入格式:第1行:整数N(数组大小)第2行:数组元素(以空格分隔)第3行:整数x
输出格式:第1行:成对1元素(以空格分隔)第2行:成对2个元素(以空格分隔)第3行:依此类推
约束:1 <= N <= 10001 <= x <= 100
样本输入:
9
1 3 6 2 5 4 3 2 4
7
样本输出:
(1 6)
(3 4)
(3 4)
(2 5)
(2 5)
(3 4)
(3 4)
我的方法::1.Take 2指针/标记的开始和结束分别指向数组的第一个和最后一个元素:2.对数组-o(nlogn)排序3.开始时
代码:
def pairSum(arr, x):
arr.sort() # nlogn
i = 0
j = len(arr) - 1
while i < j:
if arr[i] + arr[j] > x:
j -= 1
elif arr[i] + arr[j] < x:
i += 1
else: # got the match arr[i] +arr[j] ==x
if arr[i] <= arr[j]:
print(arr[i], arr[j])
if arr[j - 1] == arr[j]:
j -= 1
elif arr[i + 1] == arr[i]:
i += 1
else:
i += 1
j -= 1
else:
print(arr[j], arr[i])
if arr[i + 1] == arr[i]:
i += 1
elif arr[j - 1] == arr[j]:
j -= 1
else:
i += 1
j -= 1
我已经尝试过这个问题,并且它对于唯一元素运行良好,但是对于重复元素则失败,这是因为while循环会尽早终止。请分享您的想法:)
第一:对数组进行排序并获得while i < j:
后,这意味着在第一个else:
中条件if arr[i] <= arr[j]:
始终为真,因此我将其简化。
第二:您的问题是当您有arr[i + 1] == arr[i]
和arr[j - 1] == arr[j]
时。在这种情况下,在您的实现中,您将减小j值,从而导致一对丢失,因此我将为此条件创建一个if。
可能的更正:
#...
else: # got the match arr[i] +arr[j] ==x
print(arr[i], arr[j])
if arr[j - 1] == arr[j] and arr[i + 1] == arr[i]:
print(arr[i], arr[j])
print(arr[i], arr[j])
i += 1
j -= 1
elif arr[j - 1] == arr[j]:
j -= 1
elif arr[i + 1] == arr[i]:
i += 1
else:
i += 1
j -= 1
对于O(n)复杂度,您可以使用字典来收集与匹配总和(即target-n)相对应的数字,并在遍历列表时直接访问它:
numbers = [1, 3, 6, 2, 5, 4, 3, 2, 4]
target = 7
matches = dict()
for n in numbers:
for m in matches.get(n,[]):
print(f"{n} {m}" if n<m else f"{m} {n}")
matches.setdefault(target-n,[]).append(n)
输出:
1 6
2 5
3 4
3 4
2 5
3 4
3 4
请注意,当列表中有重复项时,实际上不可能完全达到O(n),因为要打印的结果数可能成指数增长> n
以上是关于如何用O(nlogn)或O(n)的时间复杂度在python中解决对和问题?的主要内容,如果未能解决你的问题,请参考以下文章
O(1), O(n), O(logn), O(nlogn) 的区别
在 O(nlogn) 时间复杂度中找到总和为 0 的子数组(使用分而治之)?