【双指针】双指针算法详解两道经典OJ【力扣27,力扣26,力扣38】超详细算法教程
【双指针】双指针算法详解两道经典OJ【力扣27,力扣26,力扣38】超详细算法教程

今天又又到了我们刷力扣题的时间啦!
今天博主给大家带来的三道题是:
27. 移除元素
26. 删除有序数组中的重复项
88. 合并两个有序数组
这三道题,都是双指针算法题的一个入门题,掌握这三道题,认识双指针算法,是我们今天的目标!
前言
那么这里博主先安利一下一些干货满满的专栏啦!
作者: #西城s
这是我的主页:#西城s
在食用这篇博客之前,博主在这里介绍一下其它高质量的编程学习栏目:
数据结构专栏:数据结构 这里包含了博主很多的数据结构学习上的总结,每一篇都是超级用心编写的,有兴趣的伙伴们都支持一下吧!
算法专栏:算法 这里可以说是博主的刷题历程,里面总结了一些经典的力扣上的题目,和算法实现的总结,对考试和竞赛都是很有帮助的!
力扣刷题专栏:Leetcode 想要冲击ACM、蓝桥杯或者大学生程序设计竞赛的伙伴,这里面都是博主的刷题记录,希望对你们有帮助!
C的深度解剖专栏:C语言的深度解剖 想要深度学习C语言里面所蕴含的各种智慧,各种功能的底层实现的初学者们,相信这个专栏对你们会有帮助的!
OJ27 移除元素
题目描述

算法分析
题目的意思其实很简单,其实就是把一个数在数组里面去掉。
那么很容易想到的思路就是:
- 开一个空间,将符合条件的拷贝下来,但是按照这种方法我们时间虽然是
O(n),但我们的空间就是O(n)了,不是最优解法。 - 另一种比较好想到的方法就是,写一个删除单个数字的函数,遍历数组,但是这样的时间就不是
O(n)了,因为我们删除元素的时候需要挪动数据,这样效率是非常低的。
这时候,我们可以想想双指针的方法。
双指针其实就是对一个数组用两个下标进行处理(或者两个指针)
所以这题我们可以采用覆盖的方法来解决:
定义两个指针
prev和head,head跑在前面,prev跑在后面。
实现代码
int removeElement(int* arr, int numsSize, int val) {
//1 2 2 2 3 4 5 6 2
int* ahead = arr;
int* end = arr + numsSize - 1;
int* prev = arr;
while (ahead <= end) {
if (*ahead == val) {
ahead++;
numsSize--;
}
else {
*prev = *ahead;
prev++;
ahead++;
}
}
return numsSize;
}
OJ26 删除有序数组中的重复项
题目描述

算法分析
不用多说,我们的目标肯定一定要在时间O(n),空间O(1)内完成的。
同样,和上一道题类似的思路,使用双指针,覆盖元素的方式来解决。
- 这道题唯一的两个区别,就是我们要留一个,不要完全删掉,那其实,我们只需要将上一题的
prev,在覆盖之前,先++以下就行了。同时,因为是删除重复项,所以我们的prev和ahead在初始化的时候,ahead要先往前一个位置。
这个算法其实就是一个经典的去重算法。
实现代码
int removeDuplicates(int* nums, int numsSize) {
//去重算法
//双指针
//1 2 2 3 4 5 6 2 2 2 2
int* ahead = nums + 1;
int* prev = nums;
int* end = nums + numsSize - 1;
while (ahead < end) {
if (*ahead == *prev) {
ahead++;
}
else {
prev++;
*prev = *ahead;
ahead++;
}
}
return prev-nums;
}
OJ88 合并两个有序数组
题目描述

