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

27. 移除元素 26. 删除有序数组中的重复项 88. 合并两个有序数组(双指针遍历)

目录

  • [27. 移除元素-力扣](https://leetcode.cn/problems/remove-element/description/?languageTags=c)
  • [26. 删除有序数组中的重复项](https://leetcode.cn/problems/remove-duplicates-from-sorted-array/)
  • [88. 合并两个有序数组](https://leetcode.cn/problems/merge-sorted-array/)

下面的几道题,都运用一个双指针(下标)遍历法

27. 移除元素-力扣

题目:
示例1:

输入:nums = [3,2,2,3], val = 3
输出:2, nums = [2,2]

示例2:

输入:nums = [0,1,2,2,3,0,4,2], val = 2
输出:5, nums = [0,1,4,0,3]

这道题最容易想到的思想是开辟一个新数组,然后遍历原数组,如果原数组中的某个值不等于val的值,就把这个值放到新数组中

如图:
在这里插入图片描述
最开始src指向的元素等于valsrc向后走,des不变
在这里插入图片描述
src指向的值不等于val,所以将这个值放到des指向的空间中,接着srcdes都向后移
在这里插入图片描述
接下来的步骤以此类推,最终会得到一个合适的数组

但是这个方法显然不满足题中要求的原地修改,但是我们可以借助这个思想,只不过是在原数组上进行操作

srcdes都指向原数组,其余步骤都与上面那个方法类似
在这里插入图片描述

最开始src指向的元素等于valsrc向后走,des不变
在这里插入图片描述
接着src指向的元素的值不等于val,把这个值赋给des指向的空间中,接着src des向后挪
在这里插入图片描述
src指向的元素的值不等于val,把这个值赋给des指向的空间中,接着src des向后挪
在这里插入图片描述

src指向的元素等于valsrc向后走,des不变
在这里插入图片描述
此时,src已经遍历出了数组,遍历结束,可以看到实际上操作后的数组就是[2,2],长度是2,也正好是作为下标的des的值,所以最后返回des的值。

代码如下:

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

26. 删除有序数组中的重复项

在这里插入图片描述
这道题的思想与上一题思维类似,也是运用双指针遍历法

这道题的做法是:
定义2个指针,一个作为des指向第一个元素,一个作为src指向第二个元素
如果dessrc指向的元素相同,就src++
如果dessrc指向的元素不同,因为此前des已经保存了之前的值,所以先des++,再把src的值放到des中,再src++

代码如下:

int removeDuplicates(int* nums, int numsSize){int src = 1;int des = 0;while(src<numsSize){if(nums[src]==nums[des]){src++;}else{nums[++des] = nums[src++];}}return des+1;}

88. 合并两个有序数组

在这里插入图片描述
合并2个有序数组,这里可以使用归并排序的思想,但是这题与归并思想有些区别

这道题是把值最后都归到数组nums1中,如果还是按照归并做法从前往后操作则会覆盖的值
所以这道题我们从后往前归并
在这里插入图片描述
begin1begin2中选出较大的值,放到des中,然后des--,以及对应元素较大的那个begin减1

接着还有个问题:

  • 如果begin2先循环完,因为数组都是有序的,所以这是已经合并结束
  • 如果begin1先循环完,nums2中的部分数据可能还没有合并到nums1中,所以这里可以把nums2中的元素拷贝到nums1中,拷贝的个数其实是des+1

代码如下:

void merge(int* nums1, int nums1Size, int m, int* nums2, int nums2Size, int n){int des = nums1Size-1;int begin1 = m-1;int begin2 = n-1;while(begin1>=0&&begin2>=0){if(nums1[begin1]>nums2[begin2]){nums1[des] = nums1[begin1];begin1--;des--;}else if(nums1[begin1]<=nums2[begin2]){nums1[des] = nums2[begin2];begin2--;des--;}}if(begin2<0){return;}else if(begin1<0){memmove(nums1,nums2,sizeof(int)*(des+1));}}

下面还有一个牛客网的题,也是运用双指针(下标)遍历法
牛客网:BC98 序列中删除指定数字
在这里插入图片描述

代码如下:

#include <stdio.h>
int main()
{//输入各个值int N= 0;scanf("%d",&N);int arr[N];for(int i=0;i<N;i++){scanf("%d",&arr[i]);}int val = 0;scanf("%d",&val);//删除指定数字int des = 0;for(int src=0;src<N;src++){if(arr[src]!=val){arr[des] = arr[src];des++;}}//输出修改后的序列for(int i = 0;i<des;i++){printf("%d ",arr[i]);}
}
http://www.lryc.cn/news/20091.html

相关文章:

  • 什么时候用std::move()?
  • 建立做机器学习项目的范式
  • 搭建k8s高可用集群—20230225
  • Java 修饰符和多态
  • 学了一年Java的我,想转嵌入式了
  • 【Git】Git冲突与解决方法
  • 深度剖析数据在内存的存储
  • 身高排序(绝对值大的排后面,小的排前面)
  • 高频前端面试题之HTML篇(三)
  • 使用DG备份恢复测试库的流程以及可能出现的问题
  • Springboot注释解析
  • C语言之通讯录(动态 存储文件版)
  • Linux 工具
  • Java知识复习(七)常见的设计模式(装饰、代理、观察、策略、建造)
  • Linux系统看门狗应用编程
  • Spring MVC 源码- LocaleResolver 组件
  • Servlet
  • 简单的周总结
  • Elasticsearch7.8.0版本进阶——IK中文分词器
  • 一个阿里P6的说不会接口自动化测试,他不会是自己评的吧...
  • 规则引擎与风控系统04:风控系统实例(下)
  • 我为什么选择Linux mint 21.1 “Vera“ ? Mint安装优化调教指南(分辨率DPI)
  • 雅思经验(十四)
  • 刚来的薪资20k,是我的2倍,我是真的卷不过,真的太变态了
  • 五、DeepWalk、Node2Vec论文精读与代码实战【CS224W】(Datawhale组队学习)
  • 学习 Python 之 Pygame 开发魂斗罗(四)
  • Linux 基础知识:指令与shell
  • 【数通网络交换基础梳理1】二层交换机、以太网帧、MAC地址数据帧转发原理详解
  • 《分布式技术原理与算法解析》学习笔记Day22
  • [MySQL]MySQL数据类型