Pythonで「Look-and-Say(見て言って)」数列のn番目の項を求める方法
整数 n が与えられたとき、「Look-and-Say(見て言って)」数列の n 番目の項を生成するプログラムを作成します。この数列は、直前の項を読み上げるようにして次の項を作っていく特徴的な数列です。最初のいくつかの項は以下のようになります。
- 1
- 11
- 21
- 1211
- 111221
読み方のルール
各項は、前の項を「数字の連続する個数 + その数字」という形式で読み上げることで生成されます。
- 1(イチ)
- 11(1が1つ)→ 前の項「1」を読んで「1が1つ」
- 21(1が2つ)→ 前の項「11」を読んで「1が2つ」
- 1211(2が1つ、1が1つ)→ 前の項「21」を読んで「2が1つ、1が1つ」
- 111221(1が1つ、2が1つ、1が2つ)→ 前の項「1211」を読んで「1が1つ、2が1つ、1が2つ」
解法のアプローチ
n が 1 ≤ n ≤ 30 の範囲で与えられるとき、n 番目の項を求めます。以下の手順で解くことができます。
- s を "1" に初期化します。
- n = 1 の場合は s をそのまま返します。
- i = 2 から n まで繰り返します。
- j = 0、temp = 空文字列、curr = 空文字列、count = 0 と初期化します。
- j が s の長さ未満である間、以下を繰り返します。
- curr が空文字列なら、curr := s[j]、count := 1 とし、j を1増やします。
- curr が s[j] と同じなら、count と j をそれぞれ1増やします。
- それ以外の場合は、temp に count と curr を連結し、curr を空文字列、count を 0 にリセットします。
- ループ終了後、残った count と curr を temp に追加し、s を temp で更新します。
- s を返します。
実装例
それでは、実際のコードを見て理解を深めましょう。
class Solution(object):
def solve(self, n):
s = "1"
if n == 1:
return s
for i in range(2, n+1):
j = 0
temp = ""
curr = ""
count = 0
while j < len(s):
if curr == "":
curr = s[j]
count = 1
j += 1
elif curr == s[j]:
count += 1
j += 1
else:
temp += str(count) + curr
curr = ""
count = 0
temp += str(count) + curr
s = temp
return s
ob = Solution()
n = 5
print(ob.solve(n))入力
5
出力
"111221"
まとめ
このアルゴリズムは、文字列を先頭から走査しながら同じ数字が連続している個数を数え、「個数 + 数字」の形式で新しい文字列を構築するものです。計算量は各項の長さに依存しますが、Look-and-Say 数列は項ごとに文字列が伸びていくため、n が大きくなると処理時間も増加します。ただし n ≤ 30 の制約下では十分に高速に動作します。
-
Pythonで二分木のノードとその子孫の最大絶対差を求めるプログラム
問題概要 二分木が与えられたとき、任意のノードとその子孫との間の絶対差の最大値を求めることを考えます。 例えば、次のような二分木が入力として与えられた場合を考えてみましょう。 この場合、ノード8とノード1の間の差が最も大きくなるため、出力は 7 となります。 解法のアプローチ:DFSを使った追跡 この問題は、DFS(深さ優先探索)を用いることで効率的に解けます。各ノードについて「その部分木内の最小値」と「最大値」を追跡しながら、現在のノードの値との差を順次更新していくのがポイントです。 具体的な手順は以下の通りです。 dfs() 関数を定義します。引数としてノードを受け取ります。 ノード
-
Pythonでパスカルの三角形のn番目の行を求める方法を解説
パスカルの三角形とはある数 n が与えられたとき、パスカルの三角形の n 番目(0始まり)の行を求めることを考えます。パスカルの三角形は、次のようなルールで作成できます。最上行は「1」のみで構成される2行目以降は、左上の数と右上の数を足し合わせた値が並ぶ具体的には、以下のような形になります。例えば入力が 4 の場合、出力は [1, 4, 6, 4, 1] となります。解法のアプローチこの問題は、以下の手順で解くことができます。n が 0 の場合 → [1] を返すn が 1 の場合 → [1, 1] を返すls を [1, 1]、temp を [1, 1] として初期化するi を 2 から n