【LeetCode】159. Longest Substring with At Most Two Distinct Characters

32 篇文章 0 订阅
32 篇文章 0 订阅

LeetCode159传送门

解法:

1. Brute Force方法。构建字符串S的所有可能子串,为每个子串,构建一个set,set的大小可以表征子串中字符的类别数。假设字符串长度为n,则子串个数为n\cdot (n-1)/2,时间复杂度为O(n^2),空间复杂度为O(n)

2. 使用三个指针。一个指针k指向遍历字符串的主循环中的字符位置,一个指针j指向子串的上一个不同种类字符位置,一个指针i指向当前合法子串的起始位置。当k位置字符与k-1位置字符相同时continue,当k位置与k-1位置不同时,让j存储k-1位置的字符。如此一来,若子串合法,那么k位置的字符要么与k-1位置相同,要么与j位置相同。当两者均不满足时,认为出现了第三种字符,则比较k-i长度与当前最长子串长度后,令新的起始位置i为j位置向后一位,保证子串中仅有两种字符。

Python源码:

Runtime: 40 ms, faster than 71.64% of Python online submissions forLongest Substring with At Most Two Distinct Characters.

Memory Usage: 13.1 MB, less than 18.18% of Python online submissions for Longest Substring with At Most Two Distinct Characters.

class Solution(object):
    def lengthOfLongestSubstringTwoDistinct(self, s):
        """
        :type s: str
        :rtype: int
        """
        i = 0
        j = -1
        t = 0
        for k in range(1, len(s)):
            if s[k] == s[k-1]:
                continue
            if j >= 0 and s[j] != s[k]:
                t = max(k - i, t)
                i = j + 1
            j = k - 1
        return max(len(s) - i, t)

我的心路:

    第一次在35分钟内写出一个hard问题,虽然问题本身并不难。设置了两个指针分别指向子串的首尾,一个字典保存子串中出现的两个字符和在遍历过的字符串中最后出现的位置。主循环是尾指针对原字符串的遍历。

    建立字典的方法可以轻易拓展到k种类字符的子串问题的求解上——把2改为k即可。

Runtime: 40 ms, faster than 71.64% of Python online submissions forLongest Substring with At Most Two Distinct Characters.

Memory Usage: 13.4 MB, less than 9.09% of Python online submissions forLongest Substring with At Most Two Distinct Characters.

class Solution(object):
    def lengthOfLongestSubstringTwoDistinct(self, s):
        """
        :type s: str
        :rtype: int
        """
        i = 0
        t = 0
        char_map = {}
        for j in range(len(s)):
            char_map[s[j]] = j
            if len(char_map) > 2:
                key = min(char_map, key=char_map.get)
                i = char_map.pop(key) + 1
            elif j - i + 1> t:
                t = j - i + 1
        return t
                

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值