[算法每日一练]-双指针 (保姆级教程篇 1) #A-B数对 #求和 #元音字母 #最短连续子数组 #无重复字符的最长子串 #最小子串覆盖 #方块桶

news2024/11/28 4:29:29

目录

A-B数对

解法一:双指针 

解法二:STL二分查找

解法三:map

求和

元音字母

最短连续子数组

无重复字符的最长子串

最小子串覆盖

方块桶


        

双指针特点:双指针绝不回头

        

        

A-B数对

        

解法一:双指针 

 先把数列排列成递增的就可以使用双指针了。找到满足a[r]-a[l]=c即可

 对每个l找对应的两个r,一个是满足条件且在最左边的,一个是满足条件且在最右边的

 如果刚好可以取等,那么右减左就是该情况下的答案,否则右减左就是0

#include <bits/stdc++.h>            
#define ll long long      
using namespace std;       
const int N = 2e5 + 10;
int n , c;
int a[N];
int main () 
{
	cin >> n >> c;
	for(int i = 1 ; i <= n ; i ++) cin >> a[i];
	sort(a + 1 , a + 1 + n);      //首先就必须要排序
	int l = 1, r1 = 1 , r2 = 1;
	ll ans = 0;
	for(l = 1 ; l <= n ; l ++) {
		while(r1 <= n && a[r1] - a[l] <= c) r1 ++;//对每一个数A找右边刚不满足A-B=C的数下标
		while(r2 <= n && a[r2] - a[l] < c ) r2 ++;//再找左边刚满足A-B=C的数下标
			ans += r1 - r2;
	}
	cout << ans;
	return 0;
}

解法二:STL二分查找

在有序数组找某个数不用stl用什么?

#include <bits/stdc++.h>
using namespace std;
int N, C, A[200010];

int main() {
	scanf( "%d%d", &N, &C );
	for( int i = 1; i <= N; ++i ) scanf( "%d", &A[ i ] );
	sort( A + 1, A + N + 1 );
	long long ans = 0;
	for( int i = 1; i <= N; ++i ) 
		ans += upper_bound( A + 1, A + N + 1, A[ i ] - C ) - 
			lower_bound( A + 1, A + N + 1, A[ i ] - C );
	printf( "%lld\n", ans );
	return 0;
}

解法三:map

既然要同一个值得数量,那么就拿数值存下标,说错了。这样会爆掉的,直接上map进行离散化数组就行了,什么意思?就是你别拿一个连续的玩意去存,你拿一个离散的东西去存就行了。

#include <iostream>             //A-B数对P1102   (map映射法)   (有点耗时)
#include <unordered_map>                  //A-B=C --> A-C=B
using namespace std;
typedef long long LL;
LL a[200001];
unordered_map<LL,LL> m;       //建立一个数字到出现次数的映射 map<num,times>
int main() {
    int n; LL c;LL ans=0;
    cin >> n >> c;    
    for(int i=1;i<=n;i++) {
        cin >> a[i];    
        m[a[i]]++;     //标记每个数字和对应的映射
        a[i]-=c;       //把first减c,找更新后映射的数量
    } 
    for(int i=1;i<=n;i++) ans+=m[a[i]];
    cout << ans << endl;
    return 0;
}

        

         

求和

求满足和为x所有的自然数区间,如果没有输出No

        

思路:

对每个l开头的区间尝试求解。

双指针移动时:[l,r]恰好为x就说明[l,r+1]和[l+1,r]没用了,所以整体右移l++,r++

[l,r]<x就r右移,[l,r]>x就l右移(这次的l已经没用了)

然后就是注意一下结束条件l<=x/2

#include <bits/stdc++.h>
using namespace std;
int main(){
	int x,l=1,r=2,sum=0;
	cin>>x;int f=0;
	while(l<=x/2){ //这个结束条件很有意思:l<=x/2就没必要再找了
		sum=(l+r)*(r-l+1)/2;
		if(sum==x){
			f=1;
			cout<<l<<" "<<r<<'\n';
			l++;r++;
		}
		else if(sum<x)r++;
		else l++;
	}
	if(!f)cout<<"No";
}

        

        

元音字母

给一个字符串s和整数k,求s的长度为k的子串可能包含的最大元音字母个数

输入                             输出:3
abciiidef

        

思路:

[l,r]一定是整体移动的,所以只需要观察l和r+1情况即可,如果都是或都不是,cnt不变直接不管;剩下的就是cnt++和cnt--了

