不到十個例題帶你拿下c++雙指針算法(leetcode)

移動零問題

https://leetcode.cn/problems/move-zeroes/submissions/

1.題目解析

必須在原數組進行修改,不可以新建一個數組

非零元素相對順序不變

2.算法原理

【數組劃分】【數組分塊】

這一類題會給我們一個數組,讓我們劃分區間,比如說這題,最后會劃分為兩個區間,前一段是非零元素,后一段是零,一般我們只要看到這樣的特性,腦海里就應該想到用雙指針算法來解決(利用數組下標充當指針)

定義兩個指針:

兩個指針的作用:

cur :從左往后掃描數組,遍歷數組。

dest : 已處理的區間內,非零元素的最后一個位置

如何做到:

cur從前往后遍歷的過程中:

1.遇到0元素:cur++;

2.遇到非零元素:

交換

相關知識:快速排序

雙指針的思想其實就是快排的核心思想

class Solution {
public:void moveZeroes(vector<int>& nums) {for(int cur=0,dest=-1;cur<nums.size();cur++){if(nums[cur]){swap(nums[++dest],nums[cur]);}}}
};

?

復寫零問題

https://leetcode.cn/problems/duplicate-zeros/

1.題目解析

長度固定:不能越界

在原始數組進行操作

2.算法原理:

解法:雙指針算法 先根據異地操作,然后優化成雙指針下的“就地操作”

根據異地操作,得出先模擬一遍復寫的操作,然后從后向前進行覆蓋,從前往后會發生覆蓋多的值。

總結:

1.先找到最后一個復寫的數

用雙指針模擬一遍 cur=0,dest=-1;

先判斷cur位置的值,決定dest向后移動幾步,判斷dest是否已經到了最后的位置,cur++;

2.從后向前進行操作

特例:數組越界

所以要加上一個步驟:處理越界

3.解題代碼:

