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

【LeetCode】用双指针解决移除元素问题、合并两个有序数组求解

🔥个人主页:艾莉丝努力练剑

❄专栏传送门:《C语言》、《数据结构与算法》、C语言刷题12天IO强训

🍉学习方向:C/C++方向

⭐️人生格言:为天地立心,为生民立命,为往圣继绝学,为万世开太平


 


前言:牛客网和LeetCode的刷题都不可或缺,我们都要做一做,无论是参加竞赛还是笔试面试,至少能提升你的代码能力!洛谷的题目也可以去做一做。力扣的题目对提升代码能力很有帮助,需要有一点基础,几乎都是接口型的题目,关于接口型和IO型的区别我们在本专栏的第一篇【LeetCode】力扣题——轮转数组、消失的数字、数组串联中就介绍过了,这里不再赘述。


目录

正文

一、移除元素

1、题目描述

2、思考 

3、求解

二、合并两个有序数组

1、题目描述

2、思考

3、求解

结尾


正文

LeetCode有题解功能,今天给大家带来的两道题博主都写了题解,链接放在题目链接下面了。

一、移除元素

1、题目描述

题目链接:27. 移除元素

博主的力扣题解:用双指针解决移除元素问题且时间复杂度O(n)空间复杂度O(1)

2、思考 

和轮转数组那道题有些类似,本题我们也有三种思路:

思路(1):嵌套

这里写出来循环嵌套,时间复杂度达到了O(n^2),太大了,如果这个数组的绝大部分数据都是val,这个复杂度就太low了,这个思路就直接可以out了。 

思路(2):空间换时间

是不是感觉似曾相识?没错。我们介绍轮转数组的三种思路时说的第二种方法就是空间换时间。

我们的做法是(当然上图中博主已经标注出来了):我们创建一个新的数组,我们遍历过程中,把不是val的数据,放到新数组,再把新数组的值拷贝到原数组。这个思路的时间复杂度和空间复杂度都是O(n),能不能保证不创建新的数组的情况下,还能让时间复杂度O(n)而且空间复杂度O(1)?

思路(3):双指针

我们的解题过程是:先创建两个指针变量src和dst,两个指针从左往右遍历数组,分两种情况:

(1)当src位置不是val的值(即不是val),把src位置给dst,随后src++、dst++;

(2)当src为止是val的值(即val),src++。

3、求解

之前在【数据结构与算法】专栏中的【数据结构与算法】数据结构初阶:详解顺序表和链表(二)这篇文章中我们提了一嘴(当然在铸币主包写LeetCode题解博客的时候,那篇文章还没发,只是写完了,不过主包马上就会发的,大家请等一等!)前置++和后置++,说在同一个函数里面,前置后置因为现代计算机算力的强大基本上区别不大,这里我们就可以看出两者的区别啦。

我们既然想出了时间复杂度O(n)空间复杂度O(1)的解法,那我们就用这种思路写一下代码。

int removeElement(int* nums, int numsSize, int val) 
{int dst = 0;int src = 0;while(src < numsSize){if(nums[src] != val){nums[dst] = nums[src];src++;dst++;}else{src++;}}return dst;
}

我们后置++是和前面赋值的代码分开写的,结合代码的逻辑,两者可以合并一下,写成这样:

//也可以直接在前面后置++,体现了后置++的用法
int removeElement(int* nums, int numsSize, int val) 
{int dst = 0;int src = 0;while(src < numsSize){if(nums[src] != val){nums[dst++] = nums[src++];}else{src++;}}return dst;
}

复杂度:时间复杂度: O(n),空间复杂度: O(1)。 

二、合并两个有序数组

题目链接:88. 合并两个有序数组

博主的力扣题解:双指针求解合并两个有序数组(利用有序的特性)

1、题目描述

2、思考

这个方法具体怎么运用?我们可以利用有序的特性,我们从后往前放,即两个数组nums1、nums2

我们取大的从后往前放,两个一样大,随便放一个,这里从后往前按顺序放2。这里有两种情况:

(1)在这里如果nums1还剩几个数据就不用管了;

(2)还有一种情况,如果是nums2还剩几个数据呢? 

我们先比,注意——我们只要有值的两个数比,0是不参与的,比完了把大的那个从后往前依次放进去,nums1的放完了,nums2剩下的依次从后往前放。  

3、求解

void merge(int* nums1, int nums1Size, int m, int* nums2, int nums2Size, int n) 
{int end1 = m - 1;int end2 = n - 1;int end = m + n - 1;while(end1 >= 0 && end2 >= 0){if(nums1[end1] > nums2[end2]){nums1[end] = nums1[end1];--end;--end1;}else{nums1[end] = nums2[end2];--end;--end2;}}//如果是end1,不需要处理,也就是在nums1里面while(end2 >= 0){nums1[end] = nums2[end2];--end;--end2;}
}

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


结尾

往期回顾:

【LeetCode】力扣题——轮转数组、消失的数字、数组串联

结语:本篇文章到这里就结束了,本文讲述的两道代码题并不适合C语言初学者,需要有一定的C语言基础,最好要学过数据结构与算法的算法复杂度和顺序表的知识,才能写出复杂度较优的代码来。大家一定要自己动手敲一敲,不敲的话不仅容易忘记,也不利于将来复习。

http://www.lqws.cn/news/494965.html

相关文章:

  • 动手学大模型(第二天)
  • STM32对接霍尔传感器
  • 用 Makefile 自动生成详解:从零到精通的硬核指南
  • AIGC工具平台-FishSpeech零样本语音合成
  • 第三章---需求分析
  • 最新发布 | “龙跃”(MindLoongGPT)大模型正式发布!龙跃而起,推动中国方案走向全球智能体前沿
  • 【达梦数据库】忘记SYSDBA密码处理方法-已适配
  • 电路图识图基础知识-塔式起重机控制电路识图与操作要点(三十五)
  • Flink中的反压与背压:原理、检测与应对
  • WebSocket 进阶全攻略:心跳机制、断线重连、socket.io、鉴权与WSS配置
  • 实现 el-table 中键盘方向键导航功能vue2+vue3(类似 Excel)
  • Flux Reconstruction(FR,通量重构)方法
  • GO 语言学习 之 代码风格
  • Java面试复习指南:并发编程、JVM原理与Spring框架
  • RAG-Anything:打破边界的一体化多模态文档处理引擎
  • Recent Advances in Speech Language Models: A Survey
  • 全局配置Axios后的api使用指南
  • 纯血HarmonyOS5 打造小游戏实践:扫雷(附源文件)
  • 从0开始学习R语言--Day30--函数型分析
  • Unity | AmplifyShaderEditor插件基础(第十集:噪声的种类+火焰制作-中)
  • 如何将进度传给前端呢
  • UI设计 | 审美积累 | 极繁风格(Maximalism / Complex UI)
  • 左神算法之给定一个数组arr,返回其中的数值的差值等于k的子数组有多少个
  • leetcode题解77:组合(回溯算法的门面)
  • STM32 串口通信②:蓝牙模块HC-05控制单片机
  • python常用的正则表达式及作用
  • 编程江湖-正则表达式
  • vue3 el-table row-class-name 行字体颜色失效
  • Spring Cloud微服务
  • MM-AttacKG:一种使用大型语言模型构建攻击图的多模态方法