LeetCode HOT100(二)雙指針

移動0

給定一個數組 nums,編寫一個函數將所有 0 移動到數組的末尾,同時保持非零元素的相對順序。
請注意 ,必須在不復制數組的情況下原地對數組進行操作。

輸入: nums = [0,1,0,3,12]
輸出: [1,3,12,0,0]


解法1:雙指針+交換
指針L:維護一個非零序列,L之前的元素都是非零的元素
指針R:尋找非零的元素,將其加入到L維護的序列中

public void moveZeroes(int[] nums) {int l = 0;int r = 0;while(r<nums.length){if(nums[r]!=0)swap(nums,l++,r);r++;}
}public void swap(int[] nums,int l,int r){if(l == r) return;nums[l] = nums[l] ^ nums[r];nums[r] = nums[l] ^ nums[r];nums[l] = nums[l] ^ nums[r];
}
func moveZeroes(nums []int)  {slow := 0for i,_ := range nums{if nums[i]!=0{tmp := nums[slow]nums[slow] = nums[i]nums[i] = tmpslow++}}
}

解法2:雙指針+賦值0
解法和1類似,只不過1是交換非零元素和0元素,2將非零元素全部移動到前面,后面統一賦值為0

public void moveZeroes(int[] nums) {int cur = 0;for(int i=0; i<nums.length; i++){if(nums[i]!=0){nums[cur++] = nums[i];}}for(;cur<nums.length; cur++){nums[cur] = 0;}
}

盛水最多的容器

給定一個長度為 n 的整數數組 height 。有 n 條垂線,第 i 條線的兩個端點是 (i, 0) 和 (i, height[i]) 。
找出其中的兩條線,使得它們與 x 軸共同構成的容器可以容納最多的水。
返回容器可以儲存的最大水量。
說明:你不能傾斜容器。
image.png

輸入:[1,8,6,2,5,4,8,3,7]
輸出:49
解釋:圖中垂直線代表輸入數組 [1,8,6,2,5,4,8,3,7]。在此情況下,容器能夠容納水(表示為藍色部分)的最大值為 49。


解放1:雙指針
在這里插入圖片描述

在每個狀態下,無論長板或短板向中間收窄一格,都會導致水槽 底邊寬度 ?1-1?1 變短:

  • 若向內 移動短板 ,水槽的短板 min(h[i],h[j])min(h[i], h[j])min(h[i],h[j]) 可能變大,因此下個水槽的面積 可能增大 。
  • 若向內 移動長板 ,水槽的短板 min(h[i],h[j])min(h[i], h[j])min(h[i],h[j]) 不變或變小,因此下個水槽的面積 一定變小 。

因此,初始化雙指針分列水槽左右兩端,循環每輪將短板向內移動一格,并更新面積最大值,直到兩指針相遇時跳出;即可獲得最大面積。

public int maxArea(int[] height) {int l = 0;int r = height.length-1;int area = 0;while(l<r){if(height[l]<height[r]){int cur = height[l]*(r-l);area = Math.max(area, cur);l++;}else{int cur = height[r]*(r-l);area = Math.max(area, cur);r--;}}return area;
}
func maxArea(height []int) int {l,r := 0,len(height)-1res := 0for l<r {if height[l] < height[r]{res = int(math.Max(float64(res),float64(height[l]*(r-l))))l++;}else{res = int(math.Max(float64(res),float64(height[r]*(r-l))))r--;}}return res
}

三數之和

給你一個整數數組 nums ,判斷是否存在三元組 [nums[i], nums[j], nums[k]] 滿足 i != j、i != k 且 j != k ,同時還滿足 nums[i] + nums[j] + nums[k] == 0 。請你返回所有和為 0 且不重復的三元組。
注意:答案中不可以包含重復的三元組。

輸入: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] 。
注意,輸出的順序和三元組的順序并不重要。


解法1:排序+雙指針
先排序保證數據有序,這樣就不會保存重復的數組了
接下來,外層循環確定一個 i 的值,內層循環使用左右兩端向中間移動的雙指針

