【算法】雙指針劃分思想妙解移動零

在這里插入圖片描述

Problem: 283. 移動零

文章目錄

  • 思路
  • 算法圖解分析
  • 復雜度
  • Code

思路

首先我們來講一下本題的思路

  • 本題主要可以歸到【數組劃分/數組分塊】這一類的題型。我們將一個數組中的所有元素劃分為兩段區間,左側是非零元素,右側是零元素

1.jpg

  • 那解決這一類的題我們首先想到的就是【雙指針算法】,學習過C語言的同學應該就可以知道指針是比較繁瑣和復雜,如果有興趣學習的同學可以看看我的這篇文章 鏈接
  • 不過在這里呢我們不需要去使用int*這種指針,而是直接使用數組下標來充當指針即可

好,那我們就來看看這個雙指針到底是怎樣的,要如何去使用

  • 兩個指針的作用
    • 【cur】: 從左往右掃描數組,遍歷數組
    • 【dest】:已處理的區間內,非零元素的最后一個位置
  • 可以看到,cur是我們用來遍歷數組的,從[cur, n - 1]就是還未處理的元素;那么從[0, cur]就是已經處理過的元素,但是呢本題的要求是我們要劃分出【零元素】與【非零元素】,所以呢前面的區間我們可以再度劃分為[0, dest][dest + 1, cur - 1]

3.jpg

小結一下:

[0, dest] [dest + 1, cur - 1] [cur, n - 1]

  • [0, dest] —— 非零元素
  • [dest + 1, cur - 1] —— 零元素
  • [cur, n - 1] —— 未處理元素

算法圖解分析

接下去我們就通過畫算法圖解的形式來模擬一下解題的過程

  • 我們就以題目中所給出的第一個示例為例來進行講解,因為在一開始我們還沒處理過任何的非零元素,所以對于[0, cur - 1]這段區間是沒有任何數據的,所以在一開始我們可以將【dest】這個指針置于-1的位置

4.jpg

  • 因為我們需要將非0元素移動到前面,所以呢如果遇到了0元素的話,cur++即可,將其留在這個位置上

5.jpg

  • 那當我們遇到非0元素時,就需要將其交換到前面去,那我們[0, dest]這個區間就是用來存放非0元素的,此時多了一個元素的話那dest就要加1,原本其是指向-1這個位置,那我們可以使用++dest來完成

6.jpg

  • 接下去,當數據交換過來后,我們可以去對照上面的這三個區間,可以發現最左側是非0元素,中間是0元素,右側呢則是待處理的元素。接下去我們又碰到了0元素,所以cur++

7.jpg

  • cur再后移之后呢,我們又碰到了非0元素,繼續讓dest上來然后交換二者位置上的元素

8.jpg

  • 那現在我們再來看這三個區間,左側還是保持為【非0元素】,中間為【0元素】,右側的話則是【待處理的元素】

9.jpg

  • 然后碰到非0元素后,繼續讓++dest,然后做交換

10.jpg

  • 最后的話我們來看看這個處理完后的整個區間元素:非0元素都在前面,而0元素則都在后面,[cur, n - 1]的這段區間也不存在了,說明已經沒有待處理元素了

11.jpg

復雜度

接下去我們來分析一下本題的時空復雜度

  • 時間復雜度:

本算法的核心思路參考的是【快速排序】的區間劃分,我們這里就是在不斷遍歷數組的過程中,以中間的0作為分割,然后左側是非0元素,右側是未處理的元素。在處理的過程中我們只是遍歷了一次這個數組,所以復雜度為 O ( n ) O(n) O(n)

  • 空間復雜度:

在本題中我們并沒有去開出額外的空間,所以復雜度為 O ( 1 ) O(1) O(1)

Code

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

在這里插入圖片描述

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

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

相關文章

掌握指針進階:一篇帶你玩轉函數指針、函數指針數組及指向函數指針數組的指針!!

&#x1f341;博客主頁&#xff1a;江池俊的博客 &#x1f4ab;收錄專欄&#xff1a;C語言進階之路 &#x1f4a1;代碼倉庫&#xff1a;江池俊的代碼倉庫 &#x1f3aa;我的社區&#xff1a;GeekHub &#x1f389;歡迎大家點贊&#x1f44d;評論&#x1f4dd;收藏? 文章目錄 一…