算法分析
其实这个合并,我们最容易想到的,其实就是把两个数组搞在一起,再排序一下就行了。
但是,我们要意识到,排序的代价是比较大的。因此,我们要采用双指针,归并算法。
其实这个算法就是归并排序所用的思想。
这里博主提供两种思路:
第一种思路: 如图:
这种思路和归并排序的思路有点类似,最后我们再将新开数组的内容拷贝回原来的位置就行了。
第二种思路:
我们同样可以采用覆盖方法,思路和前面两题十分类似,这里就不赘述了。
注意:
这里的遍历要从后往前,这个画个图就能很好理解了,因为从前往后跑,会覆盖原来有用的元素,所以我们要从后往前覆盖,找大的放到nums1里面去。
第二种思路的实现我们可以达到空间复杂度可以到O(1),时间复杂度O(n),博主这里提供第二种思路的实现代码
实现代码
void merge(int* nums1, int nums1Size, int m, int* nums2, int nums2Size, int n) {
int* end1 = nums1 + m - 1;
int* end2 = nums2 + n - 1;
int* end = nums1 + m + n - 1;
while ((end1 >= nums1) && (end2 >= nums2)) {
if (*end1 > *end2) {
*end-- = *end1--;
}
else if (*end1 < *end2) {
*end-- = *end2--;
}
}
while (end2 - nums2 >= 0) {
*end-- = *end2--;
}
}
尾声
看到这里相信你对双指针算法的这两道OJ已经有一定的理解了,如果你觉得有帮助的话请不要吝啬你们的点赞收藏关注和转发噢!
【双指针】双指针算法详解两道经典OJ【力扣27,力扣26,力扣38】超详细算法教程的更多相关文章
- 机器学习经典算法详解及Python实现--基于SMO的SVM分类器
原文:http://blog.csdn.net/suipingsp/article/details/41645779 支持向量机基本上是最好的有监督学习算法,因其英文名为support vector ...
- 算法进阶面试题01——KMP算法详解、输出含两次原子串的最短串、判断T1是否包含T2子树、Manacher算法详解、使字符串成为最短回文串
1.KMP算法详解与应用 子序列:可以连续可以不连续. 子数组/串:要连续 暴力方法:逐个位置比对. KMP:让前面的,指导后面. 概念建设: d的最长前缀与最长后缀的匹配长度为3.(前缀不能到最后一 ...
- 图文详解两种算法:深度优先遍历(DFS)和广度优先遍历(BFS)
参考网址:图文详解两种算法:深度优先遍历(DFS)和广度优先遍历(BFS) - 51CTO.COM 深度优先遍历(Depth First Search, 简称 DFS) 与广度优先遍历(Breath ...
- BM算法 Boyer-Moore高质量实现代码详解与算法详解
Boyer-Moore高质量实现代码详解与算法详解 鉴于我见到对算法本身分析非常透彻的文章以及实现的非常精巧的文章,所以就转载了,本文的贡献在于将两者结合起来,方便大家了解代码实现! 算法详解转自:h ...
- 【转】AC算法详解
原文转自:http://blog.csdn.net/joylnwang/article/details/6793192 AC算法是Alfred V.Aho(<编译原理>(龙书)的作者),和 ...
- 【最短路径Floyd算法详解推导过程】看完这篇,你还能不懂Floyd算法?还不会?
简介 Floyd-Warshall算法(Floyd-Warshall algorithm),是一种利用动态规划的思想寻找给定的加权图中多源点之间最短路径的算法,与Dijkstra算法类似.该算法名称以 ...
- 第二十九节,目标检测算法之R-CNN算法详解
Girshick, Ross, et al. “Rich feature hierarchies for accurate object detection and semantic segmenta ...
- 数据结构4.3_字符串模式匹配——KMP算法详解
next数组表示字符串前后缀匹配的最大长度.是KMP算法的精髓所在.可以起到决定模式字符串右移多少长度以达到跳跃式匹配的高效模式. 以下是对next数组的解释: 如何求next数组: 相关链接:按顺序 ...
- kmp算法详解
转自:http://blog.csdn.net/ddupd/article/details/19899263 KMP算法详解 KMP算法简介: KMP算法是一种高效的字符串匹配算法,关于字符串匹配最简 ...
- [转] KMP算法详解
转载自:http://www.matrix67.com/blog/archives/115 KMP算法详解 如果机房马上要关门了,或者你急着要和MM约会,请直接跳到第六个自然段. 我们这里说的K ...
随机推荐
- Mynavi Programming Contest 2021(AtCoder Beginner Contest 201)A ~ E题题解
A - Tiny Arithmetic Sequence 水题,判断3个数是否能构成等差数列 void solve() { int a, b, c; cin >> a >> b ...
- mysql 使用 trim去不掉空格 解决
使用mysql8.0时 发现 有几个空字符串怎么也过滤不掉,使用 is not null.trim()<>''.length()>=1都不行,最后查了一些资料说 trim只能去除半角 ...
- win32com操作word API精讲 第八集 Range和Selection的区别
本课程<win32com操作word API精讲&项目实战>以视频为主,文字为辅,公众号ID:一灯编程 众所周知,在word编程中Range和Selection都能实现范围的选中, ...
- C# ,使用“^”运算符对数字加密
原理:"异或"运算符"^", 用于比较两个二进制数的响应位.计算过程如果两个二进制数的相应位都为1或两个二进制数的相应位都为0,则返回0:如果两个二进制数的相应 ...
- GCC 指定运行期动态链接库搜索路径
链接器 ld 的 -rpath=dir 选项可以指定运行期 so 文件的搜索路径. GCC 的 -Wl,option 选项可以传递选项给链接器 ld. 所以组合起来,可以直接使用 -Wl,-rpath ...
- Java求一个集合的所有子集
转载请注明出处: 求一个集合的所有子集表示从一个集合当中,任取任意项或不取,所能得到的所有结果,比如有一个集合{a,b,c,d},那么{a,b}, {b, d}等都是它的子集,空集也是它的子集, 一个 ...
- kafka 性能优化与常见问题优化处理方案
本文为博主原创,未经允许不得转载: 1. JVM参数优化设置 kafka是scala语言开发,运行在JVM上,需要对JVM参数合理设置,修改bin/kafka-start-server.sh中的jv ...
- 如果诸葛亮用C#写出师表...
看到一篇18年的文章 "C++版<出师表>",站长觉得挺有意思的,就用C# 控制台也实现了一遍,技术上没啥难度,但复制代码费了1.2个小时,纯粹无聊写着玩,看者别在意枚 ...
- Linux-服务管理-service-checkconfig
- [转帖]SQL Server索引的维护 - 索引碎片、填充因子
https://www.cnblogs.com/kissdodog/archive/2013/06/14/3135412.html 这两个问题都和页密度有关,虽然两者的表现形式在本质上有所区别,但是故 ...


