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

今天又又到了我们刷力扣题的时间啦!
今天博主给大家带来的三道题是:
27. 移除元素
26. 删除有序数组中的重复项
88. 合并两个有序数组

这三道题,都是双指针算法题的一个入门题,掌握这三道题,认识双指针算法,是我们今天的目标!

前言

那么这里博主先安利一下一些干货满满的专栏啦!

作者: #西城s
这是我的主页:#西城s
在食用这篇博客之前,博主在这里介绍一下其它高质量的编程学习栏目:
数据结构专栏:数据结构 这里包含了博主很多的数据结构学习上的总结,每一篇都是超级用心编写的,有兴趣的伙伴们都支持一下吧!
算法专栏:算法 这里可以说是博主的刷题历程,里面总结了一些经典的力扣上的题目,和算法实现的总结,对考试和竞赛都是很有帮助的!
力扣刷题专栏:Leetcode 想要冲击ACM、蓝桥杯或者大学生程序设计竞赛的伙伴,这里面都是博主的刷题记录,希望对你们有帮助!
C的深度解剖专栏:C语言的深度解剖 想要深度学习C语言里面所蕴含的各种智慧,各种功能的底层实现的初学者们,相信这个专栏对你们会有帮助的!


OJ27 移除元素

题目描述


算法分析

题目的意思其实很简单,其实就是把一个数在数组里面去掉。
那么很容易想到的思路就是:

  • 开一个空间,将符合条件的拷贝下来,但是按照这种方法我们时间虽然是O(n),但我们的空间就是O(n)了,不是最优解法。
  • 另一种比较好想到的方法就是,写一个删除单个数字的函数,遍历数组,但是这样的时间就不是O(n)了,因为我们删除元素的时候需要挪动数据,这样效率是非常低的。

这时候,我们可以想想双指针的方法。
双指针其实就是对一个数组用两个下标进行处理(或者两个指针)
所以这题我们可以采用覆盖的方法来解决:

