查找小于给定数字的三胞胎



我正在尝试解决一个问题:

给出了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, r0, 1(时,它将为-1。它满足低于tsmaller将增加。
  • 第二个迭代将就像第一个迭代一样,但使用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

最新更新