3. Longest Substring Without Rep

2017-07-09  本文已影响0人  yansh15

题目描述

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

输入与输出

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        
    }
};

样例

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.

题解与分析

解法一

暴力枚举每一个可能的起始位置,通过一个 bool 数组维护当前已经出现过的字符,当发现有重复字符出现时,更新最大长度,清空数组信息,检测下一个可能的起始位置。

C++ 代码如下:

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        int maxlen = 0;
        int curlen = 0;
        bool arr[256];
        int size = s.size();
        fill(arr, arr + 256, true);
        for (int i = 0; i < size; ++i) {
            for (int j = i; j < size; ++j) {
                if (arr[s[j]]) {
                    arr[s[j]] = false;
                    ++curlen;
                }
                else
                    break;
            }
            if (curlen > maxlen)
                maxlen = curlen;
            fill(arr, arr + 256, true);
            curlen = 0;
        }
        return maxlen;
    }
};

该解法的时间复杂度为 O(n^2)

解法二

上述解法复杂度高达 O(n^2) 的原因是:每次枚举时并不能重复利用之前枚举时得到的信息,导致大量重复的判断。要想降低复杂度,必须想办法重复利用每次枚举获得的信息。

我们使用一个长度为256的 int 数组arr来记录当前每个 ascii 字符最后一次出现的位置,如果没有出现则为 -1 ;使用一个 int 变量curlen记录以上一个字符结束的最长不重复子串长度(下文简称上一子串)。

设当前字符为c,下面我们分情况讨论不同情况下如何利用arrcurlen变量更新以当前字符结束的最长不重复子串长度:

C++ 代码如下:

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        int maxlen = 0;
        int curlen = 0;
        int arr[256];
        fill(arr, arr + 256, -1);
        for (int i = 0; i < s.size(); ++i) {
            curlen = i - curlen <= arr[s[i]] ? i - arr[s[i]] : curlen + 1;
            /* 上面一行等价于该注释区域代码
            if (arr[s[i]] == -1)
                ++curlen;
            else
                if (i - curlen > arr[s[i]])
                    ++curlen;
                else
                    curlen = i - arr[s[i]];
            */
            if (curlen > maxlen)
                maxlen = curlen;
            arr[s[i]] = i;
        }
        return maxlen;
    }
};

显而易见,该解法的时间复杂度为 O(n) ,相对解法一有很大进步。

上一篇下一篇

猜你喜欢

热点阅读