双指针2s总结

5.双指针

双指针理论基础

那么vector< char > 和 string 又有什么区别呢?

其实在基本操作上没有区别,但是 string提供更多的字符串处理的相关接口,例如string 重载了+,而vector却没有。

所以想处理字符串,我们还是会定义一个string类型。

双指针套路总结

数组篇

在数组:就移除个元素很难么? (opens new window)中,原地移除数组上的元素,我们说到了数组上的元素,不能真正的删除,只能覆盖。

一些同学可能会写出如下代码(伪代码):

for (int i = 0; i < array.size(); i++) {if (array[i] == target) {array.erase(i);}
}

这个代码看上去好像是O(n)的时间复杂度,其实是O(n^2)的时间复杂度,因为erase操作也是O(n)的操作。

所以此时使用双指针法才展现出效率的优势:通过两个指针在一个for循环下完成两个for循环的工作。

字符串篇

1 其实很多数组填充类的问题,其做法都是先预先给数组扩容带填充后的大小,然后在从后向前进行操作。

这么做有两个好处:

  1. 不用申请新数组。
  2. 从后向前填充元素,避免了从前向后填充元素时,每次添加元素都要将添加元素之后的所有元素向后移动的问题。

链表篇

翻转链表是现场面试,白纸写代码的好题,考察了候选者对链表以及指针的熟悉程度,而且代码也不长,适合在白纸上写。

在链表:听说过两天反转链表又写不出来了? (opens new window)中,讲如何使用双指针法来翻转链表,只需要改变链表的next指针的指向,直接将链表反转 ,而不用重新定义一个新的链表。

思路还是很简单的,代码也不长,但是想在白纸上一次性写出bugfree的代码,并不是容易的事情。

在链表中求环,应该是双指针在链表里最经典的应用,在链表:环找到了,那入口呢? (opens new window)中讲解了如何通过双指针判断是否有环,而且还要找到环的入口。

使用快慢指针(双指针法),分别定义 fast 和 slow指针,从头结点出发,fast指针每次移动两个节点,slow指针每次移动一个节点,如果 fast 和 slow指针在途中相遇 ,说明这个链表有环。

从头结点出发一个指针,从相遇节点 也出发一个指针,这两个指针每次只走一个节点, 那么当这两个指针相遇的时候就是 环形入口的节点

N数之和篇

在哈希表:解决了两数之和,那么能解决三数之和么? (opens new window)中,讲到使用哈希法可以解决1.两数之和的问题

其实使用双指针也可以解决1.两数之和的问题,只不过1.两数之和求的是两个元素的下标,没法用双指针,如果改成求具体两个元素的数值就可以了,大家可以尝试用双指针做一个leetcode上两数之和的题目,就可以体会到我说的意思了。

使用了哈希法解决了两数之和,但是哈希法并不使用于三数之和!

使用哈希法的过程中要把符合条件的三元组放进vector中,然后在去去重,这样是非常费时的,很容易超时,也是三数之和通过率如此之低的根源所在。

去重的过程不好处理,有很多小细节,如果在面试中很难想到位。

时间复杂度可以做到O(n^2),但还是比较费时的,因为不好做剪枝操作。

所以这道题目使用双指针法才是最为合适的,用双指针做这道题目才能就能真正体会到,通过前后两个指针不算向中间逼近,在一个for循环下完成两个for循环的工作。

只用双指针法时间复杂度为O(n2),但比哈希法的O(n2)效率高得多,哈希法在使用两层for循环的时候,能做的剪枝操作很有限。

在双指针法:一样的道理,能解决四数之和 (opens new window)中,讲到了四数之和,其实思路是一样的,在三数之和的基础上再套一层for循环,依然是使用双指针法。

练习

Hjk最多团队数量

用数组代表每个人的能力,一个比赛活动要求参赛团队的最低能力值为N,每个团队可以由1人或者2人组成,且1个人只能参加1个团队,计算出最多可以派出多少只符合要求的团队。

