タイトル
https://leetcode-cn.com/problems/decode-string/
エンコードされた文字列を指定すると、そのデコードされた文字列を返します。
エンコーディングルールは次のとおりです。k[encoded_string]。つまり、角かっこ内のencoding_stringが正確にk回繰り返されます。kは正の整数であることが保証されていることに注意してください。
入力文字列は常に有効であると考えることができます。入力文字列に余分なスペースはなく、入力された角括弧は常にフォーマット要件を満たしています。
さらに、元のデータには数値が含まれていないと考えることができます。すべての数値は反復回数kを表すだけです。たとえば、3aや2 [4]のような入力は表示されません。
例:
s = "3 [a] 2 [bc]"、 "aaabcbc"を返します。s
= "3 [a2 [c]]"、 "accaccacc"を返します。s
= "2 [abc] 3 [cd] ef"、返します「abcabccdcdcdef」。
問題解決のアイデア(スタック)
参照文字列のデコード(補助スタック方式/再帰的方法、明確な説明)
- 前面から背面に1回スキャンします
- スキャンするとき、数字に遭遇したときは、
n = n*10 + int(c)
更新可能な数字を使用します - 遭遇したら
[
、スタックを使用して現在の乗数と文字列の接頭辞を格納し、これらの2つの変数をゼロにクリアします。 - 遭遇する
]
と、スタック乗数と以前の文字列プレフィックスがそれに応じて更新されます。 - このソリューションには注意が必要です。
- 文字列のプレフィックスと乗数をクリアするタイミング
- スタックの内容、スタックの後に文字列プレフィックスを更新する方法
コード(スタック)
class Solution:
def decodeString(self, s: str):
stack = []
n, res = 0, ''
for c in s:
if c.isdigit():
# - update n
n = n*10 + int(c)
elif c.isalpha():
# - update word
res += c
elif c == '[':
# - use stack to keep current n and res
stack.append([n, res])
n, res = 0, ''
elif c == ']':
# - last n and res
m, t = stack.pop()
# - update res
res = t + m*res
else:
pass
return res
問題解決のアイデア(再帰的)
参照文字列のデコード(補助スタック方式/再帰的方法、明確な説明)
- 再帰の考え方は
[
、スキャン後に文字列を]
最後まで再帰的に処理することです。 - 処理された部分文字列をスキップする必要があるため、終了インデックスを戻り値として渡す必要があります。
- 再帰的な戻り値が取得された後、文字列のプレフィックスが更新され、乗数を0にリセットすることを忘れないでください。
コード(再帰的)
class Solution:
def decodeString(self, s: str):
def dfs(i):
res, n = '', 0
while i < len(s):
c = s[i]
if c.isdigit():
n = n*10 + int(c)
elif c.isalpha():
res += c
elif c == '[':
r, i = dfs(i+1)
res += r * n
n = 0
elif c == ']':
return res, i
else:
pass
i += 1
return res, i
return dfs(0)[0]