【LeetCode】761. Special Binary String 解題報告(Python)
題目描述:
Special binary strings are binary strings with the following two properties:
- The number of 0’s is equal to the number of 1’s.
- Every prefix of the binary string has at least as many 1’s as 0’s.
Given a special string S, a move consists of choosing two consecutive, non-empty, special substrings of S, and swapping them. (Two strings are consecutive if the last character of the first string is exactly one index before the first character of the second string.)
At the end of any number of moves, what is the lexicographically largest resulting string possible?
Example 1:
Input: S = "11011000" Output: "11100100" Explanation: The strings "10" [occuring at S[1]] and "1100" [at S[3]] are swapped. This is the lexicographically largest string possible after some number of swaps.
Note:
- S has length at most 50.
- S is guaranteed to be a special binary string as defined above.
題目大意
一個特殊的二進位制字串滿足以下兩個屬性:
- 字串中0的個數等於1的個數
- 這個字串中任何字首中1的個數不少於0的個數
給了一個滿足要求的特殊字串,每次移動可以選擇兩個兩個連續的非空的特殊二進位制子串進行交換。求在一系列移動之後,能得到的字母順序的字串最大結果。
解題方法
這道題的原型是括號匹配問題。求括號匹配的經典的方法是使用cnt記數的方法,如果是左括號,那麼cnt+1,如果是右括號,那麼cnt-1,如果cnt等於0了,說明這已經是個匹配了的括號了。注意,一個括號匹配問題中可能存在多個匹配的括號,這個題也是,比如1010
如果要想在一系列移動之後,得到最大的字串,那麼可以看出要求1儘量在前面,同時0儘量在後面。我們使用list儲存那些符合要求的字串,最後排序即可。一個符合要求的字串其開頭必須是1,末尾必須是0。同時我們意識到,符合要求的字串的內部也要進行排序。比如子串1010
,要給他排序成1100
這個樣子,注意中間的字串01
並不符合題目要求,給他重新排成10
樣式,使用遞迴結構。使用i儲存上一次判斷完成的字串的結尾,用j遍歷字串。每次判斷結束一個符合要求的子串之後,要令 i = j + 1。
最壞情況下的時間複雜度是O(N!),最優情況下的時間複雜度是O(1),空間複雜度是O(N)。
class Solution(object):
def makeLargestSpecial(self, S):
"""
:type S: str
:rtype: str
"""
cnt = 0
res = list()
i= 0
for j, v in enumerate(S):
cnt += 1 if v == "1" else -1
if cnt == 0:
res.append("1" + self.makeLargestSpecial(S[i + 1:j]) + "0")
i = j + 1
return "".join(sorted(res, reverse=True))
參考資料:
日期
2018 年 10 月 2 日 —— 小藍單車莫名其妙收了我1塊錢,明明每個月免費騎10次的啊!