1. 程式人生 > 實用技巧 >leetcode 精選top面試題 - 88. 合併兩個有序陣列

leetcode 精選top面試題 - 88. 合併兩個有序陣列

88. 合併兩個有序陣列

給你兩個有序整數陣列nums1 和 nums2,請你將 nums2 合併到nums1中,使 nums1 成為一個有序陣列。

說明:

初始化nums1 和 nums2 的元素數量分別為m 和 n 。
你可以假設nums1有足夠的空間(空間大小大於或等於m + n)來儲存 nums2 中的元素。

示例:

輸入:
nums1 = [1,2,3,0,0,0], m = 3 nums2 = [2,5,6], n = 3 輸出:[1,2,2,3,5,6]

提示:

-10^9 <= nums1[i], nums2[i] <= 10^9
nums1.length == m + n
nums2.length 
== n

思路一:雙指標,從後往前歸併

雙指標從後往前歸併,兩個陣列均從陣列尾部開始遍歷,

遍歷陣列,把兩個陣列尾部元素的較大者放到num1中。

迴圈結束時,如果陣列num1還有元素,不需要管;如果陣列num2還有元素,直接複製到num1陣列中

 1 class Solution {
 2     public void merge(int[] nums1, int m, int[] nums2, int n) {
 3         // 雙指標,兩個陣列均從陣列尾部開始遍歷
 4         // 把兩個陣列尾部元素的較大者放到num1中
 5         int p = m - 1
, q = n - 1; 6 int len = m + n; 7 int index = len - 1; // 指向下個排序元素應該存放的下標 8 while(p >= 0 && q >= 0){ 9 if(nums1[p] >= nums2[q]){ 10 nums1[index--] = nums1[p--]; 11 }else{ 12 nums1[index--] = nums2[q--];
13 } 14 } 15 // 如果陣列num1還有元素,不需要管 16 // 如果陣列num2還有元素,直接複製到num1陣列中 17 while(q >= 0){ 18 nums1[index--] = nums2[q--]; 19 } 20 } 21 }

leetcode執行用時:0 ms, 在所有Java提交中擊敗了100.00%的使用者,記憶體消耗:38.8 MB, 在所有Java提交中擊敗了40.28%的使用者

複雜度分析:

時間複雜度:O(n+m)。對兩個陣列都進行了一次遍歷,所以時間複雜度為O(n+m)。

空間複雜度:O(1)。因為不需要藉助額外的陣列空間,所以空間複雜度為O(1)。

思路二:

將兩個數組合並後排序, 雖然編碼簡單,但是效率較低

1 class Solution {
2     public void merge(int[] nums1, int m, int[] nums2, int n) {
3         // 合併兩個陣列後排序
4         System.arraycopy(nums2, 0, nums1, m, n);
5         Arrays.sort(nums1);
6     }
7 }
leetcode 執行用時:1 ms, 在所有Java提交中擊敗了25.25%的使用者,記憶體消耗:38.6 MB, 在所有Java提交中擊敗了70.84%的使用者

複雜度分析:

時間複雜度:O(log(m+n))。拷貝陣列的時間開銷為O(m), 排序的時間花費是O(log(m+n))。

空間複雜度:O(1)。沒有藉助額外的陣列。