当前位置: 首页 > news >正文

算法打卡力扣第88题:合并两个有序数组(easy)

题目

题目链接
在这里插入图片描述
在这里插入图片描述

我的解答思路

首先想到的是归并排序,恰好两路归并排序算法是稳定的算法,决定套模板(3w)用空间换时间
我新开了一个数组nums3,然后之后再把nums3复制给nums1。然后因为m+n限制在200以内所以我的nums3开的210的大小

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

也是顺利通过了!
在这里插入图片描述

复杂度分析

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

另优解:从后向前的双指针法(来自gimini老师的教学)

直接在 nums1 数组上操作,但通过从末尾开始填充,完美地避免了覆盖 nums1 中尚未被比较的原始数据。
指针定义
我们需要三个指针:

p1:指向 nums1 中最后一个有效元素。初始位置为 m - 1。
p2:指向 nums2 中最后一个元素。初始位置为 n - 1。
p_merge:指向 nums1 数组的最末尾,这是我们将要填充的位置。初始位置为 m + n - 1。

Step1:初始化指针

int p1 = m-1;
int p2 = n-1;
int p_merge = m+n-1;

Step2 从后向前比较和填充

进入一个 while 循环,循环条件是 p2 >= 0。为什么是 p2?因为只要 nums2 还没合并完,我们就需要继续操作。如果 nums2 合并完了,而 nums1 还有剩余(p1 >= 0),那么这些 nums1 的元素本身就在正确的位置上,不需要移动。
在循环内部,进行比较:

情况一:p1 还在界内,并且 nums1[p1] 大于 nums2[p2]
说明当前两个数组的末尾元素中,nums1 的更大。
将这个较大的值 nums1[p1] 放入 nums1 的 p_merge 位置。

nums1[p_merge] = nums1[p1];

移动 p1 和 p_merge 指针,去比较下一个位置。

p1--;
p_merge--;

情况二:其他情况
这包含了两种子情况:

p1 还在界内,但 nums1[p1] <= nums2[p2]。

p1 已经越界了(p1 < 0),说明 nums1 的所有有效元素都已经合并完毕,现在只需要把 nums2 中剩余的元素逐个放入 nums1 的前端即可。

在这两种子情况下,我们都应该将 nums2[p2] 的值放入 nums1[p_merge] 的位置。

nums1[p_merge] = nums2[p2];

移动 p2 和 p_merge 指针。

p2--;
p_merge--;

Step3 循环结束

当 p2 变为 -1 时,循环终止。此时,所有 nums2 中的元素都已经被正确地合并到了 nums1 中,整个 nums1 数组 (0 到 m+n-1) 就变得有序了。

完整代码实现

class Solution {
public:/*** @brief 使用从后向前的双指针法合并两个有序数组* @param nums1 目标数组,长度为 m+n,后 n 个元素为0* @param m nums1 中的有效元素个数* @param nums2 要合并的数组,长度为 n* @param n nums2 中的元素个数*/void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {// 初始化指针:p1 指向 nums1 的有效元素末尾int p1 = m - 1;// p2 指向 nums2 的末尾int p2 = n - 1;// p_merge 指向 nums1 的最末尾,用于放置最终结果int p_merge = m + n - 1;// 只要 nums2 还没有被完全合并,就继续循环while (p2 >= 0) {// 如果 p1 还在界内,并且 p1 指向的元素大于 p2 指向的元素if (p1 >= 0 && nums1[p1] > nums2[p2]) {// 将 nums1[p1] 这个较大的值放到 nums1 的末尾nums1[p_merge] = nums1[p1];// 移动 p1 指针,向前一位p1--;} else {// 发生以下两种情况之一:// 1. p1 越界了 (m=0 的情况)// 2. nums2[p2] 的值大于或等于 nums1[p1] 的值// 无论哪种情况,都应将 nums2[p2] 的值放到 nums1 的当前合并位置nums1[p_merge] = nums2[p2];// 移动 p2 指针,向前一位p2--;}// 每次放置一个元素后,合并指针 p_merge 都需要向前移动p_merge--;}// 当 p2 < 0 时,循环结束。// 无需处理 p1 > 0 的情况,因为那些元素已经在正确的位置上了。}
};

也是顺利通过了,感谢gimini老师
在这里插入图片描述
时间复杂度:O(m+n)
空间复杂度:O(1)
ok see you next time~

http://www.lryc.cn/news/618449.html

相关文章:

  • 第五章 树与二叉树
  • 虚拟机高级玩法-网页也能运行虚拟机——WebAssembly
  • Day24|学习前端CSS
  • AI入门学习--AI模型评测
  • Java集合学习之forEach()遍历方法的底层原理
  • 深度解读 WizTelemetry 2.0:链路追踪如何让分布式系统“无所遁形”
  • 【2025最新版】Java基础知识学习路线图:从入门到精通的系统化指南
  • 深度贴:前端网络基础及进阶(2)
  • 【网络运维】Linux和自动化: Ansible基础实践
  • 【接口自动化】-11-接口加密签名 全局设置封装
  • 回归预测 | Matlab实现CNN-BiLSTM-self-Attention多变量回归预测
  • 如何使用gpt进行模型微调?
  • iceberg FlinkSQL 特性
  • 古风修仙主题登录页面设计与实现 附源码 ~~~
  • Iptables 详细使用指南
  • 【CSS3】录音中。。。
  • 飞算JavaAI 2.0.0深度测评:自然语言编程如何重塑Java开发范式
  • 基于 gRPC 的接口设计、性能优化与生产实践
  • 《软件工程导论》实验报告一 软件工程文档
  • 新手向:Python编写简易翻译工具
  • Jmeter性能测试过程中遇到connection reset的解决方案
  • 易语言模拟真人鼠标轨迹算法 - 非贝塞尔曲线
  • HTTP应用层协议-长连接
  • 意图驱动——机器人大脑的正确驱动方式
  • 大模型驱动的服务革命:2025智能客服机器人选型与落地路径
  • 5-终端安全检测和防御技术
  • 【北京见闻】2025年世界机器人大会——所见所闻及所思
  • Node.js 精选:50 款文件处理与开发环境工具库
  • 最终章【1】Epson机器人篇
  • Ansible 自动化介绍