LeetCode-合併兩個有序陣列
阿新 • • 發佈:2018-11-10
LeetCode-合併兩個有序陣列
Table of Contents
1 合併兩個有序陣列
1.1 題目描述
給定兩個有序整數陣列 nums1 和 nums2,將 nums2 合併到 nums1 中,使得 num1 成為一個有序陣列。
1.2 說明:
初始化 nums1 和 nums2 的元素數量分別為 m 和 n。
你可以假設 nums1 有足夠的空間(空間大小大於或等於 m + n)來儲存 nums2 中的元素。
1.3 示例:
輸入: nums1 = [1,2,3,0,0,0], m = 3 nums2 = [2,5,6], n = 3
輸出: [1,2,2,3,5,6]
2 自己的解答
2.1 思路
- 將兩個陣列分別用兩個索引進行遍歷,並且對比兩個陣列的值,將小的一方的值放入一個新陣列中.直到一方遍歷完成即可.
- 最後將新陣列的元素拷貝到nums1陣列中.
2.2 反思
- 用空間換取了時間,收效不理想,而且沒有考慮到特殊情況.譬如m或n其中一個為0等問題.
- 想法是對的,但是沒有認真審題.
- 從別人的程式碼中學到的解決方案:
- 首先nums1會出現0的佔位元素,而且都出現在m處,所以可以用索引Pos反向遍歷nums1.用i遍歷nums1的非佔位元素,用j遍歷nums2的非佔位元素.
- 為了避免nums1非佔位元素與nums2非佔位元素比較時,索引Pos與索引i衝突(進行交換的時候會覆蓋掉nums1中未比較的元素).所以可以將i也反向遍歷,即將nums1的前m個元素反轉,從
i=m-1
開始遍歷nums的元素.
2.3 程式碼
2.3.1 自己的程式碼
public static void solution(int[] nums1, int m, int[] nums2, int n) { if (n == 0) { return; } if (m == 0) { for (int i = 0; i < n; i++) { nums1[i] = nums2[i]; } return; } int[] res = new int[m + n]; // 遍歷陣列nums1 int i = 0; // 遍歷陣列nums2 int j = 0; // 遍歷陣列res int k = 0; while (i < m && j < n) { res[k++] = nums1[i] < nums2[j] ? nums1[i++] : nums2[j++]; if (i >= m) { // nums1到達尾部,將nums2中剩餘的元素轉移到res中 while (j < n) { res[k++] = nums2[j++]; } break; } if (j >= n) { // nums2到達尾部,將nums1中剩餘的元素轉移到res中 while (i < m) { res[k++] = nums1[i++]; } break; } } for (int l = 0; l < m + n; l++) { nums1[l] = res[l]; } }
2.3.2 別人的程式碼
class Solution { public void merge(int[] nums1, int m, int[] nums2, int n) { reverseArr(nums1,m); int i = m-1; int j = 0; int Pos = m+n-1; while(i > -1 || j < n ){ // 哨兵法,此時用|| if(i > -1 && j < n ){ if(nums1[i] < nums2[j]) nums1[Pos--] = nums1[i--]; else nums1[Pos--] = nums2[j++]; } else if(i == -1) nums1[Pos--] = nums2[j++]; else //j==n,剩下全取nums1 nums1[Pos--] = nums1[i--]; } reverseArr(nums1,m+n); } public void reverseArr(int[] arr,int len){ int temp; for(int i = 0; i < len/2; i++){ //可以當結論記住,i < len/2 足矣 temp = arr[i]; arr[i] = arr[len-i-1]; arr[len-i-1] = temp; } } }
Date: 2018-11-10 15:59
Created: 2018-11-10 六 16:00