#include <bits/stdc++.h>
using namespace std;
int check(char ch){
	if(ch=='a'||ch=='e'||ch=='i'||ch=='o'||ch=='u')return true;
	return false;
}
int main(){
	string s;int k;
	cin>>s>>k;
	int l=0,r=k-1,ans=0,cnt=0,len=s.size();
	for(int i=0;i<k;i++){
		if(check(s[i]))cnt++;//初始化
	}
	ans=cnt;
	while(r<len){//整体移动一次就判断一次
		if(!check(s[l])&&check(s[r+1]))cnt++;
		if(check(s[l])&&!check(s[r+1]))cnt--;
		l++;r++;
		ans=max(ans,cnt);
	}
	cout<<ans;
}

        

        

最短连续子数组

给一个含有n个非负数的数组和一个正整数m。找出该数组中满足和不小于m的长度最小的连续子数组,并返回其长度,否则返回0

输入                 输出:2
6 7
2 3 1 2 4 3

        

思路:

 在移动过程中[l,r]如果满足条件的话,一定要l++来取最小长度,否则就r++即可。

(一直都是r在默默前行,l只需要统计结果即可)

#include <bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int n,m,a[N],ans=0x3f3f3f3f;

int main(){
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		cin>>a[i];
	}
	int sum=0;
	for(int l=0,r=0;r<=n;r++){
		sum+=a[r];
		while(sum>=m){
			ans=min(ans,r-l+1);
			sum-=a[l];
			l++;
		}
	}
	cout<<(ans==0x3f3f3f3f ? 0 : ans);
}

        

        

无重复字符的最长子串

给一个字符串s,找出其中不含有重复字符的最长字串的长度。
abcabcbb

        

思路:

 首先使用map<char,int>来统计每个字符出现次数,一遍统计一遍检查是否有重复字符。

如果有,对于[l,r]就l++,直到没有再r++


#include <bits/stdc++.h>
using namespace std;
unordered_map<char,int>ma1;
string s;
int ans=0;
int main(){
	getline(cin,s);
	int len1=s.size();
	for(int l=0,r=0;r<len1;r++){
		ma1[s[r]]++;
		while(ma1[s[r]]==2){
			ma1[s[l]]--;l++;
		}
		ans=max(ans,r-l+1);
	}
	cout<<ans;
}

        

        

最小子串覆盖

给两个字符串s,t,求s中最短的包含t每一个字符的子串,若不存在就返回No
输入

ADOBECODEANXBC                输出ANXBC
BANC

        

思路:

不是找子序列啊,注意看样例。

首先要统计t字符串的字符情况,然后在对s字符串使用双指针时候,也要统计区间中的字符情况,同时记录和t字符串的字符满足个数:对应字符数量相等。

当[l,r]中已经满足条件时候,就l++取找答案,同时对应的字符数量减一,直到不满足再r++。

        

#include <bits/stdc++.h>
using namespace std;
unordered_map<char,int>ma1,ma2;
string s,t;
int ans=0x3f3f3f3f;
int main(){
	cin>>s>>t;
	int len1=s.size(),len2=t.size();
	for(int i=0;i<len2;i++)
		ma2[t[i]]++;
	int sum=0;//sum表示满足的个数
	int l=0,r=0,ll=0,rr=0;
	while(r<len1){
		ma1[s[r]]++;
		if(ma2[s[r]]!=0&&ma1[s[r]]<=ma2[s[r]])//是t的字符,且s的数量不多余
			sum++;
		if(sum==len2){
			while(ma1[s[l]]>ma2[s[l]]){//从左开始删掉多余的,l++一次删掉一次
				ma1[s[l]]--;l++;
			}
			if(r-l+1<ans){
				ans=r-l+1;
				ll=l;rr=r;//ll和rr是上次答案对应的左右指针
			}
		}
		r++;
	}	
	if(ans==0x3f3f3f3f) cout<<"No";
	else
		cout<<s.substr(ll,rr-ll+1);
}

        

        

方块桶

给n个非负整数表示连续n个竖直放置的方块,计算这样的方块可以装多少水?
12
0 1 0 2 1 0 1 3 2 1 2 1

        

思路:

其实在模拟的时候发现左边这个高度下是否可以填水取决于右边的最大高度,右边更高,那么一定可以填水,右边同理。然后两条同时开始统计就行了

