数组循环右移可以把数组分成两份,第一部分是循环右移的数目,剩下的是另一部分
设要移动的为A,剩下的为B
那么这个数组的就是AB
循环移动后数组变成BA
实例:AB = 0 1 2 3 4 5 6 7A =0 1 2B =3 4 5 6 7我们需要实现的结果是BA = 3 4 5 6 7 0 1 2
对A逆序得 A1 = 2 1 0
对B逆序得 B1 = 7 6 5 4 3
A1B1 = 2 1 0 7 6 5 4 3
对A1B1逆序得
3 4 5 6 7 0 1 2
由上面的移动过程我们可以看出,数组AB循环右移的步骤是:
1、把数组按照移动的个数划分为两部分,将这两部分分别逆序
2、将上一步得到的数组逆序
完成这个算法就是进行3次逆序。(第一步两部分逆序的时间复习度O(n/2),第二步整个数组逆序也是O(n/2))
因此整个算法的时间复杂度为O(n),n%total 可以减少冗余移位次数。
测试代码如下:
public static void main(String[] args) { int[] test = new int[10]; for (int i = 0; i < 10; i++) { test[i] = i; } cyclerShift(test, 2); for (int e : test) { System.out.print(e + " "); } } private static void cyclerShift(int[] arr, int n) { int total = arr.length; n = n % total; if (n == 0 || arr == null) return; reverse(arr, 0, n-1); reverse(arr, n, total - 1); reverse(arr, 0, total - 1); } private static void reverse(int[] arr, int begin, int end) { int n = (end + 1 - begin) / 2; for (int i = 0; i < n; i++) swap(arr, begin++, end--); } private static void swap(int[] arr, int i, int j) {
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}