剑指Offer打卡day26——AcWing 61. 最长不含重复字符的子字符串

该博客介绍了如何通过优化的双指针算法解决寻找字符串中最长不含重复字符子串的问题。首先提出了暴力求解的O(n^2)复杂度方法,然后通过观察发现指针的单调性,改用双指针法,以提高效率。具体实现中,利用哈希表记录字符出现的位置,避免重复,并动态更新最长子串长度。这种方法大大降低了时间复杂度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

【题目描述】

在这里插入图片描述

AcWing 61. 最长不含重复字符的子字符串

【思路】

暴力做法:
for(i从0到n)
for(j从i到0)
统计子串[j,i]不包含重复字符的最大长度,也就是以i为右端点,j最远能往前走多远

暴力做法是O(n^2)的复杂度,进一步优化。通过暴力做法可以发现,i、j指针具有单调性。j往右移动,i不可能往左移动。
因此可以使用双指针, i在左, j在右。遍历扫描一遍。

class Solution {
    public int longestSubstringWithoutDuplication(String s) {
        if(s == null || s.length() == 0 ) return 0;
        int []hash = new int[26];
        char c[] = s.toCharArray();
        int res = 0, n = s.length();
        for(int i = 0, j = 0; j < n; j ++)
        {
            hash[c[j] - 'a'] ++;
            //右端发生有跟左边元素发生重复 左端i指针往右移动至不重复位置
            if( hash[c[j] - 'a'] > 1){
                while( i < j){
                    hash[c[i] - 'a'] --;
                    i ++;
                    if( hash[ c[j] - 'a' ] == 1) break;
                }
            }
            res = Math.max(res, j - i + 1);
            
        }
        return res;
    }
}

使用哈希表

class Solution {
    public int lengthOfLongestSubstring(String s) {
        /*
        双指针维护最长子串区间,i在左 j在右
        */
        if(s==null || s.length() == 0){
            return 0;
        }
        int i = -1, j = 0, n = s.length();
        char c[] = s.toCharArray();
        Map<Character, Integer> map = new HashMap<>(); //统计c[j]最后一次出现的索引
        int res = 0;
        while(j < n){
            if(map.containsKey(c[j])){  // [i, j]区域出现重复
                i = Math.max(i, map.get(c[j])); //  获取左指针最右能到达的地方(上一轮c[j]出现的位置)
            }
            map.put(c[j], j); // 最新的c[j]位置
            res = Math.max(res, j - i);
            j ++;
        }
        return res;
    }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值