我正在尝试解决一个问题:
给出了n个整数数字和目标的数组,找到的数量 索引三胞胎i,j,k,带0< = i<J<K<n满足 条件num [i] nums [j] nums [k]<目标。
例如,给定的nums = [-2、0、1、3],目标= 2。
返回2.因为有两个三重态,总和小于2:
[-2,0,1] [-2,0,3]
我的算法:从列表中删除单个元素,set target = target -number_1,搜索doublets,以便number_1 number _2<目标 - 数字_1。解决问题。
问题链接是https://leetcode.com/problems/3sum-smaller/description/。
我的解决方案是:
def threeSumSmaller(nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: int
"""
nums = sorted(nums)
smaller = 0
for i in range(len(nums)):
# Create temp array excluding a number
if i!=len(nums)-1:
temp = nums[:i] + nums[i+1:]
else:
temp = nums[:len(nums)-1]
# Sort the temp array and set new target to target - the excluded number
l, r = 0, len(temp) -1
t = target - nums[i]
while(l<r):
if temp[l] + temp[r] >= t:
r = r - 1
else:
smaller += 1
l = l + 1
return smaller
我的解决方案失败:
Input:
[1,1,-2]
1
Output:
3
Expected:
1
我没有得到为什么我的解决方案通过30多个测试用例,为什么出错了。
感谢您的帮助。
一个要点是,当您在第一行中对元素进行排序时,您也会丢失索引。这意味着,尽管找到了三胞胎,但您永远不会确定您的(i, j, k)
是否会满足条件1,因为这些(i, j, k)
不是来自原始列表,而是来自新列表。
另外:每次您从数组中间摘下元素时,数组的其余部分也会迭代(尽管以不规则的方式,它仍然从tmp
中的其余元素开始。不应该这样!我正在扩大细节:
该示例在列表上迭代3次(再次是分类,因此您将失去真实的I,J和K索引(:
- 第一迭代(
i = 0, tmp = [1, -2], t = 0
(。当您总和temp[l] + temp[r]
(l, r
为0, 1
(时,它将为-1
。它满足低于t
。smaller
将增加。 - 第二个迭代将就像第一个迭代一样,但使用
i = 1
。再次会增加。 - 第三个也会增加,因为
t = 3
和总和现在为2
。
因此,您将三次计算值(尽管只能按索引顺序形成一个元组(,因为您正在通过索引的置换率迭代而不是组合他们的。因此,您不关心的这两件事:
- 排序时保留索引。
- 确保您仅在前进中迭代索引。
尝试更好地这样:
def find(elements, upper_bound):
result = 0
for i in range(0, len(elements) - 2):
upper_bound2 = upper_bound - elements[i]
for j in range(i+1, len(elements) - 1):
upper_bound3 = upper_bound2 - elements[j]
for k in range(j+1, len(elements)):
upper_bound4 = upper_bound3 - elements[k]
if upper_bound4 > 0:
result += 1
return result
似乎您在数量不止一次 ...
计数相同的三胞胎在循环的第一次迭代中,您省略了列表中的第一个1
,然后通过1
增加smaller
。然后,您省略了列表中的第二个1
,并通过1
再次增加smaller
。最后,您省略了列表中的第三个元素,-2
,当然可以通过1
增加smaller
,因为 - 好吧 - 在所有这三种情况下,您实际上都在考虑 same same same Triplet {1,1,-2}
。<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<</p>
P.S。似乎您更关心正确性而不是性能。在这种情况下,请考虑维护一组解决方案三重态,以确保您不会两次计数相同的三重态。
已经有一个很好的答案,除了您要检查算法结果,您可以在此内构建的功能中获得帮助:
import itertools
def find_(vector_,target):
result=[]
for i in itertools.combinations(vector_, r=3):
if sum(i)<target:
result.append(i)
return result
输出:
print(find_([-2, 0, 1, 3],2))
输出:
[(-2, 0, 1), (-2, 0, 3)]
如果您只需要计数,则:
print(len(find_([-2, 0, 1, 3],2)))
输出:
2