Pythonで数字列を英小文字に復号化するアルゴリズムを解説
問題の概要
数字('0'〜'9')と '#' で構成される文字列 s が与えられます。この文字列を、以下のルールに従って英語の小文字アルファベットへと復号化します。
- 文字 'a' 〜 'i' は、それぞれ '1' 〜 '9' に対応します。
- 文字 'j' 〜 'z' は、それぞれ '10#' 〜 '26#' に対応します。
例えば、入力が「10#11#12」の場合、出力は「jkab」となります。「10#」が j、「11#」が k、「1」が a、「2」が b に対応するためです。なお、常に一意なマッピングが存在すると仮定してよいものとします。
解法のアプローチ
この問題は、文字列を後ろから走査することで効率的に解けます。手順は以下の通りです。
- '1'〜'26' の各数値と対応するアルファベットを格納したマップ(辞書)を作成します。
- 結果を格納する変数 ans を空文字列で初期化し、インデックス i を文字列の末尾(長さ − 1)に設定します。
- i が 0 以上である限り、以下を繰り返します。
- s[i] が '#' の場合:直前の2文字と合わせた3文字(例:「10#」)を取り出し、マップで対応する文字に変換して ans の先頭に追加します。その後、i を 3 減らします。
- それ以外の場合:s[i] の1文字をマップで変換し、ans の先頭に追加します。i を 1 減らします。
- 最終的な ans を返します。
後ろから処理する理由は、'#' に出会った時点で、その直前の2桁の数字とセットで判断できるからです。これにより、1桁の数字と2桁の数字を正しく区別できます。
Pythonでの実装例
以下の実装を見ると、より理解が深まります。
class Solution(object):
def freqAlphabets(self, s):
m = {}
x = 'a'
for i in range(1, 27):
m[str(i)] = x
x = chr(ord(x) + 1)
ans = ""
m[''] = ''
i = len(s) - 1
while i >= 0:
if s[i] == "#":
temp = ""
for j in range(i - 2, i):
temp += s[j]
ans = m[str(temp)] + ans
i -= 3
else:
ans = m[s[i]] + ans
i -= 1
return ans
ob1 = Solution()
print(ob1.freqAlphabets("17#123#5621#"))入力
"17#123#5621#"
出力
qawefu
コードの解説
まず、for ループを使って '1' から '26' までの数値をキーとし、対応するアルファベットを値とする辞書 m を作成しています。chr() 関数と ord() 関数を組み合わせることで、'a' から順に1文字ずつずらしながらアルファベットを自動的に生成できます。
その後、文字列の末尾から走査を行います。現在位置の文字が '#' であれば、その前の2文字を含めた3文字分(例:「17#」)をひとつのキーとして扱い、対応する文字を結果に追加します。'#' がない場合は、その1文字だけをキーとして変換します。
この実装の計算量は O(n) です。文字列を一度だけ走査すればよいため、非常に効率的な手法と言えます。
-
Pythonで二分木の葉から始まる辞書順最小の文字列を求める方法
問題概要二分木のルートノードが与えられます。各ノードには0から25までの値が格納されており、これらは文字「a」から「z」に対応しています。つまり、0は「a」、1は「b」というように対応付けられています。このとき、木の葉から始まってルートで終わるパスの中で、辞書順(lexicographical order)で最も小さい文字列を見つける必要があります。例えば、次のような木を考えてみましょう。この場合、パスの値の並びは [0, 3, 25] となるため、出力は adz になります。解法のアプローチこの問題はDFS(深さ優先探索)を使って解くことができます。以下の手順で進めます。DFS走査用のメソッ
-
Pythonで文字列からn番目の文字を削除する方法
この記事では、「文字列から指定したインデックス(i番目)の文字を削除して表示する」という問題の解き方を解説します。 問題の概要 与えられた文字列から、指定されたインデックス位置にある1文字を取り除き、その結果を出力します。 Pythonでは文字列のインデックスは必ず0から始まる点に注意してください。たとえば「tutorialspoint」という文字列の場合、各文字とインデックスの対応は以下のようになります。 T u t o r i a l s p o i n t 0 1 2 3 4 5 6 7 8 9 10 11 12 13 それでは、この問題を解くためのPythonスクリプトを見ていきましょ