《力扣算法訓練提升》圖解數組篇-打卡數組統計-【189】旋轉數組
今日份打卡題[189. 旋轉數組]

給定一個數組,將數組中的元素向右移動 k 個位置,其中 k 是非負數。
具體描述

解題討論


討論歸納一:輔助數組,划分旋轉區域
第一步:根據數組長度 N 和跨步 K 計算出需要轉移至數組頭部的元素個數
第二步:將數組划分為兩個區域
注意:(邏輯區域,思想區域,這里是為了方便理解,不需要真實狀態標注)
區域一:需要旋轉到右邊的數(頭部需要旋轉到尾部的元素)
區域二:需要旋轉到左邊的數(尾部需要旋轉到頭部的元素)
第三步:遷移數據到輔助數組
先遷移區域二,在遷移區域一
第四步:拷貝回原數組
區域划分圖

動畫模擬

示例一:輔助數組,划分旋轉區域
public void rotate(int[] nums, int k) {
// 計算尾部需要移至頭部元素個數
k %= nums.length;
int N = nums.length;
int j = 0;
int[] help = new int[nums.length];
// 歸位區域二
// 即歸位需要移至頭部的元素
for (int i = N - k; i < N; i++) {
help[j++] = nums[i];
}
// 歸位區域一
// 即歸位需要移至尾部的元素
for (int i = 0; i < N - k; i++) {
help[j++] = nums[i];
}
System.arraycopy(help, 0, nums, 0, N);
}
復雜度分析
時間復雜度:O(n)。遍歷數組需要 O(n) 的時間。
空間復雜度:O(n)。需要輔助數組。
討論歸納二:輔助數組,前世今生
重點:數組元素 a[i] 通過潘多拉魔盒找到今生(a[i] 旋轉后在新的位置下標 j)
遍歷數組,找到前世 a[i] 的今生 j, 並安排到輔助數組對應的位置
魔盒:j = (i+k) % N
前世今生圖

動畫模擬

示例二:輔助數組,前世今生
public void rotate(int[] nums, int k) {
int n = nums.length;
int[] help = new int[n];
for (int i = 0; i < n; ++i) {
// 旋轉 k, 相當於 nums[i] 元素向后跨步 k 個下標
// nums 數組下標范圍是 [0, N-1]
// 跨步后下標超過N-1,從 0 繼續跨步
// 計算 nums[i] 旋轉后在輔助數組中的相對位置
int m = (i + k) % n;
help[m] = nums[i];
}
System.arraycopy(help, 0, nums, 0, n);
}
復雜度分析
時間復雜度:O(n)。其中 n 為數組的長度。
空間復雜度:O(n)。需要額外空間。
討論歸納三:翻轉數組
歸納一中,囧囧划分了旋轉區域,利用輔助數組實現區域旋轉,實現了數組旋轉的目的。
實際上,我們不需要借助輔助數組也能實現區域旋轉,達到交換目的。
首先還是利用模運算計算出需要轉移到數組頭部的元素個數。
在通過翻轉數組實現旋轉。
1 2 3 4 5 6 7 K=3
第一步:根據數組長度 N 和跨步 K 計算出需要轉移至數組頭部的元素個數
第二步:將數組划分為兩個區域
注意:(邏輯區域,思想區域,這里是為了方便理解,不需要真實狀態標注)
區域一:需要旋轉到右邊的數(頭部需要旋轉到尾部的元素)
1 2 3 4
區域二:需要旋轉到左邊的數(尾部需要旋轉到頭部的元素)
5 6 7
第三步:翻轉整個數組
7 6 5 4 3 2 1
第四部:翻轉區域二,在翻轉區域一
翻轉區域二 5 6 7
翻轉區域一 1 2 3 4
5 6 7 1 2 3 4
動畫模擬

示例三:翻轉數組
public void rotate(int[] nums, int k) {
// 計算尾部需要移至頭部元素個數
k %= nums.length;
// 翻轉數組所有元素
reverse(nums, 0, nums.length - 1);
// 翻轉已經移至頭部的元素
reverse(nums, 0, k - 1);
// 翻轉已經移至尾部的元素
reverse(nums, k, nums.length - 1);
}
// 翻轉 [start, end] 范圍內的數
public void reverse(int[] nums, int start, int end) {
while (start < end) {
int temp = nums[start];
nums[start] = nums[end];
nums[end] = temp;
start += 1;
end -= 1;
}
}

短話長說
學算法先學什么?什么階段該刷什么題?
關注我,日常打卡算法圖解。
按照力扣題目類別結構化排序刷題,從低階到高階,圖解算法(更新中...),有興趣的童鞋,歡迎一起從小白開始零基礎刷力扣,共同進步!

回復:678,獲取已分類好的部分刷題順序,后續內容會持續更新,感興趣的小伙伴自由拿取!
另外,有關分類,求小伙伴們不要再問我最后一類的起名了,奇技淫巧是個褒義詞,意思是指新奇的技藝和作品。
力扣修煉體系題目,題目分類及推薦刷題順序及題解
目前暫定划分為四個階段:
算法低階入門篇--武者鍛體
算法中級進階篇--武皇煉心
算法高階強化篇--武帝粹魂
算法奇技淫巧篇--戰斗秘典
以上分類原諒我有個修仙夢...
缺漏內容,正在努力整理中...

