合并两个有序数组

1、题目说明

给 2 个按 非递减顺序 排的整数数组 nums1、nums2,及 2 个整数 m 、n ,分别表示 nums1 和 nums2 中的元素数目。

(1)基本要求

合并 nums2 到 nums1 ,使合并后的数组nums1同样按 非递减 排序。nums1初始长为 m + n,其中前 m 个元素表示应合并的元素,若后 n 个元素为 0 ,则忽略。nums2 的长度为 n

(2)进阶要求

设计实现一个时间复杂度为 O(m + n) 的算法解决此问题

力扣官网上标注为88题,属简单类

算法示例算法示例

2、题目分析

  1. 初始元素局部有序 ( 排除快速排序 )
  2. 原地排序 —— 考虑最优,使其空间复杂度为O(1), 选择、直插、冒泡、希尔、堆排 均可,其他的不行
  3. 由示例知,要求算法稳定 —— 直插、冒泡、2路归并、基数排序 均可,其他的不行
  4. 时间复杂度为nums1数组长,即 m+n (插入排序在最好情况下可做到)
  5. 2个数组均为非递减排列,若用原地排,可考虑从后向前,由大到小搞到nums1里头

3.解题思路

从后向前遍历,每次取两者中的较大者放进 nums1最后面。有点像直接插入法

4.代码(逻辑类似,重在复习不同语法)

C版

void merge(int* nums1, int nums1Size, int m, int* nums2, int nums2Size, int n) {
    m--;
    n--; // 变成数组尾元素下标
    // tail是nums1的尾元素下标,从后向前
    int tail = nums1Size - 1;
    while (m>=0 && n>=0) {
        // 比较尾巴
        if (nums2[n] >= nums1[m]) {
            nums1[tail--] = nums2[n--];  //用完再减
        } else { // nums2<nums1 => 大的放至nums1尾部该放的位置
            nums1[tail--] = nums1[m--];
        }
    }
    while(n>=0){ //nums1的m个插完了,nums2的还没插完
        nums1[tail--] = nums2[n--];
    }
}  //时间O(m+n); 空间 O(1)

Java版

public void merge(int[] nums1, int m, int[] nums2, int n) {
        m--;
        n--;
        int len = nums1.length-1;
        while(m>=0 && n>=0){
            if(nums2[n] >= nums1[m])
                nums1[len--] = nums2[n--];
            else
                nums1[len--] = nums1[m--];
        }
        while(n>=0)
            nums1[len--] = nums2[n--];
    }

Python版

def merge(nums1: list[int], m: int, nums2: list[int], n: int) -> None:
    p1, p2, p = m - 1, n - 1, m + n - 1
    while p2 >= 0:  # nums2没插完
        if p1 >= 0 and nums1[p1] > nums2[p2]:
            nums1[p] = nums1[p1]  # 填入 nums1[p1]
            p1 -= 1
        else:
            nums1[p] = nums2[p2]  # 填入 nums2[p2]
            p2 -= 1
        p -= 1

Go版

func merge(nums1 []int, m int, nums2 []int, n int) {
	p1, p2, p := m-1, n-1, m+n-1
	for p2 >= 0 { // nums2没插完
		// nums1前m个未插完,且比nums2的大
		if p1 >= 0 && nums1[p1] > nums2[p2] {
			nums1[p] = nums1[p1]
			p1--
		} else {
			nums1[p] = nums2[p2]
			p2--
		}
		p--
	}
	fmt.Println(nums1)
}
  • 5
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

俺要工作俺想工作

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值