基于Servlet實現的管理系統(包含服務器源碼+數據庫)

資料下載鏈接 介紹 基于Servlet框架的管理系統 簡潔版 &#xff1b; 實現 登錄 、 注冊 、 增 、 刪 、 改 、 查 &#xff1b; 可繼續完善增加前端、校驗、其他功能等&#xff1b; 可作為 Servlet項目 開發練習基礎模型&#xff1b; 課程設計 、 畢業設計 開發基礎&…

JVM---jvm里的內存溢出

目錄 堆溢出 虛擬機棧和本地方法棧溢出&#xff08;棧溢出很少出現&#xff09; 方法區和運行時常量池溢出 本機內存直接溢出&#xff08;實際中很少出現、了解即可&#xff09; 堆溢出 堆溢出&#xff1a;最常見的是大list&#xff0c;list里面有很多元素 堆溢出該怎么解決…

第7章:貝葉斯分類器

貝葉斯決策論 貝葉斯分類器&#xff1a;使用貝葉斯公式 貝葉斯學習&#xff1a;使用分布估計&#xff08;不同于頻率主義的點估計&#xff09; 極大似然估計 樸素貝葉斯分類 半樸素貝葉斯 條件獨立性假設&#xff0c;在現實生活中往往很難成立。 半樸素貝葉 斯的一個常用策略…

C++學習筆記4

什么是指針&#xff1f; 指針是存儲內存地址的變量。就像int變量用于存儲整數值一樣&#xff0c;指針變量用于存儲內存地址。指針是一種指向內存單元的特殊變量。 內存單元地址通常使用的是16進制表示&#xff08;0&#xff5e;9和A&#xff5e;F&#xff09;來表示數字。顯示…

React源碼解析18(6)------ 實現useState

摘要 在上一篇文章中&#xff0c;我們已經實現了函數組件。同時可以正常通過render進行渲染。 而通過之前的文章&#xff0c;beginWork和completeWork也已經有了基本的架子。現在我們可以去實現useState了。 實現之前&#xff0c;我們要先修改一下我們的index.js文件&#x…

DAY2,ARM(特殊功能寄存器,數據操作指令,跳轉指令)

1.cmp、sub、b指令的使用&#xff1b; 代碼&#xff1a; .text .global _start _start:mov r0,#9mov r1,#15loop:cmp r0,r1beq stopsubcc r1,r1,r0subhi r0,r0,r1b loopstop:b stop .end結果&#xff1a; 2.匯編指令計算1~100之間和&#xff1b; 代碼&#xff1a; .text .gl…

【從零學習python 】47. 面向對象編程中的繼承概念及基本使用

文章目錄 繼承的基本使用代碼逐行講解說明:進階案例 繼承的基本使用 在現實生活中&#xff0c;繼承一般指的是子女繼承父輩的財產&#xff0c;父輩有的財產&#xff0c;子女能夠直接使用。 程序里的繼承 繼承是面向對象軟件設計中的一個概念&#xff0c;與多態、封裝共為面向對…

Android 13 Launcher——屏蔽上拉到應用列表

背景 Launcher定制需要將原先的應用列表去掉,可以從根源去掉,就是將上拉出現應用列表的上拉手勢直接屏蔽,讓其不能上拉出現應用列表界面,在研究的過程中順便將下拉出現負一屏的邏輯也研究了下,如下就是具體實現。 目錄 背景 一.如何屏蔽上拉出現應用列表 一.如何屏蔽上拉…

培訓報名小程序-用戶注冊

目錄 1 創建數據源2 注冊用戶3 判斷用戶是否注冊4 完整代碼總結 我們的培訓報名小程序&#xff0c;用戶每次打開時都需要填寫個人信息才可以報名&#xff0c;如果用戶多次報名課程&#xff0c;每次都需要填寫個人信息&#xff0c;比較麻煩。 本篇我們就優化一下功能&#xff0c…

線上售樓vr全景看房成為企業數字化營銷工具

