LeetCode|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.

解题思路

题目要求最长的不含重复字符的子串,那么我们可以从字符串头部依次扫描,每当遇到一个未出现过的字符就把最长长度加1,当遇到一个已出现过的字符时,结束该次扫描,并保存当前最长长度,然后将扫描位置在前一次的基础上向后挪一个字符,重复上述过程,每扫描完一次,就更新最长长度,最后得到的最长长度就是该字符串的不含重复字符的子串的最长长度。
eg:“abcab” 令maxlen=0, len=0

字符当前长度(len)最长长度(maxlen)
a10
ab20
abc30
abca33
b13
bc23
bca33
bcab33
c13
ca23
cab33

最后返回maxlen = 3。

AC代码

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
    int mark[256];//可能不止包含英文字符,考虑所有字符情况
    memset(mark, 0, 256*sizeof(int));//初始化为0,表示该字符还未出现过
    int maxlen = 0;
    for(int i = 0; i < (int)s.length(); ++i)
    {
        int len = 0, j;
        for(j = i; j < (int)s.length(); ++j)
        {
            if(mark[s[j]] == 0)
            {
                mark[s[j]] = 1;//标记该字符已出现
                len++;
            }
            else
            {
                memset(mark, 0, 256*sizeof(int));
                break;
            }
        }
        maxlen = max(maxlen, len);
        if(j == (int)s.length())//如果内循环已扫描到字符串尾,则直接返回
            return maxlen;
    }
    return maxlen;
    }
};

上面是比较简单的解题方法,不过时间复杂度稍稍有点高,达到了O(N²)。下面介绍一种时间复杂度在O(N)的方法。


看了上面的代码我们知道,mark数组是用来标记字符是否出现,其值为0表示未出现,为1表示已出现,那么我们是否可以用来保存在扫描过程中每个字符最后出现的位置呢?答案是肯定的,这样,每当我们遇到一个已出现的字符就更新它在mark中的值。

AC代码

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        int mark[256];
        memset(mark, -1, 256*sizeof(int));
        int start = -1, maxlen = 0;
        for(int i = 0; i < (int)s.length(); ++i)
        {
            if(mark[s[i]] != -1)
                start = max(start, mark[s[i]]);//防止start回退
            mark[s[i]] = i;
            maxlen = max(maxlen, i - start);
        }
        return maxlen;
    }
};

ps:如果是求不含重复字符的最长子序列的长度,那就更简单了,只需要求出该字符串中含有多少个不重复字符即为答案。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值