[LeetCode][初級演算法][排序] 合併兩個有序陣列
阿新 • • 發佈:2019-01-28
乍一看像是歸併排序,但是從題目來看明顯是可以使用原地演算法的。
使用額外陣列的方法很簡單:
void merge(int* nums1, int m, int* nums2, int n) { int * temp = malloc(sizeof(int)*(m+n)); int i=0,j = 0; while(i<m&&j<n){ temp[i+j] = nums1[i]<nums2[j]?nums1[i++]:nums2[j++]; } while(i<m){ temp[i+j] = nums1[i++]; } while(j<n){ temp[i+j] = nums2[j++]; } for(i=0;i<m+n;i++){ nums1[i] = temp[i]; } }
簡單的兩路歸併。
但是需要注意到題目的條件,nums1的容量是大於等於m+n的,也就是說可以直接把結果放進m+n。
但如何在不影響nums1原本元素的情況下進行排序?nums1的前m個空間存著待排序元素,但後n個空間一定是空的。
那麼如果從尾部開始填入排序的結果就不會有問題了,因為就算把nums2的n個元素全部塞進nums1尾部,
也不會擠到nums1自己的元素。
採用這樣的方法相當於反向歸併,從隊尾開始,取較大的元素。
void merge(int* nums1, int m, int* nums2, int n) { int idx = m + n - 1; int i = m - 1; int j = n - 1; while(i >= 0 && j >= 0) { int a = nums1[i], b = nums2[j]; if(a > b) { i--; nums1[idx--] = a; } else { j--; nums1[idx--] = b; } } while(i >= 0) { nums1[idx--] = nums1[i--]; } while(j >= 0) { nums1[idx--] = nums2[j--]; } }