在房地產業中&#xff0c;VR全景拍攝為買家提供了虛擬看房的全新體驗。買家可以通過相關設備&#xff0c;遠程參觀各個樓盤的樣板間和實景&#xff0c;感受房屋的空間布局和環境氛圍&#xff0c;極大地提高了購房決策的準確性。對于房地產開發商和中介機構來說&#xff0c;VR全…

@Async用哪個線程池

一共可以分三種情況 第一種 未在手動在項目中配置任何線程池 spring boot 會默認添加一個coreSize8的 無界線程池&#xff0c;名稱為applicationTaskExecutor &#xff08;源碼&#xff1a;org.springframework.boot.autoconfigure.task.TaskExecutionAutoConfiguration&…

如何搭建個人郵件服務hmailserver并實現遠程發送郵件

文章目錄 1. 安裝hMailServer2. 設置hMailServer3. 客戶端安裝添加賬號4. 測試發送郵件5. 安裝cpolar6. 創建公網地址7. 測試遠程發送郵件8. 固定連接公網地址9. 測試固定遠程地址發送郵件 hMailServer 是一個郵件服務器,通過它我們可以搭建自己的郵件服務,通過cpolar內網映射工…

計算機競賽 GRU的 電影評論情感分析 - python 深度學習 情感分類

1 前言 &#x1f525;學長分享優質競賽項目&#xff0c;今天要分享的是 &#x1f6a9; GRU的 電影評論情感分析 - python 深度學習 情感分類 &#x1f947;學長這里給一個題目綜合評分(每項滿分5分) 難度系數&#xff1a;3分工作量&#xff1a;3分創新點&#xff1a;4分 這…

代碼隨想錄算法訓練營第三十八天 | 理論基礎,509. 斐波那契數,70. 爬樓梯,746. 使用最小花費爬樓梯

代碼隨想錄算法訓練營第三十八天 | 理論基礎&#xff0c;509. 斐波那契數&#xff0c;70. 爬樓梯&#xff0c;746. 使用最小花費爬樓梯 理論基礎什么是動態規劃動態規劃的解題步驟動態規劃應該如何debug 509. 斐波那契數遞歸解法 70. 爬樓梯746. 使用最小花費爬樓梯 理論基礎 視…

計蒜客T1170——人民幣支付

超級水&#xff0c;不解釋&#xff0c;代碼的處理方式減低了繁瑣程度&#xff0c; #include <iostream> using namespace std;int main(int argc, char** argv) {int num0;cin>>num;int money[6]{100,50,20,10,5,1};for(int i0;i<5;i){int count0;countnum/mone…

SkyWalking 部署(包含ES)

SkyWalking安裝 結構 首先SkyWalking主要需要oapService、webApp、Elasticsearch&#xff08;可選存儲&#xff09;三個&#xff0c;接下來講一下這三個的安裝步驟&#xff0c;安裝過程中出現了一些細小的配置錯誤&#xff0c;導致用了快兩天才弄好&#xff0c;麻木了&#x…

C++超基礎語法

&#x1f493;博主個人主頁:不是笨小孩&#x1f440; ?專欄分類:數據結構與算法&#x1f440; C&#x1f440; 刷題專欄&#x1f440; C語言&#x1f440; &#x1f69a;代碼倉庫:笨小孩的代碼庫&#x1f440; ?社區&#xff1a;不是笨小孩&#x1f440; &#x1f339;歡迎大…

IDEA常用工具配置

IDEA常用工具&配置 如果發現插件市場用不了&#xff0c;可以設置Http Proxy&#xff0c;在該界面上點擊”Check connection“并輸入的地址&#xff1a;https://plugins.jetbrains.com/ 。 一、常用插件 1、MybatisX Mybaits Plus插件&#xff0c;支持java與xml互轉 2、F…

Vue-10.集成.env

.env、.env.development 和 .env.preview .env、.env.development 和 .env.preview 文件是用于配置環境變量和應用程序設置的文件&#xff0c;它們在項目開發和部署過程中起到關鍵作用。這些文件用于在不同的環境中設置不同的變量值&#xff0c;以滿足不同環境下的配置需求。 …