📌  相关文章
📜  计算具有[a,b]范围之和的数组中的三元组数(1)

📅  最后修改于: 2023-12-03 14:57:28.061000             🧑  作者: Mango

计算具有[a,b]范围之和的数组中的三元组数

在一个给定的整型数组nums中,找到所有满足条件a≤nums[i] + nums[j] + nums[k]≤b的三元组 (i, j, k) ,并返回它们的数量。

方法

我们可以使用双指针法,将数组nums排序,然后固定i,枚举j和k。由于数组已经排序,我们可以根据nums[i]+nums[j]+nums[k]与范围[a,b]的大小关系来移动指针j和k。具体步骤如下:

  1. 对数组nums进行排序。
  2. 初始化满足条件的三元组数量res为0。
  3. 枚举i从0到n-2,其中n为数组的长度。
  4. 对于固定的i,使用双指针j和k,初始值分别为i+1和n-1。
  5. 当j<k时,如果满足条件a≤nums[i]+nums[j]+nums[k]≤b,则计数器res加1,指针j向右移动一位,并跳过重复的元素;否则,如果nums[i]+nums[j]+nums[k]>b,则指针k向左移动一位;如果nums[i]+nums[j]+nums[k]<a,则指针j向右移动一位。
  6. 返回计数器res的值。

时间复杂度:O(n2)。

代码实现
def threeSumBetween(nums, a, b):
    n = len(nums)
    nums.sort()
    res = 0
    for i in range(n-2):
        j, k = i+1, n-1
        while j < k:
            if a <= nums[i]+nums[j]+nums[k] <= b:
                res += 1
                j += 1
                while j < k and nums[j] == nums[j-1]:
                    j += 1
            elif nums[i]+nums[j]+nums[k] > b:
                k -= 1
            else:
                j += 1
    return res
测试

我们使用一些测试用例进行测试:

print(threeSumBetween([1,2,3,4,5,6], 5, 11))
print(threeSumBetween([-10,-1,0,1,2,4], 2, 6))

输出结果:

19
11
解释:

在第一个测试用例中,数组nums中满足条件a≤nums[i]+nums[j]+nums[k]≤b的三元组为:

[1,2,3],[1,2,4],[1,2,5],[1,3,4],[1,3,5],[1,4,5],
[2,3,4],[2,3,5],[2,4,5],[3,4,5],[1,2,6],[1,3,6],
[1,4,6],[1,5,6],[2,3,6],[2,4,6],[2,5,6],[3,4,6],[3,5,6],[4,5,6]

共19个三元组,因此函数返回19。

在第二个测试用例中,数组nums中满足条件a≤nums[i]+nums[j]+nums[k]≤b的三元组为:

[-1,2,4],[-1,1,6],[-1,0,6],[0,1,5],[0,2,4],
[1,2,3],[1,2,4],[1,2,5],[1,3,4],[1,3,5],[1,4,5]

共11个三元组,因此函数返回11。