描述
一个数组A中存有 n 个整数,在不允许使用另外数组的前提下,将每个整数循环向右移 M( M >=0)个位置,即将A中的数据由(A0 A1 ……AN-1 )变换为(AN-M …… AN-1 A0 A1 ……AN-M-1 )(最后 M 个数循环移至最前面的 M 个位置)。如果需要考虑程序移动数据的次数尽量少,要如何设计移动的方法?
数据范围:0<n≤1000<n≤100,0≤m≤10000≤m≤1000
进阶:空间复杂度 O(1)O(1),时间复杂度 O(n)O(n)
示例1
输入:
6,2,[1,2,3,4,5,6]
返回值:
[5,6,1,2,3,4]
示例2
输入:
4,0,[1,2,3,4]
返回值:
[1,2,3,4]
备注:
(1<=N<=100,M>=0)
解题思路:
该方法基于如下的事实:将数组的元素向右移动 k 次后,尾部 m mod n 个元素会移动至数组头部,其余元素向后移动 m mod n 个位置。
1、可以先将所有元素翻转,这样尾部的 m mod n 个元素就被移至数组头部,
2、然后再翻转 [0,m mod n−1] 区间的元素
3、 最后翻转[m mod n,n−1] 区间的元素即能得到最后的答案。
实例:
以 n=7,m=3 为例进行如下展示:
| 操作 | 结果 |
| 原始数据 | 【1,2,3,4,5,6,7】 |
| 翻转所有元素 | 【7,6,5,4,3,2,1】 |
| 翻转 [0,m mod n −1] 区间的元素 | 【5,6,7,4,3,2,1】 |
| 翻转 [m mod n, n −1] 区间的元素 | 【5,6,7,1,2,3,4】 |
最后返回:【5,6,7,1,2,3,4】
def solve(self , n , m , a ):
# write code here
m = m % n
# 数组反转
# 翻转全部
self.reverse(a, 0, n - 1);
# 再翻转 【0,m-1】
self.reverse(a, 0, m - 1);
# 再翻转 【m,n-1】
self.reverse(a, m, n - 1);
return a
def reverse(self, nums, start, end):
# 数组翻转
while start < end :
# 双指针遍历翻转
temp = nums[start];
nums[start] = nums[end];
nums[end] = temp;
start += 1;
end -= 1;