Find Triplets smaller than a given number
我试图解决一个问题,其中:
Given an array of n integers nums and a target, find the number of
index triplets i, j, k with 0 <= i < j < k < n that satisfy the condition nums[i] + nums[j] + nums[k] < target.For example, given nums = [-2, 0, 1, 3], and target = 2.
Return 2. Because there are two triplets which sums are less than 2:
[-2, 0, 1] [-2, 0, 3]
我的算法:从列表中删除一个元素,设置target=target-number_,搜索doublets,使number_+number_ 问题链接是https://leetcode.com/problems/3sum-smaller/description/。 我的解决方案是:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | 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 |
我的解决方案失败:
1 2 3 4 5 6 7 | Input: [1,1,-2] 1 Output: 3 Expected: 1 |
我不明白为什么当我的解决方案通过30多个测试用例时会出现错误。
谢谢你的帮助。
一个要点是,当对第一行中的元素进行排序时,也会丢失索引。这意味着,尽管已经发现了一个三联体,但你永远无法确定你的
另外:每次从数组中间提取元素时,数组的其余部分也会重复(虽然不规则,但它仍然从
该示例在列表上迭代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 。
因此,您将对值进行三次计数(尽管按照索引的顺序只能形成一个元组),因为您正在迭代索引的排列,而不是它们的组合。所以你不关心的两件事是:
- 排序时保留索引。
- 确保只以正向方式迭代索引。
最好这样做:
1 2 3 4 5 6 7 8 9 10 11 | 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 2 3 4 5 6 7 8 | import itertools def find_(vector_,target): result=[] for i in itertools.combinations(vector_, r=3): if sum(i)<target: result.append(i) return result |
输出:
1 | print(find_([-2, 0, 1, 3],2)) |
输出:
1 | [(-2, 0, 1), (-2, 0, 3)] |
如果只想计数,那么:
1 | print(len(find_([-2, 0, 1, 3],2))) |
输出:
1 | 2 |
好像你不止一次的数同一个三倍体…
在循环的第一次迭代中,您省略了列表中的第一个
另外,似乎你更关心的是正确性而不是性能。在这种情况下,考虑维护一组解决方案三元组,以确保不将同一个三元组计数两次。