三、双指针(two-point)
文章目录
- 一、算法核心思想
- 二、算法模型
- (一)对撞指针
- 1.[704.二分查找](https://leetcode.cn/problems/binary-search/)
- (1)思路
- (2)代码
- (3)复杂度分析
- 2.[15.三数之和](https://leetcode.cn/problems/3sum/description/)
- (1)思路
- (2)代码
- (3)复杂度分析
- 3.[167.两数之和-输入有序数组](https://leetcode.cn/problems/two-sum-ii-input-array-is-sorted/description/)
- (1)思路
- (2)代码
- (3)复杂度分析
- (二)快慢指针
- 1.[392.判断子序列](https://leetcode.cn/problems/is-subsequence/)
- (1)思路
- (2)代码
- (3)复杂度分析
- 2.[876.链表的中心节点](https://leetcode.cn/problems/middle-of-the-linked-list/description/)
- (1)思路
- (2)代码
- (3)复杂度分析
- 3.[83.删除链表的重复元素](https://leetcode.cn/problems/remove-duplicates-from-sorted-list/description/)
- (1)思路
- (2)代码
- (3)复杂度分析
- 4.[283.移动0](https://leetcode.cn/problems/move-zeroes/description/)
- (1)思路
- (2)代码
- (3)复杂度分析
- 5.[5.最长回文子串](https://leetcode.cn/problems/longest-palindromic-substring/description/)
- (1)思路
- (2)代码
- (3)复杂度分析
- (三)滑动窗口
一、算法核心思想
双指针是指在遍历对象时,使用两个或多个指针进行遍历及相应的操作。大多用于数组操作,这利用了数组连序性的特点。双指针常用来降低算法的时间复杂度,因为使用两个指针可以避免多层循环。
双指针的三个关键点:
- 指针的起始位置的选取
- 指针的移动方向
- 指针的移动速度
这三个关键点是双指针算法的核心也是难点!
二、算法模型
(一)对撞指针
对撞指针:左右两个指针,向中间靠拢。
1.704.二分查找
(1)思路
数组有序的前提下用双指针进行二分查找,双指针的作用在于"二分"。首先左右两个指针l r,分别指向数组的首元素和尾元素,判断左右指针中间数组下标mid所对应的数组值与目标值的大小关系,共有如下三种情况:
nums[mid] == target 找到目标值,记录数组下标,结束
nums[mid] > target 中间的值大于目标值,应当在区间 [ l, mid-1 ] 中继续查找
nums[mid] < target 中间值小于目标值,应当在区间 [ mid+1 , r ] 中继续查找
(2)代码
class Solution {
public:int search(vector<int>& nums, int target) {if (target < nums[0] || target > nums[nums.size() - 1]) {return -1;}int left = 0, right = nums.size() - 1;while (left <= right) {int med = left + ((right - left) >> 1);if (nums[med] > target) {right = med - 1;}else if (nums[med] < target) {left = med + 1;}else {return med;}}
return -1;}
};
(3)复杂度分析
时间复杂度:O(logn)
空间复杂度:O(1)
2.15.三数之和
(1)思路
先将 nums 排序,时间复杂度为 O(NlogN)。
固定 3 个指针中最左(最小)元素的指针 k,双指针 i,j 分设在数组索引 (k,len(nums))两端。
双指针 i , j 交替向中间移动,记录对于每个固定指针 k 的所有满足 nums[k] + nums[i] + nums[j] == 0 的 i,j 组合:
- 当 nums[k] > 0 时直接break跳出:因为 nums[j] >= nums[i] >= nums[k] > 0,即 3 个元素都大于 0 ,在此固定指针 k 之后不可能再找到结果了。
- 当 k > 0且nums[k] == nums[k - 1]时即跳过此元素nums[k]:因为已经将 nums[k - 1] 的所有组合加入到结果中,本次双指针搜索只会得到重复组合。
- i,j 分设在数组索引 (k,len(nums))两端,当i < j时循环计算s = nums[k] + nums[i] + nums[j],并按照以下规则执行双指针移动:
当s < 0时,i += 1并跳过所有重复的nums[i];
当s > 0时,j -= 1并跳过所有重复的nums[j];
当s == 0时,记录组合[k, i, j]至res,执行i += 1和j -= 1并跳过所有重复的nums[i]和nums[j],防止记录到重复组合;
(2)代码
class Solution {
public:vector<vector<int>> threeSum(vector<int>& nums) {// 犹豫不决先排序,步步逼近双指针sort(nums.begin(),nums.end());vector<vector<int>> res;for (int k = 0; k < nums.size() - 2; k ++) {if (nums[k] > 0) break;if (k > 0 && nums[k] == nums[ k - 1]) continue;int i = k + 1,j = nums.size() - 1;while (i < j) {int sum = nums[k] + nums[i] + nums[j];if(sum < 0){while(i < j && nums[i] == nums[++i]);} else if (sum > 0) {while(i < j && nums[j] == nums[--j]);}else {res.push_back(vector<int>{nums[k], nums[i], nums[j]});while(i < j && nums[i] == nums[++i]);while(i < j && nums[j] == nums[--j]);} }}return res;}
};
(3)复杂度分析
时间复杂度:O(N2)
空间复杂度:O(1)
3.167.两数之和-输入有序数组
(1)思路
- 初始化: 双指针 i , j分别指向数组 numbers的左右两端 (俗称对撞双指针)。
- 循环搜索: 当双指针相遇时跳出。
- 计算和 s=numbers[i]+numbers[j]
若 s>targets,则指针j向左移动,即执行 j=j−1 。
若 s<targets ,则指针i向右移动,即执行 i=i+1 。
若 s=targets ,由于题目要求索引从1开始,因此返回数组 [i+1,j+1]。
(2)代码
class Solution {
public:vector<int> twoSum(vector<int>& numbers, int target) {if (numbers.size() == 0) {return {0,0};}int slow = 0,fast = numbers.size() - 1;while (slow < fast) {int sum = numbers[slow] + numbers[fast];if (sum < target) slow ++;else if (sum > target) fast--;else return {slow + 1,fast + 1};}return {};}
};
(3)复杂度分析
时间复杂度:O(N) N 为数组 numbers 的长度;双指针共同线性遍历整个数组。
空间复杂度:O(1)
(二)快慢指针
快慢指针:左右两个指针,一块一慢
1.392.判断子序列
(1)思路
(2)代码
class Solution {
public:bool isSubsequence(string s, string t) {int n = s.length();int m = t.length();if (s.size() == 0) return true;if (n > m) return false;int i = 0,j = 0;while (i < n && j < m) {if (s[i] == t[j]) i ++;j ++;}return i == n;}
};
(3)复杂度分析
时间复杂度:O(n+m)
空间复杂度:O(1)
2.876.链表的中心节点
(1)思路
考虑借助快慢双指针 fast, slow ,「快指针 fast」每轮走 2 步,「慢指针 slow」每轮走 1 步。
fast 的步数恒为 slow 的 2 倍,因此当快指针遍历完链表时,慢指针就指向链表中间节点。而由于长度为偶数的链表有两个中间节点,因此需要分两种情况考虑:
链表长度为奇数: 当 fast 走到链表「尾节点」时,slow 正好走到「中间节点」。
链表长度为偶数: 当 fast 走到「null」时(越过「尾节点」后),slow 正好走到「第二个中间节点」。
总结以上规律,应在当 fast 遇到或越过尾节点 时跳出循环,并返回 slow 即可。
(2)代码
/*** Definition for singly-linked list.* struct ListNode {* int val;* ListNode *next;* ListNode() : val(0), next(nullptr) {}* ListNode(int x) : val(x), next(nullptr) {}* ListNode(int x, ListNode *next) : val(x), next(next) {}* };*/
class Solution {
public:ListNode* middleNode(ListNode* head) {if (head == nullptr || head -> next == nullptr)return head;ListNode* slow = head;ListNode* fast = head;while (fast && fast -> next) {fast = fast -> next -> next;slow = slow -> next;}return slow;}
};
(3)复杂度分析
时间复杂度:O(N)
空间复杂度:O(1)
3.83.删除链表的重复元素
(1)思路
由于给定的链表是排好序的,因此重复的元素在链表中出现的位置是连续的,因此我们只需要对链表进行一次遍历,就可以删除重复的元素。
具体地,我们从指针 cur指向链表的头节点,随后开始对链表进行遍历。如果当前 cur与 cur.next对应的元素相同,那么我们就将 cur.next链表中移除;否则说明链表中已经不存在其它与cur对应的元素相同的节点,因此可以将 cur 指向 cur.next。
注意:当我们遍历到链表的最后一个节点时,cur.next 为空节点,如果不加以判断,访问 cur.next对应的元素会产生运行错误。因此我们只需要遍历到链表的最后一个节点,而不需要遍历完整个链表。
(2)代码
/*** Definition for singly-linked list.* struct ListNode {* int val;* ListNode *next;* ListNode() : val(0), next(nullptr) {}* ListNode(int x) : val(x), next(nullptr) {}* ListNode(int x, ListNode *next) : val(x), next(next) {}* };*/
class Solution {
public:ListNode* deleteDuplicates(ListNode* head) {if (head == nullptr) return head;ListNode* cur = head;while (cur -> next) {if (cur -> val == cur -> next -> val) {cur->next = cur->next->next;}else {cur = cur -> next;}}return head;}
};
(3)复杂度分析
时间复杂度:O(n),n为链表的长度。
空间复杂度:O(1)
4.283.移动0
(1)思路
/注意到以下性质:
//左指针左边均为非零数;
//右指针左边直到左指针处均为零。
//因此每次交换,都是将左指针的零与右指针的非零数交换,且非零数的相对顺序并未改变。
(2)代码
class Solution {
public:void moveZeroes(vector<int>& nums) {
//注意到以下性质:
//左指针左边均为非零数;
//右指针左边直到左指针处均为零。
//因此每次交换,都是将左指针的零与右指针的非零数交换,且非零数的相对顺序并未改变。int n = nums.size(), left = 0, right = 0;while (right < n) {if (nums[right]) {swap(nums[left++], nums[right]);}right++;}}
};
(3)复杂度分析
时间复杂度:O(n),其中 n 为序列长度。每个位置至多被遍历两次。
空间复杂度:O(1),只需要常数的空间存放若干变量。
5.5.最长回文子串
(1)思路
找回文串的难点在于,回文串的的长度可能是奇数也可能是偶数,解决该问题的核心是从中心向两端扩散的双指针技巧。
如果回文串的长度为奇数,则它有一个中心字符;如果回文串的长度为偶数,则可以认为它有两个中心字符。
(2)代码
class Solution {
public:
//找回文串的难点在于,回文串的的长度可能是奇数也可能是偶数,解决该问题的核心是从中心向两端扩散的双指针技巧。string process(string s,int l,int r) {while (l >= 0 && r < s.size() && s[l] == s[r]) {l --;r ++;} return s.substr(l + 1,r - l - 1);}string longestPalindrome(string s) {string res = "";for (int i = 0; i < s.length(); i ++) {string s1 = process(s,i,i); // 找到以 s[i] 为中心的回文串string s2 = process(s,i,i + 1);res = res.length() > s1.length() ? res : s1;res = res.length() > s2.length() ? res : s2;}return res;}
};
(3)复杂度分析
(三)滑动窗口
相关文章:
三、双指针(two-point)
文章目录 一、算法核心思想二、算法模型(一)对撞指针1.[704.二分查找](https://leetcode.cn/problems/binary-search/)(1)思路(2)代码(3)复杂度分析 2.[15.三数之和](https://leetco…...
Redis 是什么和使用场景概述(技术选型)
一、Redis 是什么 Redis是一款开源的高性能键值存储系统。它支持多种数据结构,如字符串、列表、集合、哈希表、有序集合等,并提供了丰富的操作命令和功能。Redis的主要特点包括: 内存存储:Redis将数据存储在内存中,因此…...
【数据结构】七大排序
文章目录 💐1. 插入排序🌼1.1 直接插入排序🌼1.2 希尔排序 💐2. 选择排序🌼2.1 直接选择排序🌼2.2 堆排序 💐3. 交换排序🌼3.1 冒泡排序🌼3.2 快速排序🌼3.2.…...
区块链实验室(24) - FISCO网络重构
若干次实验以后,FISCO网络中100个节点堆积了不少交易记录,消耗不少磁盘空间,见下图所示,100个节点累计消耗了10G空间。 观察每个节点的磁盘消耗,以node88为例,消耗了107MB,见下图所示。在该节点…...
AI智能写作工具有哪些?永久免费的AI智能写作工具你使用过吗?
AI智能写作是指借助人工智能技术,计算机程序可以自动生成各种文本内容,包括新闻报道、广告文案、科技文章、小说等等。这些AI写作工具通过大数据和深度学习模型,能够分析和模仿人类的写作风格,生成高质量的文本,甚至有…...
23.8.15 杭电暑期多校9部分题解
1002 - Shortest path 题目大意 对于一个数 x x x,可以进行以下三种操作: 1.将 x x x 变成 2 ∗ x 2*x 2∗x 2.将 x x x 变成 3 ∗ x 3*x 3∗x 3.将 x x x 变成 x 1 x1 x1 给定一个数 n n n,问最少操作几次才能将 1 1 1 变成…...
四个BY的区别 HIVE中
在Hive中,有四个BY比较:Order By、Sort By、Distribute By和Cluster By。 Order By是全局排序,只有一个Reducer。它可以按照升序(ASC)或降序(DESC)对结果进行排序。Order By子句通常用在SELECT语…...
计时函数与float32 float16 int8 数据转换
个人整理常用 部分来自 ncnn 计时函数 // window 平台 #include <windows.h>double get_current_time() {LARGE_INTEGER freq; // 频率LARGE_INTEGER pc; // 计数QueryPerformanceFrequency(&freq);QueryPerformanceCounter(&pc);return pc.QuadPart * 1000…...
自身免疫疾病诊断原料——博迈伦
自身免疫疾病是一类由免疫系统攻击正常组织和器官而引起的疾病。为了准确地诊断和监测自身免疫疾病,需要使用特定的诊断原料来进行实验室检测。这些诊断原料主要包括抗体试剂、抗原试剂和试剂盒等。 抗体试剂是用于检测和定量分析体内免疫系统产生的抗体的化学试剂。…...
cpu温度监测 Turbo Boost Switcher Pro for mac最新
Turbo Boost Switcher Pro是一款Mac电脑上的应用程序,旨在帮助用户控制和管理CPU的Turbo Boost功能。Turbo Boost是Intel处理器中的一项技术,可以在需要更高性能时自动提高处理器的频率。然而,这可能会导致电池消耗更快和温度升高。 以下是T…...
spring 请求 出现实体类大小写不一致 出现的问题
目录 1.问题背景 2.解决方法 但是会存在返回的既有大写也有小写的问题,需要在get方法也添加对应的注解 3.相关资料 1.问题背景 因数据库某字段存储的为json 格式,且数据库字段要求都有客户指定,因为该功能需要和其他项目进行对接。然后出现…...
zaabix实现对nginx监控
本文使用监控模板net.tcp.listen[port]实现监听端口 实验环境: 首先搭建好zabbix-server ,zabbix-agenthttps://mp.csdn.net/mp_blog/creation/editor/132622769?spm1001.2014.3001.9457 而后在zabbix-agent主机上下载一个nginx 登录zabbix网站创建主…...
基于AI视觉的表面缺陷检测设备优势显著,加速制造业数智化转型
作为生产制造过程中不可缺少的一步,表面缺陷检测广泛应用于工业领域,包括3C电子、芯片半导体、食品医药、木材等行业。但随着智能化进程加快,制造工厂生产线的质量检测压力加剧,传统人工表面缺陷检测已经无法满足当前社会较高的检…...
操作系统权限提升(二十六)之数据库提权-MySQL UDF提权
MySQL UDF提权 MySQL介绍 MySQL是最流行的开放源码SQL数据库管理系统,相对于Oracle,DB2等大型数据库系统,MySQL由于其开源性、易用性、稳定性等特点,受到个人使用者、中小型企业甚至一些大型企业的广泛欢迎,MySQL具有…...
基于 IntelliJ 的 IDE 将提供 Wayland 支持
导读对于使用 IntelliJ 开发环境的用户,JetBrains 一直致力于提供原生 Wayland 支持。 JetBrains 正在致力于为基于 IntelliJ 的 IDE 提供 Wayland 支持,以增强 Linux 桌面体验以及在 Windows Subsystem for Linux 下运行。 Wayland 支持功能尚未完成&…...
誉天在线项目~ElementPlus Tag标签用法
效果图 页面展现 <el-form-item label"课程标签"><el-tagv-for"tag in dynamicTags":key"tag"class"mx-1"closable:disable-transitions"false"close"handleClose(tag)"style"margin:5px;">…...
iText实战--Table、cell 和 page event
5.1 使用表和单元格事件装饰表 实现PdfPTableEvent 接口 实现PdfPCellEvent 接口 合并表格和单元格事件 5.2 基本构建块的事件 通用块(Chunk)功能 段落(Paragraph)事件 章节(Chapter)和 区域(…...
WampServer下载安装+cpolar内网穿透实现公网访问本地服务【内网穿透】
文章目录 前言1.WampServer下载安装2.WampServer启动3.安装cpolar内网穿透3.1 注册账号3.2 下载cpolar客户端3.3 登录cpolar web ui管理界面3.4 创建公网地址 4.固定公网地址访问 前言 Wamp 是一个 Windows系统下的 Apache PHP Mysql 集成安装环境,是一组常用来…...
Elasticsearch 入门 索引、分词器
term, match_phrase, match查询 参考 ElasticSearch match, match_phrase, term的区别 term是对输入不分词,进行全文索引查询。存储时是否启用分词器,会影响查询效果match_phase对输入分词,但要求查询时将每个term都搜到,且顺序…...
Android NDK 中有导出 sp智能指针吗?如果没有,可以用什么方法代替 android::sp 智能指针
Android NDK 中有导出 sp智能指针吗?如果没有,可以用什么方法代替 android::sp 智能指针 Author: Lycan Note: 以下问题解答通过大模型生成,主要用于个人学习和备忘,仅供参考,若有错误或者侵权,请联系我修…...
网络爬虫-----爬虫的分类及原理
目录 爬虫的分类 1.通用网络爬虫:搜索引擎的爬虫 2.聚焦网络爬虫:针对特定网页的爬虫 3.增量式网络爬虫 4.深层网络爬虫 通用爬虫与聚焦爬虫的原理 通用爬虫: 聚焦爬虫: 爬虫的分类 网络爬虫按照系统结构和实现技术&#…...
uniapp级联菜单地点区域使用label值,web端el-cascader绑定的value
效果图 一、uniapp uniapp级联菜单地点区域使用label值 1.ui使用 <uni-forms-item label="地址" name="userArea" required><view class="" style="height: 100%;display: flex;align-items: center;">...
合肥先进光源国家重大科技基础设施项目及配套工程启动会纪念
合肥先进光源国家重大科技基础设施项目及配套工程启动会纪念 卡西莫多 合肥长丰岗集里 肥鸭从此别泥塘 先平场地设围栏 进而工地筑基忙 光阴似箭指日争 源流汇智山水长 国器西北扩新地 家校又添新区园 重器托举有群力 大步穿梭两地间 科教兴邦大国策 技术盈身坦荡行…...
力扣第47天--- 第647题、第516题
# 力扣第47天— 第647题、第516题 文章目录 一、第647题--回文子串二、第516题--最长回文子序列 一、第647题–回文子串 逻辑梳理清楚了,就还行。没有想象中那么难。注意遍历顺序,i从大到小。 class Solution { public:int countSubstrings(string …...
dll文件找不到,微软官方地址
dll文件找不到,微软官方地址 文件地址dllMicrosoft Visual C 2008 Redistributable Package ATL 安全更新https://www.microsoft.com/zh-cn/download/details.aspx?id10430Visual C Redistributable for Visual Studio 2012 Update 4https://www.microsoft.com/zh…...
【音视频】FLV封装格式
基本概念 文件头(Header)文件体(Body) flv文件头 主要是看signture和typeflags flv文件体 重点:Tag包数据 Tag结构详细说明 注意: 每个Tag的头字段DataSize只是该Tag下data部分的大小,不包括Tag的header部分的大小 音频 AudioTag Data 所在…...
别再纠结线程池池大小、线程数量了,哪有什么固定公式 | 京东云技术团队
可能很多人都看到过一个线程数设置的理论: CPU 密集型的程序 - 核心数 1 I/O 密集型的程序 - 核心数 * 2 不会吧,不会吧,真的有人按照这个理论规划线程数? 线程数和CPU利用率的小测试 抛开一些操作系统,计算机原…...
Redis 数据一致性方案的分析与研究
点击下方关注我,然后右上角点击...“设为星标”,就能第一时间收到更新推送啦~~~ 一般的业务场景都是读多写少的,当客户端的请求太多,对数据库的压力越来越大,引入缓存来降低数据库的压力是必然选择,目前业内…...
【网络安全】黑客自学笔记
1️⃣前言 🚀作为一个合格的网络安全工程师,应该做到攻守兼备,毕竟知己知彼,才能百战百胜。 计算机各领域的知识水平决定你渗透水平的上限🚀 【1】比如:你编程水平高,那你在代码审计的时候就会比…...
深入解析Perlin Simplex噪声函数:在C++中构建现代、高效、免费的3D图形背景
引言 在计算机图形中,噪声是一个经常被讨论的话题。无论是为了制造自然的纹理,还是为了模拟复杂的现实世界现象,噪声函数都在其中起着关键作用。而在众多噪声函数中,Perlin Simplex 噪声无疑是最受欢迎的一种。其原因不仅在于其干…...
wordpress模版做网站/百度百科词条
Word 2013中新功能不少,当然也不能忘记老功能,今天我们要介绍的是带圈字符的输入,不会的朋友赶快擦亮眼睛,跟着小编学习一下!①启动Word2013,单击开始--字体选项卡里面的带圈字符按钮。②弹出带圈字符界面&…...
ps做的网站保存不了jpg/百度网盘登录首页
源:在 WindowMobile 上的模拟LED 显示屏插件 我在给一个对话框上的控件查找翻看合适的图标时,无形中看到了一个LED显示屏的图标,这里所说的LED显示屏是指由很多LED灯密集排列组成的点阵式LED屏,比如在股市交易所,公交车…...
网站官网建设企业/全网推广代理
2019独角兽企业重金招聘Python工程师标准>>> 浏览器禁止js跨域取数据,可能在两个方面防止,一是ajax取数据的时候发现不是同源,阻止获取数据;另外一种是ajax获取了数据,但是浏览器禁止这些数据在当前域下显示…...
wordpress文章列表调用描述/微信小程序建站
最近在测试把有米积分墙IOS版本的SDK集成到Cocos2d-x项目中,我使用的XCODE 6.1,COCOS2D-X为2.2.3,但是编译时出现如下错误: #include <string> 报错: string file not found 上述错误文件为: CCDatav…...
深圳网站建设与推广/怎么推广app
事务代码:S_ABA_72000164 支持BDT导航和分析。...
泉州市服务好的网站设计/免费个人推广引流平台
1、NPN、PNP三极管用作开关的基本电路 2、负载位置 为什么不管是NPN还是PNP,电路对应的负载要放到集电极C,而没有放到发射极E呢? 因为三极管的输入回路是从基级B控制发射极E,负载如果放到发射极E,那就会对输入回路造…...