[LeetCode]3. Longest Substring Without Repeating Characters

3. Longest Substring Without Repeating Characters

题意:计算字符串中最长不重复子串的长度。

思路:一开始的想法是利用dp来做,也确实可以做到,但是它的做法需要两层循环,外层遍历处理dp,内层遍历处理该位置的子字符串中的长度最大值,然后获取到子字符串后还要判断其是否存在重复值,时间复杂度O(n^3),显然不行!

但是,这道题目的确也是可以通过动态规划来解决的,这里并不需要像之前的需要考虑到之前的的每一种子串的情况,只需要纪录一个字符串的起始结点,既然是判断是否有重复值,直接用哈希表即可,向右移动,如果存在重复值则重新计算子串起始位置。

我们假定dp[i]表示为从起始到下标i的最长不重复子串长度。

它的状态转移方程为:

dp[i] = max(dp[i-1], 从重复位置开始计算的子串长度) (if 重复)

所以代码如下:

class Solution(object):
    def lengthOfLongestSubstring(self, s):
        """
        :type s: str
        :rtype: int
        """
        if not s:
            return 0
        dp = [0] * len(s)
        dp[0] = 1
        start = 0
        used_char = {s[0]: 0}
        for i in range(1, len(s)):
            if s[i] in used_char:
                start = max(start, used_char[s[i]] + 1)
            dp[i] = max(dp[i - 1], i - start + 1)
            used_char[s[i]] = i
        return dp[len(s) - 1]

因为这里的动态规划数组也只是用到了最后的部分,所以就直接使用一个变量维护即可。

class Solution(object):
    def lengthOfLongestSubstring(self, s):
        """
        :type s: str
        :rtype: int
        """
        start = 0
        l = len(s)
        usedchar = {}
        max_len = 0
        for i in range(l):
            # 存在,并且保证上一个的位置需要比起始的位置后面
            if s[i] in usedchar and usedchar[s[i]] >= start:
                start = usedchar[s[i]] + 1
            else:
                max_len = max(max_len, i - start + 1)
            usedchar[s[i]] = i
        return max_len
posted @ 2017-08-24 23:26  banananana  阅读(112)  评论(0编辑  收藏  举报