leetcode3-Longest Substring Without Repeating Characters

本文介绍了一种解决LeetCode题目中寻找最长无重复字符子串的有效算法。通过使用数组记录字符位置,并优化搜索过程,实现了从O(N^2)到O(N)的时间复杂度降低。文章提供了两种实现方案,一种是通过更新起始位置来避免重复搜索,另一种是通过移动起始位置并清除标记来处理重复字符。

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

听说今年南大机试有两道leetcode的原题,故开刷。今天下午刷了4道,leetcode有一个好处(或者说是坏处),就是不需要你去操心输入输出,直接完成提供给你的函数即可。代码编写、调试均可在网页上进行,这写起来还是挺爽的。多日不刷算法,手又有点生疏了,机试这种还是要多练啊。

进入正题,顾名思义这题就是求一个字符串的最长无重复字符子串。

我的思路是用一个数组记录每种字符出现的位置,当发生重复时,从上一次出现的位置的下一个字符开始继续搜索,这要能优化两层for循环原先的O(N^2)的算法。

代码如下:

class Solution {
public:
    int vis[256];
    int lengthOfLongestSubstring(string s) {
        if(s.length()==0)
            return 0;
        int begin,len,max_len,end;
        begin = end = len = max_len = 0;
        while(end<s.length())
        {
            memset(vis,-1,sizeof(vis));
            end = begin;
            while(end<s.length()&& vis[s[end]] == -1)
            {
                vis[s[end]] = end;
                end++;
            }
            max_len = max(max_len,end-begin);
            begin = vis[s[end]] + 1;
        }
        return max_len;
    }
};

但是可以看出,我在每次发生冲突后,更新一次begin后又将end重新赋值为begin,这样造成了不必要的重复搜索。

另一种思路是在发生重复时,向前一步步挪动begin,清除标记,知道不再有重复。可以严格证明该方法时间复杂度为O(n),其中移动end花费O(n),移动begin花费O(n),O(n)+O(n)=O(n)

更好思路是,判断重复发生在begin之前还是之后,若在之后,则的确有重复,若在begin之前则说明不在该子串里,不会有冲突。

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        vector<int> dict(256, -1);
        int maxLen = 0, begin = 0;
        for (int i = 0; i != s.length(); i++) {
            if (dict[s[i]] >= begin)
                begin = dict[s[i]] + 1;
            dict[s[i]] = i;
            maxLen = max(maxLen, i - begin + 1);
        }
        return maxLen;
    }
};






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值