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

codetop标签双指针题目大全解析(三),双指针刷穿地心!!!!!

复习比学习更重要,更需要投入时间,更需要花费精力

  • 1.字符串的排列
  • 2.找出字符串中第一个匹配的下标
  • 3.最大连续1的个数II
  • 4.数组中的山脉
  • 5.移除元素
  • 6.两个数组的交集II
  • 7.有序数组的平方
  • 8.删除有序数组中的重复项II
  • 9.寻找重复数
  • 10.水果成篮

1.字符串的排列

在滑动窗口总结文章里面讲解过了

二刷debug:首先,缩小窗口的条件是r-l >s1.size()。然后,必须用need.count( c )而不是need[c] >= 1。count( c ) 仅仅检查键 c 是否存在于 unordered_map 中,与键对应的值无关!而need[c]>=1是必须need中有其键并且数量大于等于1

class Solution {
public:bool checkInclusion(string s1, string s2) {unordered_map<char, int> window, need;for(char c : s1) need[c] ++;int left = 0, right = 0;int valid = 0;while(right < s2.size()){char c = s2[right];right++;if(need.count(c)){window[c]++;if(need[c] == window[c]) valid++;}while(right - left > s1.size()){char d = s2[left];left ++;if(need.count(d)){if(need[d] == window[d]) valid--;window[d]--;}}if(need.size() == valid && right - left == s1.size()){return true;}}return false;}
};

2.找出字符串中第一个匹配的下标

在这里插入图片描述
拿到手的第一想法就是,滑动窗口,输出left
但是这个要求顺序完全一样,不能是排列或者组合
查了一下KMP是专门弄这种的,学习新算法了在这里插入图片描述(我只是来做双指针的…)这篇文章是个纯刷题记录,不贴详细讲解,最多记录大致思路,需要讲解去秒杀直接部分->传送门
二刷debug:写出来了,几乎是靠背的,注意ne初始化

class Solution {
public:int strStr(string haystack, string needle) {int n = haystack.size();int m = needle.size();vector<int> ne(m, -1);// ne数组必须初始化为-1而不是0,只有-1才代表没有相同的前后缀// 建next数组for(int i = 1, j = -1; i < m; i ++){while(j != -1 && needle[i] != needle[j + 1]) j = ne[j];if(needle[i] == needle[j + 1]) j ++;ne[i] = j;}// 匹配for(int i = 0, j = -1; i < n; i ++){while(j != -1 && haystack[i] != needle[j + 1]) j = ne[j];if(haystack[i] == needle[j + 1]) j ++;if(j == m - 1){return i - m + 1;}}return -1;}
};

3.最大连续1的个数II

不是,家人们,滑动窗口为什么都划到双指针标签下了啊
题:
给定一个二进制数组 nums 和一个整数 k,如果可以翻转最多 k 个 0 ,则返回 数组中连续 1 的最大个数 。
eg:
输入:nums = [1,1,1,0,0,0,1,1,1,1,0], K = 2
输出:6
在秒杀系列的滑动窗口秒杀文章里面写过
用滑动窗口做题需要先明白3个问题

  1. 什么时候扩大窗口?更改什么数据?
  2. 什么时候缩小窗口?更改什么数据?
  3. 什么时候得到答案?

针对123的答案:

