LeetCode 面試經典 150 題:輪轉數組(三次翻轉法詳解 + 多解法對比)

在數組類算法題中,“輪轉數組” 是一道考察 “原地操作” 與 “邏輯轉換” 能力的經典題目。所謂 “輪轉”,是指將數組元素向右移動指定步數,且超出數組長度的元素需 “循環” 到數組開頭。這道題的最優解 ——三次翻轉法,能以 O (n) 時間復雜度和 O (1) 空間復雜度實現原地輪轉,是面試中高頻考察的高效思路。本文將從題目解讀、三次翻轉法原理、步驟演示,到代碼實現,再到其他解法對比,幫你徹底掌握這道題的核心邏輯。

一、題目鏈接與題干解讀

首先,你可以通過以下鏈接直接訪問題目,先自行思考解題方向:

LeetCode 題目鏈接:189.?輪轉數組

題干核心信息

題目要求如下:

給定一個整數數組 nums,將數組中的元素向右輪轉 k 個位置,其中 k 是非負數。

例如,若 nums = [1,2,3,4,5,6,7],k = 3,則輪轉后數組為 [5,6,7,1,2,3,4]。

關鍵注意點

  • k 的取值范圍:k 可能大于數組長度 n,此時輪轉效果與 “k 對 n 取模” 后的結果一致(例如 n=7,k=10,10 mod 7=3,輪轉 10 步與輪轉 3 步結果相同);
  • 原地操作要求:若想達到最優空間復雜度,需避免開辟新數組,在原數組上完成輪轉;
  • 元素順序保留:輪轉后,元素的相對順序需保持(如示例中 5、6、7 的相對順序,1、2、3、4 的相對順序均不變)。

二、核心解法:三次翻轉法(原地高效)

三次翻轉法的核心思想是 “通過翻轉操作,將‘向右輪轉’的復雜邏輯轉化為三次簡單的數組翻轉”。其本質是利用翻轉對元素順序的改變,間接實現輪轉效果,且全程無需開辟新數組,空間復雜度極低。

1. 為什么需要先對 k 取模?

由于數組輪轉 n 步后會回到原始狀態(例如 n=7,輪轉 7 步后數組不變),因此當 k≥n 時,實際需要的輪轉步數為 k_mod = k % n。這一步操作能減少不必要的計算(例如 k=10 時,只需處理 3 步而非 10 步),是優化解題的關鍵前提。

例如:

  • 當 n=7,k=3 時,k_mod=3,無需調整;
  • 當 n=7,k=10 時,k_mod=10%7=3,按 3 步處理;
  • 當 n=7,k=7 時,k_mod=0,無需輪轉(數組不變)。

2. 三次翻轉的邏輯原理

我們先明確 “向右輪轉 k 步” 的效果:數組末尾的 k 個元素會移動到數組開頭,其余元素向右順延。例如,數組[a1,a2,a3,a4,a5,a6,a7](n=7),向右輪轉 3 步后為[a5,a6,a7,a1,a2,a3,a4]—— 末尾 3 個元素[a5,a6,a7]到開頭,前 4 個元素[a1,a2,a3,a4]順延。

三次翻轉法通過以下步驟實現這一效果:

  1. 翻轉整個數組:將數組從 “前 n-k 個元素 + 后 k 個元素” 的結構,變為 “后 k 個元素的逆序 + 前 n-k 個元素的逆序”;
  1. 翻轉前 k 個元素:將 “后 k 個元素的逆序” 恢復為原順序,此時前 k 個元素就是輪轉后需要放在開頭的元素;
  1. 翻轉后 n-k 個元素:將 “前 n-k 個元素的逆序” 恢復為原順序,此時后 n-k 個元素就是輪轉后需要放在末尾的元素。

簡單來說,三次翻轉的邏輯鏈是:整體翻轉打亂順序→局部翻轉恢復目標區域順序→最終得到輪轉結果

3. 示例演示(以nums = [1,2,3,4,5,6,7],k=3為例)

步驟 1:計算 k_mod

n=7,k=3,k_mod=3%7=3。

步驟 2:第一次翻轉(翻轉整個數組)

原數組:[1,2,3,4,5,6,7]

翻轉后:[7,6,5,4,3,2,1]

作用:將末尾的 3 個元素(5,6,7)翻轉為(7,6,5),移到數組前半部分;將前 4 個元素(1,2,3,4)翻轉為(4,3,2,1),移到數組后半部分。

步驟 3:第二次翻轉(翻轉前 k_mod=3 個元素)

當前數組:[7,6,5,4,3,2,1]

翻轉前 3 個元素:[5,6,7,4,3,2,1]

作用:將前 3 個元素(7,6,5)恢復為原順序(5,6,7),這正是輪轉后需要放在開頭的元素。

