算法思想之雙指針(一)

歡迎拜訪:霧里看山-CSDN博客
本篇主題:算法思想之雙指針(一)
發布時間:2025.4.4
隸屬專欄:算法

在這里插入圖片描述

目錄

  • 雙指針算法介紹
    • 對撞指針:
    • 快慢指針:
  • 例題
    • 移動零
      • 題目鏈接
      • 題目描述
      • 算法思路
      • 代碼實現
    • 復寫零
      • 題目鏈接
      • 題目描述
      • 算法思路
      • 代碼實現
    • 快樂數
      • 題目鏈接
      • 題目描述
      • 算法思路
      • 代碼實現
    • 盛最多水的容器
      • 題目鏈接
      • 題目描述
      • 算法思路
      • 代碼實現

雙指針算法介紹

常見的雙指針有兩種形式,一種是對撞指針,一種是快慢指針。

對撞指針:

?般?于順序結構中,也稱左右指針。

  • 對撞指針從兩端向中間移動。一個指針從最左端開始,另一個從最右端開始,然后逐漸往中間逼近
  • 對撞指針的終止條件一般是兩個指針相遇或者錯開(也可能在循環內部找到結果直接跳出循環),也就是:
    • left == right (兩個指針指向同一個位置)
    • left > right (兩個指針錯開)

快慢指針:

又稱為龜兔賽跑算法,其基本思想就是使用兩個移動速度不同的指針在數組或鏈表等序列結構上移動
這種方法對于處理環形鏈表或數組非常有用。
其實不單單是環形鏈表或者是數組,如果我們要研究的問題出現循環往復的情況時,均可考慮使用快慢指針的思想。
快慢指針的實現方式有很多種,最常用的?種就是:

  • 在一次循環中,每次讓慢的指針向后移動一位,而快的指針往后移動兩位,實現一快一慢。

例題

移動零

題目鏈接

283. 移動零

題目描述

給定一個數組 nums,編寫一個函數將所有 0 移動到數組的末尾,同時保持非零元素的相對順序。

請注意 ,必須在不復制數組的情況下原地對數組進行操作。

示例 1:

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

示例 2:

輸入: nums = [0]
輸出: [0]

提示:

  • 1 <= nums.length <= 104
  • -231 <= nums[i] <= 231 - 1

進階:你能盡量減少完成的操作次數嗎?

算法思路

在本題中,我們可以用一個 cur 指針來掃描整個數組,另一個 dest 指針用來記錄非零數序列的最后一個位置。根據 cur 在掃描的過程中,遇到的不同情況,分類處理,實現數組的劃分。在 cur 遍歷期間,使 [0, dest] 的元素全部都是非零元素, [dest + 1, cur - 1] 的元素全是零。

代碼實現

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

在這里插入圖片描述

復寫零

題目鏈接

1089.復寫零

題目描述

給你一個長度固定的整數數組arr,請你將該數組中出現的每個零都復寫一遍,并將其余的元素向右平移。

注意:請不要在超過該數組長度的位置寫入元素。請對輸入的數組 就地 進行上述修改,不要從函數返回任何東西。
示例 1

輸入arr = [1,0,2,3,0,4,5,0]
輸出[1,0,0,2,3,0,0,4]
解釋:調用函數后,輸入的數組將被修改為:[1,0,0,2,3,0,0,4]

示例 2

輸入arr = [1,2,3]
輸出[1,2,3]
解釋:調用函數后,輸入的數組將被修改為:[1,2,3]

提示

  • 1 <= arr.length <= 104
  • 0 <= arr[i] <= 9

算法思路

如果從前向后進行原地復寫操作的話,由于 0 的出現會復寫兩次,導致沒有復寫的數被覆蓋掉。因此我們選擇從后往前的復寫策略。但是從后向前復寫的時候,我們需要找到最后一個復寫的數,因此我們的大體流程分兩步:

  • i. 先找到最后一個復寫的數;
  • ii. 然后從后向前進行復寫操作。

代碼實現

