首页 > 其他分享 >窗口判断子数组排列

窗口判断子数组排列

时间:2024-06-03 20:57:51浏览次数:15  
标签:cnt 排列 窗口 leq 数组 长度

题目

给定一个数组,试求有多少个长度为\(k\)的连续子数组是排列。
https://ac.nowcoder.com/acm/problem/273933

Input

第一行输入两个正整数\(n\),\(k\),代表小红拿到的数组大小和连续子数组的大小。
第二行输入\(n\)个正整数\(a_i\),代表数组中的元素
其中\(1 \leq k \leq n \leq 10^5\),\(1 \leq a_i \leq 10^5\)

5 2
1 2 1 1 2

Output

一个整数,代表长度为\(k\)的连续子数组是排列的数量

3

说明
有\(3\)个长度为\(2\)的连续子数组是排列:两个\([1,2]\)和一个\([2,1]\)。

题解

解题思路

此题核心思想为用窗口分割数组,并实现线性时间复杂度遍历。
在操作某一个窗口的时候,根据排列的定义,当\(map[a[i]]==1\)时,可将某一个窗口的第\(i\)个位置标记为合法,\(cnt++\),若\(cnt==k\)则表示一个合法排序,\(ans++\)。
注意,在窗口移动的时候,需要处理\(a[i-k]\),即原窗口的第一个数。
注意,在开始遍历之前,需要先对第一个长度为\(k\)的窗口进行判断。

Code

#include<bits/stdc++.h>
#define IOS ios::sync_with_stdio(false); cin.tie(nullptr);
using namespace std;
typedef long long LL;

signed main(){
	IOS;
	int n,k;cin>>n>>k;
    vector<int> a(n+1);
    for(int i=1;i<=n;i++) cin>>a[i];
    map<int,int> mp;
    LL ans=0,cnt=0;
    //判断第一个长度为k的子串是否为排列
    for(int i=1;i<=k;i++){
        mp[a[i]]++;
        if(a[i]>=1 and a[i]<=k and mp[a[i]]==1) cnt++;
    }
    if(cnt==k) ans++;
    //利用长度为k的窗口开始枚举
    for(int i=k+1;i<=n;i++){
        mp[a[i]]++;
        if(a[i]>=1 and a[i]<=k and mp[a[i]]==1) cnt++;
        if(a[i-k]>=1 and a[i]<=k and mp[a[i-k]]==1) cnt--;
        mp[a[i-k]]--;
        if(cnt==k) ans++;
    }
    cout<<ans<<endl;
	return 0;
}

标签:cnt,排列,窗口,leq,数组,长度
From: https://www.cnblogs.com/TaopiTTT/p/18229612

相关文章

  • GCD构造排列
    题目给定一个长度为n的数组\(a\),试复原长度为n的排列\(p\)其中\(a_i=gcd(p_1,p_2,...,p_i)\),也就是说,\(a_i\)表示排列\(p\)中前\(i\)个数字的最大公约数。(由于数组\(a\)可能是错误的,故有可能无解,此时输出\(-1\)即可)https://ac.nowcoder.com/acm/problem/269091Input输......
  • 1134高精度阶乘(数组)
    #include<stdio.h>#defineN3000//定义数组长度intmain(){inta[N],i,j,k,n;while(scanf("%d",&n)!=EOF){ for(i=0;i<N;i++)//初始化数组 a[i]=0; a[0]=1;//第一位设为1 k=0;//记录进位坐标 for(i=1;i<=n;i++)//计算阶乘......
  • Android14 WMS-窗口添加流程(二)-Server端
    Android14WMS-窗口添加流程(一)-Client端-CSDN博客本文接着上文"Android14WMS-窗口添加流程(一)-Client端"往下讲。也就是WindowManagerService#addWindow流程。目录一.WindowManagerService#addWindow标志1:mPolicy.checkAddPermission标志2:getDisplayContentOrCreate......
  • 二维数组的旋转遍历:顺时针、逆时针和对角线旋转
    在面试中,常常会遇到数组的各类旋转问题,例如以顺时针、逆时针或对角线的方式遍历二维数组。这类问题并不涉及算法,只是逻辑有点复杂,一个不小心就会导致访问越界,考验的是编程的基本功。如何优雅地解决此类问题呢?1.顺时针旋转[LeetCode54.螺旋矩阵]给你一个m行n列的矩阵 ma......
  • 数组
    今天数组所需要的导包:java.util.Arrays(用于操作数组的各种方法的实用类)常用类方法包括:sort():对数组进行排序。binarySearch():对排序好的数组进行二分查找。equals():比较两个数组是否相等。fill():用指定的值填充数组的所有元素。toString():将数组转换为字符串形式,便于输出或......
  • 滑动窗口最大值
    给你一个整数数组nums,有一个大小为k的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的k个数字。滑动窗口每次只向右移动一位。返回滑动窗口中的最大值。示例1:输入:nums=[1,3,-1,-3,5,3,6,7],k=3输出:[3,3,5,5,6,7]解释:滑动窗口的位置......
  • 数据转换-整数字节数组
    数据转换-整数字节数组一、任务详情在openEuler(推荐)或Ubuntu或Windows(不推荐)中完成下面任务,使用git管理代码,gitcommit不能少于5次1参考《GMT0009-2012SM2密码算法使用规范》第6节“数据转换”在utils.h和utils.c中完成整数与8位字节串的转换功能(10'):intInt2ByteArr......
  • Go 语言学习笔记之数组与切片
    大家好,我是码农先森。数组与切片的区别在Go语言中,数组和切片是两种不同的数据结构,它们之间有以下主要区别。参数长度:数组(Array):数组的长度是固定的,在创建时就需要指定数组的长度,无法动态改变;只有长度信息,通过len()函数获取。切片(Slice):切片是对数组的一个引用,底层使用的是......
  • 数据转换-整数字节数组
    1.c#include<stdio.h>#include<string.h>#include"utils.h"//20211102intmain(){ intp; charbytearr[100]; printf("请输入一个整型数字\n"); scanf("%d",&p); printf("把整型数转化为字节数组\n"); Int2ByteArr(p,byt......
  • 数据转换-整数字节数组
    任务详情在openEuler(推荐)或Ubuntu或Windows(不推荐)中完成下面任务,使用git管理代码,gitcommit不能少于5次1参考《GMT0009-2012SM2密码算法使用规范》第6节“数据转换”在utils.h和utils.c中完成整数与8位字节串的转换功能(10'):intInt2ByteArr(unsignedinti,unsigned......