題目來源:
https://leetcode.com/problems/rotate-array/description/
題目分析:
題目給定我們一個數組和要將數組整體向右移動的位數k,k是正數,需要我們得到一個全新的移位後的數組。下面將嘗試幾種方法來進行解決。
1.暴力檢索
採用循環的方式,直接對每一位進行相應的移位。這裏需要注意它使用的方法是將前面的元素從第0位開始依次與最後一位交換,這樣的結局恰好就可以實現將最後一位移到首尾,然後後面的位數依次向後移的效果。將這個過程循環k次即可得到結果。雖然其空間複雜度爲O(1),類似於在原地進行了運算,但是其時間複雜度爲O(n*K),所以在檢測時會因爲時間複雜度超時而不能過檢。其代碼如下:
class Solution:
def rotate(self, nums, k):
"""
:type nums: List[int]
:type k: int
:rtype: void Do not return anything, modify nums in-place instead.
"""
for i in range(k):
previous=nums[len(nums)-1]
for j in range(len(nums)):
temp=nums[j]
nums[j]=previous
previous=temp
return nums
2.使用額外的數組
另一種想法是再創造一個數組,將下標爲i的元素都放在下標爲i+k的位置,最後再將正確的值賦給原來的數組。這個有個小tip,就是要將數組後面的元素放到前面來實現循環k位,可以將所有元素的下標都加上k然後對數組長度進行取餘,那麼就自動實現了循環了!
下面將針對我寫代碼過程中遇到的一些問題來闡明需要注意的一些點。
1.首先,我是想將新的列表設爲空列表的。但是需要注意的是空列表必須從a[0]開始賦值,而不能直接從a[k]開始賦值,因此會報關於下標的錯誤。
2.關於得到新的數組,將其賦予給原數組的問題。一開始我想採用nums=a[:]進行直接賦值,但需要注意的是在函數中,這樣的操作實際上可以看成是改變了nums指針的位置,而nums本身的值並沒有發生變化,要想改變它的值,必須使用下標或者無返回值的那些方法纔可以。
其代碼如下:
class Solution:
def rotate(self, nums, k):
"""
:type nums: List[int]
:type k: int
:rtype: void Do not return anything, modify nums in-place instead.
"""
a=nums[:]
for i in range(len(nums)):
a[(i+k)%(len(nums))]=nums[i]
for j in range(len(nums)):
nums[j]=a[j]
其時間複雜度爲O(n),其空間複雜度也爲O(n)
3.採用切片的方法
我們觀察實現的數組,比如原數組爲[1,2,3,4,5,6,7],k=3,則我們應該得到的翻轉後的數組應該爲[5,6,7,1,2,3,4],我們可以看成先將它從4,5之間切開,然後將後面的部分加上前面的部分從而組成一個新的數組。其代碼爲:
class Solution:
def rotate(self, nums, k):
"""
:type nums: List[int]
:type k: int
:rtype: void Do not return anything, modify nums in-place instead.
"""
nums[:]=nums[len(nums)-k:]+nums[:(len(nums)-k)]
需要注意的是,一定要寫成nums[:]纔會對nums進行修改,如果只寫成nums,是不會改變它的值的。