題目
給定乙個陣列,將陣列中的元素向右移動 k 個位置,其中 k 是非負數。
示例 1:
輸入: [1,2,3,4,5,6,7] 和 k = 3
輸出: [5,6,7,1,2,3,4]
移動過程:
1.向右旋轉 1 步: [7,1,2,3,4,5,6]
2.向右旋轉 2 步: [6,7,1,2,3,4,5]
3.向右旋轉 3 步: [5,6,7,1,2,3,4]
示例 2:
輸入: [-1,-100,3,99] 和 k = 2
輸出: [3,99,-1,-100]
移動過程:
1.向右旋轉 1 步: [99,-1,-100,3]
2.向右旋轉 2 步: [3,99,-1,-100]
說明:
1.盡可能想出更多的解決方案,至少有三種不同的方法可以解決這個問題。
2.要求使用空間複雜度為 o(1) 的 原地 演算法。
題目分析
該題的目的是按照步數來向右移動整個陣列的元素位置。如果不加說明裡面第二條空間複雜度為 o(1) 的限制,該題很容易解決,直接另外新建乙個同大的陣列來儲存移動的資料即可快速解決。但有了這個限制之後,程式設計時就需要考慮程式記憶體的問題。該題的解決方法多種多樣,這裡我將詳細介紹我在刷這題時的思路。
第一步:由於傳遞進入函式的k(步數)值取值沒有限制,因此,需要考慮如何最快根據k來確定移動步數。舉個例子,假設陣列為,如果給定k為10000,我們難道要真的移動10000次嗎?顯然是不可能這樣做的。這裡之所以可以快速確定實際的移動步數是因為陣列的大小是固定的,當k值等於陣列大小時,裡面的元素移動後正好和原來一樣,相當於沒有移動。因此,無論k值多大,我們實際上只要進行一次的陣列元素移動即可。以示例1為例,陣列大小為7,任取k值,實際上只要用k對7取餘即可。因此實際移動步數=k%7。
第二步:考慮根據移動步數來確定原陣列每個元素移動後的新位置。由於第一步已經確定移動步數,因此,新位置很容易確定,將原位置下標加上移動步數即可。但這裡要考慮下新位置的越界情況。
第三步:有了前兩步,對於給定下標的陣列元素,我們能直接得到它移動後的位置。因此,首先將陣列元素和新位置上原來的數值進行交換,然後記住剛剛新的位置,計算該位置移動後的新位置,並將該位置原來的數值(已經不在該位置上,因為之前已經交換了)和新位置上的數值進行交換,迴圈下去,直到陣列所有元素都移動完為止。該過程如下圖(以示例1為例):先移動最後乙個元素7,首先計算該元素的新位置下標為2,因此將該位置與下標為2的位置上的元素3互換。此時計算元素3的最終位置為5,因此將元素3與下標為5的元素6互換。然後再計算元素6的最終位置為1,因此將元素6與下標為1的元素2互換。接下來計算元素2的最終位置為4,因此將元素2與下標為4的元素5互換。繼續計算元素5的最終位置為0,因此將元素5與下標為0的元素1互換。最後計算元素1的最終位置為3,將1與下標為3的元素4互換得到最終的移動結果。
從圖中可以看出來,對於示例的陣列來說,完成移動只需要六次的交換會即可。對於大小為n的陣列,完成移動只需要n-1次交換。
leetcode測試**如下:
class
solution
i++;}
}}};
執行結果如下:
vs下完整**如下:
#include
#include
using
namespace std;
class
solution
i++;}
}}};
intmain()
;int k=3;
solution object;
object.
rotate
(a,k)
;return0;
}
LeetCode刷題之788 旋轉數字
我不知道將去向何方,但我已在路上!輸入 10 輸出 4 解釋 在 1,10 中有四個好數 2,5,6,9。注意 1 和 10 不是好數,因為他們在旋轉之後不變。class solution def rotateddigits self,n int int deffun num a s str num...
LeetCode 旋轉陣列
將包含n 個元素的陣列向右旋轉 k 步。例如,如果 n 7 k 3,給定陣列 1,2,3,4,5,6,7 向右旋轉後的結果為 5,6,7,1,2,3,4 注意 盡可能找到更多的解決方案,這裡最少有三種不同的方法解決這個問題。要求空間複雜度為 o 1 關聯的問題 反轉字串中的單詞 ii public ...
LeetCode 旋轉陣列
給定乙個陣列,將陣列中的元素向右移動 k 個位置,其中 k 是非負數。示例 1 輸入 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...