循環移位算法


循環移位法

參考文章:內容連接。文章主要從數組,字符串,鏈表三種情況下,介紹循環移位的具體實現。這里只梳理一下文章脈絡。

數組循環移位

方法一:取模法

這個方法在 Leetcode 189 中已經用過了,作者這里考慮了兩種新情況:

  • 如果移位位數 K 是數組長度 len(s) 的倍數的話,那么就不用移位了;
  • 如果 K 是負數,就是往相反方向(向左移)

方法二:時間換空間

如果要解決上面的問題,那我們便一次一次的考慮,總共移動 K 次。這樣時間復雜度變成了 O(N*K),最大可達 O(N^2)。

方法三:空間換時間

就是將數組長度變成原來的兩倍,拼在一起。這在 leetcode-189 也有相關的描述。

三次翻轉法

所謂“翻轉”,比如[0,N],就是把 0 和 N 交換位置,1和(N-1)交換位置……。算法描述:

  • 先把[0, n - k - 1]翻轉
  • 然后把[n - k, n - 1]翻轉
  • 最后把[0, n - 1]翻轉

這個算法其實很好證明。我們用箭頭代表方向:

  • 初始數組為 A->B | C->D
  • 經過前兩次反轉后變成了 B<-A | D<-C
  • 最后整體翻轉,C->D | A->B
  • 翻轉看箭頭的方向就好了,這是自己想的比較直觀的證明。實現翻轉的代碼描述為:
while (start < end) {
    t = list[start];
    list[start] = list[end];
    list[end] = t;
    start++;
    end--;
}

字符串移位

這里給出的例題為檢查是否包含的問題。直觀解法是每移動一次就判斷一次,那么需要判斷 len(s) 次。

暴力法

就是上面最直觀的方法。實現思路是:已知 S1 和 S2,每次都把 S1 左移一位,用指針 P1 和 P2 開始對兩個字符串開始檢查;每左移一次,兩個指針就循環檢查一次。

用空間換時間

拼接兩個 S1 字符串,然后用兩個指針開始對於新的 S1 和 S2 進行檢查。

取模法

取模法實際上是對於空間換時間算法的取巧。我們假設 S1 后面還有一個 S1,實際上是用取模的方法實現的。

鏈表循環移位

源於 leetcode-61,難度中等。這里便不再展開了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM