[Java]数组循环位移

数组[n-1], 循环位移k位, 时间复杂度O(n)

方法A, 此算法的设计思路是什么呢?

1) 分为0 ~ k, k ~ n-1 两部分, 分别逆序

2) 0 ~ n-1 逆序

public class ArrayShift {

	static public void shift(Object[] ary, int k) {
		int n = ary.length;
		k = k % n;
		if(k < 0)
			k = k + n;
		reverse(ary, 0, n - k - 1);
		reverse(ary, n - k, n - 1);
		reverse(ary, 0, n - 1);

	}

	static void reverse(Object[] ary, int start, int end) {
		Object t;
		for (; start < end; start++, end--) {
			t = ary[start];
			ary[start] = ary[end];
			ary[end] = t;
		}
		
	}
	
}

方法B, 自己胡乱想的,是否符合时间复杂度要求?

1) 假设右移k位, 则将数组A 最末的k个元素与 0 ~ k 交换,使得0 ~ k位置顺序符合要求, 并得到 A[k+1] , A[k+2] ..... A[1], A[2] ... A[k] 组成的长度为n-k的数组A‘

2) 如果A‘长度小于k, k = k % A.length;

3) A’ 位移k位, 递归至数组长度0 或 k = 0

public class ArrayShift {

	public static void shift(Object[] ary, int k){
		int n = ary.length;
		k = k % n;
		if (k > 0){
			shiftRight(ary, 0 , n , k);
		}else{
			shiftRight(ary, 0 , n , n+k);
		}
		
	}	
		
	 static void shiftRight(Object[] ary, int start, int n, int k){

		 if (n > 0 && k > 0) {
			for (int i = 0; i < k; i++) {
				swap(ary, n + start - k + i, start + i);
				}
			if ( n > k * 2  ){
				shiftRight(ary, start + k, n - k, k);
			}else{
				int r = k % (n - k);
				shiftRight(ary, start + k, n - k , r);
			}
		}

	 }		
	
         static void swap(Object[] ary, int m, int n){
 		Object tmp;
    	        tmp = ary[m];
		ary[m] = ary[n];
		ary[n] = tmp;
	 }
	
}







你可能感兴趣的:(十年)