#include <bits/stdc++.h>
using namespace std;
const int N=1e6+10;
int n,a[N],maxl,maxr,ans;
int main(){
	cin>>n;
	for(int i=1;i<=n;i++)cin>>a[i];
	maxl=a[1],maxr=a[n];
	int l=1,r=n;
	while(l<r){
		if(maxl<=maxr){
			l++;
			maxl=max(maxl,a[l]);
			ans+=maxl-a[l];
		}
		else{
			r--;
			maxr=max(maxr,a[r]);
			ans+=maxr-a[r];
		}
	}
	cout<<ans;
}

        

        

         

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

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

相关文章

GDPU 数据结构 课后作业(持续更新……)

文章目录 第 1 章第 2 章&#x1f437; 作业1&#x1f437; 作业2 第 3 章&#x1f437; 作业1&#x1f437; 作业2 第 4 章第 5、6 章二叉树&#x1f437; 作业1 第 7 章 哈夫曼树第 8 章 图&#x1f437; 图 1&#x1f437; 图 2&#x1f437; 图 3 第9 章 排序 第 1 章 第 2…

STM32F103

提示&#xff1a;来源正点原子&#xff0c;参考STM32F103 战舰开发指南V1.3PDF资料 文章目录 前言一、pandas是什么&#xff1f;二、使用步骤 1.引入库2.读入数据总结 前言 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1a; 开发环境硬件普中科技&#xff0c;接…

javaSwing酒店管理系统

一、 使用方法&#xff1a; 在使用前&#xff0c;需要到druid.properties 配置文件中&#xff0c;修改自己对应于自己数据库的属性&#xff1b;如用户名&#xff0c;密码等 driverClassNamecom.mysql.cj.jdbc.Driver urljdbc:mysql:///hotel?useUnicodetrue&characterEn…

【C++】:AVL树

朋友们、伙计们&#xff0c;我们又见面了&#xff0c;本期来给大家解读一下有关多态的知识点&#xff0c;如果看完之后对你有一定的启发&#xff0c;那么请留下你的三连&#xff0c;祝大家心想事成&#xff01; C 语 言 专 栏&#xff1a;C语言&#xff1a;从入门到精通 数据结…

C语言 内联函数 + 递归函数

函数分类 内联函数 1&#xff09;内联函数在编译时将函数的代码直接插入到调用它的地方&#xff0c;而不是通过函数调用的方式执行&#xff0c;从而减少了函数调用的开销&#xff0c;提高了代码的执行速度 2&#xff09;使用 inline 关键字来声明 3&#xff09;将函数声明为内联…

深入理解Dubbo-4.Dubbo扩展SPI

&#x1f44f;作者简介&#xff1a;大家好&#xff0c;我是爱吃芝士的土豆倪&#xff0c;24届校招生Java选手&#xff0c;很高兴认识大家&#x1f4d5;系列专栏&#xff1a;Spring源码、JUC源码、Kafka原理、分布式技术原理&#x1f525;如果感觉博主的文章还不错的话&#xff…

Redis探秘:AOF日志与数据持久性之旅

第1章&#xff1a;引言 大家好&#xff0c;我是小黑&#xff0c;咱们今天来聊聊Redis。你知道吗&#xff0c;Redis作为一个超高效的内存数据库&#xff0c;真的是超级给力。它可以秒速处理数据&#xff0c;让咱们的应用运行得飞快。但是&#xff0c;小黑得告诉你&#xff0c;虽…

四. 基于环视Camera的BEV感知算法-BEVFormer

目标 前言0. 简述1. 算法动机&开创性思路2. 主体结构3. 损失函数4. 性能对比5. BEVFormerv2总结下载链接参考 前言 自动驾驶之心推出的《国内首个BVE感知全栈系列学习教程》&#xff0c;链接。记录下个人学习笔记&#xff0c;仅供自己参考 本次课程我们来学习下课程第四章—…

nginx多ip部署

1.修改网卡信息自定义多个IP 进入/etc/sysconfig/network-scripts&#xff0c;编辑ifcfg-ens33网卡文件。将dhcp动态分配修改成static&#xff0c;同时添加ip地址子网掩码、网关和DNS。 修改完成后重启网卡&#xff0c;systemctl restart network 2.修改nginx配置文件 有几个…

【数据结构实践课设】新生报道注册管理信息系统

