Leetcode(3)-无重复字符的最长子串

给定一个字符串,找出不含有重复字符的最长子串的长度。

示例:

给定 "abcabcbb" ,没有重复字符的最长子串是 "abc" ,那么长度就是3。

给定 "bbbbb" ,最长的子串就是 "b" ,长度是1。

给定 "pwwkew" ,最长子串是 "wke" ,长度是3。请注意答案必须是一个子串,"pwke" 是 子序列  而不是子串。

自己的思路: 从第一个字符开始,每次遍历,都打入unorder_map中,用count函数判断是否出现过了,如果出现过就到此为止,证明从第一个字符最长的不重复子串就到这里。开始从第二个字符用同样的方法开始。然后再判断以各个字符为首的最大长度。这个做法时间太长。

int lengthOfLongestSubstring(string s) 
{
    if(s.empty()) return 0;
    int maxlength = 1;
    unordered_map<int,int> m;
    for(int k=0;k<s.size();k++)
    {
        m.erase(m.begin(),m.end());
        int l=0;
        for(int i = k;i<s.size();i++)
        {
            if(m.count(s[i]))
            {
                break;
            }
            else
            {
                m[s[i]]=i;
                l++;
            }
        }
        maxlength = maxlength>l ? maxlength : l;
    }
    return maxlength;
}

需要注意的地方是:在每次遍历时,map要清空,不然上次的遍历的结果会影响这次的判断。

还有一种更简单的做法。就是用一个数组去记录每个字符最后一次出现的位置,这样的话,我们只需要从头到尾遍历一次,每遍历一个字符,记录下当前的长度,并比较出最大长度,每个字符的起始位置都初始化为-1,在遍历的同时更新,如果该字符最后一次出现的位置比起始位置要大,那就意味着出现了重复元素,那下一个起始位置就要从当前算了。

int lengthOfLongestSubstring(string str) {
        int vis[130];//vis[i] 记录字符i最后一次出现的位置
        memset(vis, -1, sizeof vis);
        int n = (int)str.size();     
        int ans = 0;//最后结果
        int pre = -1;    //记录当前不重复子串的起始位置
        for (int i = 0; i < n; i ++) {
            // 比较当前字符最后一次出现的位置vis[str[i]]:
            //     如果大于pre(当前不重复子串的起始位置)那么子串的起始位置就要变成vis[str[i]] + 1了
            //     如果小于pre,那么就无关紧要了,这个子串可以加入到不重复子串中
            pre = pre > vis[str[i]] ? pre : vis[str[i]];
            int cnt = i - pre;
            ans = ans < cnt ? cnt : ans;
            vis[str[i]] = i;
        }
        return ans;
    }

猜你喜欢

转载自www.cnblogs.com/mini-coconut/p/9034608.html