题解 | #旋转数组#
旋转数组
http://www.nowcoder.com/practice/e19927a8fd5d477794dac67096862042
开始题解前,先通过一个例子,直观的感受下移动的效果。
a = [1,2,3,4]
n = m = 4
a = [1,2,3,4] # m = 0,移动0次,即不需要移动
a = [4,1,2,3] # m = 1,移动一次
a = [3,4,1,2] # m = 2,移动两次
a = [2,3,4,1] # m = 3,移动三次
a = [1,2,3,4] # m = 4,移动四次
a = [4,1,2,3] # m = 5,移动五次
分析例子可知:针对 n,m的数值大小的不同需要分情况考虑。
情况1: m = 0
此种情况下,是不需要移动的,直接返回原数组就好。即:
if m == 0:
return a
情况2: m == n,即移动的次数等于数组的长度
此种情况下,相当于做了一个环形移动,之后又回到了原地。即:
if m == n:
return a
情况3: m < n,即移动的次数小于数组的长度
通过对演示例子的分析可知:
移动4次的结果相当于在移动4次结果的基础上在移动一次
移动3次的结果相当于在移动2次结果的基础上在移动一次
移动2次的结果相当于在移动1次结果的基础上在移动一次
而移动一次的结果,我们可以理解为:取出数组的最后一个元素,插入到数组的第一位 即移动一次的实现逻辑为:
value = a.pop() # 取出最后一个元素,此时a = [1,2,3]
a.insert(0,value) # 将取出的元素,插入到数组的第一位,此时a = [4,1,2,3]
那么,移动n次的结果相当于在第一次的基础上,循环移动(n-1)次,则实现逻辑为:
for i in range(m):
value = a.pop()
a.insert(0,value)
情况4: m > n, 即移动的次数大于数组长度
此种情况下可以理解为: m = xn + y,即x次整数倍的移动,再加上y次移动。 由情况123的分析可知,移动X的结果等于原数组,而y是小于m的,因此移动y次的逻辑适用于情况3.
综上所述,实现代码为:
class Solution:
def solve(self , n: int, m: int, a: List[int]) -> List[int]:
if m == 0 or m == n:
return a
else:
for i in range(m%n):
value = a.pop()
a.insert(0, value)
return a