题目描述:给定一个数组,将数组中的元素向右移动 k 个位置,其中 k 是非负数。
解题思路一:先用一个临时数组存储最终结果,然后再一个一个赋值
class Solution:
def rotate(self, nums: List[int], k: int) -> None:
"""
Do not return anything, modify nums in-place instead.
"""
n = len(nums)
k %= n
idx = 0
tmp = nums[n-k:] + nums[:n-k]
for i in range(n):
nums[i] = tmp[i]
解题思路二:先将数组逆序,这样就将后k个移到前面,剩余的都移到后面的位置,然后再前k个逆序,后n-k个逆序
class Solution:
def rotate(self, nums: List[int], k: int) -> None:
"""
Do not return anything, modify nums in-place instead.
"""
n = len(nums)
k %= n
idx = 0
nums.reverse()
for i in range(k//2):
nums[i], nums[k-i -1] = nums[k-i-1], nums[i]
for i in range((n-k)//2):
nums[i+k], nums[n-1-i] = nums[n-1-i], nums[i+k]
解题思路三:环装替换,每次都将一个数字移到他最终的位置,然后再考虑被替换掉的那个位置,这样最后可能会回到起点,导致有些没有完成替换,循环多次这样的替换,循环的次数为n和k的最大公约数,详细数学推导见leetcode
class Solution:
def rotate(self, nums: List[int], k: int) -> None:
"""
Do not return anything, modify nums in-place instead.
"""
def gcd(n, k):
return n if k == 0 else gcd(k, n%k)
n = len(nums)
k %= n
if k == 0:return
num = gcd(n, k)
for i in range(num):
next_id = (i+k) %n
next_num = nums[next_id]
prev = nums[i]
while(next_id != i):
nums[next_id] = prev
prev = next_num
next_id = (next_id + k) % n
next_num = nums[next_id]
nums[next_id] = prev