步驟 4:第三次翻轉(翻轉后 n-k_mod=4 個元素)

當前數組:[5,6,7,4,3,2,1]

翻轉后 4 個元素:[5,6,7,1,2,3,4]

作用:將后 4 個元素(4,3,2,1)恢復為原順序(1,2,3,4),這正是輪轉后需要放在末尾的元素。

最終結果與題目預期完全一致,驗證了三次翻轉法的正確性。

4. 翻轉操作的實現

翻轉數組的某一段(從索引 left 到索引 right)是三次翻轉法的基礎操作,實現邏輯如下:

  • 初始化兩個指針,left 指向段的起始索引,right 指向段的結束索引;
  • 交換 left 和 right 指向的元素,然后 left 向右移動 1 位,right 向左移動 1 位;
  • 重復上述操作,直到 left ≥ right(即指針相遇或交叉,段內元素全部交換完畢)。

例如,翻轉數組[7,6,5](left=0,right=2):

  • 交換 7 和 5 → [5,6,7],left=1,right=1;
  • left ≥ right,翻轉結束。

三、其他常見解法(對比參考)

除了三次翻轉法,“輪轉數組” 還有其他解法,雖然復雜度不如三次翻轉法最優,但能幫助我們從不同角度理解問題,以下簡要介紹兩種:

1. 額外數組法(空間復雜度 O (n))

思路

開辟一個與原數組長度相同的新數組,將原數組中 “需要輪轉的元素” 按目標順序放入新數組,最后將新數組的值復制回原數組。

  • 對于原數組索引 i 的元素,輪轉后在新數組的索引為 (i + k) % n(向右輪轉 k 步);
  • 也可直接定位:新數組前 k 個元素對應原數組末尾 k 個元素(索引 n-k 到 n-1),新數組后 n-k 個元素對應原數組前 n-k 個元素(索引 0 到 n-k-1)。
優缺點
  • 優點:邏輯直觀,易于理解和實現,無需復雜的翻轉操作;
  • 缺點:需要開辟額外數組,空間復雜度為 O (n),不如三次翻轉法高效。

2. 多次右移法(時間復雜度 O (nk))

思路

每次只將數組向右輪轉 1 步,重復 k 次。輪轉 1 步的邏輯是:保存數組最后一個元素,然后將其余元素從后向前依次右移 1 位,最后將保存的元素放到數組開頭。

優缺點
  • 優點:邏輯簡單,無需復雜算法,僅需基礎的元素移動操作;
  • 缺點:時間復雜度為 O (nk)(每次輪轉 1 步需 O (n) 時間,共 k 次),當 k 較大時(如 k=n),時間復雜度會達到 O (n2),效率極低。

四、復雜度分析(三次翻轉法)

1. 時間復雜度:O (n)

  • 翻轉操作的時間復雜度:翻轉一段長度為 L 的數組,需要交換 L//2 次元素,時間復雜度為 O (L);
  • 三次翻轉的總時間:第一次翻轉整個數組(O (n)),第二次翻轉前 k 個元素(O (k)),第三次翻轉后 n-k 個元素(O (n-k)),總時間為 O (n) + O (k) + O (n-k) = O (n);
  • 整體時間:加上 k 取模的 O (1) 操作,總時間復雜度為 O (n)。

2. 空間復雜度:O (1)

  • 整個過程僅用到了幾個額外變量(如 left、right 指針,k_mod 等),沒有開辟新的數組或其他數據結構;
  • 所有翻轉操作都在原數組上完成,額外空間的使用與數組長度 n 無關,因此空間復雜度為常數級的 O (1)。

五、三次翻轉法代碼實現

以下以 Python,Java 為例,實現三次翻轉法,核心是先實現 “段翻轉” 函數,再執行三次翻轉:

1,Python

class Solution:def rotate(self, nums: List[int], k: int) -> None:def reversed(i: int, j: int):while i < j:nums[i], nums[j] = nums[j], nums[i]i, j = i + 1, j - 1n = len(nums)k %= nreversed(0, n - 1)reversed(0, k - 1)reversed(k, n - 1)

2,Java

class Solution {int[] nums;public void rotate(int[] nums, int k) {this.nums = nums;int n = nums.length;k %= n;reversed(0, n - 1);reversed(0, k - 1);reversed(k, n - 1);}private void reversed(int i, int j) {for (; i < j; i++, j--) {int t = nums[i];nums[i] = nums[j];nums[j] = t;}}
}

你可以將上述代碼復制到 LeetCode 編輯器中測試,完全符合題目要求。

六、總結與拓展

