合併兩個有序陣列Java實現
阿新 • • 發佈:2019-01-07
兩個已經排序的陣列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; } }