  1. 当可替换次数k>=0的时候扩大窗口,更改窗口里面1的个数,让窗口里面都是1,等于0的时候也扩,万一窗口外面不需要改呢。
  2. 当可替换次数k<0的时候缩小窗口,可替换次数++,以便继续扩大
  3. k>=0的时候,窗口内部都是1,len更新
class Solution {
public:int longestOnes(vector<int>& nums, int k) {int left = 0, right = 0;int windowOneCount = 0;int res = 0;while(right < nums.size()){//right是0也++,是1就windowOneCount++,自身也++if(nums[right] == 1){windowOneCount ++;}right ++;//窗口里面0的个数超过了k,就开始缩小窗口while(right - left - windowOneCount > k){if(nums[left] == 1) windowOneCount --;left ++;}res = max(res, right - left);}return res;}
};

4.数组中的山脉

在这里插入图片描述
先找到可能得山顶,再双指针两边扩展,记录res
留意l,r,i的边界
二刷debug:注意双指针两边扩展的手法,还有边界问题,如果是只能到倒数第二个元素的话,i<.size()-1即可

class Solution {
public:int longestMountain(vector<int>& arr) {int l = 0, r = 0, res = 0;for(int i = 1; i < arr.size() - 1; i ++){if(arr[i] > arr[i - 1] && arr[i] > arr[i + 1]){l = i - 1;r = i + 1;while(l > 0 && arr[l] > arr[l - 1]) l --;while(r < arr.size() - 1 && arr[r] > arr[r + 1]) r ++;res = max(res, r - l + 1);}}return res;}
};

5.移除元素

移除val,返回新数组的长度
双指针里也有这题,秒啦

class Solution {public int removeElement(int[] nums, int val) {int i = 0;for (int n : nums)if (n != val) {nums[i] = n;i++;}return i;}
}

6.两个数组的交集II

给nums1和nums2,以数组的形式返回两数组里都存在的数,并且这个数的次数要等于两个数组中这个数出现次数更少的那个

别人的代码是真的优雅
这个代码先记录了nums1中每个元素出现的次数到umap中
再在nums2中for每个元素
如果元素在umap中有记录则将其push进res,并且umap记录数–

假如nums1中才是数字出现少的那个,那么umap[nums1]会先到0,以至于res不了nums2的元素,假如nums2才是数字出现少的那个,那么if(nums2)会先空

太优雅了o(╥﹏╥)o

class Solution {
public:vector<int> intersect(vector<int>& nums1, vector<int>& nums2) {unordered_map<int, int> umap;vector<int> res;for(int i = 0; i < nums1.size(); i ++) umap[nums1[i]]++;for(int i = 0; i < nums2.size(); i ++){if(umap[nums2[i]]){res.push_back(nums2[i]);umap[nums2[i]] --;}}return res;}
};

7.有序数组的平方

给一个非递减的数组,现在需要你将每个元素都平方,然后递增排序,返回nums。注意,需要时间复杂度是O(n)

sort的家伙,以后面试也排人后面!!!!

sort的复杂度是O(nlogn),所以不能用sort,只能用双指针

这里有个十分关键的点,就是:原本的数组本身就是有序的,是一个非递减的数组,那么即使数组中元素有正有负,绝对值最大的元素肯定是在数组的两端的,即数组平方的最大值是在数组的两端的。

所以我们可以使用两个双指针i,j一个指向起始位置,一个指向数组的末尾。
定义一个新的数组result用于储存新的有序平方后的元素。

class Solution {
public://双指针vector<int> sortedSquares(vector<int>& A) {int k = A.size() - 1; //指向新数组的末尾,从后往前赋值vector<int> result(A.size(), 0);for (int i = 0, j = A.size() - 1; i <= j;) { // 注意这里要i <= j,因为最后要处理两个元素if (A[i] * A[i] < A[j] * A[j]) { //判断条件1:尾部元素更大result[k--] = A[j] * A[j];j--;}else {result[k--] = A[i] * A[i]; //判断条件2:头部元素更大i++;}}return result;}
};

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

给你一个有序数组 nums ,请你 原地 删除重复出现的元素,使得出现次数超过两次的元素只出现两次 ,返回删除后数组的新长度。

不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。

前2个肯定不用删,所以可以跳过,从j = 2开始比
还是太优雅了这代码

二刷debug:不会,很难理解

class Solution {
public:int removeDuplicates(vector<int>& nums) {if(nums.size() <= 2) return nums.size();int i = 2;for(int j = 2; j < nums.size(); j ++){if(nums[j] != nums[i - 2]){nums[i] = nums[j];i ++;}}return i;}
};

9.寻找重复数

在这里插入图片描述

不可以用sort也不可以用额外数组
这个要求真的是把我路都堵死了…
二刷debug:不会…
数组小技巧:数组也可以看做链表来做
以图为例,天然就有数组链表0->1->3->2->4
fast = nums[nums[fast]]相当于fast = fast->next->next
slow = nums[slow]相当于slow = slow->next
在这里插入图片描述
几刷?:容易写成return nums[slow],实际上最后一个是slow = nums[slow],所以直接写成return slow就可以了

class Solution {
public:int findDuplicate(vector<int>& nums) {int fast = 0, slow = 0;while(true){fast = nums[nums[fast]];slow = nums[slow];if(fast == slow) break;}slow = 0;while(fast != slow){fast = nums[fast];slow = nums[slow];}return slow;}
};

10.水果成篮

fruits数组,fruits[i]代表一种水果,比如fruits[2] = 1,,代表香蕉
现在有fruits.size()棵水果树,每次只能摘一颗树
现在有2个篮子,每个篮子装一种水果,问最多能摘多少棵数

fruit = [1,2,1],有两种水果树,所以能摘三棵,都能摘,篮子装得下

滑动窗口。要注意不需要window.size() == need,也要计算len,因为有while(window.size() > need)在,窗口不是小了就是刚刚好,不可能大,如果fruit的水果树种类本来就不足2个,就可以返回
另外,当缩小窗口,导致其中一个苹果树没了,window应该erase掉。否则还占用一个size

二刷debug:小于等于2的水果树种类也可以,另外unordered_map类型可以使用erase

class Solution {
public:int totalFruit(vector<int>& fruits) {unordered_map<int, int> window;int need = 2;int len = 0;int left = 0, right = 0;while(right < fruits.size()){int c = fruits[right];right++;window[c]++;;while(window.size() > need){int d = fruits[left];left++;window[d]--;if(window[d] == 0) window.erase(d);}len = max(len, right - left);}return len;}
};

相关文章:

codetop标签双指针题目大全解析(三),双指针刷穿地心!!!!!

复习比学习更重要&#xff0c;更需要投入时间&#xff0c;更需要花费精力 1.字符串的排列2.找出字符串中第一个匹配的下标3.最大连续1的个数II4.数组中的山脉5.移除元素6.两个数组的交集II7.有序数组的平方8.删除有序数组中的重复项II9.寻找重复数10.水果成篮 1.字符串的排列 …...

HarmonyOS应用六之应用程序进阶一

目录&#xff1a; 1、UIAbility的冷启动和UIAbility热启动2、静态资源和动态资源的访问3、页面跳转3.1、页面返回跳转 4、HAR的ArkUI组件、接口、资源&#xff0c;供其他应用或当前应用的其他模块引用4.1、导出HAR的ArkUI组件4.2、引用HAR的ArkUI组件 5、循环渲染6、状态管理最…...

vue开发中变量第一次双向绑定无效,界面并没有变化,第二次则又好了。

这个问题出现的太频繁了,基本大部分用户都遇到这个情况。大部分是弹框的情况。代码如下: <el-dialog:visible.sync="isShowCode" @close="closeCode()"><div class="u4259f"><edite-edite-code isNoShowClose="true"…...

C++基础(8)——string的相关面试题

目录 1.字符串转成整数 2.字符串相加 3.高精度加法模板&#xff08;acwing&#xff09; 4.验证回文串 1.字符串转成整数 题目&#xff1a;将一个字符串转换成一个整数&#xff0c;要求不能使用字符串转换整数的库函数。数值为0或者字符串不是一个合法的数值则返回0。输入的…...

【Docker】06-DockerCompose

1. Docker compose 2. Docker Compose部署项目 docker-compose.yml version: "3.8"services:mysql:image: mysqlcontainer_name: mysqlports:- "3307:3306"environment:TZ: Asia/ShanghaiMYSQL_ROOT_PASSWORD: 123volumes:- "/root/docker/mysql/…...

代码随想录训练营Day27 | 77. 组合 | 216.组合总和III | 17.电话号码的字母组合

学习文档&#xff1a;代码随想录 (programmercarl.com) 视频链接&#xff1a;代码随想录算法公开课 | 最强算法公开课 | 代码随想录 (programmercarl.com) Leetcode 77. 组合 题目描述 给定两个整数 n 和 k&#xff0c;返回范围 [1, n] 中所有可能的 k 个数的组合。 你可以…...

Linux文件重定向文件缓冲区

目录 一、C文件接口 二、系统文件I/O 2.1认识系统文件I/O 2.2系统文件I/O 2.3系统调用和库函数 2.4open( )的返回值--文件描述符 2.5访问文件的本质 三、文件重定向 3.1认识文件重定向 3.2文件重定向的本质 3.3在shell中添加重定向功能 3.4stdout和stderr 3.5如何理…...

训练贪吃蛇ai的后续记录

发现可以结合遗传算法的思路&#xff0c;产生更好的效果。 即每训练一段时间&#xff0c;就停下来测试一下新模型的效果。如果效果优于记录中最好的&#xff0c;则继续导入该模型并训练。重复几次&#xff0c;效果可能更好。 例如&#xff0c;昨晚我便通过唯一一个在十次测试中…...

WPF 手撸插件 八 操作数据库一

1、本文将使用SqlSugar创建Sqlite数据库&#xff0c;进行入门的增删改查等操作。擦&#xff0c;咋写着写着凌乱起来了。 SqlSugar官方文档&#xff1a;简单示例&#xff0c;1分钟入门 - SqlSugar 5x - .NET果糖网 2、环境SqlSugar V5.0版本需要.Net Framework 4.6 &#xff0…...

代数结构基础 - 离散数学系列(八)

目录 1. 群&#xff08;Group&#xff09; 群的定义 群的示例 2. 环&#xff08;Ring&#xff09; 环的定义 环的示例 3. 域&#xff08;Field&#xff09; 域的定义 域的示例 域在密码学中的应用 4. 实际应用场景 1. 对称性与加密 2. 误差检测与纠正 3. 数据编码…...

函数的arguments为什么不是数组?如何转化为数组?

因为arguments本身并不能调用数组方法&#xff0c;它是一个另外一种对象类型&#xff0c;只不过属性从0开始排&#xff0c;依次为0 1 2…最后还有callee和length属性&#xff0c;我们也把这样的对象成为类数组。 常见的类数组还有&#xff1a; 1.用getElementsByTagName/Class…...

Java之反射

目录 反射 定义 主要用途 反射相关的类 Class类中【获得类相关方法】 Class类中【获得类中属性相关的方法】 Class类中【获得类中注解相关的方法】 Class类中【获得类中构造器相关的方法】 Class类中【获得类中方法相关的方法】 获得Class对象 代码示例1 代码示例…...

3dsMax添加天空盒

点击渲染&#xff0c;环境 &#xff0c; 点击位图 找到要设置的天空HDR&#xff0c;可以使用HDR(EXR)贴图 一个可以下载HDR贴图的网站 https://polyhaven.com/hdris在渲染的时候不要使用使用微软输入法&#xff0c;3dsmax会卡死&#xff0c; 在渲染的时候不要使用使用微软…...

C语言的类型提升机制

概念 在C语言中&#xff0c;整数类型按照其大小可以分为以下几类&#xff08;从小到大&#xff09;&#xff1a; charshortintlonglong long 当在表达式中涉及这些类型的混合运算时&#xff0c;较小的类型会被提升为较大的类型。具体规则如下&#xff1a; ①char 和 short …...

Pandas和Seaborn数据可视化

Pandas数据可视化 学习目标 本章内容不需要理解和记忆&#xff0c;重在【查表】&#xff01; 知道数据可视化的重要性和必要性知道如何使用Matplotlib的常用图表API能够找到Seaborn的绘图API 1 Pandas数据可视化 一图胜千言&#xff0c;人是一个视觉敏感的动物&#xff0c;大…...

爬虫(Python版本)

1.爬虫的法律问题 爬虫技术&#xff08;Web Scraping&#xff09;指通过程序自动访问网页并提取其中的数据。在使用爬虫的过程中&#xff0c;涉及到一些法律法规和合规性问题。 常见法律风险 ①未经授权的访问&#xff1a;很多网站对爬虫行为设置了限制。如果未获得授权就进行…...

【分布式训练 debug】VS Code Debug 技巧:launch.json实用参数

VS Code Debug技巧&#xff1a;launch.json实用参数 在使用Visual Studio Code (VS Code)进行调试时&#xff0c;launch.json文件是一个强大的工具&#xff0c;它允许你自定义调试会话。以下是一些实用的参数&#xff0c;可以帮助你更有效地调试Python代码。 1. 调试第三方库…...

pycharm连接linux服务器需要提前安装ssh服务

在 Debian 或 Ubuntu 系统上&#xff0c;使用 APT&#xff1a; bash复制代码 sudo apt-get install openssh-server 在基于 RPM 的系统如 CentOS 或 RHEL 上&#xff0c;使用 YUM 或 DNF&#xff1a; bash复制代码 sudo yum install openssh-server 或对于较新的 RHEL/Cent…...

通信工程学习:什么是LAN局域网、MAN城域网、WAN广域网

LAN局域网、MAN城域网、WAN广域网 LAN&#xff08;Local Area Network&#xff0c;局域网&#xff09;、MAN&#xff08;Metropolitan Area Network&#xff0c;城域网&#xff09;和WAN&#xff08;Wide Area Network&#xff0c;广域网&#xff09;是计算机网络中根据覆盖范围…...

LeetCode热题100速通

一丶哈希 1、两数之和&#xff08;简单&#xff09; 给定一个整数数组 n u m s nums nums 和一个整数目标值 t a r g e t target target&#xff0c;请你在该数组中找出 和为目标值 t a r g e t target target 的那 两个 整数&#xff0c;并返回它们的数组下标。 你可以假设…...

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…...

Linux 文件类型,目录与路径,文件与目录管理

文件类型 后面的字符表示文件类型标志 普通文件&#xff1a;-&#xff08;纯文本文件&#xff0c;二进制文件&#xff0c;数据格式文件&#xff09; 如文本文件、图片、程序文件等。 目录文件&#xff1a;d&#xff08;directory&#xff09; 用来存放其他文件或子目录。 设备…...

C++中string流知识详解和示例

一、概览与类体系 C 提供三种基于内存字符串的流&#xff0c;定义在 <sstream> 中&#xff1a; std::istringstream&#xff1a;输入流&#xff0c;从已有字符串中读取并解析。std::ostringstream&#xff1a;输出流&#xff0c;向内部缓冲区写入内容&#xff0c;最终取…...

让AI看见世界:MCP协议与服务器的工作原理

让AI看见世界&#xff1a;MCP协议与服务器的工作原理 MCP&#xff08;Model Context Protocol&#xff09;是一种创新的通信协议&#xff0c;旨在让大型语言模型能够安全、高效地与外部资源进行交互。在AI技术快速发展的今天&#xff0c;MCP正成为连接AI与现实世界的重要桥梁。…...

【HarmonyOS 5 开发速记】如何获取用户信息(头像/昵称/手机号)

1.获取 authorizationCode&#xff1a; 2.利用 authorizationCode 获取 accessToken&#xff1a;文档中心 3.获取手机&#xff1a;文档中心 4.获取昵称头像&#xff1a;文档中心 首先创建 request 若要获取手机号&#xff0c;scope必填 phone&#xff0c;permissions 必填 …...

均衡后的SNRSINR

本文主要摘自参考文献中的前两篇&#xff0c;相关文献中经常会出现MIMO检测后的SINR不过一直没有找到相关数学推到过程&#xff0c;其中文献[1]中给出了相关原理在此仅做记录。 1. 系统模型 复信道模型 n t n_t nt​ 根发送天线&#xff0c; n r n_r nr​ 根接收天线的 MIMO 系…...

Java求职者面试指南:计算机基础与源码原理深度解析

Java求职者面试指南&#xff1a;计算机基础与源码原理深度解析 第一轮提问&#xff1a;基础概念问题 1. 请解释什么是进程和线程的区别&#xff1f; 面试官&#xff1a;进程是程序的一次执行过程&#xff0c;是系统进行资源分配和调度的基本单位&#xff1b;而线程是进程中的…...

C++课设:简易日历程序(支持传统节假日 + 二十四节气 + 个人纪念日管理)

名人说:路漫漫其修远兮,吾将上下而求索。—— 屈原《离骚》 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 专栏介绍:《编程项目实战》 目录 一、为什么要开发一个日历程序?1. 深入理解时间算法2. 练习面向对象设计3. 学习数据结构应用二、核心算法深度解析…...

三分算法与DeepSeek辅助证明是单峰函数

前置 单峰函数有唯一的最大值&#xff0c;最大值左侧的数值严格单调递增&#xff0c;最大值右侧的数值严格单调递减。 单谷函数有唯一的最小值&#xff0c;最小值左侧的数值严格单调递减&#xff0c;最小值右侧的数值严格单调递增。 三分的本质 三分和二分一样都是通过不断缩…...

日常一水C

多态 言简意赅&#xff1a;就是一个对象面对同一事件时做出的不同反应 而之前的继承中说过&#xff0c;当子类和父类的函数名相同时&#xff0c;会隐藏父类的同名函数转而调用子类的同名函数&#xff0c;如果要调用父类的同名函数&#xff0c;那么就需要对父类进行引用&#…...