class Solution {
public:void duplicateZeros(vector<int>& arr) {int n = arr.size();int cur = 0, dest = -1;// 找到最后覆寫的數while(dest < n){if(arr[cur] == 0)dest+=2;elsedest++;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--];}}}
};

在這里插入圖片描述

快樂數

題目鏈接

202.快樂數

題目描述

編寫一個算法來判斷一個數n是不是快樂數。
快樂數 定義為:

  • 對于一個正整數,每一次將該數替換為它每個位置上的數字的平方和。
  • 然后重復這個過程直到這個數變為 1,也可能是 無限循環 但始終變不到 1。
  • 如果這個過程 結果為 1,那么這個數就是快樂數。

如果n是 快樂數 就返回 true ;不是,則返回 false
示例 1

輸入n = 19
輸出true
解釋
12 + 92 = 82
82 + 22 = 68
62 + 82 = 100
12 + 02 + 02 = 1

示例 2

輸入n = 2
輸出false

提示
1 <= n <= 231 - 1

算法思路

根據上述的題目分析,我們可以知道,當重復執行 x的時候,數據會陷入到一個循環之中。而快慢指針有一個特性,就是在一個圓圈中,快指針總是會追上慢指針的,也就是說他們總會相遇在一個位置上。如果相遇位置的值是1 ,那么這個數一定是快樂數;如果相遇位置不是1的話,那么就不是快樂數。

代碼實現

class Solution {
public:int BitSum(int n){int num = 0;while(n>0){int x = n %10;n /= 10;num+=x*x;}return num;}bool isHappy(int n) {int slow = n, fast = BitSum(n);while(slow != fast){slow = BitSum(slow);fast = BitSum(BitSum(fast));} return slow == 1;}
};

在這里插入圖片描述

盛最多水的容器

題目鏈接

11. 盛最多水的容器

題目描述

給定一個長度為 n 的整數數組 height 。有 n 條垂線,第 i 條線的兩個端點是 (i, 0) (i, height[i])

找出其中的兩條線,使得它們與 x 軸共同構成的容器可以容納最多的水。

返回容器可以儲存的最大水量。

說明:你不能傾斜容器。

示例 1
在這里插入圖片描述

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

示例 2

輸入height = [1,1]
輸出1

提示:

  • n == height.length
  • 2 <= n <= 105
  • 0 <= height[i] <= 104

算法思路

設兩個指針 leftright分別指向容器的左右兩個端點,此時容器的容積 :
v = (right - left) * min( height[right], height[left])
容器的左邊界為 height[left] ,右邊界為 height[right]
為了方便敘述,我們假設左邊邊界小于右邊邊界
如果此時我們固定一個邊界,改變另一個邊界,水的容積會有如下變化形式:

