3.无重复字符的最长子串

    

本体题意:求一段连续的子串的长度,其子串字符不能重复,即“abcdefg”,而“abcda”里的a就重复了

我们第一个能想到的解法就是暴力解法:固定一个下标i,j往后遍历记录字母出现的次数,如果有重复的则记录结果,j则回到i位置i++,j=i,在重新遍历记录结果,即:双指针,但这个解法时间复杂度为O(n^2)

如下图:

那么有没有更优的解法呢 ?

先思考一个问题:当j遍历到停止的时候,是不是只有j指向的元素重复了,如果j之前的元素重复了那么j就会在前面提前结束,结果就是当遇到第一个重复的元素的时候j就会停止,那么j应不应该回来呢?答案是不需要,因为只有j指向的元素是重复的,这个重复的元素就在i和j之间(包括i和j),那是不是只要让i进行移动到与j重复的元素停下来,然后删掉判断是不是还有与j重复的,如果有就继续往后走,如果没有就让j继续往后遍历,最坏的情况就是与j刚好相遇,由此而知这个思想是基于双指针的一个优化,就是滑动窗口

算法实现:j往后遍历统计字符有没有重复的则需要一个哈希表,又因为都是字符,所以可以用数组加上下标映射关系来模拟哈希表,

代码如下

int lengthOfLongestSubstring(string s) {
        int a[128]={0};
        int left=0,right=0,ans=0;
        while(right<s.size())
        {
            // 处理下标的映射关系
            a[s[right]-0]++;
            
            //处理与j重复的元素
            while(a[s[right]-0]>1)
            {
                a[s[left]-0]--;
                left++;
            }
            //每次求得一个区间则更新结果
            ans=max(ans,right-left+1);
            right++;
        }
        return ans;
    }

2层for循环,而时间时间复杂度而是O(n),最坏的情况就是j和i都遍历的一遍数组,即:O(2n),系数忽略不计

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值