標籤:strong color 需要 4行 [88 div 原理 臨時 and
題目:合并已排序數組
難度:Easy
題目內容:
Given two sorted integer arrays nums1 and nums2, merge nums2 into nums1 as one sorted array.
翻譯:
給定兩個排序的整數數組nums1和nums2,將nums2合并到nums1中作為一個排序數組。
注意:
nums1和nums2中初始化的元素數量分別為m和n。
nums1有足夠的空間(大小大於或等於m+n)來容納nums2中的額外元素。
我的思路:此處和歸併排序中的小段歸併有點像,不一樣的地方在於在於其中nums1數組的長度是合并之後的長度。
這樣一來用傳統的歸併排序中的合并就不行了,因為在合并過程中可能將nums1數組中的數覆蓋掉(eg.【4,5,0,0】【1,2】)
除非再建立一個臨時數組,將二者合并一起放入此數組中,然後再將此數組的值全部複製到nums1,那這樣nums1的長度就沒什麼意義了。
所以可以考慮歸併排序的第二種方法———插入排序。原理不再贅述。把nums2直接當作接在nums1後面的數即可。
三個指標:i 表示此時nums2的位置(從0開始);j表示此時nums1的位置(從m-1開始);k表示內部迴圈中nums1的位置。
My Code:
1 public void merge(int[] nums1, int m, int[] nums2, int n) { 2 int j = m - 1; 3 for (int i = 0; i < n; i++) { 4 if (j == -1 || nums2[i] >= nums1[j] ) { 5 while (i < n) { 6 nums1[++j] = nums2[i++]; 7 } 8 return; 9 } else {10 int k = j;11 for (; k > -1 && nums1[k] > nums2[i]; k--) {12 nums1[k+1] = nums1[k];13 }14 nums1[k+1] = nums2[i];15 j++;16 }17 }18 }
我的複雜度:O(N*M) 空間複雜度 O(1)
編碼過程中的問題:
1、第4行,當m==0的時候,nums1內也是有一個0的,此時如果不加以判斷,就會把0當作元素直接進入歸併排序中去,然後就會越界,所以加入 j == -1 || 。
eg.【0】m=0【1】n=1。
2、第15行,忘記了此時放入了一個,nums1的指標需要向右移動一個 —— j++
答案代碼:
1 public void merge(int A[], int m, int B[], int n) {2 int i = m-1, j = n-1, k = m+n-1;3 while (i>-1 && j>-1)4 A[k--] = A[i] > B[j] ? A[i--] : B[j--];5 while (j>-1) 6 A[k--] = B[j--];7 }
答案思路:
既然從前往後會覆蓋到,但是後面全是0,那麼從後往前就不會覆蓋到了。
(就算極端情況,A內全部小於B,後面的0剛好夠B放,不會出現覆蓋情況)
1、當 i 且 j 都沒消耗完時,從後往前,誰大誰就入,並且相應指標消耗1;
2、如果 j 還沒消耗完,則將B內剩下的都放入A;(此時如果A沒消耗完也不需要管了,因為本來就已經在A裡面按順序排好了)
LeetCode第[88]題(Java):Merge Sorted Array(合并已排序數組)