//每個指針移動時跳過重復元素版,力扣不友好,時間還不如不跳過的快
public List<List<Integer>> threeSum(int[] nums) {List<List<Integer>> res = new ArrayList<>();Arrays.sort(nums);int i=0; while(i<nums.length-2){int sum = -nums[i];int j=i+1; int k=nums.length-1;while(j<k){int cur = nums[j]+nums[k];if(cur > sum){while( j<k && nums[k]==nums[k-1])k--;k--;}else if(cur < sum){while( j<k && nums[j]==nums[j+1])j++;j++;}else{List<Integer> tmp = new ArrayList<>();tmp.add(nums[i]);tmp.add(nums[j]);tmp.add(nums[k]);res.add(tmp);while( j<k && nums[k]==nums[k-1])k--;k--;while( j<k && nums[j]==nums[j+1])j++;j++;}}while(i<nums.length-2 && nums[i+1]==nums[i])i++;i++;}return res;
}//不跳過版
public List<List<Integer>> threeSum(int[] nums) {List<List<Integer>> res = new ArrayList<>();Arrays.sort(nums);int i=0; while(i<nums.length-2){int sum = -nums[i];int j=i+1; int k=nums.length-1;while(j<k){int cur = nums[j]+nums[k];if(cur > sum)k--;else if(cur < sum)j++;else{List<Integer> tmp = new ArrayList<>();tmp.add(nums[i]);tmp.add(nums[j]);tmp.add(nums[k]);res.add(tmp);while(j<k&&nums[k]==nums[k-1])k--;k--;}}while(i<nums.length-2 && nums[i+1]==nums[i])i++;i++;}return res;
}
func threeSum(nums []int) [][]int {res := make([][]int,0)sort.Ints(nums)for i,v:=range nums{if i==len(nums)-2 {break}if i>0&&nums[i]==nums[i-1] {continue}target := -v;l,r := i+1,len(nums)-1for l<r {sum := nums[l]+nums[r]if sum>target{for l<r&&nums[r]==nums[r-1]{r--}r--;}else if sum<target{for l<r&&nums[l]==nums[l+1]{l++}l++}else{res = append(res,[]int{v,nums[l],nums[r]})for l<r&&nums[l]==nums[l+1]{l++}l++}}}return res
}

接雨水

給定 n 個非負整數表示每個寬度為 1 的柱子的高度圖,計算按此排列的柱子,下雨之后能接多少雨水。
在這里插入圖片描述

輸入:height = [0,1,0,2,1,0,1,3,2,1,2,1]
輸出:6
解釋:上面是由數組 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度圖,在這種情況下,可以接 6 個單位的雨水(藍色部分表示雨水)。


解法1:最大前綴+最大后綴
對于每一個柱子能接的水,取決于:

  1. 當前柱子高度h0
  2. 當前柱子左側最高的柱子h1,當前柱子右側最高的柱子h2,取二者最小的值
  3. 當前柱子能接的水為:min(h1,h2)-h0
public int trap(int[] height) {int len = height.length;int pre[] = new int[len];int suf[] = new int[len];pre[0] = height[0];for(int i=1; i<len; i++){pre[i] = Math.max(pre[i-1],height[i]);}suf[len-1] = height[len-1];for(int i=len-2; i>=0; i--){suf[i] = Math.max(suf[i+1],height[i]);}int sum = 0;for(int i=0; i<len; i++){int low = Math.min(pre[i],suf[i]);sum += (low-height[i]);}return sum;
}
func trap(height []int) int {if len(height)<3 {return 0}leng := len(height)leftMax := make([]int,leng)rightMax := make([]int,leng)leftMax[0] = height[0]for i:=1; i<len(height); i++ {if(leftMax[i-1]>height[i]){leftMax[i] = leftMax[i-1]}else{leftMax[i] = height[i]}}rightMax[len(height)-1] = height[len(height)-1]for i:=len(height)-2; i>=0; i-- {if rightMax[i+1]>height[i] {rightMax[i] = rightMax[i+1]}else{rightMax[i] = height[i]}}res := 0for i:=0; i<len(height); i++ {var curHeight intif(leftMax[i]>rightMax[i]){curHeight = rightMax[i]}else{curHeight = leftMax[i]}res+=(curHeight-height[i])}return res
}

解法2:雙指針,解法1的節省空間的方法
解法1為了維持每個位置的左右邊界最大值,使用數組來表示,可以使用雙指針來代替數組。
每次雙指針移動之后比較最大值,小的一方先移動。

public int trap(int[] height) {int len = height.length;int res = 0;int left = 0;int right = len-1;int leftMax = 0;int rightMax = 0;while(left<=right){leftMax = Math.max(leftMax,height[left]);rightMax = Math.max(rightMax,height[right]);if(leftMax<=rightMax){res+=(leftMax-height[left++]);}else{res+=(rightMax-height[right--]);}}return res;
}

