一个数组A中存有 n 个整数,在不允许使用另外数组的前提下,将每个整数循环向右移 M( M >=0)个位置,即将A中的数据由(A0 A1 ……AN-1 )变换为(AN-M …… AN-1 A0 A1 ……AN-M-1 )(最后 M 个数循环移至最前面的 M 个位置)。如果需要考虑程序移动数据的次数尽量少,要如何设计移动的方法?
数据范围:
,
进阶:空间复杂度
,时间复杂度
6,2,[1,2,3,4,5,6]
[5,6,1,2,3,4]
4,0,[1,2,3,4]
[1,2,3,4]
(1<=N<=100,M>=0)
import java.util.*;
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
* 旋转数组
* @param n int整型 数组长度
* @param m int整型 右移距离
* @param a int整型一维数组 给定数组
* @return int整型一维数组
*/
public int[] solve (int n, int m, int[] a) {
if(m==0)return a;
int[] res=new int[a.length];
m=m%a.length;
System.arraycopy(a, 0, res, m, a.length-m);
System.arraycopy(a, a.length-m, res, 0, m);
return res;
}
} public int[] solve (int n, int m, int[] a) {
// write code here
m%=n; // 防止n=10 m=11这种情况
reverse(a ,0 ,n-m-1);
reverse(a ,n-m ,n-1);
reverse(a ,0 ,n-1);
return a;
}
public void reverse(int[] arr ,int start ,int end){
while(start<end){
int temp=arr[start];
arr[start++]=arr[end];
arr[end--]=temp;
}
} public int[] solve (int n, int m, int[] a) {
//截取倒数m个数,放到数组a的最前面
//逆转全部,逆转前m个,逆转后(n-m)个
m=m%n;
reverse(a,0,n-1);
reverse(a,0,m-1);
reverse(a,m,n-1);
return a;
}
public void reverse(int[] a,int begin,int end){
while(begin<=end){
int tmp=a[begin];
a[begin]=a[end];
a[end]=tmp;
//更新指标
begin++;
end--;
}
} 从第0个位置开始,将第0个位置的值移入第 (0+m)%n 个位置,需要提前保存下一个位置的值,做 n 次操作。
public int[] solve (int n, int m, int[] a) {
// write code here
if(a.length <= 1) return a;
if(m > n) m = m % n;
if(m % 2 == 0) {
// 两次
int curIndex = 0;
int curValue = a[curIndex];
int nextIndex = (curIndex + m) % n;
int nextValue = a[nextIndex];
for(int i=0; i<n/2; i++) {
a[nextIndex] = curValue;
curIndex = nextIndex;
curValue = nextValue;
nextIndex = (curIndex + m) % n;
nextValue = a[nextIndex];
}
curIndex = 1;
curValue = a[curIndex];
nextIndex = (curIndex + m) % n;
nextValue = a[nextIndex];
for(int i=0; i<n/2; i++) {
a[nextIndex] = curValue;
curIndex = nextIndex;
curValue = nextValue;
nextIndex = (curIndex + m) % n;
nextValue = a[nextIndex];
}
} else {
// 一次
int curIndex = 0;
int curValue = a[curIndex];
int nextIndex = (curIndex + m) % n;
int nextValue = a[nextIndex];
for(int i=0; i<n; i++) {
a[nextIndex] = curValue;
curIndex = nextIndex;
curValue = nextValue;
nextIndex = (curIndex + m) % n;
nextValue = a[nextIndex];
}
}
return a;
} import java.util.*;
public class Solution {
/**
* 旋转数组
* @param n int整型 数组长度
* @param m int整型 右移距离
* @param a int整型一维数组 给定数组
* @return int整型一维数组
*/
public int[] solve (int n, int m, int[] a) {
// write code here
m=m%n;
m=n-m;
for(int i=0;i<m/2;i++){
int temp=a[i];
a[i]=a[m-1-i];
a[m-1-i]=temp;
}
for(int i=m;i<(a.length+m)/2;i++){
int temp=a[i];
a[i]=a[a.length-1+m-i];
a[a.length-1+m-i]=temp;
}
for(int i=0;i<a.length/2;i++){
int temp=a[i];
a[i]=a[a.length-1-i];
a[a.length-1-i]=temp;
}
return a;
}
} import java.util.*;
public class Solution {
/**
* 旋转数组
* @param n int整型 数组长度
* @param m int整型 右移距离
* @param a int整型一维数组 给定数组
* @return int整型一维数组
*/
public int[] solve (int n, int m, int[] a) {
// write code here
int temp=0;
for(int t=1;t<=m;t++){
temp=a[n-1];
for(int i=n-2;i>=0;i--){
a[i+1]=a[i];
}
a[0]=temp;
}
return a;
}
} import java.util.*;
public class Solution {
/**
* 旋转数组
* @param n int整型 数组长度
* @param m int整型 右移距离
* @param a int整型一维数组 给定数组
* @return int整型一维数组
*/
public int[] solve (int n, int m, int[] a) {
// write code here
int length = m % n;
reverse(a, 0, n - 1);
reverse(a, 0, length - 1);
reverse(a, length, n - 1);
return a;
}
public void reverse(int[] a, int left, int right) {
while (left < right) {
int temp = a[left];
a[left++] = a[right];
a[right--] = temp;
}
}
} import java.util.*;
public class Solution {
public int[] solve (int n, int m, int[] a) {
m = m % n;
exchange(a, 0, n-1);
exchange(a, 0,m-1);
exchange(a, m,n-1);
return a;
}
public void exchange(int[] a, int start, int end){
while(start < end){
int tmp = a[start];
a[start] = a[end];
a[end] = tmp;
start++;
end--;
}
}
} public class Solution {
/**
* 旋转数组
* @param n int整型 数组长度
* @param m int整型 右移距离
* @param a int整型一维数组 给定数组
* @return int整型一维数组
*/
public int[] solve (int n, int m, int[] a) {
m%=n;
//三次反转
if(m == 0) return a;
reverse(0,n,a);
reverse(0,m,a);
reverse(m,n,a);
return a;
}
public void reverse(int l, int r, int[] a){
while(l<r){
int tmp = a[l];
a[l++]=a[--r];
a[r]=tmp;
}
}
} public int[] solve (int n, int m, int[] a) {
if (m % n == 0) return a;
reverse(a, 0, n - 1);
reverse(a, 0, m % n - 1);
reverse(a, m % n, n - 1);
return a;
}
public void reverse(int[] arr, int l, int r) {
while (l < r) {
arr[l] = arr[l] ^ arr[r] ^ (arr[r] = arr[l]); // 使用异或来交换(省行数)
l++; r--;
}
} 6,2,[1,2,3,4,5,6]三次翻转:
import java.util.*;
public class Solution {
public int[] solve (int n, int m, int[] a) {
m = m % n;
for (int i = 0; i < m; i++)
for (int j = i + m; j % n != i; j++) {//一次交换后,元素便放置到了正确位置
int tmp = a[i];
a[i] = a[j % n];
a[j % n] = tmp;
}
return a;
}
} import java.util.*;
public class Solution {
/**
* 旋转数组
* @param n int整型 数组长度
* @param m int整型 右移距离
* @param a int整型一维数组 给定数组
* @return int整型一维数组
*/
public int[] solve (int n, int m, int[] a) {
// write code here
m = m % n;//m是移动次数
List<Integer> rest = new ArrayList<Integer>();//用于存放移动时会超出数组的元素
for(int i = n - m ; i < n ; i ++){
rest.add(a[i]);//取出剩余超出的数存到集合中去
}
//对那些移动时不会超出数组的元素开始移动
for(int i = n - 1 - m ; i >= 0; i --){
a[i + m] = a[i];
}
//最后将集合中的元素直接从开头按顺序存放就可以
for(int i = 0 ; i < rest.size() ; i ++){
a[i] = rest.get(i);
}
return a;
}
} import java.util.*;
public class Solution {
/**
* 旋转数组
* @param n int整型 数组长度
* @param m int整型 右移距离
* @param a int整型一维数组 给定数组
* @return int整型一维数组
*/
public int[] solve (int n, int m, int[] a) {
// write code here
for(int i = 0; i < m; i++){
youYi(a);
}
return a;
}
public void youYi(int[] a){
int tail = a[a.length - 1]; // 获取最后一个元素
// 循环右移
for(int i = a.length - 1; i >= 1; i--){
a[i] = a[i - 1];
}
a[0] = tail;
}
}