跳转至

259. 较小的三数之和 🔒

题目描述

给定一个长度为 n 的整数数组和一个目标值 target ,寻找能够使条件 nums[i] + nums[j] + nums[k] < target 成立的三元组  i, j, k 个数(0 <= i < j < k < n)。

 

示例 1:

输入: nums = [-2,0,1,3], target = 2
输出: 2 
解释: 因为一共有两个三元组满足累加和小于 2:
     [-2,0,1]
     [-2,0,3]

示例 2:

输入: nums = [], target = 0
输出: 0 

示例 3:

输入: nums = [0], target = 0
输出: 0 

 

提示:

  • n == nums.length
  • 0 <= n <= 3500
  • -100 <= nums[i] <= 100
  • -100 <= target <= 100

解法

方法一:排序 + 双指针 + 枚举

由于元素的顺序不影响结果,我们可以先对数组进行排序,然后使用双指针的方法来解决这个问题。

我们先将数组排序,然后枚举第一个元素 \(\textit{nums}[i]\),并在 \(\textit{nums}[i+1:n-1]\) 的区间内使用双指针分别指向 \(\textit{nums}[j]\)\(\textit{nums}[k]\),其中 \(j\)\(\textit{nums}[i]\) 的下一个元素,而 \(k\) 是数组的最后一个元素。

  • 如果 \(\textit{nums}[i] + \textit{nums}[j] + \textit{nums}[k] < \textit{target}\),那么对于任意 \(j \lt k' \leq k\) 的元素,都有 \(\textit{nums}[i] + \textit{nums}[j] + \textit{nums}[k'] \lt \textit{target}\),一共有 \(k - j\) 个这样的 \(k'\),我们将 \(k - j\) 累加到答案中。接下来,将 \(j\) 右移一个位置,继续寻找下一个满足条件的 \(k\),直到 \(j \geq k\) 为止。
  • 如果 \(\textit{nums}[i] + \textit{nums}[j] + \textit{nums}[k] \geq \textit{target}\),那么对于任意 \(j \leq j' \lt k\) 的元素,都不可能使得 \(\textit{nums}[i] + \textit{nums}[j'] + \textit{nums}[k] \lt \textit{target}\),因此我们将 \(k\) 左移一个位置,继续寻找下一个满足条件的 \(k\),直到 \(j \geq k\) 为止。

枚举完所有的 \(i\) 后,我们就得到了满足条件的三元组的个数。

时间复杂度 \(O(n^2)\),空间复杂度 \(O(\log n)\)。其中 \(n\) 是数组 \(\textit{nums}\) 的长度。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
class Solution:
    def threeSumSmaller(self, nums: List[int], target: int) -> int:
        nums.sort()
        ans, n = 0, len(nums)
        for i in range(n - 2):
            j, k = i + 1, n - 1
            while j < k:
                x = nums[i] + nums[j] + nums[k]
                if x < target:
                    ans += k - j
                    j += 1
                else:
                    k -= 1
        return ans
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
class Solution {
    public int threeSumSmaller(int[] nums, int target) {
        Arrays.sort(nums);
        int ans = 0, n = nums.length;
        for (int i = 0; i + 2 < n; ++i) {
            int j = i + 1, k = n - 1;
            while (j < k) {
                int x = nums[i] + nums[j] + nums[k];
                if (x < target) {
                    ans += k - j;
                    ++j;
                } else {
                    --k;
                }
            }
        }
        return ans;
    }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
class Solution {
public:
    int threeSumSmaller(vector<int>& nums, int target) {
        ranges::sort(nums);
        int ans = 0, n = nums.size();
        for (int i = 0; i + 2 < n; ++i) {
            int j = i + 1, k = n - 1;
            while (j < k) {
                int x = nums[i] + nums[j] + nums[k];
                if (x < target) {
                    ans += k - j;
                    ++j;
                } else {
                    --k;
                }
            }
        }
        return ans;
    }
};
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
func threeSumSmaller(nums []int, target int) (ans int) {
    sort.Ints(nums)
    n := len(nums)
    for i := 0; i < n-2; i++ {
        j, k := i+1, n-1
        for j < k {
            x := nums[i] + nums[j] + nums[k]
            if x < target {
                ans += k - j
                j++
            } else {
                k--
            }
        }
    }
    return
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
function threeSumSmaller(nums: number[], target: number): number {
    nums.sort((a, b) => a - b);
    const n = nums.length;
    let ans = 0;
    for (let i = 0; i < n - 2; ++i) {
        let [j, k] = [i + 1, n - 1];
        while (j < k) {
            const x = nums[i] + nums[j] + nums[k];
            if (x < target) {
                ans += k - j;
                ++j;
            } else {
                --k;
            }
        }
    }
    return ans;
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/**
 * @param {number[]} nums
 * @param {number} target
 * @return {number}
 */
var threeSumSmaller = function (nums, target) {
    nums.sort((a, b) => a - b);
    const n = nums.length;
    let ans = 0;
    for (let i = 0; i < n - 2; ++i) {
        let [j, k] = [i + 1, n - 1];
        while (j < k) {
            const x = nums[i] + nums[j] + nums[k];
            if (x < target) {
                ans += k - j;
                ++j;
            } else {
                --k;
            }
        }
    }
    return ans;
};

评论

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy