zoukankan      html  css  js  c++  java
  • leetcode常规算法题复盘(第八期)——重构字符串

    题目原文

    767. 重构字符串

    给定一个字符串S,检查是否能重新排布其中的字母,使得两相邻的字符不同。

    若可行,输出任意可行的结果。若不可行,返回空字符串。

    示例 1:

    输入: S = "aab"
    输出: "aba"
    

    示例 2:

    输入: S = "aaab"
    输出: ""
    

    注意:

    • S 只包含小写字母并且长度在[1, 500]区间内。

    标准题解

    最大堆:

     1 class Solution:
     2     def reorganizeString(self, S: str) -> str:
     3         if len(S) < 2:
     4             return S
     5         
     6         length = len(S)
     7         counts = collections.Counter(S)
     8         maxCount = max(counts.items(), key=lambda x: x[1])[1]
     9         if maxCount > (length + 1) // 2:
    10             return ""
    11         
    12         queue = [(-x[1], x[0]) for x in counts.items()]
    13         heapq.heapify(queue)
    14         ans = list()
    15 
    16         while len(queue) > 1:
    17             _, letter1 = heapq.heappop(queue)
    18             _, letter2 = heapq.heappop(queue)
    19             ans.extend([letter1, letter2])
    20             counts[letter1] -= 1
    21             counts[letter2] -= 1
    22             if counts[letter1] > 0:
    23                 heapq.heappush(queue, (-counts[letter1], letter1))
    24             if counts[letter2] > 0:
    25                 heapq.heappush(queue, (-counts[letter2], letter2))
    26         
    27         if queue:
    28             ans.append(queue[0][1])
    29         
    30         return "".join(ans)
    31 
    32 
    33 #作者:LeetCode-Solution
    34 #链接:https://leetcode-cn.com/problems/reorganize-string/solution/zhong-gou-zi-fu-chuan-by-leetcode-solution/
    35 #来源:力扣(LeetCode)
    36 #著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

    复杂度分析

        时间复杂度:O(nlog⁡∣Σ∣+∣Σ∣)O(nlog|Sigma| + |Sigma|)O(nlog∣Σ∣+∣Σ∣),其中 nnn 是字符串的长度,ΣSigmaΣ 是字符集,在本题中字符集为所有小写字母,∣Σ∣=26|Sigma|=26∣Σ∣=26。
        遍历字符串并统计每个字母的出现次数,时间复杂度是 O(n)O(n)O(n)。
        将每个字母加入最大堆,字母个数最多为 ∣Σ∣|Sigma|∣Σ∣,这里设真正出现的小写字母数量为 ∣Σ′∣|Sigma'|∣Σ′∣,那么时间复杂度是 O(∣Σ∣)O(|Sigma|)O(∣Σ∣) 加上 O(∣Σ′∣log⁡∣Σ′∣)O(|Sigma'|log|Sigma'|)O(∣Σ′∣log∣Σ′∣) 或 O(∣Σ′∣)O(|Sigma'|)O(∣Σ′∣)。前者是对数组进行遍历的时间复杂度 O(∣Σ∣)O(|Sigma|)O(∣Σ∣),而后者取决于是将每个字母依次加入最大堆,时间复杂度为 O(∣Σ′∣log⁡∣Σ′∣)O(|Sigma'|log|Sigma'|)O(∣Σ′∣log∣Σ′∣);还是直接使用一次堆的初始化操作,时间复杂度为 O(∣Σ′∣)O(|Sigma'|)O(∣Σ′∣)。
        重构字符串需要对最大堆进行取出元素和添加元素的操作,取出元素和添加元素的次数都不会超过 nnn 次,每次操作的时间复杂度是 O(log⁡∣Σ′∣)O(log|Sigma'|)O(log∣Σ′∣),因此总时间复杂度是 O(nlog⁡∣Σ′∣)O(nlog|Sigma'|)O(nlog∣Σ′∣)。由于真正出现的小写字母数量为 ∣Σ′∣|Sigma'|∣Σ′∣ 一定小于等于字符串的长度 nnn,因此上面的时间复杂度中 O(n)O(n)O(n),O(∣Σ′∣log⁡∣Σ′∣)O(|Sigma'|log|Sigma'|)O(∣Σ′∣log∣Σ′∣) 和 O(∣Σ′∣)O(|Sigma'|)O(∣Σ′∣) 在渐进意义下均小于 O(nlog⁡∣Σ′∣)O(nlog|Sigma'|)O(nlog∣Σ′∣),只需要保留 O(∣Σ∣)O(|Sigma|)O(∣Σ∣)。由于 ∣Σ′∣≤∣Σ∣|Sigma'| leq |Sigma|∣Σ′∣≤∣Σ∣,为了不引入额外符号,可以将时间复杂度 O(nlog⁡∣Σ′∣)O(nlog|Sigma'|)O(nlog∣Σ′∣) 写成 O(nlog⁡∣Σ∣)O(nlog|Sigma|)O(nlog∣Σ∣)。
        总时间复杂度是 O(nlog⁡∣Σ∣+∣Σ∣)O(nlog|Sigma| + |Sigma|)O(nlog∣Σ∣+∣Σ∣)。

        空间复杂度:O(∣Σ∣)O(|Sigma|)O(∣Σ∣),其中 ΣSigmaΣ 是字符集,在本题中字符集为所有小写字母,∣Σ∣=26|Sigma|=26∣Σ∣=26。这里不计算存储最终答案字符串需要的空间(以及由于语言特性,在构造字符串时需要的额外缓存空间),空间复杂度主要取决于统计每个字母出现次数的数组和优先队列。

    作者:LeetCode-Solution
    链接:https://leetcode-cn.com/problems/reorganize-string/solution/zhong-gou-zi-fu-chuan-by-leetcode-solution/
    来源:力扣(LeetCode)
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

    计数

     1 class Solution:
     2     def reorganizeString(self, S: str) -> str:
     3         if len(S) < 2:
     4             return S
     5         
     6         length = len(S)
     7         counts = collections.Counter(S)
     8         maxCount = max(counts.items(), key=lambda x: x[1])[1]
     9         if maxCount > (length + 1) // 2:
    10             return ""
    11         
    12         reorganizeArray = [""] * length
    13         evenIndex, oddIndex = 0, 1
    14         halfLength = length // 2
    15 
    16         for c, count in counts.items():
    17             while count > 0 and count <= halfLength and oddIndex < length:
    18                 reorganizeArray[oddIndex] = c
    19                 count -= 1
    20                 oddIndex += 2
    21             while count > 0:
    22                 reorganizeArray[evenIndex] = c
    23                 count -= 1
    24                 evenIndex += 2
    25         
    26         return "".join(reorganizeArray)
    27 
    28 
    29 #作者:LeetCode-Solution
    30 #链接:https://leetcode-cn.com/problems/reorganize-string/solution/zhong-gou-zi-fu-chuan-by-leetcode-solution/
    31 #来源:力扣(LeetCode)
    32 #著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

    复杂度分析

        时间复杂度:O(n+∣Σ∣)O(n+|Sigma|)O(n+∣Σ∣),其中 nnn 是字符串的长度,ΣSigmaΣ 是字符集,在本题中字符集为所有小写字母,∣Σ∣=26|Sigma|=26∣Σ∣=26。
        遍历字符串并统计每个字母的出现次数,时间复杂度是 O(n)O(n)O(n)。
        重构字符串需要进行 nnn 次放置字母的操作,并遍历每个字母得到出现次数,时间复杂度是 O(n+∣Σ∣)O(n+|Sigma|)O(n+∣Σ∣)。
        总时间复杂度是 O(n+∣Σ∣)O(n+|Sigma|)O(n+∣Σ∣)。

        空间复杂度:O(∣Σ∣)O(|Sigma|)O(∣Σ∣),其中 nnn 是字符串的长度,ΣSigmaΣ 是字符集,在本题中字符集为所有小写字母,∣Σ∣=26|Sigma|=26∣Σ∣=26。这里不计算存储最终答案字符串需要的空间(以及由于语言特性,在构造字符串时需要的额外缓存空间),空间复杂度主要取决于统计每个字母出现次数的数组和优先队列。空间复杂度主要取决于统计每个字母出现次数的数组。

    作者:LeetCode-Solution
    链接:https://leetcode-cn.com/problems/reorganize-string/solution/zhong-gou-zi-fu-chuan-by-leetcode-solution/
    来源:力扣(LeetCode)
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

  • 相关阅读:
    清除 Windows 系统垃圾的 bat
    java通过System.getProperty获取系统属性
    【转】Angular之constructor和ngOnInit差异及适用场景
    p中不能包含div
    How to make PostgreSQL functions atomic?
    How to chain a command after sudo su?
    javascript柯里化
    如何在Angular优雅编写HTTP请求
    angular default project (angular.json的解读)
    error:crosses initialization of ...的解决办法
  • 原文地址:https://www.cnblogs.com/monkiki/p/14066267.html
Copyright © 2011-2022 走看看