力扣面试经典算法150题:合并两个有序数组

算法

本篇开始,正式进入算法刷题篇。

题目来源于力扣面试经典150题。

题目链接:https://leetcode.cn/studyplan/top-interview-150/

合并两个有序数组

题目选自150题中的数组/字符串一类,题目难度:简单。

题目描述

给定两个按非递减顺序排列的整数数组 nums1nums2,以及两个整数 mn,分别代表 nums1nums2 中的实际元素数量。将 nums2 中的所有元素合并到 nums1 中,使得 nums1 成为一个有序数组。

  • 注意:
    • 数组 nums1 的长度等于 m + n,意味着它有足够的空间容纳 nums2 中的所有元素。
    • 不要使用额外的数组空间,你应该在原地修改输入数组并在使用 O(1) 额外空间的条件下完成此操作。
  • 示例:
    • 输入:
      nums1 = [1,2,3,0,0,0], m = 3
      nums2 = [2,5,6], n = 3
    • 输出:
      nums1 = [1,2,2,3,5,6]
  • 解释:
    • 数组 nums1 的前 m 个元素 [1,2,3] 是已排序的。
    • 数组 nums2 的所有元素 [2,5,6] 也是已排序的。
    • 合并后,nums1 应该包含 [1,2,2,3,5,6],并且仍然保持有序状态。

题目分析

题目要求我们在不使用额外空间的情况下,将两个已排序的数组合并成一个新的有序数组。

由于 nums1 已经预留了足够的空间来存放 nums2 中的元素,因此我们可以通过某种方式直接在 nums1 上进行操作。

为了保证合并后的数组仍然有序,我们需要找到一种方法,能够确保较大的元素被放置在数组的后面,较小的元素被放置在前面。对于这种数组的排序算法,如果是递增排序(从小到大),我们采取从数组尾部开始比较元素并放置;反之如果是递减排序(从大到小),我们就采取从数组头部开始进行元素的比较与放置。

解题思路

  1. 递增排序的数组,我们从尾部开始比较与放置元素,所以我们需要定义出三个变量,分别作为nums1nums2nums1(合并后)数组的最大索引值。
  2. 很明显算法必须必须使用循环语句实现,那么循环条件必须是能同时拿到两个初始数组的元素才能进行循环,因为两个数组的元素需要作比较。
  3. 算法的核心内容也就是循环语句中的内容是对两个数组的元素大小比较,将大的值放入到合成后的数组中,就是nums1
  4. 由于两个数组长度不等,可能存在一个数组元素取完,另一个元素未取完的场景,因此我们需要对长度较长的数组单独做一次循环,直接较长的数组的元素也取完。在本题中,由于两数组合并到nums1数组,所以nums1的长度是大于nums2的长度。注意这里指的是长度,而不是实际的元素个数。

实际算法代码

根据以上分析和思路,我们可以写出以下代码:

java 复制代码
    public static void main(String[] args) {
        // 示例数据
        int[] nums1 = {1, 2, 3, 0, 0, 0};
        int m = 3;
        int[] nums2 = {2, 5, 6};
        int n = 3;

        // 调用合并方法
        merge(nums1, m, nums2, n);

        // 输出合并后的数组
        System.out.println(Arrays.toString(nums1));
    }

	 /**
     * 合并两个有序数组
     *
     * @param nums1 第一个有序数组
     * @param m     nums1 中实际元素的数量
     * @param nums2 第二个有序数组
     * @param n     nums2 中实际元素的数量
     */
    private static void merge(int[] nums1, int m, int[] nums2, int n) {
    	// nums1 的最后一个实际元素的索引
        int i = m - 1; 
        // nums2 的最后一个元素的索引
        int j = n - 1; 
        // 合并后数组的最后一个位置的索引
        int k = m + n - 1; 

        // 从后向前比较和放置元素
        while (i >= 0 && j >= 0) {
        	// 取较大的元素放入合并后的数组中,并且注意k的值要减1,因为我们是从尾部开始处理,要往上一个位置放元素
        	// 被取出元素的数组索引要减1,下次取的时候就是上一个位置元素
            if (nums1[i] > nums2[j]) {
                nums1[k] = nums1[i];
                k--;
                i--;
            } else {
                nums1[k] = nums2[j];
                k--;
                j--;
            }
        }

        // 如果 nums2 还有剩余元素,则将其复制到 nums1 的前面
        // 解题思路4
        while (j >= 0) {
            nums1[k] = nums2[j];
            k--;
            j--;
        }
    }

验证

算法编码编写完毕,进行验证。启动main函数,效果如下:

力扣执行:

完美通过!

相关推荐
小刘不想改BUG5 分钟前
LeetCode 70 爬楼梯(Java)
java·算法·leetcode
老歌老听老掉牙14 分钟前
使用 SymPy 进行向量和矩阵的高级操作
python·线性代数·算法·矩阵·sympy
张伯毅21 分钟前
Java 类型参数 T、R 、 O 、K、V 、E 、? 区别
java·开发语言
lifallen23 分钟前
Flink checkpoint
java·大数据·算法·flink
爱尚你199326 分钟前
Java并发编程:读写锁与普通互斥锁的深度对比
java·lock·readwritelock
比特森林探险记37 分钟前
Go 中的 Map 与字符处理指南
c++·算法·golang
比特森林探险记39 分钟前
Go 中 map 的双值检测写法详解
java·前端·golang
IT_Octopus40 分钟前
多线程下使用缓存+锁Lock, 出现“锁失效” + “缓存未命中竞争”的缓存击穿情况,双重检查缓存解决问题
java·spring·缓存
杰哥技术分享1 小时前
IDEA 打开文件乱码
java·ide·intellij-idea
猫头虎1 小时前
[特殊字符]解决 “IDEA 登录失败。不支持早于 14.0 的 GitLab 版本” 问题的几种方法
java·ide·网络协议·http·https·gitlab·intellij-idea