LeetCode-3. Longest Substring Without Repeating Characters

问题:给定一个字符串,查找不重复的最长子字符串的长度。

Example 1:

Input: "abcabcbb"
Output: 3 
Explanation: The answer is "abc", with the length of 3. 

Example 2:

Input: "bbbbb"
Output: 1
Explanation: The answer is "b", with the length of 1.

Example 3:

Input: "pwwkew"
Output: 3
Explanation: 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:两重循环,暴力查找

我用木鱼脑袋想出来的方法其实就是我们的通常的思维逻辑。从第一个字符开始往后查看,边查看边计数,下一个字符只要和之前所遇到的连续的字符都不一样,则不重复字符串长度加1。如果遇到和之前连续字符串中相同的字符,则本次查找结束,从第二个字符开始重复这个过程。最后返回所有查找次数中长度最长的那个长度。时间复杂度为O(n²),测试显示超时o(╥﹏╥)o

#Python
class Solution(object):
    def lengthOfLongestSubstring(self, s):
        """
        :type s: str
        :rtype: int
        """
        if len(s) == 1:return 1    #对长度为1的字符串单独处理
        d = {};l = n = 0    #字典d用来存储每次查找中已经找过的字符
        for i in range(len(s)):    #依次以每个字母为开头进行查找
            for j in range(i,len(s)):    
                if s[j] not in d:    #本次查找中字符没出现过
                    d[s[j]] = j;n = n + 1    #n记录本次查找中的不同字符数串长度
                    if n > l:l = n    #l记录所有查找次数中的最长字符串长度
                else:
                    d = {};n = 0    #如果出现重复字符,则本次查找结束,d和n清空以备下次查找
                    break
        return l

方法2:滑动窗口

这是一个简单的想法,假设有字符串”abcabcad”,显然最长不重复字段长度为3,如果我们能找到第0个字符a和第3个字符a,直接用它们的下标相减,就能得到所要长度。所以关键就是找到一个字符串的首位下标和第一个重复元素的下标。以Python代码为例,l = max(l,j-i+1),假如字符串全都不同,那么末尾减去首位加上1才是全长,所以是j-i+1,不是j-i;d[s[j]] = j + 1是跟j-i+1对应的,设有一段字符串”bcdancd”,最长非重复段在”dancd”里,长度为4,如果d[s[j]] = j ,那么第一个d对应的下标是i=2,第一个重复的d对应的下标是j=6,那么l = max(l,j-i+1)计算出来为5,即把重复的那个字符也算进长度里了。该算法时间复杂度为O(n)。

#Python
class Solution(object):
    def lengthOfLongestSubstring(self, s):
        """
        :type s: str
        :rtype: int
        """
        d = {};l = 0;i = 0    
        for j in range(len(s)):
            if s[j] in d:    #遇到重复字符
                i = max(i,d[s[j]])    #求最近的重复字符
            l = max(l,j-i+1)    #求最大长度
            d[s[j]] = j + 1    #d用来存放相同字符最近的下标值
        return l
//C++
class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        int n = s.length(),l = 0;
        std::unordered_map<int,int> m;
        for(int j = 0,i = 0;j < n;j++){
            if (m.find(s[j]) != m.end()){
                i = max(i,m[s[j]]);
            }
            l = max(l,j - i + 1);
            m[s[j]] = j + 1;
        }
        return l;
    }
};

 

点赞