Longest Substring Without Repeating Characters

题意为给出一个字符串,找出其中没有重复字符的最长子序列的长度。brute force的复杂度为O(n^3).依次查找每个子字符串是否含有重复字符,并比较长度。开始看到题目,想用DP解决,在已有目前最长子序列的情况下,比较把当前字符串放入和不放入,哪个子序列长度会更大,但是这种解法的复杂度为O(n^2),也不理想。

一种比较好的解法是贪心策略,维护一个变量maxlen保存目前已有的不重复子序列的最大长度。维护一个sliding window,left为左起点,right为右端点。同时维护一个map,保存窗口中的<char,index>键值对。每次右端点向右移动一格,如果 s[right]不在map中,则窗口中的字符串长度加1,否则说明窗口中已经有和s[right]的重复的元素,要更新left的值,left的值为重复元素的后一个值,此时也要删去重复元素之前的在窗口中的值,对map做更新,这种思路的代码如下:

class Solution(object):
    def lengthOfLongestSubstring(self, s):
        """
        :type s: str
        :rtype: int
        """
        length = len(s)
        left=maxlen = 0
        map = {}
        for right in xrange(length):
            if map.has_key(s[right]):
               index = map[s[right]]
               for i in xrange(left,index+1):
                   map.pop(s[i])
               left = index+1
            else:
               maxlen = max(maxlen,right-left+1)
            map[s[right]] = right
                 
        return maxlen
                
        

此种解法,虽然left和right都扫了一遍,但是存在多次删map元素的过程,复杂度不能保证为O(n)。一种更优的解法,不删map元素,在取index的时候,同时判断index比不比left大,即在不在窗口中,再采取操作,代码如下:

class Solution(object):
    def lengthOfLongestSubstring(self, s):
        """
        :type s: str
        :rtype: int
        """
        length = len(s)
        maxlen = left = 0
        map = {}
        
        for right in xrange(length):
            if map.has_key(s[right]) and map[s[right]] >= left:
               index = map[s[right]]
               left = index+1
            else:
               maxlen = max(maxlen,right-left+1)
            map[s[right]] = right
        
        return maxlen
                
        

时间复杂度O(n),存储空间为常量大小,最大256,所以空间复杂度为O(1)。

原文地址:https://www.cnblogs.com/sherylwang/p/5406342.html