循環移位法
參考文章:內容連接。文章主要從數組,字符串,鏈表三種情況下,介紹循環移位的具體實現。這里只梳理一下文章脈絡。
數組循環移位
方法一:取模法
這個方法在 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,難度中等。這里便不再展開了。