1. 程式人生 > >陣列:如何把一個數組迴圈右移K位

陣列:如何把一個數組迴圈右移K位

問題描述:

假設要把陣列12345678右移2位,變為78123456。

分析:

方法一:

比較移位前後陣列序列的形式,不難看出,其中有兩段序列的順序是不變的,即就是 78 和 123456, 可以把這兩段看做兩個整體,右移k位就是把陣列的兩部分交換一下。時間複雜度為O(n)

步驟:

1)逆序陣列子序列123456,陣列序列的形式為65432178

2)逆序陣列子序列78, 陣列序列的形式變為65432187

3)全部逆序, 陣列序列的形式為78123456

程式碼:

private void shift_k1(int[] a, int k) {
		int n = a.length;
		k = k % n;
		reverse(a,0,n-k-1);
		reverse(a,n-k,n-1);
		reverse(a,0,n-1);
	}
private void reverse(int[] a, int i, int j) {
		for(; i<j; i++,j--){
			int tmp = a[i];
			a[i] = a[j];
			a[j] = tmp;
		}
	}

方法二:

使用arraylist來儲存k位後面的數,陣列的前K位依次向後移動k位,最後將集合中的後k位數放到a的前k位中,注意對於K需要%a.length.

程式碼:

private int[] shift_k(int[] a, int k) {
		k = k % a.length;
		if(k == 0){
			return a;
		}
		ArrayList<Integer> q = new ArrayList<Integer>();
		for(int j=a.length-k; j<a.length; j++){
			q.add(a[j]);
		}
		for(int i=a.length-k-1; i>=0; i--){
			a[i+k] = a[i];
		}
		for(int i=0; i<k; i++){
			a[i] = q.get(i);
		}
		return a;
	}