[算法] 優先算法(二): 雙指針算法(下)

🌸個人主頁:https://blog.csdn.net/2301_80050796?spm=1000.2115.3001.5343
🏵?熱門專欄:🍕 Collection與數據結構 (91平均質量分)https://blog.csdn.net/2301_80050796/category_12621348.html?spm=1001.2014.3001.5482
🧀Java EE(94平均質量分) https://blog.csdn.net/2301_80050796/category_12643370.html?spm=1001.2014.3001.5482
🍭MySql數據庫(93平均質量分)https://blog.csdn.net/2301_80050796/category_12629890.html?spm=1001.2014.3001.5482
🍬算法(97平均質量分)https://blog.csdn.net/2301_80050796/category_12676091.html?spm=1001.2014.3001.5482
感謝點贊與關注~~~
在這里插入圖片描述

目錄

  • 1. 有效三角形的個數(難度:🔵2度)
  • 2.兩數之和(難度:🟢1度)
  • 3. 三數之和(難度:🟠4度)
  • 4.四數之和(難度:🔴5度)

1. 有效三角形的個數(難度:🔵2度)

OJ鏈接

  • 題目描述

購物車內的商品價格按照升序記錄于數組 price。請在購物車中找到兩個商品的價格總和剛好是 target。若存在多種情況,返回任一結果即可。
示例 1:
輸入:price = [3, 9, 12, 15], target = 18
輸出:[3,15] 或者 [15,3]
示例 2:
輸入:price = [8, 21, 27, 34, 52, 66], target = 61
輸出:[27,34] 或者 [34,27]

  • 算法原理
    先將數組排序
    我們可以固定?個==「最?邊」,然后在?這條邊?的有序數組中找出?個?元組==,使這個?元組之和?于這個最?邊。由于數組是有序的,我們可以利?「對撞指針」來優化。
    設最?邊枚舉到i 位置,區間[left, right] 是i 位置左邊的區間(也就是?它?的區間):
    • 如果nums[left] + nums[right] > nums[i] :
      • 說明[left, right - 1] 區間上的所有元素均可以與nums[right] 構成?nums[i] ?的?元組
      • 滿?條件的有right - left 種
      • 此時right 位置的元素的所有情況相當于全部考慮完畢, right– ,進?下?輪判斷
    • 如果nums[left] + nums[right] <= nums[i] :
      • 說明left 位置的元素是不可能與[left + 1, right] 位置上的元素構成滿?條件的?元組
      • left 位置的元素可以舍去, left++ 進?下輪循環
  • 代碼編寫
class Solution {public int triangleNumber(int[] nums) {Arrays.sort(nums);int ret = 0;for (int n = nums.length-1;n >= 2;n--){//n固定最大邊int left = 0;int right = n-1;while (left < right){if (nums[left] + nums[right] <= nums[n]){//舍去比right小的元素left++;}else{//比left大的元素全部符合條件ret+=right-left;right--;}}}return ret;}
}

2.兩數之和(難度:🟢1度)

OJ鏈接

  • 題目描述

給定一個整數數組 nums 和一個整數目標值 target,請你在該數組中找出 和為目標值 target 的那 兩個 整數,并返回它們的數組下標。
你可以假設每種輸入只會對應一個答案。但是,數組中同一個元素在答案里不能重復出現。
你可以按任意順序返回答案。
示例 1:
輸入:nums = [2,7,11,15], target = 9
輸出:[0,1]
解釋:因為 nums[0] + nums[1] == 9 ,返回 [0, 1] 。
示例 2:
輸入:nums = [3,2,4], target = 6
輸出:[1,2]
示例 3:
輸入:nums = [3,3], target = 6
輸出:[0,1]

  • 算法原理
    • 初始化left , right 分別指向數組的左右兩端(這?不是我們理解的指針,?是數組的下
      標)
    • 當left < right 的時候,?直循環
      • 當nums[left] + nums[right] == target 時,說明找到結果,記錄結果,并且返回;
      • 當nums[left] + nums[right] < target 時:
        • 對于nums[left] ??,此時nums[right] 相當于是nums[left] 能碰到的最?值別忘了,這?是升序數組)。如果此時不符合要求,說明在這個數組??,沒有別的數符合nums[left] 的要求了(最?的數都滿?不了你,你已經沒救了)。因此,我們可以?膽舍去這個數,讓left++ ,去?較下?組數據;
        • 那對于nums[right] ??,由于此時兩數之和是?于?標值的, nums[right] 還可以選擇?nums[left] ?的值繼續努?達到?標值,因此right 指針我們按兵不動;
      • 當nums[left] + nums[right] > target 時,同理我們可以舍去nums[right] (最?的數都滿?不了你,你也沒救了)。讓right– ,繼續?較下?組數據,?left 指針不變(因為他還是可以去匹配?nums[right] 更?的數的)。
  • 代碼編寫
class Solution {public int[] twoSum(int[] price, int target) {int left = 0;int right = price.length-1;while (left < right){if (price[left]+price[right] == target){return new int[]{price[left],price[right]};}else if (price[left]+price[right] < target){left++;}else{right--;}}return new int[0];}
}

3. 三數之和(難度:🟠4度)

OJ鏈接

