LeetCode 88. 合并两个有序数组

LeetCode 88. 合并两个有序数组 | 新手从零刷题全过程(超详细踩坑记录)

一、题目描述

给你两个非递减有序的整数数组 nums1nums2,以及 mn

  • m:nums1 的有效元素个数
  • n:nums2 的有效元素个数
  • nums1 长度为 m+n,后面 n 个 0 为占位空间

要求:原地合并到 nums1 中,不返回新数组,最终保持升序。

二、解题思路总览

本题我使用了两种解法

  1. 暴力法:先合并 + 整体排序(新手入门最快)
  2. 最优解法:逆向双指针(面试标准最优解)

我全程记录了新手所有真实踩坑,非常适合零基础算法入门。


方法一:暴力解法(先合并后排序)

1. 解题思路

我首先没有考虑到使用集合中原本存在的顺序,选择直接把nums2的数据插入到nums1中了

  1. nums2 所有元素复制到 nums1 尾部空位
  2. 直接对 nums1 整体排序
  3. 原地修改,无需新开数组

2. 我新手踩坑记录

  • 错误:循环条件写成 i < m
  • 正确:必须 i < n
  • 原因:n=0 时如果继续循环,会数组越界

3. AC 代码

import java.util.Arrays;

class Solution {
    public void merge(int[] nums1, int m, int[] nums2, int n) {
        // 将nums2全部复制到nums1尾部
        for(int i = 0; i < n; i++){
            nums1[m + i] = nums2[i];
        }
        // 整体排序
        Arrays.sort(nums1);
    }
}

4. 复杂度分析

时间复杂度:(O((m+n)\log(m+n)))
空间复杂度:(O(1))

5. 优缺点

优点:逻辑最简单、不容易写错、快速过题
缺点:没有利用数组已有序的条件,效率差,面试不推荐

方法二:最优解法|逆向双指针(核心重点)

1. 为什么要从后往前?

正序合并会覆盖 nums1 未读取的有效数据
nums1 尾部有空位,从后往前填不会覆盖数据

2. 指针定义

p1:nums1 有效元素末尾 m-1
p2:nums2 末尾 n-1
p3:nums1 最终填充位置末尾 m+n-1

3. 算法流程

两个数组都有值时,谁大谁放最后
对应指针前移,填充指针一定前移
遍历结束后,如果 nums2 还有剩余小数,全部拷贝到前面

4. 我刷题全程真实踩坑(新手必看)

坑 1:Java/Python 语法混淆
错误:p1>=0 and p2>=0
正确:p1 >= 0 && p2 >= 0
坑 2:赋值符号与判断符号混淆
错误:if(nums1[p1] = nums2[p2])
正确:if(nums1[p1] == nums2[p2])
坑 3:相等时同时移动两个指针(致命 BUG)
错误:相等时 p1–、p2-- 一起移动
后果:跳过数据、数组顺序错乱
坑 4:忘记移动填充指针 p3
后果:数据反复覆盖同一个位置
坑 5:缺少第二段 while
后果:nums1 提前遍历完、nums2 剩余负数 / 小数无法合并

5. 最终完整 AC 代码

class Solution {
    public void merge(int[] nums1, int m, int[] nums2, int n) {
        int p1 = m - 1;
        int p2 = n - 1;
        int p3 = m + n - 1;

        // 双数组同时遍历,从后往前取大数
        while(p1 >= 0 && p2 >= 0){
            if(nums1[p1] > nums2[p2]){
                nums1[p3] = nums1[p1];
                p1--;
            }else{
                nums1[p3] = nums2[p2];
                p2--;
            }
            p3--;
        }

        // 处理nums2剩余元素(关键边界)
        while(p2 >= 0){
            nums1[p3] = nums2[p2];
            p2--;
            p3--;
        }
    }
}

6. 复杂度分析

时间复杂度:(O(m+n)) 线性遍历,最优解
空间复杂度:(O(1)) 原地操作

7. 全部边界覆盖

n = 0:nums2 为空,直接返回
m = 0:直接复制 nums2 全部数据
存在相同元素、存在负数全部通过

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值