定义两个指针prevheadhead跑在前面,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,在覆盖之前,先++以下就行了。同时,因为是删除重复项,所以我们的prevahead在初始化的时候,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】超详细算法教程的更多相关文章

  1. 机器学习经典算法详解及Python实现--基于SMO的SVM分类器

    原文:http://blog.csdn.net/suipingsp/article/details/41645779 支持向量机基本上是最好的有监督学习算法,因其英文名为support vector  ...

  2. 算法进阶面试题01——KMP算法详解、输出含两次原子串的最短串、判断T1是否包含T2子树、Manacher算法详解、使字符串成为最短回文串

    1.KMP算法详解与应用 子序列:可以连续可以不连续. 子数组/串:要连续 暴力方法:逐个位置比对. KMP:让前面的,指导后面. 概念建设: d的最长前缀与最长后缀的匹配长度为3.(前缀不能到最后一 ...

  3. 图文详解两种算法:深度优先遍历(DFS)和广度优先遍历(BFS)

    参考网址:图文详解两种算法:深度优先遍历(DFS)和广度优先遍历(BFS) - 51CTO.COM 深度优先遍历(Depth First Search, 简称 DFS) 与广度优先遍历(Breath ...

  4. BM算法  Boyer-Moore高质量实现代码详解与算法详解

    Boyer-Moore高质量实现代码详解与算法详解 鉴于我见到对算法本身分析非常透彻的文章以及实现的非常精巧的文章,所以就转载了,本文的贡献在于将两者结合起来,方便大家了解代码实现! 算法详解转自:h ...

  5. 【转】AC算法详解

    原文转自:http://blog.csdn.net/joylnwang/article/details/6793192 AC算法是Alfred V.Aho(<编译原理>(龙书)的作者),和 ...

  6. 【最短路径Floyd算法详解推导过程】看完这篇,你还能不懂Floyd算法?还不会?

    简介 Floyd-Warshall算法(Floyd-Warshall algorithm),是一种利用动态规划的思想寻找给定的加权图中多源点之间最短路径的算法,与Dijkstra算法类似.该算法名称以 ...

  7. 第二十九节,目标检测算法之R-CNN算法详解

    Girshick, Ross, et al. “Rich feature hierarchies for accurate object detection and semantic segmenta ...

  8. 数据结构4.3_字符串模式匹配——KMP算法详解

    next数组表示字符串前后缀匹配的最大长度.是KMP算法的精髓所在.可以起到决定模式字符串右移多少长度以达到跳跃式匹配的高效模式. 以下是对next数组的解释: 如何求next数组: 相关链接:按顺序 ...

  9. kmp算法详解

    转自:http://blog.csdn.net/ddupd/article/details/19899263 KMP算法详解 KMP算法简介: KMP算法是一种高效的字符串匹配算法,关于字符串匹配最简 ...

  10. [转] KMP算法详解

    转载自:http://www.matrix67.com/blog/archives/115 KMP算法详解 如果机房马上要关门了,或者你急着要和MM约会,请直接跳到第六个自然段.    我们这里说的K ...

随机推荐

  1. Codeforces Round #619 (Div. 2) A-D

    比赛链接:Here 1301A. Three Strings 题意: 给三个相同长的字符串 \(a,b,c\)​ ,对于每个位置 \(i\)​ ,你必须做一次操作:交换 \(a_i\)​ 和 \(c_ ...

  2. AtCoder Beginner Contest 211 (C ~ E) 个人题解

    比赛链接:Here A.B题跳过 C - chokudai 题意: 给出一个字符串,问有多少个字串能构成 chokudai 这道题算是一个简单DP,只要计算某个位置对构成 chokudai 的贡献值即 ...

  3. vue 状态管理 四、Action用法

    系列导航 vue 状态管理 一.状态管理概念和基本结构 vue 状态管理 二.状态管理的基本使用 vue 状态管理 三.Mutations和Getters用法 vue 状态管理 四.Action用法 ...

  4. 【驱动】以太网扫盲(二)phy寄存器简介

    PHY 寄存器的地址空间为 5 位,从 0 到 31 最多可以定义 32 个寄存器(随着芯片功能不断增加,很多 PHY 芯片采用分页技术来扩展地址空间以定义更多的寄存器),IEEE802.3 定义了地 ...

  5. prettier配置项说明

    Prettier 特点 一键改变代码风格,无需改变开发风格 => 1. 安装Node 环境 自行安装 => 2. 安装 Prettier 全局安装npm install --global ...

  6. 信息收集-CDN绕过

    什么是CDN加速? CDN 的全称是 Content Delivery Network,即内容分发网络.CDN 是构建在现有网络基础之上的智能虚拟网络,依靠部署在各地的边缘服务器, 通过中心平台的负载 ...

  7. Python毕业设计推荐

    今天给大家推荐几个基于python/django的毕业设计/课程设计. 1. 网上商城系统 这是一个基于python+vue开发的商城网站,平台采用B/S结构,后端采用主流的Python语言进行开发, ...

  8. [转帖]shell编程之条件语句

    目录 一.条件测试 test命令 文件测试与整数测试 文件测试 整数值比较 字符串测试与逻辑测试 字符串比较 逻辑测试 二.if语句 if单分支语句 单分支结构 if双分支语句 双分支结构 if多分支 ...

  9. [转帖]RHEL/CentOS 7中的网络暨network.service与NetworkManager.service详解

    在RHEL/CentOS 6及以前的版本中,网络功能是通过一系列网络相关的脚本文件实现,如/etc/init.d/network文件,及如下/sbin/if*文件等. [root@myserver ~ ...

  10. Grafana监控Oracle数据库的表大小等信息

    Grafana监控Oracle数据库的表大小等信息 方案 oracledb_exporter 以及 prometheus grafana 使用的SQL以及配置文件 [[metric]] context ...