  • 題目描述

給你一個整數數組 nums ,判斷是否存在三元組 [nums[i], nums[j], nums[k]] 滿足 i != j、i != k 且 j != k ,同時還滿足 nums[i] + nums[j] + nums[k] == 0 。請
你返回所有和為 0 且不重復的三元組。
注意:答案中不可以包含重復的三元組。
示例 1:
輸入:nums = [-1,0,1,2,-1,-4]
輸出:[[-1,-1,2],[-1,0,1]]
解釋:
nums[0] + nums[1] + nums[2] = (-1) + 0 + 1 = 0 。
nums[1] + nums[2] + nums[4] = 0 + 1 + (-1) = 0 。
nums[0] + nums[3] + nums[4] = (-1) + 2 + (-1) = 0 。
不同的三元組是 [-1,0,1] 和 [-1,-1,2] 。
注意,輸出的順序和三元組的順序并不重要。
示例 2:
輸入:nums = [0,1,1]
輸出:[]
解釋:唯一可能的三元組和不為 0 。
示例 3:
輸入:nums = [0,0,0]
輸出:[[0,0,0]]
解釋:唯一可能的三元組和為 0 。

  • 算法原理
    與兩數之和稍微不同的是,題?中要求找到所有「不重復」的三元組。那我們可以利?在兩數之和那??的雙指針思想,來對我們的暴?枚舉做優化:
    • 排序
    • 然后固定?個數a
    • 在這個數后?的區間內,使?「雙指針算法」快速找到兩個數之和等于-a 即可
      但是要注意的是,這道題??需要有==「去重」操作==~
    • 找到?個結果之后, left 和right 指針要「跳過重復」的元素
    • 當使?完?次雙指針算法之后,固定的a 也要「跳過重復」的元素

最后一點要注意的是在去重操作移動指針的時候,不要出現越界情況.
還有一點小優化就是,在i遍歷到>0的數據的時候,就可以停止了,這是因為在剩下的數字中再也找不得兩個數字加起來等于負數了.

  • 代碼編寫
class Solution {public List<List<Integer>> threeSum(int[] nums) {List<List<Integer>> ret = new ArrayList<>();Arrays.sort(nums);for (int i = 0;i < nums.length;){if (nums[i] > 0){//遇到大于0的,一定沒有兩個數使得條件成立break;}int left = i + 1;int right = nums.length-1;while(left < right){if (nums[left] + nums[right] == -nums[i]){List<Integer> a = new ArrayList<>();a.add(nums[i]);a.add(nums[left]);a.add(nums[right]);ret.add(a);left++;right--;while(left < nums.length && nums[left] == nums[left-1]){//left去重,且不可以越界left++;}while(right > 0 && nums[right] == nums[right+1]){//right去重且不可以越界right--;}}else if (nums[left] + nums[right] < -nums[i]){//與前面兩數之和的原理相同left++;}else{right--;}}//i去重i++;while(i < nums.length && nums[i] == nums[i-1]){//不可以越界i++;}}return ret;}
}

4.四數之和(難度:🔴5度)

  • 題目描述

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

