一个数组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; } }