输入描述
第一行代表总人数,范围1-500000
第二行数组代表每个人的能力
数组大小,范围1-500000
元素取值,范围1-500000
第三行数值为团队要求的最低能力值,范围1-500000
输出描述
最多可以派出的团队数量

用例
输入 5
3 1 5 7 9
8
输出 3
说明 3、5组成一队 1、7一队 9自己一队 输出3
输入 7
3 1 5 7 9 2 6
8
输出 4
说明 3、5组成一队,1、7一队,9自己一队,2、6一队,输出4
输入 3
1 1 9
8
输出 1
说明 9自己一队,输出1

解题思路
对人员能力数组进行升序排序,以便后续处理。
使用两个指针 l 和 r 分别指向数组的开头和结尾。
首先处理单人组队的情况,即能力大于等于最低要求的人数统计出来。
然后进入双人组队的逻辑:当 l 小于 r 时,进行以下循环:
计算当前 l和 r 指向的人的能力之和 sum。
如果 sum 大于等于 minCap,则可以组成一个团队,团队数量加一,同时移动 l 和 r 指针。
如果 sum 小于 minCap,则需要将能力较低的人剔除,移动 l 指针。
最终返回团队数量作为结果。

#include <iostream>
#include <vector>
#include <algorithm>int getteams(int& N, std::vector<int>& caps, int& target) {int l = 0, r = N - 1;std::sort(caps.begin(), caps.end());int team = 0;//单人组队while(l <= r) {if (caps[r] >= target) {team ++;}else {break;}r--;}//双人组队while(l < r) {if (caps[l] + caps[r] >= target) {l++;r--;team ++;}else {l++;}}return team;
}int main() {int N;std::cin >> N;std::vector<int> caps(N, 0);for (int i = 0; i < N; i++) {std::cin >> caps[i];}int target;std::cin >> target;int res = getteams(N, caps, target);std::cout << res << std::endl;return 0;
}

Hjk数组连续和

给定一个含有N个正整数的数组, 求出有多少个连续区间(包括单个正整数), 它们的和大于等于x。

输入描述
第一行两个整数N x(0 < N <= 100000, 0 <= x <= 10000000)
第二行有N个正整数(每个正整数小于等于100)。

输出描述
输出一个整数,表示所求的个数。
注意:此题对效率有要求,暴力解法通过率不高,请考虑高效的实现方式。

用例
输入
3 7
3 4 7
输出 4
说明 第一行的3表示第二行数组输入3个数,第一行的7是比较数,用于判断连续数组是否大于该数;组合为 3 + 4; 3 + 4 + 7; 4 + 7; 7; 都大于等于指定的7;所以共四组。

输入
10 10000
1 2 3 4 5 6 7 8 9 10
输出 0
说明 所有元素的和小于10000,所以返回0。、

#include <iostream>
#include <vector>int getRegionNum(std::vector<int>& nums, int& x) {int left = 0;int sum = 0;int count = 0;for (int right = 0; right < nums.size(); right ++) {sum += nums[right];while (sum >= x) {count += (nums.size() - right);sum -= nums[left];left ++;}}return count;
}int main() {int N, x;std::cin >> N >> x;std::vector<int> nums(N, 0);for (int i = 0; i < N; i++) {std::cin >> nums[i];}int res = getRegionNum(nums, x);std::cout << res << std::endl;return 0;
}

Hjk五子棋爱好者

题目
张兵和王武喜欢玩五子棋。现在轮到张兵了,他面前的棋盘上有一排棋子。

棋子规则:
-1 表示白子
0 表示没子,是个空位
1 表示黑子

一排棋子中,棋子数量L要满足:1 < L < 40,并且L是奇数。

你要写个程序帮张兵找到最佳的落子位置。怎么判断“最佳”呢?

找个空位(0)落子,使得这种颜色的棋子连在一起的数量最多。

如果有多个这样的空位,选中间的那个。
但是,连在一起的棋子数量不能超过5个。

