<LeetCode OJ> 3. Longest Substring Without Repeating Characters

本文探讨了寻找字符串中最长无重复字符子串的问题,并提供了两种有效算法。一种通过滑动窗口跟踪字符最后出现的位置,另一种利用字符位置数组实现高效查找。

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

Total Accepted: 147289  Total Submissions: 668349  Difficulty: Medium

Given a string, find the length of the longest substring without repeating characters.

Examples:

Given "abcabcbb", the answer is "abc", which the length is 3.

Given "bbbbb", the answer is "b", with the length of 1.

Given "pwwkew", the answer is "wke", with the length of 3.

 Note that the answer must be a substring"pwke" is a subsequence and not a substring.


分析:

以下答案为错误答案

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        int maxLen=0,tmplen=1;
        int i=0;
        while(i<s.size())
        {
            unordered_map<int,int> mapping;
            tmplen=0;
            while(i<s.size() && mapping.find(s[i])==mapping.end())
            {
                    tmplen++;
                    mapping[s[i]]=i;
                    i++;
            }
            if(tmplen>maxLen)
                 maxLen=tmplen;
        }
        return maxLen;
    }
};

以下案例通不过:

Input: "dvdf"
Output: 2
Expected: 3




学习别人的

算法一

具体分析见程序

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        int maxLen=0;
        int begin=0,end=0;
        unordered_map<char,int> mapping;
        while(end<s.size())
        {
            if(mapping.find(s[end])!=mapping.end())//如果存在就改变起始位置
                begin=max(begin,mapping[s[end]]+1);//源起始位置与重复点的后一个位置较大者
            
            mapping[s[end]]=end;//更新位置
            maxLen=max(maxLen,end-begin+1);//更新以end位置为止的最长不重复字符串
            end++;
        }
        return maxLen;
    }
};

别人算法二

1)用一个locs来存储每一个字符在字符串中的位置。其实这是一个对于字符串问题的通用方法,因为字符本质上就是一个Unique的数字,因此建立一个数组,数组的下标表示这个字符的ASCII码,元素表示其在字符串中的位置即可。

2)另外一个逻辑就是当遇到和之前重复的字符(前一次出现称为Occur 1, 当前出现称为Occur 2)时,即遇到了一个可能的最大值;

3)进行比较后,将下一次扫描的起点设置为刚才这个重复字符的Occur 1的后一位即可。看到一张图,觉得很不错,转载过来:


间复杂度为O(N),时间复杂度为O(1)

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        vector<int> locs(256,-1);
        int idx = -1;//本质就是在,始终维护i与idx之间的元素不重复
        int max = 0;//idx为当前不重复子串的开始位置-1
        for (int i = 0; i < s.size(); i++)
        {
            if (locs[s[i]] > idx)//如果当前字符出现过,那么当前子串的起始位置为这个字符上一次出现的位置+1
                idx = locs[s[i]];//此if条件很精妙
            if (i - idx > max)//更新最大不重复字串
                max = i - idx;
            locs[s[i]] = i;
        }
        return max;
    }
};



注:本博文为EbowTang原创,后续可能继续更新本文。如果转载,请务必复制本条信息!

原文地址:http://blog.youkuaiyun.com/ebowtang/article/details/50490187

原作者博客:http://blog.youkuaiyun.com/ebowtang

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值