1. 程式人生 > >合併兩個有序陣列Java實現

合併兩個有序陣列Java實現

兩個已經排序的陣列A和B,A的陣列前M項有值,A的空間足夠大足夠大能容納A+B中的所有元素,將B中所有元素插入A中使合併後的陣列有序;

剛開始接觸題就想到暴力解法,先將B加入到A的後面,然後對組合後的陣列進行排序,假設A和B的長度分別是M,N,那麼用快排平均也需要nlog(n)的時間複雜度;顯然不是一種很好的做法;

第二種想法是再利用一個數組,然後A和B分別比較較小的元素加入到新的陣列中,這樣時間複雜度是O(M+N),但是空間複雜度又增加了O(M);這種也不是好辦法;

第三種想法是在A的左邊開始和b比較然後將B插入A中,這種演算法移動元素的次數較多;移動一次的時間複雜度O(M),這種演算法的時間複雜度是O(M*N);顯然也不是好辦法;

第四種,也是比較推薦的演算法是,先算出A和B的總長度,由於陣列中後面的元素是空的,可以從後往前複製,時間複雜度是O(M+N);空間複雜度是O(1);這種想法是比較好的,基於第四種演算法的思想做了如下的Java實現

package design;

public class ArrayCombine {
	public static void main(String args[]) throws Exception {
		int[] source1 = new int[50];
		source1[0] = 1;
		source1[1] = 2;
		source1[2] = 5;
		source1[3] = 9;
		source1[4] = 13;
		int[] source2 = new int[] { 1, 3, 4, 8, 10 };
		mergeArray(source1, source2, 5);
		mergeArray(source1, source2, 100);
		mergeArray(source1, null, 5);
		mergeArray(null, source2, 5);
		mergeArray(source1, source2, 4);
	}

	/**
	 * @param source
	 * @param append
	 * @return
	 */
	public static int[] mergeArray(int[] source, int[] append, int m) {
		/** 先進行判空,如果都非空,長度為0可認為是正確的 */
		if (source == null || append == null) {
			System.out.println("有一個數組是空的");
			return null;
		}
		/** source的長度和已有M不匹配 */
		if (m > source.length) {
			System.out.println("陣列的長度和已有M不匹配");
			return null;
		}
		
		int n = append.length;
		int length = m + n;
		
		if (source.length < length) {
			System.out.println("陣列1的空間不夠容納陣列1和2中的元素");
			return null;
		}
		
		int i = length - 1;
		// M+N次運算
		for (; i >= 0 && m > 0 && n > 0; i--) {
			if (source[m - 1] > append[n - 1]) {
				source[i] = source[m - 1];
				m--;
			} else {
				source[i] = append[n - 1];
				n--;
			}
		}
		// 比較完剩餘的元素能順利插入
		while (m > 0) {
			source[i--] = source[m--];
		}
		while (n > 0) {
			source[i--] = append[n--];
		}
		for (int count = 0; count < length; count++) {
			System.out.println(source[count]);
		}
		return source;
	}
}