LeetCode-3. Longest Substring Without Repeating Characters

Description

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.

Solution 1(C++)

class Solution{
public:
    int lengthOfLongestSubstring(string s) {
        int reslen = 0;
        int left = 0, right = 0;
        vector<int> vec(256, -1);
        for(; right<s.size(); right++){
            if(vec[s[right]] != -1){
                left = max(left, vec[s[right]]+1);
            }
            vec[s[right]] = right;
            reslen = max(reslen, right-left+1);
        }
        return reslen;
    }
};

Solution 2(C++)

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

算法分析

搞清楚了题目的意思就比较容易获得算法思路,注意题目要求的是连续子串的长度,所以情况处理就比较简单。

  1. 设定reslen表示连续子串的长度,left表示连续子串的左边界,right表示连续子串的右边界,则reslen=right-left+1。
  2. 让right遍历字符串s,由于要记录遍历过的字符与相应的位置索引,考虑到字符串s中的字符都是ASCII码,所以用一个256位的vec,来记录遍历过的字符,初始值设为-1,表示对应字符没有出现。字符一旦出现,就由-1变成对于字符在s中的索引。
  3. right遍历字符串s,如果字符没有重复出现,就一直便利,如果重复出现,就将重复出现的字符的索引更新为现在的right,并且,left往前移动1位(这样left与right之间的子字符串就又保持所有字符仅出现一次)。
  4. 不断更新当前reslen与right-left+1之间的最大值。直到遍历结束。

注意3中的,left更新时要往前移动一位,所以解法一中使用了:

left = max(left, vec[s[right]]+1);

就是为了防止:对于”abba”,当right遍历到第二个a时,结果left更新到了第一个b处,从而得到错误的答案。

程序分析

略。

猜你喜欢

转载自blog.csdn.net/zy2317878/article/details/80793473
今日推荐