目录 1.主要框架 2.写入文件 3.读取文件 4.注册学生信息 5.增加学生信息 6.删除学生信息 7.按姓名查询 8.按班级查询 9.按专业查询 10.打印学生信息 11.完整代码 &#x1f308;嗨&#xff01;我是Filotimo__&#x1f308;。很高兴与大家相识&#xff0c;希望我的博客能对你有所…

【S32K3环境搭建】-0.4-使用SEGGER J-Link烧录调试程序

【S32K3_MCAL从入门到精通】合集&#xff1a; S32K3_MCAL从入门到精通https://blog.csdn.net/qfmzhu/category_12519033.html 导入一个编译没有报错的S32K312工程。接着在菜单栏中&#xff0c;依次选择Debug下拉箭头 -- > Debug Configuration&#xff1b; 在弹出的Create…

FL Studio 21注册机激活码序列号下载 附激活码

FL Studio 21 keygen激活码序列号是一款基于同名软件激活程序。操作非常简单。用户只需使用本激活工具生成激活码&#xff0c;即可一键激活软件所有功能&#xff0c;无需付费。去购买注册程序&#xff0c;永久免费使用所有功能。很多用户应该都知道&#xff0c;专业的编辑工具只…

SpringCloud-高级篇(六)

&#xff08;1&#xff09;Seata架构 &#xff08;2&#xff09;部署TC服务 修改注册中心&#xff1a;做服务注册&#xff0c;tc服务配置注册中心&#xff0c;tc服务可以做集群&#xff0c;他也是一个服务 &#xff0c;微服务里面RM 跟TM跟它建立联系肯定是基于注册中心去找&a…

using dapers on diffusers: Dreambooth, Texual Inversion, LoRA and IP-Adapter

using dapers on diffusers: Dreambooth, Texual Inversion, LoRA and IP-Adapter 参考自&#xff1a;https://huggingface.co/docs/diffusers/using-diffusers/loading_adapters 如今&#xff0c;对于 diffusion 模型&#xff0c;有许多高效的训练技术来微调一个定制化的模型&…

gittee使用教学

一、git简介 Git是一个开源的分布式版本控制系统&#xff0c;用于敏捷高效的处理任何大小项目的版本管理。 核心功能&#xff1a; 项目的版本管理 团队协同开发 二、准备工作 1、下载 Git 2、除了选择安装位置以外&#xff0c;其他都无脑安装 3、检查一下安装情况 win…

Android系统中使用Cunit测试C/C++接口

Android系统中使用Cunit测试C/C接口 Cunit是C/C语言的单元测试框架&#xff0c;但常用于Windows和Linux开发中。 Android系统中经常有jni、so库、hal service等都是C/C实现&#xff0c;本文讲解如何将Cunit嵌入Android中&#xff0c;用于测试一些C/C api。 Cunit简介 Cunit是很…

Post Quantum Fuzzy Stealth Signatures and Applications

目录 笔记后续的研究方向摘要引言贡献模块化框架模糊构造实施适用于FIDO Post Quantum Fuzzy Stealth Signatures and Applications CCS 2023 笔记 后续的研究方向 摘要 自比特币问世以来&#xff0c;基于区块链的加密货币中的私人支付一直是学术和工业研究的主题。隐形地址…

Java 何时会触发一个类的初始化

Java 何时会触发一个类的初始化&#xff1f; 使用new关键字创建对象访问类的静态成员变量 或 对类的静态成员变量进行赋值调用类的静态方法反射调用类时&#xff0c;如 Class.forName()初始化子类时&#xff0c;会先初始化其父类&#xff08;如果父类还没有进行过初始化的话&a…

动态规划_最小花费爬楼

//给你一个整数数组 cost &#xff0c;其中 cost[i] 是从楼梯第 i 个台阶向上爬需要支付的费用。一旦你支付此费用&#xff0c;即可选择向上爬一个或者两个台阶。 // // 你可以选择从下标为 0 或下标为 1 的台阶开始爬楼梯。 // // 请你计算并返回达到楼梯顶部的最低花费。 …

小模型学习(1)-人脸识别

【写作背景】因为最近一直在研究大模型&#xff0c;在与客户进行交流时&#xff0c;如果要将大模型的变革性能力讲清楚&#xff0c;就一定要能将AI小模型的一些原理和效果讲清楚&#xff0c;进而形成对比。当然这不是一件简单的事情&#xff0c;一方面大模型分析问题的的本质原…