解法3:單調棧
棧內元素依然是單調遞減。
image.png
當遇到相等的時候也要出棧,但是在計算面積的時候,由于左右邊界中有一條邊界和當前計算的柱子高度相等,所以高度差是0,計算出來也沒影響。

public int trap(int[] height) {int len = height.length;Deque<Integer> stack = new ArrayDeque<>();int res = 0;for(int i=0; i<len; i++){while(!stack.isEmpty() && height[stack.peek()]<=height[i]){int curIndex = stack.pop();if(stack.isEmpty()) break;int preIndex = stack.peek();res+=((i-1-preIndex)*(Math.min(height[preIndex],height[i])-height[curIndex]));}stack.push(i);}return res;
}

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

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

相關文章

“論基于構件的軟件開發方法及其應用”寫作框架,軟考高級論文,系統架構設計師論文

論文真題 基于構作的軟件開發 (Component-Based Software Development&#xff0c;CBSD) 是一種基于分布對象技術、強調通過可復用構件設計與構造軟件系統的軟件復用途徑。基于構件的軟件系統中的構件可以是COTS &#xff08;Commercial-Off-the-Shelf&#xff09;構件&#x…

Spring Boot輕松整合Minio實現文件上傳下載功能

一、Linux 安裝Minio 安裝 在/root/xxkfz/soft目錄下面創建文件minio文件夾&#xff0c;進入minio文件夾&#xff0c;并創建data目錄&#xff1b; [rootxxkfz soft]# mkdir minio [rootxxkfz soft]# cd minio [rootxxkfz minio]# mkdir data 執行如下命令進行下載 [rootxx…

Java內存劃分詳解:從基礎到進階

Java內存劃分詳解&#xff1a;從基礎到進階 1. 程序計數器&#xff08;Program Counter Register&#xff09;2. Java虛擬機棧&#xff08;Java Virtual Machine Stack&#xff09;3. 堆&#xff08;Heap&#xff09;4. 方法區&#xff08;Method Area&#xff09;5. 運行時常量…

DDD架構面試問題

基礎概念 什么是領域驅動設計&#xff08;DDD&#xff09;&#xff1f; 請解釋一下DDD的核心思想和目標。 DDD中的領域&#xff08;Domain&#xff09;是什么&#xff1f; 請描述一下領域的概念以及它在軟件開發中的重要性。 什么是限界上下文&#xff08;Bounded Context&am…

ArduPilot開源代碼之OpticalFlow_backend

ArduPilot開源代碼之OpticalFlow_backend 1. 源由2. Library設計3. 重要例程3.1 OpticalFlow_backend::_update_frontend3.2 OpticalFlow_backend::_applyYaw 4. 總結5. 參考資料 1. 源由 光流計是一種低成本定位傳感器&#xff0c;所有的光流計設備傳感驅動代碼抽象公共部分統…

[計網初識1] TCP/UDP

學習內容 1.TCP建立鏈接的3次握手&#xff0c;斷開連接的4次揮手 2.TCP報文段組成 內容 1.TCP 建立連接的3次握手? 假設主動方是客戶端&#xff0c;被動方是服務端。 第一次 客戶端給服務端發送 “hello,我是客戶端” (TCP段中 SYN1) 第二次 服務端給客戶端發送"我接…

從零開始的python學習生活2

接上封裝 class Phone:__volt0.5def __keepsinglecore(self):print("讓cpu以單核運行")def if5G(self):if self.__volt>1:print("5G通話已開啟")else:self.__keepsinglecore()print("電量不足&#xff0c;無法使用5G通話&#xff0c;已經設置為單…

Django項目創建的準備工作【 2 】

【 一 】調整后端目錄 #1 目錄結構 """ ├── luffy_api├── logs/ # 項目運行時/開發時日志目錄 - 包├── manage.py # 腳本文件├── luffy_api/ # 項目主應用&#xff0c;開發時的代碼保存 - 包├── apps/ …

【Git基本操作】添加文件 | 修改文件 | 及其各場景下.git目錄樹的變化

目錄 1. 添加文件&add操作和commit操作 2. .git樹狀目錄的變化 3. git其他操作 4. 修改文件 4.1 git status 4.2 git diff 1. 添加文件&add操作和commit操作 add操作&#xff1a;將工作區中所有文件的修改內容 添加進版本庫的暫存區中。commit操作&#xff1a;…

云端編碼:將您的技術API文檔安全存儲在iCloud的最佳實踐

云端編碼&#xff1a;將您的技術API文檔安全存儲在iCloud的最佳實踐 作為一名技術專業人士&#xff0c;管理不斷增長的API文檔庫是一項挑戰。iCloud提供了一個無縫的解決方案&#xff0c;允許您在所有設備上存儲、同步和訪問您的個人技術API文檔。本文將指導您如何在iCloud中高…

系統服務綜合實驗(dns服務,nfs服務)

題目&#xff1a;現有主機 node01 和 node02&#xff0c;完成如下需求&#xff1a; 1、在 node01 主機上提供 DNS 和 WEB 服務 2、dns 服務提供本實驗所有主機名解析 3、web服務提供 www.rhce.com 虛擬主機 4…

three-tile: 1. 第一個three-tile程序

上篇介紹了&#xff1a;three-tile&#xff1a; 一個開源的輕量級三維瓦片庫-CSDN博客 three-tile 是一個開源的輕量級三維瓦片庫&#xff0c;它基于threejs使用typescript開發&#xff0c;提供一個三維地形模型&#xff0c;能輕松給你的應用增加三維瓦片地圖。 項目地址&…

C#知識|賬號管理系統:UI層-添加賬號窗體設計思路及流程。

哈嘍,你好啊,我是雷工! 前邊練習過詳情頁窗體的設計思路及流程: 《C#知識|上位機UI設計-詳情窗體設計思路及流程(實例)》 本節練習添加賬號窗體的UI設計,以下為學習筆記。 01 效果展示 02 添加窗體 在UI層添加Windows窗體,設置名稱為:FrmAddAcount.cs 設置窗體屬…

Nginx七層(應用層)反向代理:UWSGI代理uwsgi_pass篇

Nginx七層&#xff08;應用層&#xff09;反向代理 UWSGI代理uwsgi_pass篇 - 文章信息 - Author: 李俊才 (jcLee95) Visit me at CSDN: https://jclee95.blog.csdn.netMy WebSite&#xff1a;http://thispage.tech/Email: 291148484163.com. Shenzhen ChinaAddress of this a…

數據結構模板2

Trie樹&#xff1a;用來高效存儲和查找字符串集合的數據結構&#xff1a; 模板題&#xff1a;https://www.acwing.com/problem/content/837/ AC代碼&#xff1a; #include<bits/stdc.h> using namespace std; int son[100010][26],cnt[100010],idx; char str[100010]; …

數據的洞察力:SQL Server Analysis Services在數據分析中的卓越應用

數據的洞察力&#xff1a;SQL Server Analysis Services在數據分析中的卓越應用 在商業智能和數據分析領域&#xff0c;SQL Server Analysis Services (SSAS) 是一款強大的工具&#xff0c;它提供了多維數據和數據挖掘模型的創建、部署和管理功能。本文將深入探討如何在SQL Se…

云端生活,智能管理:在iCloud中打造您的個人購物清單與預算計劃

云端生活&#xff0c;智能管理&#xff1a;在iCloud中打造您的個人購物清單與預算計劃 在快節奏的現代生活中&#xff0c;個人財務管理和購物規劃變得尤為重要。iCloud提供了一個強大的平臺&#xff0c;讓我們能夠存儲、同步和共享個人購物清單與預算計劃。本文將詳細介紹如何…

代碼隨想錄算法訓練營第二十九天

452. 用最少數量的箭引爆氣球 這道題目我原本的想法是只要當前的氣球半徑范圍在已有的箭頭能夠擊穿的氣球半徑內就可以實現 但是 箭射出去的地方是一個值 而不是一個范圍 因此有相同的重疊范圍的許多氣球并一定都有相同的值&#xff0c;因此這種方法不可取 這題的主要局部最…

最短路徑算法(算法篇)

算法之最短路徑算法 最短路徑算法 概念&#xff1a; 考查最短路徑問題&#xff0c;可能會輸入一個賦權圖(也就是邊帶有權的圖)&#xff0c;則一條路徑的v1v2…vN的值就是對路徑的邊的權求和&#xff0c;這叫做賦權路徑長&#xff0c;如果是無權路徑長就是單純的路徑上的邊數。…

mac安裝配置cmake

本機是2015 macbook pro mid&#xff0c;已經有點老了&#xff0c;用homebrew下cmake老出問題 其實cmake官網安裝也不麻煩 一、官網下載對應安裝包 Download CMake 和所有dmg文件一樣安裝 二、改成命令行使用 一般來說 tutorial 給的都是命令行build 命令行的設置如下&am…