LeetCode - 18 四數之和

題目來源

18. 四數之和 - 力扣(LeetCode)

題目描述

給你一個由?n?個整數組成的數組?nums?,和一個目標值?target?。請你找出并返回滿足下述全部條件且不重復的四元組?[nums[a], nums[b], nums[c], nums[d]]?(若兩個四元組元素一一對應,則認為兩個四元組重復):

  • 0 <= a, b, c, d?< n
  • abc?和?d?互不相同
  • nums[a] + nums[b] + nums[c] + nums[d] == target

你可以按?任意順序?返回答案 。

    示例

    示例 1:

    輸入:nums = [1,0,-1,0,-2,2], target = 0
    輸出:[[-2,-1,1,2],[-2,0,0,2],[-1,0,0,1]]
    

    示例 2:

    輸入:nums = [2,2,2,2,2], target = 8
    輸出:[[2,2,2,2]]

    提示

    • 1 <= nums.length <= 200
    • -10^9 <= nums[i] <= 10^9
    • -10^9 <= target <= 10^9

    題目解析

    本題是?LeetCode - 15 三數之和-CSDN博客?的進階版,解題思路一致。

    三數之和、四數之和初始時都是需要將數組升序,方便后續雙指針。

    三數之和:固定三元組中一個最小值索引 i 然后定義雙指針 L?= i+1,R?= len(nums) - 1,如果此時三元組之和 sum = nums[i] + nums[L] + nums[R]

    • sum > target,則 R -= 1,因為數組已經升序,因此 R 指針左移,則 nums[R] 變小,對應的三數之和也會變小
    • sum < target,則 L += 1,因為數組已經升序,因此 L 指針右移,則 nums[L] 變大,對應的三數之和也會變大
    • sum == target,則此時 (nums[i], nums[L], nums[R]) 和為 tagret 的三元組。

    四數之和:固定四元組中最小兩個值的索引 i,j,然后定義雙指針 L = j + 1,R = len(nums) - 1,如果此時四元組之和 sum = nums[i] + nums[j] + nums[L] + nums[R]

    • sum > target,則 R -= 1,因為數組已經升序,因此 R 指針左移,則 nums[R] 變小,對應的四數之和也會變小
    • sum < target,則 L += 1,因為數組已經升序,因此 L 指針右移,則 nums[L] 變大,對應的四數之和也會變大
    • sum == target,則此時 (nums[i], nums[j], nums[L], nums[R]) 和為 tagret 的四元組。

    使用雙指針的好處是,避免了暴力枚舉四元組的四個元素,而是只需要暴力枚舉 四元組的最小兩個元素,剩余的四元組中較大兩個元素可以通過同向雙指針優化求解。

    之后就是 三元組/四元組 去重問題,這里不推薦得到所有和為 target 的四元組,然后進行去重,而是在求解四元組的過程中就可以去重。這里去重分為兩類:

    • 基于 i,j 去重
    • 基于 L,R 去重

    基于 i,j 去重

    比如 nums = [1,1,1,2,3,4],target=10

    如上圖所示,紅色框部分,其中 i? 的位置相同,L,R運動過程也相同,只是 j 的位置發生了變化,但是 j 指向的元素值是沒有改變的。

    因此當 nums[j] == nums[j - 1] 時,我們可以跳過,比如上圖 i = 0,j = 2 的過程可以跳過,因為產生的必然是重復的四元組。

    如上圖所示,紅色框部分,其中 j 的位置相同,L,R的運動過程也相同,只是 i 的位置發生了變化,但是 i 指向的元素值時沒有改變的。

    因此當 nums[i] == nums[i-1] 時,我們可以跳過,比如上圖 i = 1,j=2 的過程可以跳過,因為產生的必然時重復的四元組。

    經過上面去重操作,最終只需要進行下面綠色框步驟:

    基于 L,R 去重

    比如用例 nums = [1,2,3,3,3,4,4,4],target=10

    如下圖,綠色框發現了一個target=10的四元組,那么下一步,我們可以:

    • L += 1,L 右移后,若 nums[L] == nums[L-1],則此時 i,j,R 未發生變化,則必然和之前四元組重復,我們可以繼續 L += 1
    • R -= 1,R 左移后,若 nums[R] == nums[R+1],則此時 i,j,L 未發生變化,則必然和之前四元組重復,我們可以繼續 R -= 1

    C源碼實現

    #include <stdio.h>
    #include <stdlib.h>/*** Return an array of arrays of size *returnSize.* The sizes of the arrays are returned as *returnColumnSizes array.* Note: Both returned array and *columnSizes array must be malloced, assume* caller calls free().*/
    int cmp(const void *a, const void *b) { return *((int *) a) - *((int *) b); }int **fourSum(int *nums, int numsSize, int target, int *returnSize,int **returnColumnSizes) {qsort(nums, numsSize, sizeof(nums[0]), cmp);int **result = (int **) malloc(sizeof(int *) * 1000);int result_size = 0;for (int i = 0; i < numsSize - 3; i++) {if (i > 0 && nums[i] == nums[i - 1])continue;for (int j = i + 1; j < numsSize - 2; j++) {if (j > i + 1 && nums[j] == nums[j - 1])continue;int l = j + 1;int r = numsSize - 1;while (l < r) {long sum = (long) nums[i] + nums[j] + nums[l] + nums[r];if (sum > target) {r--;} else if (sum < target) {l++;} else {int *tuple = (int *) malloc(sizeof(int) * 4);tuple[0] = nums[i];tuple[1] = nums[j];tuple[2] = nums[l];tuple[3] = nums[r];result[result_size++] = tuple;do {l++;} while (l < r && nums[l] == nums[l - 1]);do {r--;} while (r > l && nums[r] == nums[r + 1]);}}}}*returnSize = result_size;*returnColumnSizes = (int *) malloc(sizeof(int) * result_size);for (int i = 0; i < result_size; i++) {(*returnColumnSizes)[i] = 4;}return result;
    }//int main() {
    //    int nums[] = {1, 0, -1, 0, -2, 2};
    //    int numsSize = 6;
    //    int target = 0;
    //
    //    int returnSize = 0;
    //    int *returnColumnSizes = (int *) calloc(1000, sizeof(int));
    //
    //    int **results = fourSum(nums, numsSize, target, &returnSize, &returnColumnSizes);
    //
    //    for (int i = 0; i < returnSize; i++) {
    //        printf("[");
    //        for (int j = 0; j < returnColumnSizes[i]; j++) {
    //            printf("%d", results[i][j]);
    //            if (j < returnColumnSizes[i] - 1) printf(",");
    //        }
    //        printf("]\n");
    //    }
    //
    //    return 0;
    //}

    C++源碼實現

    class Solution {
    public:vector<vector<int>> fourSum(vector<int>& nums, int target) {sort(nums.begin(), nums.end());vector<vector<int>> results;int n = nums.size();for (int i = 0; i < n - 3; i++) {if (i > 0 && nums[i] == nums[i - 1])continue;for (int j = i + 1; j < n - 2; j++) {if (j > i + 1 && nums[j] == nums[j - 1])continue;int l = j + 1;int r = n - 1;while (l < r) {long sum = (long)nums[i] + nums[j] + nums[l] + nums[r];if (sum > target) {r--;} else if (sum < target) {l++;} else {results.emplace_back(vector<int>{nums[i], nums[j], nums[l], nums[r]});do {l++;} while (l < r && nums[l] == nums[l - 1]);do {r--;} while (r > l && nums[r] == nums[r + 1]);}}}}return results;}
    };

    Java源碼實現

    class Solution {public List<List<Integer>> fourSum(int[] nums, int target) {Arrays.sort(nums);List<List<Integer>> results = new ArrayList<>();for (int i = 0; i < nums.length - 3; i++) {if (i > 0 && nums[i] == nums[i - 1]) continue;for (int j = i + 1; j < nums.length - 2; j++) {if (j > i + 1 && nums[j] == nums[j - 1]) continue;int l = j + 1;int r = nums.length - 1;while (l < r) {long sum = (long) nums[i] + nums[j] + nums[l] + nums[r];if (sum > target) {r--;} else if (sum < target) {l++;} else {ArrayList<Integer> tuple = new ArrayList<>();tuple.add(nums[i]);tuple.add(nums[j]);tuple.add(nums[l]);tuple.add(nums[r]);results.add(tuple);do {l++;} while (l < r && nums[l] == nums[l - 1]);do {r--;} while (r > l && nums[r] == nums[r + 1]);}}}}return results;}
    }

    Python源碼實現

    class Solution(object):def fourSum(self, nums, target):""":type nums: List[int]:type target: int:rtype: List[List[int]]"""nums.sort()results = []n = len(nums)for i in range(n - 3):if i > 0 and nums[i] == nums[i - 1]:continuefor j in range(i + 1, n - 2):if j > i + 1 and nums[j] == nums[j - 1]:continuel = j + 1r = n - 1while l < r:total = nums[i] + nums[j] + nums[l] + nums[r]if total > target:r -= 1elif total < target:l += 1else:results.append((nums[i], nums[j], nums[l], nums[r]))while l + 1 <= r and nums[l] == nums[l + 1]:l += 1while r - 1 >= l and nums[r] == nums[r - 1]:r -= 1l += 1r -= 1return results
    

    JavaScript源碼實現

    /*** @param {number[]} nums* @param {number} target* @return {number[][]}*/
    var fourSum = function (nums, target) {nums.sort((a, b) => a - b);const results = [];for (let i = 0; i < nums.length - 3; i++) {if (i > 0 && nums[i] == nums[i - 1]) continue;for (let j = i + 1; j < nums.length - 2; j++) {if (j > i + 1 && nums[j] == nums[j - 1]) continue;let l = j + 1;let r = nums.length - 1;while (l < r) {const sum = nums[i] + nums[j] + nums[l] + nums[r];if (sum > target) {r--;} else if (sum < target) {l++;} else {results.push([nums[i], nums[j], nums[l], nums[r]]);do {l++;} while (l < r && nums[l] == nums[l - 1]);do {r--;} while (r > l && nums[r] == nums[r + 1]);}}}}return results;
    };

    本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
    如若轉載,請注明出處:http://www.pswp.cn/bicheng/71413.shtml
    繁體地址,請注明出處:http://hk.pswp.cn/bicheng/71413.shtml
    英文地址,請注明出處:http://en.pswp.cn/bicheng/71413.shtml

    如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

    相關文章

    pt100 2線和3線的區別?

    3線比2線更穩定一些&#xff1b; 在電路中&#xff0c;b和c是不連接在一起的&#xff1b; 測試的時候&#xff0c;b和c是接在一起的&#xff0c;也就是說pt100中b和c是連接在一起的 3線比2線多一個反饋&#xff1b; 平時測試的時候&#xff0c;測試一下ab或者ac 都是一樣的…

    使用QT讀取文件,生成json文件

    前言&#xff1a; 最近我遇到了一個需要讀取本地文件生成json文件的問題&#xff0c;在這里分享下如何在qt中寫一個生成json的程序當然也可以使用一些可視化的工具來寫json文件(比如&#xff1a;notepad–,還有一些ide都可以)&#xff0c;但未免太過于麻煩本文會以一個以qmake…

    國產編輯器EverEdit -告別東找西找!一鍵打開當前文件所在目錄!

    1 文件操作 2 應用場景 在文件編輯過程中&#xff0c;有時需要對文件進行一些操作&#xff0c;比如&#xff1a;在命令窗口輸入文件路徑、文件名&#xff0c;進入到文件目錄&#xff0c;對文件進行壓縮等&#xff0c;如果沒有直達命令&#xff0c;用戶需要通過文件管理器找到目…

    【Docker】百度網盤:基于VNC的Web訪問及后臺下載

    本教程通過 Docker Compose 部署百度網盤的 VNC 版本&#xff0c;實現24小時不間斷下載、雙模式訪問、數據持久化、自動重啟和安全加密控制等核心功能。 目錄結構規劃 建議使用以下目錄結構&#xff08;可根據實際情況調整&#xff09;&#xff1a; ~/baidunetdisk/├── d…

    立創實戰派ESP32-S3燒錄小智AI指南

    小智 AI 聊天機器人-開源項目介紹 本項目是一個開源項目&#xff0c;主要用于教學目的。我們希望通過這個項目&#xff0c;能夠幫助更多人入門 AI 硬件開發&#xff0c;了解如何將當下飛速發展的大語言模型應用到實際的硬件設備中。無論你是對 AI 感興趣的學生&#xff0c;還是…

    【設計模式】【創建型模式】原型模式(Prototype)

    &#x1f44b;hi&#xff0c;我不是一名外包公司的員工&#xff0c;也不會偷吃茶水間的零食&#xff0c;我的夢想是能寫高端CRUD &#x1f525; 2025本人正在沉淀中… 博客更新速度 &#x1f44d; 歡迎點贊、收藏、關注&#xff0c;跟上我的更新節奏 &#x1f3b5; 當你的天空突…

    Weblogic 反序列化漏洞深度剖析與復現

    目錄 一、引言 二、Weblogic 反序列化漏洞原理 &#xff08;一&#xff09;什么是反序列化 &#xff08;二&#xff09;Weblogic 反序列化漏洞產生機制 三、Weblogic 反序列化漏洞危害 四、Weblogic 反序列化漏洞復現 &#xff08;一&#xff09;復現環境準備 &#xff…

    2025年02月19日Github流行趨勢

    項目名稱&#xff1a;OmniParser 項目地址url&#xff1a;https://github.com/microsoft/OmniParser 項目語言&#xff1a;Jupyter Notebook 歷史star數&#xff1a;12878 今日star數&#xff1a;2153 項目維護者&#xff1a;yadong-lu, ThomasDh-C, aliencaocao, nmstoker, kr…

    深入解析 iOS 視頻錄制(三):完整錄制流程的實現與整合

    深入解析 iOS 視頻錄制&#xff08;一&#xff09;&#xff1a;錄制管理核心MWRecordingController 類的設計與實現 深入解析iOS視頻錄制&#xff08;二&#xff09;&#xff1a;自定義UI的實現??????? 深入解析 iOS 視頻錄制&#xff08;三&#xff09;&#xff1a;完…

    基于豆瓣2025電影數據可視化分析系統的設計與實現

    ??本項目旨在通過對豆瓣電影數據進行綜合分析與可視化展示&#xff0c;構建一個基于Python的大數據可視化系統。通過數據爬取收集、清洗、分析豆瓣電影數據&#xff0c;我們提供了一個全面的電影信息平臺&#xff0c;為用戶提供深入了解電影產業趨勢、影片評價與演員表現的工…

    tcp協議連接,和傳輸數據

    1、連接 這個是通用的 2、傳送數據 當連接建立后&#xff0c;客戶端和服務器都可以主動發送數據&#xff0c;分別如下 1》客戶端先發送數據 這里是單向的&#xff0c;服務器沒有對客戶端的數據內容進行應答&#xff0c;只是單純的對報文應答ack 2》服務器先發送數據

    2024年國賽高教杯數學建模C題農作物的種植策略解題全過程文檔及程序

    2024年國賽高教杯數學建模 C題 農作物的種植策略 原題再現 根據鄉村的實際情況&#xff0c;充分利用有限的耕地資源&#xff0c;因地制宜&#xff0c;發展有機種植產業&#xff0c;對鄉村經濟的可持續發展具有重要的現實意義。選擇適宜的農作物&#xff0c;優化種植策略&…

    鴻蒙開發:V2版本裝飾器之@Monitor裝飾器

    前言 本文代碼案例基于Api13。 隨著官方的迭代&#xff0c;在新的Api中&#xff0c;對于新的應用開發&#xff0c;官方已經建議直接使用V2所屬的裝飾器進行開發了&#xff0c;所以&#xff0c;能上手V2的盡量上手V2吧&#xff0c;畢竟&#xff0c;V2是V1的增強版本&#xff0c;…

    國產編輯器EverEdit - 獨門暗器:自動監視剪貼板內容

    1 監視剪貼板 1.1 應用場景 如果需要對剪貼板的所有歷史進行記錄&#xff0c;并進行分析和回顧&#xff0c;則可以使用監視剪貼板功能&#xff0c;不僅在EverEdit中的復制會記錄&#xff0c;在其他應用的復制也會記錄。 1.2 使用方法 新建一個空文檔(重要&#xff1a;防止擾亂…

    pdf轉換成word在線 簡單好用 支持批量轉換 效率高 100%還原

    pdf轉換成word在線 簡單好用 支持批量轉換 效率高 100%還原 在數字化辦公的浪潮中&#xff0c;文檔格式轉換常常讓人頭疼不已&#xff0c;尤其是 PDF 轉 Word 的需求極為常見。PDF 格式雖然方便閱讀和傳輸&#xff0c;但難以編輯&#xff0c;而 Word 格式卻能靈活地進行內容修…

    深入探索C語言中的字符串處理函數:strstr與strtok

    在C語言的字符串處理領域&#xff0c; strstr 和 strtok 是兩個非常重要的函數&#xff0c;它們各自承擔著獨特的功能&#xff0c;為開發者處理字符串提供了強大的支持。 一、strstr函數&#xff1a;字符串查找的利器 strstr 函數用于在一個字符串中查找另一個字符串的首次出現…

    AIGC(生成式AI)試用 21 -- Python調用deepseek API

    1. 安裝openai pip3 install openai########################## Collecting openaiUsing cached openai-1.61.1-py3-none-any.whl.metadata (27 kB) Collecting anyio<5,>3.5.0 (from openai)Using cached anyio-4.8.0-py3-none-any.whl.metadata (4.6 kB) Collecting d…

    關于使用雪花算法生成唯一ID,返回給前端ID不一致的問題

    問題 在某個項目中,使用雪花算法生成的唯一ID,從數據庫查詢到數據后返回給前端,但是前端接受到的數據ID和數據庫原先生成的不一致 但是前端展示的數據: 原因 原因是后端使用Long類型來存儲雪花算法生成的ID,但是這個數值已經超過前端數值類型的范圍,導致前端在存儲這個數值…

    Windows 啟動 SSH 服務

    Windows 啟動 SSH 服務 一、OpenSSH Server 安裝 以 Win10 系統為例 打開設置 -> 系統 -> 可選功能 在 添加的功能 查看是否安裝了 OpenSSH 服務 或者 OpenSSH Server 如果沒有安裝&#xff0c;找到 系統->添加可選功能 -> 查看功能->搜索 OpenSSH 服務 ->…

    C#功能測試

    List 內部元素為引用 src[0]為"11" List<Source> src new List<Source>(); src.Add(new Source() { Name "1", Age 1, Description "1" }); src.Add(new Source() { Name "2", Age 2, Description "2"…