Leetcode-字符串

# coding=utf-8
"""
@File: task_05.py
-----------------------------------------
@Author: Jack
@Time: 2020/1/14/014 21:23
@Email:jack18588951684@163.com
-----------------------------------------
"""
from collections import defaultdict, deque, Counter


class Solution:
    def lengthOfLongestSubstring(self, s):
        """
        1. 无重复字符的最长子串
        https://leetcode-cn.com/problems/longest-substring-without-repeating-characters/
        给定一个字符串,请你找出其中不含有重复字符的最长子串的长度。
        示例1
        输入: "abcabcbb"
        输出: 3
        解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
        ================================================================================
        执行结果:通过
        执行用时 :88 ms,在所有 Python3 提交中击败了40.87%的用户
        内存消耗 :13.3 MB,在所有 Python3 提交中击败了34.20%的用户
        """
        if not s:
            return 0
        left = 0
        lookup = set()
        n = len(s)
        max_len = 0
        cur_len = 0
        for i in range(n):
            cur_len += 1
            while s[i] in lookup:
                lookup.remove(s[left])
                left += 1
                cur_len -= 1
            if cur_len > max_len:
                max_len = cur_len
            lookup.add(s[i])
        return max_len

    def findSubstring(self, s, words):
        """
        2. 串联所有单词的子串
        https://leetcode-cn.com/problems/substring-with-concatenation-of-all-words/
        给定一个字符串s和一些长度相同的单词 words。找出 s 中恰好可以由 words 中所有单词串联形成的子串的起始位置。
        注意子串要与 words 中的单词完全匹配,中间不能有其他字符,但不需要考虑 words 中单词串联的顺序。
        示例1
        输入:
          s = "barfoothefoobarman",
          words = ["foo","bar"]
        输出:[0,9]
        解释:
        从索引 0 和 9 开始的子串分别是 "barfoo" 和 "foobar" 。输出的顺序不重要, [9,0] 也是有效答案。
        示例2
        输入:
          s = "wordgoodgoodgoodbestword",
          words = ["word","good","best","word"]
        输出:[]
        =========================================================================================================
        执行结果:通过
        执行用时 :44 ms,在所有 Python3 提交中击败了100.00%的用户
        内存消耗 :13.5 MB,在所有 Python3 提交中击败了11.02%的用户
        """
        if not s or not words or not words[0]:
            return list()
        s_len, word_len = len(s), len(words[0])
        words_total_len = word_len * len(words)
        loopring = defaultdict(deque)
        count = Counter(words)
        res = list()

        for start in range(word_len):
            loopring.clear()
            end = start
            while start + words_total_len <= s_len:
                word = s[end:end + word_len]
                end += word_len
                if word in count:
                    queue = loopring[word]
                    queue.append(end)
                    while queue[0] < start:
                        queue.popleft()
                    if len(queue) > count[word]:
                        start = queue.popleft()
                    if start + words_total_len == end:
                        res.append(start)
                else:
                    start = end
        return res

    def balancedString(self, s):
        """
        3. 替换子串得到平衡字符串
        https://leetcode-cn.com/problems/replace-the-substring-for-balanced-string/
        有一个只含有'Q', 'W', 'E','R'四种字符,且长度为 n的字符串。假如在该字符串中,这四个字符都恰好出现n/4次,那么它就是一个「平衡字符串」。
        给你一个这样的字符串 s,请通过「替换一个子串」的方式,使原字符串 s变成一个「平衡字符串」。你可以用和「待替换子串」长度相同的任何其他字符串来完成替换。
        请返回待替换子串的最小可能长度。
        如果原字符串自身就是一个平衡字符串,则返回 0。
        示例1:
        输入:s = "QWER"
        输出:0
        解释:s 已经是平衡的了。
        示例2:
        输入:s = "QQWE"
        输出:1
        解释:我们需要把一个 'Q' 替换成 'R',这样得到的 "RQWE" (或 "QRWE") 是平衡的。
        示例3:
        输入:s = "QQQW"
        输出:2
        解释:我们可以把前面的 "QQ" 替换成 "ER"。
        示例4:
        输入:s = "QQQQ"
        输出:3
        解释:我们可以替换后 3 个 'Q',使 s = "QWER"。
        ==================================================================================
        执行结果:通过
        执行用时 :436 ms,在所有 Python3 提交中击败了33.49%的用户
        内存消耗 :13.3 MB,在所有 Python3 提交中击败了100.00%的用户
        """
        n = len(s)
        average = n // 4
        import collections
        counter = collections.Counter(s)
        saveCounter = collections.Counter()
        # 所有超过1/4的都是需要转换的集中
        for key, val in counter.items():
            if val > average:
                saveCounter[key] = val
        if not saveCounter:
            return 0

        l = r = 0
        count = float("inf")
        for r in range(n):
            # 每一个如果都要需要转化的过程中,则滑动窗口需要包含,直到滑动窗口足够大,saveCounter包含的元素对应的次数都要小于等于average
            if s[r] in saveCounter:
                saveCounter[s[r]] -= 1
            while l <= r:
                include = True
                for ch in 'QWER':
                    if saveCounter[ch] > average:
                        include = False
                        break
                if include:
                    # 如果滑动窗口已经包含了 那么接下来我们将左边右移,需要将s[l] 次数++
                    count = min(count, r - l + 1)
                    saveCounter[s[l]] += 1
                    l += 1
                else:
                    break
        return count


if __name__ == "__main__":
    s = Solution()
    str1 = "abcabcbb"
    str2 = "bbbbb"
    str3 = "pwwkew"
    res1 = s.lengthOfLongestSubstring(str1)
    res2 = s.lengthOfLongestSubstring(str2)
    res3 = s.lengthOfLongestSubstring(str3)
    print("==================题1输出===================")
    print(res1)
    print(res2)
    print(res3)
    print("============================================")

    str4 = "barfoothefoobarman"
    words = ["foo", "bar"]
    res4 = s.findSubstring(str4, words)
    print("==================题2输出===================")
    print(res4)
    print("============================================")

    str5 = "QWER"
    str6 = "QQWE"
    str7 = "QQQW"
    str8 = "QQQQ"
    res5 = s.balancedString(str5)
    res6 = s.balancedString(str6)
    res7 = s.balancedString(str7)
    res8 = s.balancedString(str8)
    print("==================题3输出===================")
    print(res5)
    print(res6)
    print(res7)
    print(res8)
    print("============================================")

输出结果:

==================1输出===================
3
1
3
============================================
==================2输出===================
[0, 9]
============================================
==================3输出===================
0
1
2
3
============================================
发布了33 篇原创文章 · 获赞 5 · 访问量 4630
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 1024 设计师: 上身试试

分享到微信朋友圈

×

扫一扫,手机浏览