LeetCode题解(Week 16):3. Longest Substring Without Repeating Characters

原题目:

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.

中文大意

给定一个字符串,判断这个字符串不包含重复字符的最长子串,注意这里的子串并不是子序列。意味着子串中的元素在原字符串是连续不间断的。如 “pwwkew”中,”pwke”就不能成为答案,因为p与wke是间断的。

题解

class Solution {
public:
int lengthOfLongestSubstring(string s) {
    if (s.empty()) return 0;
    if(s.size()==1) return 1;
    set<char> exist;  //记录出现在当前子串中的元素
    int left = 0, right = 0; //用于记录当前子串的头尾
    int res = 0;
    exist.insert(s[right]);
    while (right != s.size()-1)
    {
        right++;
        if (exist.count(s[right])) //如果下一个元素已经出现过,就需要对子串进行调整了
        {
            int newleft = right - 1;
            for (; s[newleft] != s[right]; newleft--){}
            for (int i = left; i < newleft; i++)
                exist.erase(s[i]);
            left = newleft + 1;   //子串的头部设定为"与right最接近的,并且与right重复的元素的下一位"
        }
        exist.insert(s[right]);
        int currlen = right - left + 1;
        res = max(res, currlen);
    }
    return res;
}
};

题解

这道题的关键在于如何处理重复,我们可以用一个set来保存当前子串中的元素。由于题目需要求的是连续子串,我们可以很自然的想到用两个变量left,right来遍历字符串,一开始我们可以将left,right都设为0,意味着最初的子串只有第一个字符。然后根据right来遍历(right++)

  • 每次遍历时,先将判断新加入的元素s[right]是否在set中,如果不存在,意味着这时候不需要对left进行调整
  • 否则需要对left进行调整,简单来说,就是调整到”与right最接近的,并且与right重复的元素的下一位”

    • 例如,当前的子串为”abcd”,而新的字符为’c’
    • 那么如果我们需要加入新的字符,就必须将”abcd”中的’c’以及以前的子串”abc”去掉
    • 因此调整后的left应该是’d’所在的下标,与新的元素组成新的子串’dc’
  • 每次计算当前子串的长度right-left+1,取最大的作为答案

综上,算法的时间复杂度为O(n),空间复杂度也为O(n).

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值