LeetCode 3. Longest Substring Without Repeating Characters (思维题?)

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.

题目链接:https://leetcode.com/problems/longest-substring-without-repeating-characters/description/

你以为是DP?我一开始也以为是DP,想了一下DP公式推不出来,放弃。但其实不用DP也可以做。

  1. 因为要求每一个字符只出现一次,那么其实可以维护一个flagword,如果相应的flag已经(被之前的字符)设为true,那么就说明有重复的字符,长度需要从遇见的重复字符中的第一个之后开始重新统计,如”abcbbc”,假设现在在abc(长度3)后遇到了b,此时就在1和3这两个位置上遇到了b,于是当前的最大长度就要从1(因为这是第一个)之后(就是2)开始计算,长度为2。(最长的当然依旧是3;这里需要维护一个最大的长度)
  2. 于是相应地需要维护一个当前考虑子串的起始位置和结束位置。
class Solution(object):
    def lengthOfLongestSubstring(self, s):
        """
        :type s: str
        :rtype: int
        """
        strLen = len(s)
        flags = {}
        lastIndex = {}
        result = 0
        currentEnd = 0
        currentStart = 0
        i = 0
        while i < strLen:    
            # 如果当前子串长度大于最大长度时:
            if currentEnd - currentStart > result:
                #print("current: ", currentStart, currentEnd, result)
                result = currentEnd - currentStart
                #print("now: ", currentStart, currentEnd, result)
            charIndex = ord(s[i])
            if charIndex not in flags:
                #print("not in flags. set flag.")
                flags[charIndex] = True
                lastIndex[charIndex] = i
                currentEnd += 1
                #print("flag: ", charIndex, lastIndex[charIndex], currentStart, currentEnd)
                i += 1
            else:
                #print("in flags. retract.")
                # 在遇到重复字符时需要注意:假如之前遇到的重复字符已经在
                # 当前起始位置之前,那么这一个字符不应被视为重复字符(因为
                # 已经不计算在当前子串内),且不需要根据其位置改变当前的字串
                # 起始位置。
                if lastIndex[charIndex] >= currentStart:
                    currentStart = lastIndex[charIndex] + 1
                lastIndex[charIndex] = i
                currentEnd += 1

                #print("flag: ", charIndex, lastIndex[charIndex], currentStart, currentEnd)
                i += 1

        if currentEnd - currentStart > result:
            result = currentEnd - currentStart
        return result

你可能感兴趣的:(ACM)