AcWing 799. 最长连续不重复子序列(双指针算法)

本文介绍了一种解决最长无重复数字连续子序列问题的高效算法。通过使用哈希映射,该算法能在O(n)时间内找到给定整数序列中最长的不包含重复数字的连续子序列,并输出其长度。

给定一个长度为n的整数序列,请找出最长的不包含重复数字的连续区间,输出它的长度。

输入格式

第一行包含整数n。

第二行包含n个整数(均在0~100000范围内),表示整数序列。

输出格式

共一行,包含一个整数,表示最长的不包含重复数字的连续子序列的长度。

数据范围

1≤n≤1000001≤n≤100000

输入样例:

5
1 2 2 3 5

输出样例:

3
import java.io.*;
import java.lang.*;
import java.util.*;
class Main{
    
    public static void main(String[] args)throws Exception{
        BufferedReader buf = new BufferedReader(new InputStreamReader(System.in));
        int n = Integer.valueOf(buf.readLine());
        String[] strNums = buf.readLine().split(" ");
        int[] nums = new int[n];
        for(int i = 0; i < n; ++i){
            nums[i] = Integer.valueOf(strNums[i]);
        }
        HashMap<Integer, Integer>map = new HashMap<>();
        int max = 0;
        for(int i = 0, j = 0; i < n; ++i){
            map.put(nums[i], map.getOrDefault(nums[i], 0) + 1);
            while (j < i && map.get(nums[i]) > 1){
                map.put(nums[j], map.get(nums[j]) - 1);
                j++;
            }
            max = Math.max(max, i - j + 1);
        }
        System.out.print(max);
    }
}

 

### 使用双指针算法实现最长连续重复子序列 为了找到最长连续重复子序列,可以采用双指针(也称为滑动窗口)的方法来优化效率。这种方法通过两个指针`left`和`right`定义一个动态变化的窗口,在遍历过程中调整窗口大小并记录最大长度。 下面是一个具体的 C++ 示例代码: ```cpp class Solution { public: int lengthOfLongestSubstring(string s) { unordered_map<char, int> window; int left = 0, right = 0; int maxLength = 0; while (right < s.size()) { char c = s[right]; ++window[c]; // 将新字符加入窗口 // 如果存在重复,则移动左边界直到没有重复为止 while (window[c] > 1) { char d = s[left]; --window[d]; ++left; } // 更新最大长度 maxLength = max(maxLength, right - left + 1); ++right; // 扩展右边界 } return maxLength; } }; ``` 在这个例子中,使用了一个哈希表 `unordered_map<char, int>` 来跟踪当前窗口内的字符频率。当遇到重复字符时,会收缩左侧边界的范围直至消除重复项,从而保持窗口内所有字符唯一性的同时寻找可能的最大长度[^2]。 #### 关键点解释 - **窗口扩展**:每次循环都将右侧指针向右移一位,并把对应的字符计入窗口。 - **处理重复**:一旦发现某个字符的数量超过一次,就逐步增加左侧指针的位置,减少该字符计数,直到再有重复。 - **更新结果**:每当成功构建一个新的含重复字符的子串时,都会尝试刷新全局变量 `maxLength` 记录下的最优解。 这种策略能够有效地降低时间复杂度至 O(n),其中 n 是字符串的长度,因为每个索引最多只会被访问两次(一次作为起点,另一次作为终点),这相比暴力枚举方法有了显著改进[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值