输入:

第一行:当前要下的棋子颜色(1或-1)
第二行:当前棋盘上的棋子排列
输出:

一个数字,表示落子位置的下标(如果没有好位置,输出-1)
例如:

输入:
1
-1 0 1 1 1 0 1 -1 1

输出:

5

说明 当前为黑子(1),放置在下标为5的位置,黑子的最大连续长度,可以由35

示例2

-1
-1 0 1 1 1 0 1 0 1 -1 1
1
当前为白子,唯一可以放置的位置下标为1,白子的最大长度,由1变为2

示例3

1
0 0 0 0 1 0 0 0 0 1 0
5
可行的位置很多,5最接近中间的位置坐标

分析

维护两个指针来遍历棋盘,分别表示连续棋子的起始和结束位置。在遍历过程中,我们寻找可以放置新棋子的位置(即0的位置),并判断放置新棋子后能形成的最长连续同色棋子的长度。

#include <iostream>
#include <vector>
#include <string>
#include <sstream>int getindex(std::vector<int>& nums, int& color) {int resindex = -1;int longgestCommbo = 0;int centerindex = nums.size() / 2;for (int i = 0; i < nums.size(); i++) {if (nums[i] == 0) {int combo = 1;int left = i - 1;while (left >= 0 && nums[left] == color) {combo += 1;left --;}int right = i + 1;while (right < nums.size() && nums[right] == color) {combo += 1;right ++;}//如果连起来大于5跳过if (combo > 5) continue;if (combo > longgestCommbo) {resindex = i;longgestCommbo = combo;}else if(combo == longgestCommbo && (std::abs(i - centerindex) < std::abs(resindex - centerindex))) {resindex = i;longgestCommbo = combo;}}}return resindex;
}int main() {int color;std::cin >> color;std::cin.ignore();std::string cheses;std::getline(std::cin, cheses);std::stringstream ss(cheses);std::vector<int> nums;std::string token;while (std::getline(ss, token,' ')) {nums.push_back(std::stoi(token));}//测试用// for (int i : nums) {//     std::cout << i <<  " ";// }int index = getindex(nums, color);std::cout << index << std::endl;return 0;}

Hjk跳房子二

跳房子,也叫跳飞机,是一种世界性的儿童游戏。

游戏参与者需要分多个回合按顺序跳到第1格直到房子的最后一格,然后获得一次选房子的机会,直到所有房子被选完,房子最多的人获胜。

跳房子的过程中,如果有踩线等违规行为,会结束当前回合,甚至可能倒退几步。

假设房子的总格数是count,小红每回合可能连续跳的步数都放在数组steps中,请问数组中是否有一种步数的组合,可以让小红三个回合跳到最后一格?

如果有,请输出索引和最小的步数组合(数据保证索引和最小的步数组合是唯一的)。注意:数组中的步数可以重复,但数组中的元素不能重复使用。

输入描述

第一行输入为房子总格数count,它是int整数类型。

第二行输入为每回合可能连续跳的步数,它是int整数数组类型

输出描述

返回索引和最小的满足要求的步数组合(顺序保持steps中原有顺序)

备注

· count≤10000

· 3≤steps.length≤10000

·-100000≤steps[]≤100000

输入
[1,4,5,2,0,2]
9
输出
[4,5.0]
说明
无

示例2

输入
[1,5,2,0,2.4]
9
输出
[5,2,2]
说明
无

示例3

输入
[-1,2.4,9]
12
输出
[-1.4.9]
说明
无

本题是leetcode三数之和变种

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/803099.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java常用类(二)

常用类&#xff08;二&#xff09; Object类 超类&#xff0c;基类&#xff0c;所有类的直接或间接父类&#xff0c;位于继承树的最高层任何类&#xff0c;如没有书写extends显示继承某个类&#xff0c;都默认直接继承Object类&#xff0c;否则为间接继承Object类中所定义的方…

C语言题目:数组寻找最小绝对值

题目描述 输入10个数&#xff0c;找出其中绝对值最小的数&#xff0c;将它和最后一个数交换&#xff0c;然后输出这10个数。 输入格式 十个数 输出格式 交换后的十个数 样例输入 10 2 30 40 50 60 70 80 90 100 样例输出 10 100 30 40 50 60 70 80 90 2 代码解析 包含…

扫描IP开放端口该脚本用于对特定目标主机进行常见端口扫描(加载端口字典)或者指定端口扫描,判断目标主机开

扫描IP开放端口该脚本用于对特定目标主机进行常见端口扫描(加载端口字典)或者指定端口扫描,判断目标主机开 #/bin/bash #该脚本用于对特定目标主机进行常见端口扫描(加载端口字典)或者指定端口扫描,判断目标主机开放来哪些端口 #用telnet方式 IP$1 #IP119.254.3.28 #获得IP的前…

BUUCTF刷题十一道(12)SSTI专题一

文章目录 学习文章[Flask]SSTI[GWCTF 2019]你的名字[第三章 web进阶]SSTI[pasecactf_2019]flask_ssti[NewStarCTF 公开赛赛道]BabySSTI_One[Dest0g3 520迎新赛]EasySSTI[NewStarCTF 公开赛赛道]BabySSTI_Two[NewStarCTF 公开赛赛道]BabySSTI_Three[GYCTF2020]FlaskApp[CSCCTF 2…

网易云歌曲评论抓取

网易云歌曲评论爬取 步骤1.找到一首歌曲2.按下F12键打开开发者模式,对其进行抓包3.查找获得评论数据的接口4.对获得评论数据接口进行分析5.构建加密函数方法一方法二运行结果全部代码使用Js文件只使用python新的代码小结与展望这次的任务是获取网易云音乐下面的评论,涉及的知…

List接口(1) | ArrayList

参考阅读&#xff1a;ArrayList 源码分析 一、特点 ArrayList 继承于 AbstractList &#xff0c;实现了 List, RandomAccess, Cloneable, java.io.Serializable 这些接口&#xff0c;具有以下特点&#xff1a; 支持添加&#xff0c;删除和查找操作支持随机快速访问&#xff…

前端ocr技术:electron+vue3中使用tesseract插件识别图片中字符

同学们可以私信我加入学习群&#xff01; 正文开始 前言一、electron各种csp问题二、试用插件总结 前言 项目需要ocr技术识别图片中的中文字符&#xff0c;本来这部分是后端的工作&#xff0c;但是因为各种原因&#xff0c;决定前端也做一个版本。 在ai时代之前&#xff0c;o…

基于spring boot的漫画之家系统

基于spring boot的漫画之家系统设计与实现 开发语言&#xff1a;Java 框架&#xff1a;springboot JDK版本&#xff1a;JDK1.8 服务器&#xff1a;tomcat7 数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09; 数据库工具&#xff1a;Navicat11 开发软件&…

pta L1-012 计算指数

L1-012 计算指数 分数 5 全屏浏览 切换布局 作者 陈越 单位 浙江大学 真的没骗你&#xff0c;这道才是简单题 —— 对任意给定的不超过 10 的正整数 n&#xff0c;要求你输出 2n。不难吧&#xff1f; 输入格式&#xff1a; 输入在一行中给出一个不超过 10 的正整数 n。 …

Java排序算法

冒泡排序 相邻两个元素比较&#xff0c;每次排序获得一个当前排序区间的最大值 // 冒泡排序 // 外层循环每次最后一个元素已经是最大的了&#xff0c;所以每次循环都减少一个元素 for (int i arr.length - 1; i >0; i--) {// 内层循环每次都是从第一个元素开始&#xff0c;…

鲁棒线性模型估计(Robust linear model estimation)

鲁棒线性模型估计 1.RANSAC算法1.1 算法的基本原理1.2 迭代次数N的计算1.3 参考代码 参考文献 当数据中出现较多异常点时&#xff0c;常用的线性回归OLS会因为这些异常点的存在无法正确估计线性模型的参数&#xff1a; W ( X T X ) − 1 X T Y \qquad \qquad W(X^TX)^{-1}X^T…

力扣热题100_链表_19_删除链表的倒数第 N 个结点

文章目录 题目链接解题思路解题代码 题目链接 19. 删除链表的倒数第 N 个结点 给你一个链表&#xff0c;删除链表的倒数第 n 个结点&#xff0c;并且返回链表的头结点。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4,5], n 2 输出&#xff1a;[1,2,3,5] 示例 2&am…

数据结构—图

图的基本概念 图就是由顶点的有穷非空集合和顶点之间的边组成的集合。通常表示为&#xff1a;G(V,E)&#xff0c;其中&#xff0c;G 表示一个图&#xff0c;V 表示顶点的集合&#xff0c;E 表示边的集合。 顶点 图中的数据元素&#xff0c;我们称之为顶点&#xff0c;图至少有…

2024年3月电子学会青少年软件编程 中小学生Python编程等级考试一级真题解析(判断题)

2024年3月Python编程等级考试一级真题解析 判断题&#xff08;共10题&#xff0c;每题2分&#xff0c;共20分&#xff09; 26、turtle 画布的坐标系原点是在画布的左上角 答案&#xff1a;错 考点分析&#xff1a;考查turtle相关知识&#xff0c;turtle画布坐标系是在画布的…

KNN分类算法的MATLAB实现以及可视化

一、KNN简介 KNN算法&#xff0c;即K-Nearest Neighbors&#xff0c;是一种常用的监督学习算法&#xff0c;可以用于分类问题&#xff0c;并且在实际应用中取得了广泛的成功。 二、KNN算法的基本原理 对于给定的测试样本&#xff0c;KNN算法首先计算它与训练集中所有样本的距…

服务器硬件基础知识解析

导言 在当今信息化时代&#xff0c;服务器扮演着至关重要的角色&#xff0c;它们是存储、处理和传输数据的关键设备。本文将介绍服务器硬件的基础知识&#xff0c;包括服务器的组成部分、硬件选型和性能评估等内容&#xff0c;旨在帮助读者更好地理解和应用服务器技术。 服务…

【数据库】规划与分析

目录 1.规划与分析 的步骤&#xff08;3步&#xff09;&#xff1f; 2.系统规划与定义 的步骤&#xff08;4步&#xff09;&#xff1f; 3.可行性分析 的步骤&#xff08;4步&#xff09;&#xff1f;&#xff08;-表示包括 、和/表示并列&#xff09; 4.项目规划 的步…

Vue - 你知道Vue2中对象动态新增属性,视图无法更新的原因吗

难度级别:中高级及以上 提问概率:55% 这道题面试官会这样描述,比如有这样一个场景,一个对象里有name属性,可以正常显示在页面中。但后续动态添加了一个age属性,通过调试打印发现对象里的age属性已经添加了上了,但试图中却没有展示出来,…

Axure案例分享—垂直手风琴(附下载地址)

今天分享的案例是Axure8(兼容9和10)制作的垂直手风琴 一、功能介绍 折叠或展开多个面板内容&#xff0c;默认为展开一项内容&#xff0c;点击任一收起的选项&#xff0c;展开面板&#xff0c;其他面板收起二、制作过程 原型是由矩形组件以及动态面板构成&#xff0c; 拖入一…

Collection与数据结构 二叉树(一):二叉树的性质与基本操作

1. 树形结构 1.1 概念1 (了解) 树是一种非线性的数据结构&#xff0c;它是由n&#xff08;n>0&#xff09;个有限结点组成一个具有层次关系的集合。把它叫做树是因为它看起来像一棵倒挂的树&#xff0c;也就是说它是根朝上&#xff0c;而叶朝下的。它具有以下的特点&#…