三次翻轉法是解決 “輪轉數組” 問題的最優解,其核心優勢在于 “線性時間 + 常數空間”,且邏輯可遷移到類似的 “元素循環移動” 問題中。需要注意的是,三次翻轉法的邏輯不僅適用于 “向右輪轉”,也可調整為 “向左輪轉”:

拓展:向左輪轉 k 步的三次翻轉法

若題目要求 “向左輪轉 k 步”(例如[1,2,3,4,5,6,7]向左輪轉 3 步,結果為[4,5,6,7,1,2,3]),只需調整三次翻轉的順序:

  1. 計算 k_mod = k % n;
  1. 第一次翻轉:翻轉前 k_mod 個元素;
  1. 第二次翻轉:翻轉后 n-k_mod 個元素;
  1. 第三次翻轉:翻轉整個數組。

例如,[1,2,3,4,5,6,7]向左輪轉 3 步:

  • 翻轉前 3 個元素:[3,2,1,4,5,6,7];
  • 翻轉后 4 個元素:[3,2,1,7,6,5,4];
  • 翻轉整個數組:[4,5,6,7,1,2,3],與預期結果一致。

掌握三次翻轉法的核心邏輯,能幫你輕松應對 “數組輪轉” 的各種變體問題,體現算法思維的靈活性。

希望通過本文的講解,你能不僅學會 “輪轉數組” 的解法,更能深入理解三次翻轉法的原理,將其靈活應用到類似的 “元素順序調整” 問題中,提升面試競爭力。

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

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

相關文章

網絡編程---TCP

1.TCP&#xff1a;傳輸控制協議&#xff0c;位于傳輸層2.TCP的特性&#xff1a;a.使用流式套接字&#xff0c;數據連續&#xff0c;有順序b.TCP是可靠傳輸&#xff0c;有有應答機制ACK&#xff0c;即收到數據后會明確告知發送方已收到數據&#xff1b;若發送方沒有在預計時間收…

對計算機網絡模型的理解

文章目錄 目錄 前言 一、Internet 的核心特點 二、Internet 的組成結構 1. 硬件基礎&#xff1a;網絡運行的 “物理載體” 2. 軟件支撐&#xff1a;網絡運行的 “功能橋梁” 3. 協議規則&#xff1a;網絡運行的 “通用語言” 三、OSI 七層參考模型&#xff08;理論標準&…

每日一算:分發糖果

在算法面試中&#xff0c;“分發糖果” 是一道經典的貪心算法應用題&#xff0c;核心考察對 “局部最優推導全局最優” 的理解。本文將從問題分析出發&#xff0c;提供兩種主流解題思路&#xff0c;并附上 C 實現代碼&#xff0c;幫助你徹底掌握這道題。一、問題重述題目要求有…

【WorkManager】無法在 Direct Boot 模式下初始化

【WorkManager】無法在 Direct Boot 模式下初始化一、問題描述二、問題分析2.1 關于 Direct Boot 模式2.2 支持 Direct Boot 模式2.3 手動初始化 WorkManager 組件2.4 WorkManager 不支持 Direct Boot 的官方修改三、解決方案一、問題描述 在使用 WorkManager 庫來實現開機上報…

Hybrid應用性能優化實戰分享(本文iOS 與 H5為例,安卓同理)

前言在移動應用開發中&#xff0c;Hybrid 架構因其跨平臺特性和開發效率優勢被廣泛采用。然而&#xff0c;WebView 的性能問題一直是開發者面臨的挑戰。本文將基于實際項目經驗&#xff0c;分享 iOS Hybrid 應用的核心優化策略&#xff0c;涵蓋 WebView 池化、預加載、用戶體驗…

點積、叉積、矩陣行列式詳解、線性相關與線性無關、矩陣的秩、矩陣可逆與不可逆詳解

1.向量 1.1 點積&#xff08;Dot Product&#xff09; 1.1.1 定義 點積是在求一個標量&#xff0c;點積結果沒有方向。 對于兩個向量u(u1,u2,u3),v(v1,v2,v3)\bold{u}(u_1,u_2,u_3),\bold{v}(v_1,v_2,v_3)u(u1?,u2?,u3?),v(v1?,v2?,v3?) 點積定義為&#xff1a;u?vu1v1u…

Mac安裝nvm詳細教程(超簡單)

本章教程,主要介紹如何在Mac操作系統上安裝nvm. 我們使用官方一鍵安裝腳本,完成安裝 一、安裝步驟 curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.3/install.sh | bash配置環境變量,編輯.zshrc文件 vim .zshrcexport NVM_DIR="$(

【selenium】網頁元素找不到?從$(‘[placeholder=“手機號“]‘)說起

