LeetCode 75. 顏色分類 - 雙指針法高效解決(Java實現)

文章目錄

    • 問題描述
    • 算法思路:三指針分區法
      • 核心思想
      • 指針定義
    • Java實現
    • 算法執行流程
    • 關鍵問題解析:為什么交換0后不需要重新檢查?
      • 交換0時的兩種情況分析
      • 詳細解釋:
    • 復雜度分析
    • 示例演示(輸入:[2,0,2,1,1,0])
    • 總結

本文介紹一種時間復雜度O(n)、空間復雜度O(1)的優雅解法,通過雙指針技術實現顏色分類的一趟掃描排序

問題描述

給定一個包含紅色(0)、白色(1)和藍色(2)的數組 nums,原地對它們進行排序,使得相同顏色的元素相鄰,并按照紅色、白色、藍色的順序排列。

示例:

輸入:nums = [2,0,2,1,1,0]
輸出:[0,0,1,1,2,2]

算法思路:三指針分區法

核心思想

使用三個指針將數組分為四個區域:

  1. [0, p0):已排序的0區域
  2. [p0, curr):已排序的1區域
  3. [curr, p2]:待處理區域
  4. (p2, end]:已排序的2區域

指針定義

  • p0:指向下一個0應放置的位置(0區域的右邊界)
  • p2:指向下一個2應放置的位置(2區域的左邊界)
  • curr:當前遍歷指針,負責處理元素交換

Java實現

class Solution {public void sortColors(int[] nums) {if (nums == null || nums.length < 2) return;int p0 = 0;                   // 0區域右邊界int p2 = nums.length - 1;     // 2區域左邊界int curr = 0;                 // 當前遍歷指針while (curr <= p2) {switch (nums[curr]) {case 0:// 將0交換到0區域swap(nums, curr++, p0++);break;case 1:// 1保留在中間區域curr++;break;case 2:// 將2交換到2區域swap(nums, curr, p2--);// 注意:curr不自增,需檢查交換來的新元素break;}}}// 輔助交換函數private void swap(int[] nums, int i, int j) {int temp = nums[i];nums[i] = nums[j];nums[j] = temp;}
}

算法執行流程

  1. 初始化指針

    • p0 = 0(0區域起始位置)
    • p2 = nums.length-1(2區域起始位置)
    • curr = 0(從數組開頭遍歷)
  2. 元素處理邏輯

    • 遇到0:與p0交換,p0curr右移
    • 遇到1:跳過,curr右移
    • 遇到2:與p2交換,p2左移(curr不變)
  3. 終止條件curr > p2(所有元素處理完畢)

關鍵問題解析:為什么交換0后不需要重新檢查?

交換0時的兩種情況分析

情況條件交換前狀態交換后狀態
情況1curr > p0nums[p0] = 1nums[curr] = 1
情況2curr == p0自身交換保持不變

詳細解釋:

  1. curr > p0

    • p0位置必定是1(因為0區域和1區域已排序)
    • 交換后curr位置變為1 → 可直接跳過處理(1屬于中間區域)
  2. curr == p0

    • 自身交換無實際變化
    • 元素保持0 → 屬于已排序區域

結論:交換0后curr位置的新元素只可能是0或1,都無需再次處理,因此可以直接移動curr指針。

復雜度分析

指標說明
時間復雜度O(n)單次遍歷完成排序
空間復雜度O(1)僅使用常數級額外空間

示例演示(輸入:[2,0,2,1,1,0])

步驟操作數組狀態指針變化
1初始狀態[2,0,2,1,1,0]p0=0, p2=5, curr=0
2處理2:交換curr?p2[0,0,2,1,1,2]p2=4
3處理0:交換curr?p0[0,0,2,1,1,2]p0=1, curr=1
4處理0:交換curr?p0[0,0,2,1,1,2]p0=2, curr=2
5處理2:交換curr?p2[0,0,1,1,2,2]p2=3
6處理1:跳過[0,0,1,1,2,2]curr=3
7處理1:跳過[0,0,1,1,2,2]curr=4 > p2(結束)

總結

雙指針法解決顏色分類問題的核心在于:

