LeetCode 刷题记录 88. Merge Sorted Array

题目:
Given two sorted integer arrays nums1 and nums2, merge nums2 into nums1 as one sorted array.

Note:

The number of elements initialized in nums1 and nums2 are m and n respectively.
You may assume that nums1 has enough space (size that is greater or equal to m + n) to hold additional elements from nums2.
Example:

Input:
nums1 = [1,2,3,0,0,0], m = 3
nums2 = [2,5,6], n = 3

Output: [1,2,2,3,5,6]
解法1:
暴力法
设置两个指针i和j分别指向nums1和nums2
直接用nums2的每一位数字与num1相比较,

  1. 如果nums2的数字较小,则需插入到nums1数组中,但是在这之前需要将num1的所有数字都往后移,右移代码nums1[k] = nums1[k-1],考虑到前面的会覆盖后面的,所以我们从后往前遍历,m+j是我们已经排好的数量,所以最后一个要移动的下标为m+j-1,最前面的一个数字的下标为i,即k-1的范围为[i,m+j-1],所以k的范围为[i+1,m+j]
  2. 否则,i++即可
    如果i == (m + j) 说明nums1的数字已经遍历完了,直接将剩下的nums2的数字插入到nums1中去即可
class Solution {
public:
    void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
        int i = 0;
        int j = 0;
        while(j < n){
            if(i == (m + j)){
                while(j < n){
                    nums1[m + j] = nums2[j];
                    j++;
                }
                return;
            }
            if(nums2[j] < nums1[i]){
                for(int k = m+j; k > i; k--){
                    nums1[k] = nums1[k-1];
                }
                nums1[i] = nums2[j];
                i++;
                j++;
            } else {
                i++;
            }
        }
    }
};

解法2:
归并排序:
正常的归并排序需要三个数组,nums1数组,nums2数组和合并的数组
该题将nums1数组和合并数组合成一个数组,所以为了用上归并排序的思想,我们首先需要将num1中的元素先往后移n个单位,还是从最后一位m-1往前移到0,每个元素往后移n个位置
然后按正常的归并排序来做,只不过nums1从n开始,普通的归并排序最后还要检查下num1和num2剩下元素,但是在本题中只需检查num2即可,因为num1已经在合并后的数组中了
然后正常
c++:

class Solution {
public:
    void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
        for(int count = 1; count <= m; count++){
            nums1[m+n-count] = nums1[m-count];
        }
        int i = n;
        int j = 0;
        int k = 0;
        while(i < (m+n) && j < n){
            if(nums1[i] < nums2[j]){
                nums1[k++] = nums1[i++];
            } else {
                nums1[k++] = nums2[j++];
            }
        }
        while(j < n){
            nums1[k++] = nums2[j++];
        }
    }
};

java中可以用System.arraycopy(nums1, 0, nums1, n, m);来实现数组的向后移n个单位
其中函数的四个参数为原数组、原数组要复制的起始位置,要复制的数组,要复制的开始位置,复制的长度
在本题中我们要将nums1中从0开始的m个元素复制到nums1中,从下标n开始

class Solution {
    public void merge(int[] nums1, int m, int[] nums2, int n) {
        // for(int count = 1; count <= m; count++){
        //     nums1[m+n-count] = nums1[m-count];
        // }
        
        System.arraycopy(nums1, 0, nums1, n, m);
        int i = n;
        int j = 0;
        int k = 0;
        while(i < (m+n) && j < n){
            if(nums1[i] < nums2[j]){
                nums1[k++] = nums1[i++];
            } else {
                nums1[k++] = nums2[j++];
            }
        }
        while(j < n){
            nums1[k++] = nums2[j++];
        }
    }
}

python最后可以整体复制

class Solution(object):
    def merge(self, nums1, m, nums2, n):
        """
        :type nums1: List[int]
        :type m: int
        :type nums2: List[int]
        :type n: int
        :rtype: None Do not return anything, modify nums1 in-place instead.
        """
        for count in xrange(1,m+1):
            nums1[m+n-count] = nums1[m-count];
        
        i,j,k = n,0,0
        
        while i < (m+n) and j < n:
            if nums1[i] < nums2[j]:
                nums1[k] = nums1[i]
                i+=1
            else:
                nums1[k] = nums2[j]
                j+=1
            k+=1
        
        if j < n:
            nums1[k:] = nums2[j:]
        

解法3:
换一种思维我们不必要从最小的数开始归并,而是从最大的数开始归并,这样就不用将nums1中的数向后移了
c++:

class Solution {
public:
    void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
        
        int i = m-1;
        int j = n-1;
        int k = m+n-1;
        while(i >= 0 && j >= 0){
            if(nums1[i] > nums2[j]){
                nums1[k--] = nums1[i--];
            } else {
                nums1[k--] = nums2[j--];
            }
        }
        while(j >=0){
            nums1[k--] = nums2[j--];
        }
    }
};

java:

class Solution {
    public void merge(int[] nums1, int m, int[] nums2, int n) {
       
        
        int i = m-1;
        int j = n-1;
        int k = m+n-1;
        while(i >= 0 && j >= 0){
            if(nums1[i] > nums2[j]){
                nums1[k--] = nums1[i--];
            } else {
                nums1[k--] = nums2[j--];
            }
        }
        while(j >=0){
            nums1[k--] = nums2[j--];
        }
    }
}

注意python列表前闭后开,所以最后nums1[:k+1] = nums2[:j+1]

class Solution(object):
    def merge(self, nums1, m, nums2, n):
        """
        :type nums1: List[int]
        :type m: int
        :type nums2: List[int]
        :type n: int
        :rtype: None Do not return anything, modify nums1 in-place instead.
        """
        
        
        i,j,k = m-1,n-1,m+n-1
        
        while i >=0 and j >= 0:
            if nums1[i] > nums2[j]:
                nums1[k] = nums1[i]
                i-=1
            else:
                nums1[k] = nums2[j]
                j-=1
            k-=1
        
        if j >= 0:
            nums1[:k+1] = nums2[:j+1]
        
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值