[LeetCode] 259. 3Sum Smaller 三數之和較小值


 

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 問題的一個變形,讓我們求三數之和小於一個目標值,那么最簡單的方法就是窮舉法,將所有的可能的三個數字的組合都遍歷一遍,比較三數之和跟目標值之間的大小,小於的話則結果自增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) 的時間復雜度內實現,那么借鑒之前那兩道題 3Sum Closest 和 3Sum 中的方法,采用雙指針來做,這里面有個 trick 就是當判斷三個數之和小於目標值時,此時結果應該加上 right-left,因為數組排序了以后,如果加上 num[right] 小於目標值的話,那么加上一個更小的數必定也會小於目標值,然后將左指針右移一位,否則將右指針左移一位,參見代碼如下:

 

解法二:

// 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;
    }
};

 

Github 同步地址:

https://github.com/grandyang/leetcode/issues/259

 

類似題目:

3Sum Closest

3Sum

Valid Triangle Number 

Two Sum Less Than K

 

參考資料:

https://leetcode.com/problems/3sum-smaller/

https://leetcode.com/problems/3sum-smaller/discuss/68817/Simple-and-easy-understanding-O(n2)-JAVA-solution

https://leetcode.com/problems/3sum-smaller/discuss/68820/Accepted-and-Simple-Java-O(n2)-solution-with-detailed-explanation


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM