每日一道 LeetCode (56):四數之和

2021-03-02 極客挖掘機
每日一道 LeetCode (56):四數之和

每天 3 分鐘,走上算法的逆襲之路。

前文合集

每日一道 LeetCode 前文合集

代碼倉庫

GitHub:https://github.com/meteor1993/LeetCode

Gitee:https://gitee.com/inwsy/LeetCode

題目:四數之和

難度:中等

題目來源:https://leetcode-cn.com/problems/4sum/

給定一個包含 n 個整數的數組 nums 和一個目標值 target,判斷 nums 中是否存在四個元素 a,b,c 和 d ,使得 a + b + c + d 的值與 target 相等?找出所有滿足條件且不重複的四元組。

注意:

答案中不可以包含重複的四元組。

示例:

給定數組 nums = [1, 0, -1, 0, -2, 2],和 target = 0。

滿足要求的四元組集合為:
[
  [-1,  0, 0, 1],
  [-2, -1, 1, 2],
  [-2,  0, 0, 2]
]

解題思路

這道題有點方,雖然前面曾經做過一個三數之和的題,但是看到這個題完全沒和前面的那道題產生聯繫。

最蠢的方案就是套 4 層循環,暴力循環 4 次,雖然我沒這麼幹,但是這麼幹肯定超時,我在題解的評論裡面見到有人真的用了 4 層循環,真的猛士,這道題 4 層循環想要寫通並不是那麼簡單的。

除了 4 層循環,那麼 3 層循環行不行,當然可以,答案上給出來的就是三重循環。

套路還是和之前的三數之和一樣,使用雙指針,使用兩層循環分別枚舉前兩個數,之後使用雙指針在同一重循環中枚舉剩下兩個數。

首先確定紅色和藍色的 i 和 j ,然後在剩下的數中尋找目標,向右移動綠色的箭頭,直到找到一個結果,把這個結果存下來,繼續移動,當綠色移動結束後,將藍色向右移動一位,接著移動綠色的箭頭進行尋找,直到紅色的箭頭移動至 num.length - 3 的位置為止。

代碼上我加了注釋,看起來應該比較清晰:

public class Solution {
    public List<List<Integer>> fourSum(int[] nums, int target) {
        List<List<Integer>> result = new ArrayList<>();
        if (nums == null || nums.length < 4) return result;
        // 先對數組做排序
        Arrays.sort(nums);
        int length = nums.length;
        for (int i = 0; i < length - 3; i++) {
            // 特殊情況判斷
            // 最小數字不可重複
            if (i > 0 && nums[i] == nums[i - 1]) continue;
            // 如果和大於 target ,那麼接下來所有的結果肯定都大於 target ,直接 break
            if (nums[i] + nums[i + 1] + nums[i + 2] + nums[i + 3] > target) break;
            // 最大的結果也小於 target 時,直接最小數進入下一次循環
            if (nums[i] + nums[length - 3] + nums[length - 2] + nums[length - 1] < target) continue;
            for (int j = i + 1; j < length - 2; j++) {
                // 特殊情況判斷,和最小的數字判斷規則相同
                if (j > i + 1 && nums[j] == nums[j - 1]) continue;
                if (nums[i] + nums[j] + nums[j + 1] + nums[j + 2] > target) break;
                if (nums[i] + nums[j] + nums[length - 2] + nums[length - 1] < target) continue;
                // left 和 right 分別代表第 3 、4 個數
                int left = j + 1, right = length - 1;
                while (left < right) {
                    int sum = nums[i] + nums[j] + nums[left] + nums[right];
                    // 當結果和 target 相同時
                    if (sum == target) {
                        // 結果存入 result 中
                        result.add(Arrays.asList(nums[i], nums[j], nums[left], nums[right]));
                        // 去重第三個數
                        while (left < right && nums[left] == nums[left + 1]) left++;
                        left++;
                        // 去重第四個數
                        while (left < right && nums[right] == nums[right - 1]) right--;
                        right--;
                    } else if (sum < target) {
                        left++;
                    } else {
                        right--;
                    }
                }
            }
        }
        return result;
    }
}