  1. 通過p0p2維護已排序區域
  2. curr指針動態處理待排序區域
  3. 巧妙利用交換操作實現元素歸位
  4. 利用數組分區特性優化操作步驟(交換0后無需重檢)

該算法是荷蘭國旗問題的經典解法,體現了雙指針技術在數組原地操作中的高效性,是面試中的高頻考點。

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

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

相關文章

【MySQL】C語言連接

要使用C語言連接mysql&#xff0c;需要使用mysql官網提供的庫&#xff0c;大家可以去官網下載 我們使用C接口庫來進行連接 要正確使用&#xff0c;我們需要做一些準備工作: 保證mysql服務有效在官網上下載合適自己平臺的mysql connect庫&#xff0c;以備后用 下載開發庫 s…

NFS 掛載配置與優化最佳實踐指南

文章目錄 NFS 掛載配置與優化最佳實踐指南1. 服務器端配置1.1 安裝 NFS 服務1.2 配置共享目錄常用配置選項說明 1.3 啟動與檢查服務 2. 客戶端掛載2.1 安裝 NFS 客戶端2.2 掛載 NFS 共享2.3 自動掛載 3. 客戶端掛載選項4. 性能優化與故障排查4.1 性能優化建議4.2 常見問題排查 …

3D PDF如何制作?SOLIDWORKS MBD模板定制技巧

SOLIDWORKS制作3D PDF模版 SOLIDWORKS MBD能夠幫助工程師以清晰直觀的方式描述產品尺寸信息。在3D PDF文件中&#xff0c;用戶可以自由旋轉和移動視圖&#xff0c;方便查看模型的各個尺寸細節。 本文將帶您一步步學習如何使用SOLIDWORKS MBD制作專業的3D PDF模板&#xff0c;…

Unity-QFramework框架學習-MVC、Command、Event、Utility、System、BindableProperty

QFramework QFramework簡介 QFramework是一套漸進式、快速開發框架&#xff0c;適用于任何類型的游戲及應用項目&#xff0c;它包含一套開發架構和大量的工具集 QFramework的特性 簡潔性&#xff1a;QFramework 強調代碼的簡潔性和易用性&#xff0c;讓開發者能夠快速上手&a…

R3GAN訓練自己的數據集

簡介 簡介&#xff1a;這篇論文挑戰了"GANs難以訓練"的廣泛觀點&#xff0c;通過提出一個更穩定的損失函數和現代化的網絡架構&#xff0c;構建了一個簡潔而高效的GAN基線模型R3GAN。作者證明了通過合適的理論基礎和架構設計&#xff0c;GANs可以穩定訓練并達到優異…

【PhysUnits】15.1 引入P1后的加一特質(add1.rs)

一、源碼 代碼實現了類型系統中的"加一"操作&#xff08;Add1 trait&#xff09;&#xff0c;用于在編譯期進行數字的增量計算。 //! 加一操作特質實現 / Increment operation trait implementation //! //! 說明&#xff1a; //! 1. Z0、P1,、N1 1&#xff0…

記錄算法筆記(2025.5.29)最小棧

設計一個支持 push &#xff0c;pop &#xff0c;top 操作&#xff0c;并能在常數時間內檢索到最小元素的棧。 實現 MinStack 類: MinStack() 初始化堆棧對象。void push(int val) 將元素val推入堆棧。void pop() 刪除堆棧頂部的元素。int top() 獲取堆棧頂部的元素。int get…

Android高級開發第一篇 - JNI(初級入門篇)

文章目錄 Android高級開發JNI開發第一篇&#xff08;初級入門篇&#xff09;&#x1f9e0; 一、什么是 JNI&#xff1f;? 為什么要用 JNI&#xff1f; ?? 二、開發環境準備開發工具 &#x1f680; 三、創建一個支持 JNI 的 Android 項目第一步&#xff1a;創建新項目項目結構…

PyTorch Image Models (timm) 技術指南

timm PyTorch Image Models (timm) 技術指南功能概述 一、引言二、timm 庫概述三、安裝 timm 庫四、模型加載與推理示例4.1 通用推理流程4.2 具體模型示例4.2.1 ResNeXt50-32x4d4.2.2 EfficientNet-V2 Small 模型4.2.3 DeiT-3 large 模型4.2.4 RepViT-M2 模型4.2.5 ResNet-RS-1…

openEuler安裝MySql8(tar包模式)

操作系統版本&#xff1a; openEuler release 22.03 (LTS-SP4) MySql版本&#xff1a; 下載地址&#xff1a; https://dev.mysql.com/downloads/mysql/ 準備安裝&#xff1a; 關閉防火墻&#xff1a; 停止防火墻 #systemctl stop firewalld.service 關閉防火墻 #systemc…

從零開始的數據結構教程(六) 貪心算法

&#x1f36c; 標題一&#xff1a;貪心核心思想——發糖果時的最優分配策略 貪心算法 (Greedy Algorithm) 是一種簡單直觀的算法策略。它在每一步選擇中都采取在當前狀態下最好或最優&#xff08;即最有利&#xff09;的選擇&#xff0c;從而希望得到一個全局最優解。這就像你…

CPP中CAS std::chrono 信號量與Any類的手動實現

前言 CAS&#xff08;Compare and Swap&#xff09; 是一種用于多線程同步的原子指令。它通過比較和交換操作來確保數據的一致性和線程安全性。CAS操作涉及三個操作數&#xff1a;內存位置V、預期值E和新值U。當且僅當內存位置V的值與預期值E相等時&#xff0c;CAS才會將內存位…

Axure設計案例——科技感對比柱狀圖

想讓數據對比展示擺脫平淡無奇&#xff0c;瞬間抓住觀眾的眼球嗎&#xff1f;那就來看看這個Axure設計的科技感對比柱狀圖案例&#xff01;科技感設計風格運用獨特元素打破傳統對比柱狀圖的常規&#xff0c;營造出一種極具沖擊力的視覺氛圍。每一組柱狀體都仿佛是科技戰場上的士…

怒更一波免費聲音克隆和AI配音功能

寶子們&#xff01; 最近咱軟件TransDuck的免費聲音克隆和AI配音功能被大家用爆啦&#xff01;感謝各位自來水瘋狂安利&#xff01;&#xff01; DD這里也是收到好多用戶提的寶貴建議&#xff01;所以&#xff0c;連夜肝了波更新&#xff01; 這次重點更新使用克隆音色進行A…

UDP協議原理與Java編程實戰:無連接通信的奧秘

1.UDP協議核心原理 1. 無連接特性&#xff1a;快速通信的基石 UDP&#xff08;User Datagram Protocol&#xff0c;用戶數據報協議&#xff09;是TCP/IP協議族中無連接的輕量級傳輸層協議。與TCP的“三次握手”建立連接不同&#xff0c;UDP通信無需提前建立鏈路&#xff0c;發送…

vue-seamless-scroll 結束從頭開始,加延時后滾動

今天遇到一個大屏需求&#xff1a; 1??初始進入頁面停留5秒&#xff0c;然后開始滾動 2??最后一條數據出現在最后一行時候暫停5秒&#xff0c;然后返回1?? 依次循環&#xff0c;發現vue-seamless-scroll的方法 ScrollEnd是監測最后一條數據消失在第一行才回調&#xff…

[Protobuf] 快速上手:安全高效的序列化指南

標題&#xff1a;[Protobuf] (1)快速上手 水墨不寫bug 文章目錄 一、什么是protobuf&#xff1f;二、protobuf的特點三、使用protobuf的過程&#xff1f;1、定義消息格式&#xff08;.proto文件&#xff09;(1)指定語法版本(2)package 聲明符 2、使用protoc編譯器生成代碼&…

uniapp調用java接口 跨域問題

前言 之前在Windows10本地 調試一個舊項目&#xff0c;手機移動端用的是Uni-app&#xff0c;vue的版本是v2。后端是java spring-boot。運行手機移動端的首頁請求后臺接口老是提示錯誤信息。 錯誤信息如下&#xff1a; Access to XMLHttpRequest at http://localhost:8080/api/…

[ Qt ] | Qlabel使用

目錄 屬性 setTextFormat 插入圖片 設置圖片根據窗口大小實時變化 邊框和對其方式 ?編輯 設置縮進 設置伙伴 Qlabel可以用來顯式圖片和文字 屬性 text textFormat Qlabel獨有的機制&#xff1a;buddy setTextFormat 插入圖片 設置圖片根據窗口大小實時變化 Qt中表…

Springboot 項目一啟動就獲取HttpSession

在 Spring Boot 項目中&#xff0c;HttpSession 是有狀態的&#xff0c;通常只有在用戶發起 HTTP 請求并建立會話后才會創建。因此&#xff0c;在項目啟動時&#xff08;即應用剛啟動還未處理任何請求&#xff09;是無法獲取到 HttpSession 的。 方法一&#xff1a;使用 HttpS…