「2.1」收集雪花

 

「2.1」收集雪花

题目描述

不同的雪花往往有不同的形状。在北方的同学想将雪花收集起来,作为礼物送给在南方的同学们。一共有 n 个时刻,给出每个时刻下落雪花的形状,用不同的整数表示不同的形状。在收集的过程中,同学们不希望有重复的雪花。你可以从任意 a 时刻开始,在 b 时刻停止。a 到 b 时刻中间的雪花也都将被收集。他们希望收集的雪花最多。

输入格式

第一行一个正整数 n;

第 2 行 n 个非负整数表示 n 个时刻雪花的形状。

输出格式

最多能收集雪花的数量。

样例输入1

5
1 2 3 2 1

样例输出1

3

注释说明

注:使用读优化!!!

对于 97 分的数据,1≤n≤10^6,0≤xi≤10^8。(为原始数据)
应用户要求,加入 3 分的数据,1≤n≤10^6,0≤xi≤10^9。

#include<bits/stdc++.h>
using namespace std;
int n,a[1000003],last[1000005],ans=1,b[1000005];
map<int,int>mp;
int main() {
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
		scanf("%d",&a[i]);
		b[i]=a[i];
	}
	sort(b+1,b+1+n);
    int tot=unique(b+1,b+n+1)-b-1;
    for(int i=1;i<=tot;i++){
    	mp[b[i]]=i;
	}
	for(int i=1,j=1;i<=n;i++){
		int laai=last[mp[a[i]]];
	//	printf("%d\n",laai);
		if(laai>=j){
			j=laai+1;
		}
		last[mp[a[i]]]=i;
		ans=max(ans,i-j+1);
	}
	printf("%d\n",ans);
}
/*
8
2 8 2 4 5 1 2 4
*/

<think>好的,用户现在问的是关于“1464:收集雪花”的问题。首先,我需要确定这个题目的具体内容,因为用户可能直接用了题号而没有给出详细描述。考虑到之前的对话,用户之前询问过“1463:门票”,当时我假设了一个动态规划的问题。现在用户继续问下一个题号1464,可能是同一平台或同一竞赛中的题目,比如来自某个在线判题系统。 接下来,我需要回忆或查找这个题号对应的题目内容。假设题目“1464:收集雪花”是类似收集雪花的问题,可能涉及滑动窗口或双指针算法,因为这类题目常见于处理子数组或子序列中的唯一元素问题。例如,力扣上的“无重复字符的最长子串”问题,或者类似的问题变种,可能需要找到最长的连续不重复子数组的长度,或是计算所有可能的子数组数量等。 首先,我需要确认问题的大致描述。假设题目要求:给定一个数组,每个元素代表一片雪花的类型,需要找到所有连续子序列中不重复雪花的最大长度,或者计算这样的子序列的数量。另一种可能是,每片雪花有一个唯一的编号,收集雪花时不能重复,求最多能收集多少片,即最长无重复子数组的长度。 接下来,考虑解题方法。通常,这类问题使用滑动窗口(双指针)技术,维护一个窗口,右指针扩展,左指针在遇到重复时调整,以保持窗口内的元素唯一。同时,需要一个哈希表或数组来记录每个元素最后出现的位置,以便快速判断是否重复。 然后,我需要构建解题步骤。例如: 1. 初始化左指针和右指针,都从0开始。 2. 使用一个哈希表记录当前窗口内元素的最新索引。 3. 右指针逐步右移,如果当前元素在哈希表中存在且索引大于等于左指针,则移动左指针到重复元素的下一个位置。 4. 更新最大窗口长度。 5. 直到右指针遍历完整个数组。 同时,需要考虑时间复杂度和空间复杂度。滑动窗口方法通常是O(n)的时间复杂度,空间复杂度取决于元素种类,使用哈希表的话是O(n)。 另外,需要处理可能的边界情况,例如数组为空、所有元素都相同、所有元素都不同等情况。 用户可能希望得到详细的步骤解释,包括如何初始化变量、如何移动指针、如何更新结果等。此外,可能需要给出示例代码,比如Python的实现,并解释关键部分。 可能还需要比较不同的解法,例如暴力法(O(n^2))和滑动窗口法的优劣,说明为什么滑动窗口更高效。 另外,用户可能没有给出具体的问题描述,因此需要基于常见的类似题目进行假设,并建议用户提供更详细的信息以获得更准确的解答。例如,题目可能有不同的约束条件或变种,比如允许最多k次重复,或者需要统计所有满足条件的子数组数量,而不是仅找最长的一个。 最后,需要确保回答结构清晰,分步骤说明,代码正确,并符合之前用户要求的格式,如使用中文、LaTeX公式正确等。</think>--- ### **问题假设与解析** 假设题目为:给定一个长度为 `n` 的数组 `snow`,每个元素代表雪花的唯一编号。需要找到 **最长的连续子序列**,使得子序列中的雪花编号 **不重复**。求该子序列的最大长度。 **输入示例** ``` 5 1 2 3 2 1 ``` **输出示例** ``` 3 ``` **解释**:最长无重复子序列为 `[1,2,3]` 或 `[3,2,1]`,长度为3。 --- ### **算法选择:滑动窗口(双指针)** 核心思想:维护一个窗口 `[left, right]`,通过右指针扩展窗口,左指针在遇到重复时调整窗口,保持窗口内元素唯一。 --- ### **分步解析** #### **步骤1:初始化变量** - `left = 0`:窗口左边界。 - `max_len = 0`:记录最大长度。 - `last_seen = {}`:哈希表,记录每个雪花编号最后出现的位置。 #### **步骤2:遍历右指针** 对每个右指针 `right`(从0到n-1): 1. 若当前雪花 `snow[right]` 已在 `last_seen` 中且其位置 `>= left`,说明重复,需移动左指针到 `last_seen[snow[right]] + 1`。 2. 更新 `last_seen[snow[right]] = right`。 3. 计算当前窗口长度 `right - left + 1`,更新 `max_len`。 #### **步骤3:复杂度分析** - 时间复杂度:$O(n)$,每个元素被访问一次。 - 空间复杂度:$O(k)$,`k` 为雪花编号种类数。 --- ### **示例代码(Python)** ```python n = int(input()) snow = list(map(int, input().split())) last_seen = {} max_len = left = 0 for right in range(n): current = snow[right] if current in last_seen and last_seen[current] >= left: left = last_seen[current] + 1 # 移动左指针跳过重复位置 last_seen[current] = right # 记录当前元素最新位置 max_len = max(max_len, right - left + 1) print(max_len) ``` --- ### **关键点解释** 1. **哈希表记录位置**:快速判断重复并定位到冲突位置。 2. **左指针跳跃移动**:避免逐个移动左指针,直接跳过重复区间的左端。 3. **实时更新最大值**:每次右指针移动后都计算窗口长度。 --- ### **扩展讨论** 1. **统计所有无重复子序列的数量**:需结合动态规划或组合数学。 2. **允许最多重复k次**:修改条件为记录出现次数而非唯一性。 3. **空间优化**:若雪花编号范围已知(如ASCII字符),可用数组代替哈希表。 --- 若题目有其他具体约束,请提供完整描述以进一步优化解答!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值