題目鏈接
tag:
- Medium
- Two Pointers
question:
??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.
Example:
Input: nums = [-2,0,1,3], and target = 2
Output: 2
Explanation: Because there are two triplets which sums are less than 2:
[-2,0,1]
[-2,0,3]
Follow up: Could you solve it in O(n2) runtime?
方法一:
思路:這道題是 3Sum 問題的一個變形链瓦,讓我們求三數(shù)之和小于一個目標(biāo)值玻募,那么最簡單的方法就是窮舉法狸捅,將所有的可能的三個數(shù)字的組合都遍歷一遍席揽,比較三數(shù)之和跟目標(biāo)值之間的大小注祖,小于的話則結(jié)果自增1,參見代碼如下:询一,代碼如下:
// O(n^3)
class Solution {
public:
int threeSumSmaller(vector<int>& nums, int target) {
int res = 0;
sort(nums.begin(), nums.end());
for (int i = 0; i < int(nums.size() - 2); ++i) {
int left = i + 1, right = nums.size() - 1, sum = target - nums[i];
for (int j = left; j <= right; ++j) {
for (int k = j + 1; k <= right; ++k) {
if (nums[j] + nums[k] < sum) ++res;
}
}
}
return res;
}
};
方法二:
思路:題目中的 Follow up 讓我們在 O(n^2) 的時間復(fù)雜度內(nèi)實現(xiàn)隐孽,那么借鑒之前那兩道題 3Sum Closest 和 3Sum 中的方法,采用雙指針來做健蕊,這里面有個 trick 就是當(dāng)判斷三個數(shù)之和小于目標(biāo)值時菱阵,此時結(jié)果應(yīng)該加上 right-left,因為數(shù)組排序了以后缩功,如果加上 num[right] 小于目標(biāo)值的話晴及,那么加上一個更小的數(shù)必定也會小于目標(biāo)值,然后將左指針右移一位嫡锌,否則將右指針左移一位虑稼,參見代碼如下:
// O(n^2)
class Solution {
public:
int threeSumSmaller(vector<int>& nums, int target) {
if (nums.size() < 3) return 0;
int res = 0, n = nums.size();
sort(nums.begin(), nums.end());
for (int i = 0; i < n - 2; ++i) {
int left = i + 1, right = n - 1;
while (left < right) {
if (nums[i] + nums[left] + nums[right] < target) {
res += right - left;
++left;
}
else --right;
}
}
return res;
}
};