class Solution {
public:void duplicateZeros(vector<int>& arr) {int cur=0,dest=-1,n=arr.size();//先模擬while(cur<n){if(arr[cur]) dest++;else         dest+=2;if(dest>=n-1) break;cur++;}//判斷邊界if(dest==n){arr[n-1]=0;dest-=2;cur--;}//從后向前while(cur>=0){if(arr[cur]==0){arr[dest--]=0;arr[dest--]=0;cur--;}else arr[dest--]=arr[cur--];}}
};

?

快樂數問題

https://leetcode.cn/problems/happy-number/

1.題目解析

一直替換

分為兩種情況:

變成一

無限循環

兩種情況

2.算法原理

有沒有發現,一直平方到最后,一定會成環

解法:快慢雙指針

1.定義快慢雙指針

2.慢指針每次向后移動一步,快指針每次走兩步

3.判斷相遇的時候的值即可

雙指針只是一種思想,不需要一定定義雙指針,在這個題中快指針就是平方兩次,慢指針平方一次

為什么會一定會重復

證明方法:

鴿巢原理(抽屜原理):

n個巢穴 n+1個鴿子-->至少有一個巢穴里面的鴿子數量大于1

3.解題代碼

class Solution {
public:int Sum(int n){int sum=0;while(n){int g=n%10;sum+=g*g;n/=10;}return sum;}bool isHappy(int n) {int slow=n,fast=Sum(n);while(slow!=fast){slow=Sum(slow);fast=Sum(Sum(fast));}return slow==1;}
};

盛水最多的容器

https://leetcode.cn/problems/container-with-most-water/

1.題目解析

只能水平放置,也就是找最大的矩形

2.算法原理

解法一:暴力枚舉:雙重循環

優點:想法簡單

缺點:時間復雜度過高

解法二:頭尾雙指針:

v=h*w

寬度一直在減小,而高度有兩種情況,變大或變小,在寬度一直在變小的情況下,我們高度必須選擇更高的

3.解題代碼


class Solution {
public:int maxArea(vector<int>& height) {int left=0,right=height.size()-1;int v=-1;while(left<right){int tv=min(height[left],height[right])*(right-left);v=max(tv,v);if(height[left]>height[right])  right--;else                            left++;}return v;}
};

和為s的兩個數字問題

1.題目解析

有序數組

隨意輸出一對

2.算法原理

解法一:暴力枚舉 雙重循環 n^2復雜度

解法二:利用單調性,使用雙指針算法解決問題

首尾相加

判斷數值,如果大于目標值,right--反之left++,因為數組是有序的

3.解題代碼

vector<int> twosum(vector &nums,int t)
{int left =0,right=nums.size()-1;while(left<right){int sum=nums[left]+nums[right];if(sum>t) right--;else if(sum<t) left++;else return {num[left],nums[right]};}//照顧編譯器return {-1,-1};
}

有效三角形個數

https://leetcode.cn/problems/valid-triangle-number/

1.題目解析

相同的不算一個

2.講解算法原理

補充數學知識:給我們三個數,判斷是否能構成三角形

我們僅需要一個公式,就能判斷是否能構成三角形:

如果我們已經知道三個數的大小順序,只需要a+b>c(c是最大的數)

優化:先對整個數組排序

解法一:暴力枚舉

for(i=0;i<n;i++)

for(j=i+1;j<n;j++)for(k=j+1;k<n;k++)check(i,j,k)

解法二:利用單調性,使用雙指針算法來解決問題

①先固定最大的數

②在最大的數的左區間里,使用雙指針算法,快速統計

3.解題代碼

class Solution {
public:int triangleNumber(vector<int>& nums) {int n=nums.size();int ret=0;sort(nums.begin(),nums.end());for(int i=n-1;i>=2;i--){int left=0,right=i-1;while(left<right){if(nums[left]+nums[right]>nums[i]){ret+=right-left;right--;}else{left++;}}}return ret;}
};

三數之和問題

https://leetcode.cn/problems/3sum/

1.題目解析

三個數的下標不同

答案不可重復(去重)

有可能沒有答案

2.算法原理

解法一:先排序+暴力枚舉+利用set去重o(n^3)

解法二:排序+雙指針:

找到右邊區間兩數之和為左邊數字的相反即可

1.排序

2.固定一個數a

3.在該數后邊的區間,利用雙指針的算法,快速找到和為-a的兩個數

處理細節問題:

1.去重:

找到一種結果之后,left和right指針要跳過重復元素。

當使用完一次雙指針算法之后,i也要跳過重復元素(避免越界)

2.不漏:

找到一種結果后,不要“停”,縮小區間,繼續尋找

3。解題代碼

class Solution {
public:vector<vector<int>> threeSum(vector<int>& nums) {sort(nums.begin(),nums.end());vector<vector<int>> ret;int n=nums.size();for(int i=0;i<n;){if(nums[i]>0) break;int left=i+1,right=n-1,t=-nums[i];while(left<right){int sum=nums[left]+nums[right];if(sum<t) left++;else if(sum>t) right--;else{ret.push_back({nums[i],nums[left],nums[right]});left++,right--;while(left<right&&nums[left]==nums[left-1]) left++;while(left<right&&nums[right]==nums[right+1]) right--;}}i++;while(i<n&&nums[i]==nums[i-1]) i++;}return ret;}
};

四數之和

https://leetcode.cn/problems/4sum/

1.題目解析

三數之和的進階版本,基本算法原理和三數之和大差不差

2.算法原理

解法一:排序+暴力枚舉

四個循環,絕對超時

解法二:排序+雙指針

1.依次固定一個數i

2.在i后面的區間內,利用三數之和找到三個數,讓他們三個的和等于target-i;

{

1.依次固定一個j

2.在j后邊的區間里,利用“雙指針找到兩個數,使得這兩個數之和等于target-i-j”

}

處理細節問題:

不重,不漏

3.解題代碼:

class Solution {
public:vector<vector<int>> fourSum(vector<int>& nums, int target) {vector<vector<int>> ret;//1.排序sort(nums.begin(),nums.end());//2.利用雙指針解決問題int n=nums.size();for(int i=0;i<n;){//利用三數之和for(int j=i+1;j<n;){int left=j+1,right=n-1;long long aim=(long long)target-nums[i]-nums[j];while(left<right){int sum=nums[left]+nums[right];if(sum<aim) left++;else if(sum>aim) right--;else{ret.push_back({nums[i],nums[j],nums[left++],nums[right--]});//去重1while(left<right&&nums[left]==nums[left-1]) left++;while(left<right&&nums[right]==nums[right+1]) right--;}}//去重2j++;while(j<n&&nums[j]==nums[j-1]) j++;			}//去重3i++;while(i<n&&nums[i]==nums[i-1]) i++;}  return ret;}
};

覺得有幫助的慣用老爺麻煩點點關注!!!

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

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

相關文章

【機器學習】Nonlinear Independent Component Analysis - Aapo Hyv?rinen

Linear independent component analysis (ICA) x i ( k ) ∑ j 1 n a i j s j ( k ) for all i 1 … n , k 1 … K ( ) x_i(k) \sum_{j1}^{n} a_{ij}s_j(k) \quad \text{for all } i 1 \ldots n, k 1 \ldots K \tag{} xi?(k)j1∑n?aij?sj?(k)for all i1…n,k1…K()…

VUE語法-$refs和ref屬性的使用

1、$refs和ref屬性的使用 1、$refs:一個包含 DOM 元素和組件實例的對象&#xff0c;通過模板引用注冊。 2、ref實際上獲取元素的DOM節點 3、如果需要在Vue中操作DOM我們可以通過ref和$refs這兩個來實現 總結:$refs可以獲取被ref屬性修飾的元素的相關信息。 1.1、$refs和re…

PS_魔幻

首先打開一個背景圖片 然后ctrl j復制一層背景 在調整中將圖片改成黑白顏色 點擊調整中的 色相/飽和度 調整明度 點擊畫筆工具&#xff0c;并且設置畫筆模板 調節畫筆大小&#xff0c;將筆記本電腦涂個概況 然后再新建色相/飽和度 勾選著色 調節背景顏色至喜歡 右鍵混合選項 …

04-React腳手架 集成Axios

初始化React腳手架 前期準備 1.腳手架: 用來幫助程序員快速創建一個基于xxx庫的模板項目 1.包含了所有需要的配置&#xff08;語法檢查、jsx編譯、devServer…&#xff09;2.下載好了所有相關的依賴3.可以直接運行一個簡單效果 2.react提供了一個用于創建react項目的腳手架庫…

【華為OD機試python】分糖果【2023 B卷|100分】

【華為OD機試】-真題 !!點這里!! 【華為OD機試】真題考點分類 !!點這里 !! 題目描述 小明從糖果盒中隨意抓一把糖果,每次小明會取出一半的糖果分給同學們。 當糖果不能平均分配時,小明可以選擇從糖果盒中(假設盒中糖果足夠) 取出一個糖果或放回一個糖果。 小明最少需要多…

【喵叔閑扯】---小談靜態類和單例模式

靜態類&#xff08;Static Class&#xff09;和單例&#xff08;Singleton&#xff09;都是在編程中用于實現特定類型的設計模式或代碼組織方式。它們在不同的情境下有不同的用途和特點。 靜態類&#xff08;Static Class&#xff09; 靜態類是一種類&#xff0c;它的方法和屬性…

一鍵去水印免費網站快速無痕處理圖片、視頻水印

水印問題往往是一個大麻煩。即使我們只想將這些照片保留在我們的個人相冊中以供懷舊&#xff0c;水印也可能像頑固的符號一樣刺激我們的眼睛。為了解決這個問題&#xff0c;我們需要不斷探索創新的解決方案&#xff0c;讓我們深入研究一款強大的一鍵去水印免費網站“水印云”。…

Rust并發編程:理解線程與并發

大家好&#xff01;我是lincyang。 今天我們來深入探討Rust中的并發編程&#xff0c;特別是線程的使用和并發的基本概念。 Rust中的線程 Rust使用線程來實現并發。線程是操作系統可以同時運行的最小指令集。在Rust中&#xff0c;創建線程非常簡單&#xff0c;但與此同時&…

ubuntu 系統 怎么判斷系統有沒有GPU

在 Ubuntu 系統中&#xff0c;您可以通過幾種方式來檢查系統是否包含顯卡&#xff0c;以及顯卡的詳細信息。以下是一些常用的方法&#xff1a; lspci 命令&#xff1a; 打開終端。輸入 lspci | grep VGA 命令。這將顯示系統中所有的 VGA 兼容設備&#xff0c;通常是您的顯卡。 …

二叉搜索樹java實現

顧名思義&#xff0c;二叉搜索樹是一棵二叉樹&#xff0c;每個節點就是一個對象&#xff0c;這個對象包含屬性left、right和parent。left指向節點的左孩子&#xff0c;right指向節點的右孩子&#xff0c;parent指向節點的父節點&#xff08;雙親&#xff09;。如果某個孩子節點…

scala的類介紹

scala的類、抽象類、接口、對象 class :類&#xff0c; 通過new關鍵字來實例化&#xff0c;每次實例化都會創建一個新的對象&#xff1b;用來定義普通的類。object&#xff1a;對象&#xff0c;用來定義一個單例對象的&#xff0c;它只有一個實例&#xff0c;且在程序運行期間…

黑馬點評筆記 redis實現緩存

文章目錄 什么是緩存?為什么要使用緩存 如何使用緩存功能實現緩存模型和思路代碼實現 緩存更新策略數據庫緩存不一致解決方案代碼實現 什么是緩存? 緩存(Cache),就是數據交換的緩沖區,俗稱的緩存就是緩沖區內的數據,一般從數據庫中獲取,存儲于本地代碼(例如: 例1:Static fi…

vr小鼠虛擬解剖實驗教學平臺減少了受感染風險

家畜解剖實驗教學是培養畜牧獸醫專業學生實際操作能力的專業教學活動中的核心手段。采取新型教學方式與手段&#xff0c;合理設置實驗教學內容&#xff0c;有助于激發學生的操作積極性&#xff0c;促進實踐教學的改革。 家畜解剖VR仿真教學是一種借助VR虛擬現實制作和web3d開發…

常用通信接口、協議:SCCB

一、概述 SCCB(串行攝像頭控制總線)是由歐姆尼圖像技術公司&#xff08;OmniVision&#xff09;開發的一種類IIC的總線&#xff0c;主要用于其OV系列的圖像傳感器上&#xff08;但目前有很多家的圖像傳感器都有采用該控制總線&#xff09;。相對于IIC總線來說SCCB與之最主要的差…

java基礎-集合

1、集合 在java中&#xff0c;集合&#xff08;Collection&#xff09;指的是一組數據容器&#xff0c;它可以存儲多個對象&#xff0c;并且允許用戶通過一些方法來訪問與操作這些對象。j 集合的實現原理都基于數據結構和算法&#xff0c;如下&#xff1a; 數據結構&#xff1…

振南技術干貨集:制冷設備大型IoT監測項目研發紀實(2)

注解目錄 1.制冷設備的監測迫在眉睫 1.1 冷食的利潤貢獻 1.2 冷設監測系統的困難 &#xff08;制冷設備對于便利店為何如何重要&#xff1f;了解一下你所不知道的便利店和新零售行業。關于電力線載波通信的論戰。&#xff09; 2、電路設計 2.1 防護電路 2.1.1 強電防護 …

基于JavaWeb+SSM+Vue教學輔助微信小程序系統的設計和實現

基于JavaWebSSMVue教學輔助微信小程序系統的設計和實現 源碼獲取入口前言主要技術系統設計功能截圖Lun文目錄訂閱經典源碼專欄Java項目精品實戰案例《500套》 源碼獲取 源碼獲取入口 前言 1.1 概述 隨著信息時代的快速發展&#xff0c;互聯網的優勢和普及&#xff0c;人們生活…

[項目管理-33/創業之路-87/管理者與領導者-127]:如何提升自己項目管理的能力和水平

目錄 前言&#xff1a; 一、項目經理的角色定位 1.1 項目經理的職責 1.2 不同矩陣類型的項目&#xff0c;項目經理的職責 1.3 項目經理的角色定位 1.4 項目經理的發展路徑 二、項目經理項目理論和知識結構 三、軟件項目經理在計算機水平的提升 四、項目經理業務知識的…

nodejs微信小程序+python+PHP-儲能電站運營管理系統的設計與實現-計算機畢業設計推薦

目 錄 摘 要 I ABSTRACT II 目 錄 II 第1章 緒論 1 1.1背景及意義 1 1.2 國內外研究概況 1 1.3 研究的內容 1 第2章 相關技術 3 2.1 nodejs簡介 4 2.2 express框架介紹 6 2.4 MySQL數據庫 4 第3章 系統分析 5 3.1 需求分析 5 3.2 系統可行性分析 5 3.2.1技術可行性&#xff1a;…

七、通過libfdk_aac編解碼器實現aac音頻和pcm的編解碼

前言 測試環境&#xff1a; ffmpeg的4.3.2自行編譯版本windows環境qt5.12 AAC編碼是MP3格式的后繼產品&#xff0c;通常在相同的比特率下可以獲得比MP3更高的聲音質量&#xff0c;是iPhone、iPod、iPad、iTunes的標準音頻格式。 AAC相較于MP3的改進包含&#xff1a; 更多的采…