網頁元素找不到&#xff1f;從$(‘[placeholder“手機號”]’)說起總結&#xff1a;控制臺不騙人&#xff0c;元素選不到&#xff0c;八成是寫法、時機或環境的問題。我們在寫網頁自動化腳本或者調試頁面的時候&#xff0c;經常遇到一個讓人頭疼的問題&#xff1a;明明元素就在…

SSE 模仿 GPT 響應

后端代碼 const express require(express) const cors require(cors);const app express(); app.use(cors()); const port 3000;app.listen(port, () > {console.log(Server running at http://localhost:${port}/); });const msg 全國同胞們&#xff0c; 尊敬的各位國…

MAC 多個版本 JDK進行切換

1.查看本機所有的jdk/usr/libexec/java_home -V2、打開bash_profile文件。可以在終端vim ~/.bash_profile打開&#xff0c;也可以打開訪達shiftcmdG然后輸入/Users/mac/.bash_profile&#xff08;本機bash_profile的路徑&#xff09;加入新的環境變量格式如下&#xff08;參考我…

shell 中 expect 詳解

一、概述Expect是一個免費的編程工具語言&#xff0c;用來實現自動和交互式任務進行通信&#xff0c;而無需人的干預。Expect的作者DonLibes在1990年開始編寫Expect時對Expect做有如下定義&#xff1a;Expect是一個用來實現自動交互功能的軟件套件。通過expect系統管理員可以創…

第4講 機器學習基礎概念

機器學習作為人工智能的子領域&#xff0c;專注于訓練計算機算法自動發現數據中的模式與關聯關系。以下是其核心基礎概念&#xff1a;4.1 數據數據是機器學習的基石。缺乏數據&#xff0c;算法將無從學習。數據可呈現為結構化數據&#xff08;如電子表格、數據庫&#xff09;和…

Go組合式繼承:靈活替代方案

Go 語言沒有傳統面向對象編程中的繼承機制&#xff0c;但通過組合和接口實現類似功能。Go 更提倡組合優于繼承的設計原則&#xff0c;這種設計方式更靈活且易于維護。結構體組合&#xff08;偽繼承&#xff09;通過嵌套結構體實現類似繼承的效果。子結構體可以直接訪問父結構體…

Verilog三段式FSM,實現十字路口紅綠燈

運行環境&#xff1a;VCS verdi狀態說明&#xff1a;S0 &#xff1a; 初始狀態 S1 &#xff1a; 東西方向綠燈亮&#xff0c;南北方向紅燈亮&#xff1b;點亮30周期 S2 &#xff1a; 東西方向黃燈亮&#xff0c;南北方向紅燈亮&#xff1b;點亮2 周期 S3 &#xff1a; 東西方向…

java 將pdf轉圖片

如何將pdf文件轉為圖片 import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.rendering.PDFRenderer; import javax.imageio.ImageIO; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; public class Pdf2Png {/**…

手搓Spring

目錄 兩種方法創建Spring容器 自定義Spring容器及前置操作 Spring掃描邏輯實現 createBean()方法 getBean()方法 依賴注入&#xff08;DI&#xff09; BeanNameAware接口 InitializingBean接口 BeanPostProcessor接口 AOP的實現 Spring 是一個輕量級的 Java 開發框架…

.NET 單文件程序詳解:從原理到實踐

C# 混淆加密大師在最新版本中, 提供了.NET單文件解包打包功能, 它可以快速解包官方打包的單文件程序&#xff0c;恢復為原始的多文件結構。也可以對解包后的程序集進行混淆與加密&#xff0c;有效提升逆向門檻。最后還能重新打包成單文件程序&#xff0c;保持對用戶友好的分發形…

Spring面試題記錄?

請簡述 Spring 框架的核心是什么&#xff1f;它主要包含了哪些核心模塊&#xff1f; spring的核心模塊主要有spring-core&#xff08;工具類&#xff0c;資源加載&#xff09;&#xff0c;spring-bean&#xff08;bean的定義&#xff0c;創建&#xff0c;封裝&#xff09;&…

一次緩存引發的文件系統數據不一致問題排查與深度解析

01 起因EFC&#xff08;Elastic File Client&#xff09;是 NAS 自研的分布式文件系統客戶端&#xff0c;最近完成了對緩存架構的更新&#xff0c;現在支持多個客戶端之間構成分布式緩存&#xff0c;底層支持 NAS、CPFS 和 OSS。由于開發時間較短&#xff0c;一直沒有做 NAS 場…

Spring Boot Gateway 教程:從入門到精通

一、Spring Cloud Gateway 簡介Spring Cloud Gateway 是基于 Spring 5、Project Reactor 和 Spring Boot 2 構建的 API 網關&#xff0c;旨在為微服務架構提供一種簡單而有效的路由管理方式。它取代了 Netflix Zuul&#xff0c;提供了更高效和更強大的網關解決方案。核心特點&a…