1. 程式人生 > >LeetCode-合併兩個有序陣列

LeetCode-合併兩個有序陣列

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 思路

  1. 將兩個陣列分別用兩個索引進行遍歷,並且對比兩個陣列的值,將小的一方的值放入一個新陣列中.直到一方遍歷完成即可.
  2. 最後將新陣列的元素拷貝到nums1陣列中.

2.2 反思

  1. 用空間換取了時間,收效不理想,而且沒有考慮到特殊情況.譬如m或n其中一個為0等問題.
  2. 想法是對的,但是沒有認真審題.
  3. 從別人的程式碼中學到的解決方案:
    • 首先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

Author: devinkin

Created: 2018-11-10 六 16:00

Validate