  • 容器的寬度?定變小。
  • 由于左邊界較小,決定了水的高度。如果改變左邊界,新的水面高度不確定,但是?定不會超過右邊的柱子高度,因此容器的容積可能會增大。
  • 如果改變右邊界,無論右邊界移動到哪里,新的水面的高度一定不會超過左邊界,也就是不會
    超過現在的水面高度,但是由于容器的寬度減小,因此容器的容積一定會變小的。

由此可見,左邊界和其余邊界的組合情況都可以舍去。所以我們可以 left++ 跳過這個邊界,繼續去判斷下?個左右邊界。

當我們不斷重復上述過程,每次都可以舍去大量不必要的枚舉過程,直到left right 相遇。期間產生的所有的容積里面的最大值,就是最終答案。

代碼實現

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

在這里插入圖片描述

?? 寫在最后:以上內容是我在學習以后得一些總結和概括,如有錯誤或者需要補充的地方歡迎各位大佬評論或者私信我交流!!!

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

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

相關文章

【11408學習記錄】英語寫作黃金模板+語法全解:用FTC數據泄漏案掌握書信結構與長難句拆解(附思維導圖)

2025.04.04 英語寫作書信寫作第一段私人信件公務信函 語法總結——簡單句簡單句的核心&#xff1a;謂語動詞的變化詞性的拓展限定詞 形容詞與副詞介詞短語 成分的擴展同位語插入語 非謂語動詞 每日一句詞匯 第一步&#xff1a;辨別第二步&#xff1a;斷開第三步&#xff1a;簡化…

手機顯示5GA圖標的條件

最近有星友問在什么情況下才能顯示5G-A&#xff1f;雖然這個我也不知道&#xff0c;但是我有幾個運營商的5G終端白皮書&#xff0c;從上面就可以找到答案。 如上是幾個運營商顯示5G-A的條件&#xff0c;基本上考慮的都是3CC的情況&#xff0c;聯通還有考慮200M CA 2CC的場景&am…

網絡:華為數通HCIA學習:IP路由基礎

華為HCIA學習 IP路由基礎路由協議或路由種類以及對應路由的優先級按工作區域分類&#xff1a;按工作機制及算法分類&#xff1a;路由的優先級路由器選擇最優路由的順序是什么? 前言自治系統LAN和廣播域路由選路IP路由表路由度量建立路由表最長匹配原則路由器轉發數據包總結 IP…

Docker 鏡像相關的基本操作

一、Docker 鏡像基本操作 1. 查找鏡像 命令&#xff1a; docker search <鏡像名稱> 示例&#xff1a;查找 CentOS 鏡像&#xff1a; docker search centos 命令解釋&#xff1a; 默認從 Docker Hub 官方倉庫上搜索鏡像。搜索結果包含多個列&#xff1a; NAME&…

Linux文件特殊權限管理及進程和線程

acl 權限優先級 擁有者 > 特殊指定用戶 > 權限多的組 >權限少的組 > 其他 mask閾值 mask是能夠賦予指定用戶權限的最大閥值 當設定完畢文件的acl列表之后用chmod縮小了文件擁有組的權力 mask會發生變化 恢復&#xff1a; setfacl -m m: 權限 :rwx 文件/…

NVIDIA AgentIQ 詳細介紹

NVIDIA AgentIQ 詳細介紹 1. 引言 NVIDIA AgentIQ 是一個靈活的庫&#xff0c;旨在將企業代理&#xff08;無論使用何種框架&#xff09;與各種數據源和工具無縫集成。通過將代理、工具和代理工作流視為簡單的函數調用&#xff0c;AgentIQ 實現了真正的可組合性&#xff1a;一…

算法設計與分析5(動態規劃)

動態規劃的基本思想 將一個問題劃分為多個不獨立的子問題&#xff0c;這些子問題在求解過程中可能會有些數據進行了重復計算。我們可以把計算過的數據保存起來&#xff0c;當下次遇到同樣的數據計算時&#xff0c;就可以查表直接得到答案&#xff0c;而不是再次計算 動態規劃…

怎么理解量子比特模型,遷移到量子計算機開始編程

怎么理解量子比特模型&#xff0c;遷移到量子計算機開始編程 視頻鏈接&#xff1a; 好的現在是2025年的3月最后一天,3月31號,今天我們討論的話題是量子編程,也就是在量子計算機上,使用特定的語言進行軟件開發。當然我們要討論的,不是,量子編程的某一門語言的技術細節,而是考慮…

使用Expo框架開發APP——詳細教程

在移動應用開發日益普及的今天&#xff0c;跨平臺開發工具越來越受到開發者青睞。Expo 是基于 React Native 的一整套工具和服務&#xff0c;它能夠大幅降低原生開發的門檻&#xff0c;讓開發者只需關注業務邏輯和界面實現&#xff0c;而不用糾結于復雜的原生配置。本文將從零開…

windows技術基礎知識

NT架構 NT 就是new techonology 的英文單詞縮寫&#xff0c;是微軟1993年推出操作系統的重大升級&#xff0c;如內存管理&#xff0c;安全機制&#xff0c;多任務&#xff0c;多線程支持。在此之前操作系統都是基于MS-DOS上面的圖形化界面&#xff0c;只有有限的內存管理和多任…

迪杰斯特拉+二分+優先隊列+拓撲+堆優化(奶牛航線Cowroute、架設電話線dd、路障Roadblocks、奶牛交通Traffic)

原文地址 https://fmcraft.top/index.php/Programming/2025040402.html 主要算法 迪杰斯特拉Dijkstra 題目列表 P1&#xff1a;奶牛航線Cowroute 題目描述 題目描述 Bessie已經厭倦了農場冬天的寒冷氣候&#xff0c;她決定坐飛機去更溫暖的地方去度假。不幸的是&#xf…

#Liunx內存管理# 在32bit Linux內核中,用戶空間和內核空間的比例通常是3:1,可以修改成2:2嗎?

在32位Linux內核中&#xff0c;用戶空間和內核空間的3:1默認比例可以修改為2:2&#xff0c;但需要權衡實際需求和潛在影響。以下是具體分析&#xff1a; 一、修改可行性 1.技術實現 通過內核啟動參數調整虛擬地址空間劃分&#xff0c;例如在GRUB配置中添加mem2G參數&#xff0c…

JAVA:使用 Curator 進行 ZooKeeper 操作的技術指南

1、簡述 Apache Curator 是一個基于 ZooKeeper 的 Java 客戶端庫&#xff0c;它極大地簡化了使用 ZooKeeper 的開發工作。Curator 提供了高層次的 API&#xff0c;封裝了很多復雜的 ZooKeeper 操作&#xff0c;例如連接管理、分布式鎖、Leader 選舉等。 在分布式系統中&#…

Julia語言的測試覆蓋率

Julia語言的測試覆蓋率探討 引言 在現代軟件開發中&#xff0c;測試是確保軟件質量的重要環節。隨著軟件的復雜度不斷增加&#xff0c;測試覆蓋率作為衡量測試質量的一個重要指標&#xff0c;受到了越來越多開發者的關注。Julia語言作為一種高性能的動態編程語言&#xff0c;…

【萬字總結】前端全方位性能優化指南(八)——Webpack 6調優、模塊聯邦升級、Tree Shaking突破

構建工具深度優化——從機械配置到智能工程革命 當Webpack配置項突破2000行、Node進程內存耗盡告警時,傳統構建優化已觸及工具鏈的物理極限:Babel轉譯耗時占比超60%、跨項目模塊復用催生冗余構建、Tree Shaking誤刪關鍵代碼引發線上事故……構建流程正從「工程問題」演變為「…

使用MCP服務器實現AI任務完成通知:讓Cursor更智能

0. 簡介 在使用AI工具進行長時間任務時&#xff0c;常常需要等待結果。MCP&#xff08;Model Context Protocol&#xff09;服務器"mcp_server_notify"提供了一個優雅的解決方案&#xff0c;讓AI在完成任務后通過系統通知提醒你。本文將介紹如何在Cursor中配置和使用…

Java面試黃金寶典33

1. 什么是存取控制、 觸發器、 存儲過程 、 游標 存取控制 定義&#xff1a;存取控制是數據庫管理系統&#xff08;DBMS&#xff09;為保障數據安全性與完整性&#xff0c;對不同用戶訪問數據庫對象&#xff08;如表、視圖等&#xff09;的權限加以管理的機制。它借助定義用戶…

DataX實戰教程

需求&#xff1a; 用datax同步mysql&#xff1a; 192.168.236.134中test1庫的user表到192.168.236.136中test1庫的user表 步驟&#xff1a; 下載安裝包 https://github.com/alibaba/DataX/blob/master/userGuid.md 進入引導頁 https://github.com/alibaba/DataX/blob/ma…

C#/.NET/.NET Core技術前沿周刊 | 第 32 期(2025年3.24-3.31)

前言 C#/.NET/.NET Core技術前沿周刊&#xff0c;你的每周技術指南針&#xff01;記錄、追蹤C#/.NET/.NET Core領域、生態的每周最新、最實用、最有價值的技術文章、社區動態、優質項目和學習資源等。讓你時刻站在技術前沿&#xff0c;助力技術成長與視野拓寬。 歡迎投稿、推薦…

c++基礎-----c++ 成員變量初始化順序

操作系統&#xff1a;ubuntu22.04 IDE:Visual Studio Code 編程語言&#xff1a;C11 描述 在C中&#xff0c;類的成員變量初始化的順序是由它們在類中聲明的順序決定的&#xff0c;而不是由它們在構造函數初始化列表中的順序決定的。這意味著無論你在構造函數初始化列表中如何…