你好伙伴stackoverflowers,我正在练习我的Python,给我一个例子问题(实际上是谷歌面试练习题)并遇到了一个问题,我不知道如何a)姿势正确(因此模糊的标题),b)克服。
问题是:对于一组数字(给定或随机),在数组中找到唯一的数字对,当求和时给出给定的数字。 E.G:找到数组中的数字对,下面加上6。
[1 2 4 5 11]
所以在上面的例子中:
[1,5] and [2,4]
我写的代码是:
from secrets import *
i = 10
x = randbelow(10)
number = randbelow(100) #Generate a random number to be the sum that we are after#
if number == 0:
pass
else:
number = number
array = []
while i>0: #Generate a random array to use#
array.append(x)
x = x + randbelow(10)
i -= 1
print("The following is a randomly generated array:\n" + str(array))
print("Within this array we are looking for a pair of numbers which sum to " + str(number))
for i in range(0,10):
for j in range(0,10):
if i == j or i>j:
pass
else:
elem_sum = array[i] + array[j]
if elem_sum == number:
number_one = array[i]
number_two = array[j]
print("A pair of numbers within the array which satisfy that condition is: " + str(number_one) + " and " + str(number_two))
else:
pass
如果没有找到对,我想要一行"没有找到对和#34;。我正在考虑尝试/除外,但不确定它是否正确或如何实现它。此外,我不确定如何阻止重复对出现(仅限唯一对),例如,如果我想要22作为总和并拥有数组:
[7, 9, 9, 13, 13, 14, 23, 32, 41, 45]
[9,13] would appear twice
最后请原谅我,如果有冗余/代码没有高效编写,我会慢慢学习,所以任何其他提示都会非常感激!
感谢阅读:)
答案 0 :(得分:0)
您可以简单地添加一个布尔,其中包含“至少找到一对?”的答案。
在代码的开头将其初始化为found = false
。
然后,只要找到一对(包含当前print
命令的条件块),只需添加found = true
。
在所有搜索(双for
循环`)之后,添加:
if not found:
print("No pairs were found")
答案 1 :(得分:0)
您可以只迭代列表一次,从目标编号中减去当前编号,然后查看剩余部分是否在列表中,而不是实际比较每对数字。如果首先将列表转换为set
,则可以在O(1)中完成查找,从O(n²)到O(n)的整体复杂度降低。此外,整个事情可以在列表理解的单行中完成:
>>> nums = [1, 2, 4, 5, 11]
>>> target = 6
>>> nums_set = set(nums)
>>> pairs = [(n, target-n) for n in nums_set if target-n in nums_set and n <= target/2]
>>> print(pairs)
[(1, 5), (2, 4)]
要打印配对或某些消息,您可以使用or
关键字。 x or y
被解释为x if x else y
,因此如果结果集为空,则打印消息,否则结果集自身。
>>> pairs = []
>>> print(pairs or "No pairs found")
No pairs found
更新:如果添加到自身的数字等于目标,则上述情况可能会失败,但仅在集合中包含一次。在这种情况下,您可以使用collections.Counter
代替set
并首先检查该数字的多重性。
>>> nums = [1, 2, 4, 5, 11, 3]
>>> nums_set = set(nums)
>>> [(n, target-n) for n in nums_set if target-n in nums_set and n <= target/2]
[(1, 5), (2, 4), (3, 3)]
>>> nums_counts = collections.Counter(nums)
>>> [(n, target-n) for n in nums_counts if target-n in nums_counts and n <= target/2 and n != target-n or nums_counts[n] > 1]
[(1, 5), (2, 4)]
答案 2 :(得分:0)
2件事:
从2个打印语句开始,我会array = list(set(array))
将问题空间减少到[7, 9, 13, 14, 23, 32, 41, 45]
。
假设所有相关数字都是正数,我会丢弃number
以上的数字。 :
array = [x for x in array if x < number]
给[7, 9, 9, 13, 13, 14]
array
: smaller_array = [x for x in list(set(array)) if x < number]
,提供array == [7, 9, 13, 14]
完成这两个步骤后,你可以做很多事情。我完全清楚我没有回答你的问题,但是从这里你得到了这个。 ^这是我认为谷歌想要看到的那种东西。