相關焦點

  • 每天一道leetcode18-四數之和
    正當班主任要繼續發話,只聽到角落默默想起來一個聲音:」K2」前言 2018.11.20號打卡今天的題目leetcode61:https://leetcode-cn.com/problems/rotate-list/description/昨天的題解題目 每天一道leetcode18- 四數之和分類:雙指針
  • ​LeetCode刷題實戰18: 四數之和
    所以,為了提高大家的算法能力,這個公眾號後續每天帶大家做一道算法題,題目就從LeetCode上面選 !今天和大家聊的問題叫做四數之和 ,我們先來看題面:https://leetcode-cn.com/problems/4sum/Given an array nums of n integers and an integer target, are there elements a, b, c, and d in nums such
  • 每日一道 LeetCode (39):多數元素
    ❞前文合集每日一道 LeetCode 前文合集代碼倉庫GitHub:https://github.com/meteor1993/LeetCodeGitee:https://gitee.com/inwsy/LeetCode
  • 四數之和(18)-四數之和(454)-LeetCode
    18 四數之和給定一個包含 n 個整數的數組 nums 和一個目標值 target,判斷
  • 每日一道 LeetCode (16):求 x 的平方根
    ❞前文合集每日一道 LeetCode 前文合集代碼倉庫GitHub:https://github.com/meteor1993/LeetCodeGitee:https://gitee.com/inwsy/LeetCode
  • LeetCode-18.四數之和(4Sum)
    四數之和給定一個包含 n 個整數的數組 nums 和一個目標值 target,判斷 nums 中是否存在四個元素 a,b,c 和 d ,使得 a + b + c + d 的值與 target 相等?找出所有滿足條件且不重複的四元組。注意:答案中不可以包含重複的四元組。
  • 每日一道 LeetCode (21):對稱二叉樹
    ❞前文合集每日一道 LeetCode 前文合集代碼倉庫GitHub:https://github.com/meteor1993/LeetCodeGitee:https://gitee.com/inwsy/LeetCode
  • 每天學一道leetcode:103. 二叉樹的鋸齒形層次遍歷
    前言歡迎閱讀小王同學的長篇連載文章之《每天學一道leetcode》。如果您從前做過這道題目,可以從小王同學的文章裡增強對該題目的記憶和印象,思考一下小王同學給出的思路和解法有沒有優化的空間。題目分析103題是leetcode中一道中等難度的題目,這道題目是二叉樹的層次遍歷的變形題。小王同學曾經分析過二叉樹的層次遍歷這道題目,地址在
  • 三數之和 | Leetcode題解
    1, 2, -1, -4\],滿足要求的三元組集合為:\[  \[-1, 0, 1\],  \[-1, -1, 2\]\]難度:支持語言:JavaScript、Python、C++相關標籤相關企業思路採用分治的思想找出三個數相加等於
  • 每天學一道leetcode:152.乘積最大子序列
    面試各位同學大家好,歡迎閱讀小王同學的長篇連載文章之《每天學一道leetcode》。今天小王同學給大家帶來的是leetcode第152題「乘積最大子序列」。如果您從前做過這道題目,可以從小王同學的文章裡增強對該題目的記憶和印象,思考一下小王同學給出的思路和解法有沒有優化的空間。
  • 每天一道leetcode61-旋轉鍊表
    正當班主任要繼續發話,只聽到角落默默想起來一個聲音:」K2」前言 2018.11.21號打卡今天的題目leetcode26:https://leetcode-cn.com/problems/remove-duplicates-from-sorted-array/description/昨天的題解題目 每天一道leetcode61
  • 【每日一題】leetcode刷題指南之Longest Consecutive Sequence
    假設我們碰到一個數i,要求包含這個數的連續序列的長度我們會去向左找i-1、i-2、i-3…是否在數組中,再向右找i+1、i+2、i+3…是否在序列中,直到找到第一個不在數組中的為止,然後即可知道i所在序列的長度。
  • leetcode 45. 跳躍遊戲--每天刷一道leetcode算法系列!
    leetcode 45. 跳躍遊戲--每天刷一道leetcode算法系列!(本篇)題目描述給定一個非負整數數組,你最初位於數組的第一個位置。數組中的每個元素代表你在該位置可以跳躍的最大長度。你的目標是使用最少的跳躍次數到達數組的最後一個位置。
  • leetcode每日一題:49.字母異位詞分組
    leetcode每日一題:49.字母異位詞分組:https://leetcode-cn.com/problems/group-anagrams/一起刷題吧一、題意分析 輸入:由字符串組成的列表(數組)輸出:將由同樣的字母和字母個數組成的不同序列放在一個列表裡,然後整體做為一個列表輸出難度
  • 每日一道 LeetCode (50):字符串轉換整數 (atoi)
    ❞前文合集每日一道 LeetCode 前文合集代碼倉庫GitHub:https://github.com/meteor1993/LeetCodeGitee:https://gitee.com/inwsy/LeetCode
  • LeetCode-15.三數之和(3Sum)
    三數之和給你一個包含 n 個整數的數組 nums,判斷 nums 中是否存在三個元素 a,b,c ,使得 a + b + c = 0 ?請你找出所有滿足條件且不重複的三元組。注意:答案中不可以包含重複的三元組。
  • ​LeetCode刷題實戰179:最大數
    算法的重要性,我就不多說了吧,想去大廠,就必須要經過基礎知識和業務邏輯面試+算法面試。
  • LeetCode-1.兩數之和(Two Sum)
    相信每個想刷leetcode的人,第一次打開網站,就從這道題開始的。一起起航吧,Great Voyage.
  • 三數之和姊妹題——LeetCode題目16:最接近的三數之和
    找出 nums 中的三個整數,使得它們的和與 target 最接近。返回這三個數的和。假定每組輸入只存在唯一答案。示例輸入:nums=[-1, 2, 1, 4], target=1輸出:2解釋:與 target 最接近的三個數的和為 2. (-1 + 2 + 1 = 2).
  • LeetCode Weekly Contest 204 題解
    這裡本蛙把數組過了一遍,記錄連續正數的數字個數和連續不為0數字個數, 以及連續不為0數字的子數組裡,第一個負數的下標, 就可以推導出答案了。的其實只要考慮到以下幾種情況就基本可以了:1.答案可能是最長的連續正數的數字個數。2.答案可能是最長的連續不為0數字個數。但這裡我們可能要一直插到數組最後一個元素或者0才能得到,而且那時候積還有可能是負數。