切換
舊版
前往
大廳
主題

LeetCode - 189. Rotate Array 解題心得

Not In My Back Yard | 2020-09-03 00:00:29 | 巴幣 0 | 人氣 213

題目連結:


題目意譯:
給定一陣列 num,往右旋轉該陣列 k 步,其中 k 為非負整數。

進階:
試圖得出盡可能多的解答,這題存在至少 3 種相異的解法。
你可以 O(1) 額外空間原地(In-Place)做出這題嗎?

限制:
1 ≦ nums.length ≦ 2 × 10 ^ 4
保證 nums[i] 可以存在 32 有號整數裡。
k ≧ 0



範例測資:
範例 1:
輸入: nums = [1,2,3,4,5,6,7] , k = 3
輸出: [5,6,7,1,2,3,4]
解釋:
往右轉 1 步: [7,1,2,3,4,5,6]
往右轉 2 步: [6,7,1,2,3,4,5]
往右轉 3 步: [5,6,7,1,2,3,4]

範例 2:
輸入: nums = [-1,-100,3,99] , k = 2
輸出: [3,99,-1,-100]
解釋:
往右轉 1 步: [99,-1,-100,3]
往右轉 2 步: [3,99,-1,-100]


解題思維:
首先,暴力法當然可行。因為可以看到每向右旋轉 num.length 次就會回到原本的樣子。因此我們可以將 k 值除以 num.length 取餘數,作為新的 k 值。接著就是一個一個的交換之步驟,全部交換後才算一次,然後要跑 k 次。

不介意使用額外空間的話,可以使用額外的陣列。對於每個位置 i 的元素放到 i + k (超過範圍要繞回到開頭繼續算)的位置。然後再將新陣列的內容複製回來即可。



當然,有 O(num.length) 時間複雜度又是 O(1) 空間複雜度的做法,如下:
舉例來說,現有 6 個數 5 4 8 7 6 3 ,位置索引值為 0 1 2 3 4 5,要往右旋轉 2 步。

我們將數字分為恰好 2 組,一組為索引值 0 2 4 ,另一組為 1 3 5。可以看到每一組中的相鄰數字差距剛好為 2 。

將位置 i 作為基準。第一次先跟位置 i + k 的元素交換,所以 i 跑到了應該要去的位置即 i + k,而現在位置 i 的元素是原本的位置 i + k 的元素;接著第二次再跟位置 i + 2k 的交換……以此類推。直到繞回來到位置 i 時,即停止步驟。而這就是每一「組」數字要做的事。

將每一組各自跑完上面的步驟之後即完成要求。而對於一般情況,數字分組的組數 = GCD(num.length, k) ,其中 GCD 代表最大公因數。




此次分享到此為止,如有任何更加簡潔的想法或是有說明不清楚之地方,也煩請各位大大撥冗討論。

創作回應

更多創作