Unique Values 满足条件的区间数(双指针)

文章讨论了一种使用双指针技术来解决寻找和为K的无重复元素子矩阵数量的问题。通过遍历数组,更新最近出现元素的位置并计算区间数,最后得出结果。文章提到了两种不同的实现思路,虽然第二个例子在求区间数量上的方法有误,但都展示了双指针在处理这类问题中的应用。
摘要由CSDN通过智能技术生成

感觉双指针的主要思想就是就是摒弃显然已经被排除的一段

统计和为 k k k的子矩阵,枚举区间右端点 r r r,当 [ l , r ] [l,r] [l,r]子段和超过 k , l k,l kl右移
因为显然[l,r]不能包含在满足要求的矩阵中(太大了),要缩小,摒弃掉l列以左的所有
双指针分别是区间左右端点 [ l , r ] [l,r] [l,r],区间数 r e s + = ( r − l + 1 ) res+=(r-l+1) res+=(rl+1)

Unique Values(序列S中不含重复元素的连续子序列的数量)

这里要求是区间中不含重复元素,当出现重复元素(此时出现在下标i,上一次 m p [ a [ i ] ] ) mp[a[i]]) mp[a[i]])
要摒弃掉mp[a[i]]以左的元素,有个注意点,

  • 1、双指针分别是 l a s t 和 r last和r lastr l a s t last last是上一段满足条件的区间段的最后一个元素,
    l a s t last last以左(包含 l a s t last last)已经被摒弃掉了,如果根据 m p mp mp判断出序列中之前有重复元素,
    要先判断该元素出现的上一个位置 m p [ a [ i ] ] mp[a[i]] mp[a[i]]是否在 l a s t last last之前,即已经被摒弃掉了
    如果已经被摒弃掉了就不需要考虑,否则才要摒弃掉 m p [ a [ i ] ] mp[a[i]] mp[a[i]]及以左所有
  • 2、其次区间数 r e s + = ( r − l a s t ) res+=(r-last) res+=(rlast)
#include<bits/stdc++.h>
using namespace std;
#define int long long int
map<int,int>mp;
const int N=1e5+10;
int n;
int a[N];
signed main(){
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>a[i];
	}
	int res=0;// 1 2 3 4
	int last=0;
	for(int i=1;i<=n;i++){
		if(mp[a[i]]){	
			if(mp[a[i]]>last)last=mp[a[i]];
			//2 12 3  12 3 2 6 9  遍历到最后一个2,last=第一个3
		}
		res+=(i-last);//last是上一段满足条件的区间段的最后一个元素
		mp[a[i]]=i;
	}	
	cout<<res;
    return 0;
}

以下思路是对的,但是求(last,r]这段的子区间数量 方式不对,也不知道为啥不对,给的两个样例也都通过了
不过双指针求区间数量的常见做法都是 每次遍历(一个端点,左指针或右指针)时,利用左右指针相减

#include<bits/stdc++.h>
using namespace std;
#define int long long int
map<int,int>mp;
const int N=1e5+10;
int n;
int a[N];
signed main(){
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>a[i];
	}
	int len=0;
	int res=n;
	int last=0;
	for(int i=1;i<=n;i++){
		if(mp[a[i]]==0||mp[a[i]]<last){
			len++;
			mp[a[i]]=i;
		}
		else{
			
			len=i-mp[a[i]];// 1 2 3 4
			res+=(1+len)*len/2-len;
			last=mp[a[i]];
			mp[a[i]]=i;
		}
	}
	res+=(1+len)*len/2-len;
	cout<<res;
    return 0;
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值