描述
一个数组A中存有 n 个整数,在不允许使用另外数组的前提下,将每个整数循环向右移 M( M >=0)个位置,
即将A中的数据由(A0 A1 ……AN-1 )变换为(AN-M …… AN-1 A0 A1 ……AN-M-1 )
(最后 M 个数循环移至最前面的 M 个位置)。如果需要考虑程序移动数据的次数尽量少,要如何设计移动的方法?
数据范围:0<n≤10,0≤m≤1000
进阶:空间复杂度 O(1),时间复杂度 O(n)
问题分析:提交完代码查看其他提交排名前面的几个代码,几乎都额外申请了数组空间,明显不符合题目要求。
那么如何让空间复杂度O(1)实现循环移位呢。
通过观察发现,其实是数租后面的k个移动到前面,那么我们可以反转数租,然后让前面k个和后面n-k个继续反转。
下面通过一个例子来观察:假设原数租为:1,2,3,4,5,6,7,8,9,10。输入m=3;
1、整体反转:10,9,8,7,6,5,4,3,2,1;
2、前k位反转:8,9,10,7,6,5,4,3,2,1;
3、后面n-k为反转:8,9,10,1,2,3,4,5,6,7.
完美的没有用额外空间实现了循环右移m位。
class Solution { public: vector<int> solve(int n, int m, vector<int>& a) { if(n<=1) return a;//当数组长度<=1,不管怎么移动都不变 if(m%n==0) return a;//当移动n的倍数,相当于没移动 int k=m%n;//计算需要右移的位数,因为可能m>n reverse(a.begin(),a.end());//整个反转 reverse(a.begin(),a.begin()+k);//0~k位置反转 reverse(a.begin()+k,a.end());//k~n位置反转 return a; } };