  • 算法原理
    a. 依次固定?個數a
    b. 在這個數a 的后?區間上,利?
    「三數之和」找到三個數
    ,使這三個數的和等于target -a 即可。
  • 代碼編寫
class Solution {public List<List<Integer>> fourSum(int[] nums, int target) {List<List<Integer>> ret = new ArrayList<>();Arrays.sort(nums);for (int i = 0; i < nums.length;){for (int j = i+1;j < nums.length;){int left = j+1;int right = nums.length-1;long t = (long)target-nums[j]-nums[i];while(left < right){if (nums[left] + nums[right] == t){List<Integer> a = new ArrayList<>();a.add(nums[left]);a.add(nums[right]);a.add(nums[j]);a.add(nums[i]);ret.add(a);left++;right--;while(left < nums.length && nums[left] == nums[left-1]){left++;}while(right > 0 && nums[right] == nums[right+1]){right--;}}else if(nums[left] + nums[right] < t){left++;}else{right--;}}j++;while(j < nums.length && nums[j] == nums[j-1]){j++;}}i++;while(i < nums.length && nums[i] == nums[i-1]){i++;}}return ret;}
}

從今天的代碼中,我們可以發現,這幾道題目在不停的利用數組的單調性和雙指針在優化暴力解法,排除掉暴力解法中的一些無效情況,以后在我們做題的時候,要充分利用單調性和雙指針的配合.

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

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

相關文章

基于transformers框架實踐Bert系列6-完形填空

本系列用于Bert模型實踐實際場景&#xff0c;分別包括分類器、命名實體識別、選擇題、文本摘要等等。&#xff08;關于Bert的結構和詳細這里就不做講解&#xff0c;但了解Bert的基本結構是做實踐的基礎&#xff0c;因此看本系列之前&#xff0c;最好了解一下transformers和Bert…

自己動手寫docker——Namespace

Linux Namespace linux Namespace用于隔離一系列的系統資源&#xff0c;例如pid&#xff0c;userid&#xff0c;netword等&#xff0c;借助于Linux Namespace&#xff0c;可以實現容器的基本隔離。 Namespce介紹 Namespace類型系統調用參數作用Mount NamespaceCLONE_NEWNS隔離…

Python筑基之旅-MySQL數據庫(一)

目錄 一、MySQL數據庫 1、簡介 2、優點 2-1、開源和免費 2-2、高性能 2-3、可擴展性 2-4、易用性 2-5、靈活性 2-6、安全性和穩定性 2-7、豐富的功能 2-8、結合其他工具和服務 2-9、良好的兼容性和移植性 3、缺點 3-1、對大數據的支持有限 3-2、缺乏全文…

微服務如何做好監控

大家好&#xff0c;我是蒼何。 在脈脈上看到這條帖子&#xff0c;說阿里 P8 因為上面 P9 斗爭失敗走人&#xff0c;以超齡 35 被裁&#xff0c;Boss 上找工作半年&#xff0c;到現在還處于失業中。 看了下溝通記錄&#xff0c; 溝通了 1000 多次&#xff0c;但沒有一個邀請投遞…

uniapp中使用 iconfont字體

下載 iconfont 字體文件 打開 iconfont.css 文件&#xff0c;修改一下 把文件 復制到 static/iconfont/… 目錄下 在App.vue中引入iconfont 5. 使用iconfont 使用 iconfont 有兩種方式&#xff0c; 一種是 class 方式&#xff0c; 一種是使用 unicode 的方式 5.1 使用 class 的…

【Mac】Dreamweaver 2021 for mac v21.3 Rid中文版安裝教程

軟件介紹 Dreamweaver是Adobe公司開發的一款專業網頁設計與前端開發軟件。它集成了所見即所得&#xff08;WYSIWYG&#xff09;編輯器和代碼編輯器&#xff0c;可以幫助開發者快速創建和編輯網頁。Dreamweaver提供了豐富的功能和工具&#xff0c;包括代碼提示、語法高亮、代碼…

51單片機學習(1)2-1點亮一個LED

#include <REGX52.H> void() { p20xFE;//1111 1110 while(1) { //讓程序停了下來了。 } }

教你一分鐘搭建適合IT人員的在線開發工具箱

文章目錄 1. 使用Docker本地部署it-tools2. 本地訪問it-tools3. 安裝cpolar內網穿透4. 固定it-tools公網地址 本篇文章將介紹如何在Windows上使用Docker本地部署IT- Tools&#xff0c;并且同樣可以結合cpolar實現公網訪問。 在前一篇文章中我們講解了如何在Linux中使用Docker搭…

Anaconda Jupyter 報錯及解決方法記錄

一、AttributeError: module lib has no attribute X509_V_FLAG_CB_ISSUER_CHECK 背景&#xff1a;Anaconda更新版本后&#xff0c;運行import oss2時報錯 ~/anaconda3/lib/python3.8/site-packages/OpenSSL/crypto.py in X509StoreFlags() 1535 NOTIFY_POLICY _lib…

【Java基礎】集合(1) —— Collection

存儲不同類型的對象: Object[] arrnew object[5];數組的長度是固定的, 添加或刪除數據比較耗時 集合: Object[] toArray可以存儲不同類型的對象隨著存儲的對象的增加&#xff0c;會自動的擴容集合提供了非常豐富的方法&#xff0c;便于操縱集合相當于容器&#xff0c;可以存儲多…

探索Git之旅:倉庫代碼版本控制藝術

探索Git之旅&#xff1a;倉庫代碼版本控制藝術 引言Git基礎與核心概念什么是版本控制&#xff1f;Git的工作流程分布式特性 Git實戰操作指南安裝與配置克隆倉庫日常操作分支管理解決沖突 高級技巧與最佳實踐Git FlowGit鉤子Git別名 安全與性能考量結語與引發討論 引言 在軟件開…

馮喜運:5.16黃金是否突破阻力?黃金原油趨勢分析

【黃金消息面分析】&#xff1a;周四(5月16日)亞市盤中&#xff0c;現貨黃金延續昨日升勢&#xff0c;金價目前最高觸及2397.44美元/盎司&#xff0c;為4月19日以來新高。FXStreet首席分析師Valeria Bednarik撰文&#xff0c;對黃金技術前景進行分析。Bednarik指出&#xff0c;…

「51媒體」北京財經媒體有哪些?媒體邀約宣傳

傳媒如春雨&#xff0c;潤物細無聲&#xff0c;大家好&#xff0c;我是51媒體網胡老師。 北京作為中國的首都&#xff0c;擁有眾多的財經媒體&#xff0c;這些媒體在財經新聞報道、經濟分析、市場研究等方面發揮著重要作用。根據搜索結果&#xff0c;以下是一些北京地區的財經…

富格林:曝光虛假套路規避虧損

富格林指出&#xff0c;在現貨黃金市場中&#xff0c;交易時間很充足投資機會也多的是&#xff0c;但為什么還是有人虧損甚至爆倉呢&#xff1f;其實導致這種情況&#xff0c;是因為有一些投資者不知道其中的虛假套路&#xff0c;很容易就一頭栽進去了。要規避虛假套路帶來的虧…

CV每日論文--2024.5.15

1、Can Better Text Semantics in Prompt Tuning Improve VLM Generalization? 中文標題&#xff1a;更好的文本語義在提示微調中能否提高視覺語言模型的泛化能力? 簡介&#xff1a;這篇論文介紹了一種新的可學習提示調整方法,該方法超越了僅對視覺語言模型進行微調的傳統方…

Lazyboy品牌發布會“球幕氣膜”

Lazyboy品牌發布會“球幕氣膜”為品牌活動提供了一個獨特、現代化、環保的展示空間。這座球幕氣膜不僅為發布會提供了一個視覺震撼的場地&#xff0c;也為與會嘉賓帶來了全新的體驗。作為輕空間&#xff08;江蘇&#xff09;膜科技有限公司&#xff08;以下簡稱“輕空間”&…

使用Docker在阿里云ECS上部署Gitlab,提供代碼托管、CICD 和 docker鏡像服務

文章目錄 使用Docker在阿里云ECS上部署Gitlab1.購買一個數據&#xff0c;掛載到/data用于存儲gitlab相關數據2. 部署docker引擎3. 調整ssh的默認端口&#xff0c;將22端口留給gitlab4. 部署gitlab5. 進入docker容器獲取gitlab的默認密碼6. 登錄gitlab&#xff0c;完成gitlab-ru…

linux ndk編譯搭建測試

一、ndk下載 NDK 下載 | Android NDK | Android Developers 二、ndk環境變量配置 ndk解壓&#xff1a; unzip android-ndk-r26d-linux.zip 環境變量配置&#xff1a; export NDK_HOME/rd/own/test/android-ndk-r26d/ export PATH$PATH:$NDK_HOME 三、編譯測試驗證 …

虛函數應用和原理

虛函數的表現形式 用子類初始化父類指針, 調用虛函數時, 仍然調用的是子類的虛函數 測試代碼如下 #include <iostream> #include <string.h>using namespace std;class A { public:void test() { cout << a << endl; };virtual void test2 (){ cout …

LeetCode-2589. 完成所有任務的最少時間【棧 貪心 數組 二分查找 排序】

LeetCode-2589. 完成所有任務的最少時間【棧 貪心 數組 二分查找 排序】 題目描述&#xff1a;解題思路一&#xff1a;貪心暴力解題思路二&#xff1a;棧二分查找解題思路三&#xff1a;簡化版 題目描述&#xff1a; 你有一臺電腦&#xff0c;它可以 同時 運行無數個任務。給你…