Pythonでフラッドフィル(塗りつぶし)アルゴリズムを実装して色を一括置換する方法
2次元グリッドがあり、各セルには文字列 "r"・"g"・"b" のいずれかの色が格納されているとします。このグリッドに対して、行 r・列 c を起点として、指定した色 target でフラッドフィル(flood fill:塗りつぶし)操作を行います。
フラッドフィルとは、開始セル grid[r][c] と同じ色を持ち、上下左右に隣接して連結しているすべてのセルを、目標色 target へ一括置換する操作です。画像編集ソフトの「バケツツール」でおなじみのアルゴリズムですね。
入力例と出力例
たとえば、次のようなグリッドが与えられたとします。
| R | R | R |
| R | G | B |
| G | B | B |
ここで (0, 0) を起点に緑("g")で塗りつぶすと、結果は次のようになります。
| G | G | G |
| G | G | B |
| G | B | B |
(0, 0) に連結していた赤("r")のセルがすべて緑("g")に置き換えられました。一方、連結していないセルは元の色のまま変化しません。
解法のアプローチ:DFS(深さ優先探索)
この問題は、深さ優先探索(DFS)を再帰的に使うことで簡潔に実装できます。手順は以下の通りです。
- 訪問済みセルを記録するための集合
seenを用意する oldcolorに開始セルmatrix[r][c]の元の色を保存する- 再帰関数
dfs(i, j)を定義する dfsの中では、(i, j) がグリッドの範囲内にあり、未訪問で、かつ色がoldcolorと一致する場合に、次の処理を行う- (i, j) を
seenに追加する matrix[i][j]をtargetに更新する- 上下左右の4方向に対して再帰的に
dfsを呼び出す
- (i, j) を
- メイン処理から
dfs(r, c)を呼び出し、最後にmatrixを返す
実装コード
それでは、実際のPythonコードを見てみましょう。
class Solution:
def solve(self, matrix, r, c, target):
def dfs(i, j):
if (
i >= 0
and i < len(matrix)
and j >= 0
and j < len(matrix[0])
and (i, j) not in seen
and matrix[i][j] == oldcolor
):
seen.add((i, j))
matrix[i][j] = target
dfs(i + 1, j)
dfs(i, j + 1)
dfs(i, j - 1)
dfs(i - 1, j)
seen = set()
oldcolor = matrix[r][c]
dfs(r, c)
return matrix
ob = Solution()
matrix = [ ["r", "r", "r"], ["r", "g", "b"], ["g", "b", "b"] ]
r = 0
c = 0
target = "g"
print(ob.solve(matrix, r, c, target))
入力
matrix = [
["r", "r", "r"],
["r", "g", "b"],
["g", "b", "b"] ]
r = 0
c = 0
target = "g"
出力
[['g', 'g', 'g'], ['g', 'g', 'b'], ['g', 'b', 'b']]
計算量と実装上の注意点
このアルゴリズムの計算量は以下の通りです。
- 時間計算量: O(行数 × 列数)。各セルは最大1回しか訪問されないためです。
- 空間計算量: O(行数 × 列数)。再帰呼び出しのスタックと
seen集合が最悪ケースでグリッド全体分のメモリを消費します。
なお、非常に大きなグリッドを扱う場合は、Pythonの再帰上限(デフォルトで約1000回)に達する可能性があります。その際は sys.setrecursionlimit() で上限を引き上げるか、スタックを使った反復版DFS、あるいはキューを使ったBFS(幅優先探索)への書き換えを検討するとよいでしょう。
-
PythonとOpenCVで特定の色(青)を検出する方法
画像処理は難しく感じられるかもしれませんが、実は思っているほど複雑ではありません。このチュートリアルでは、PythonとOpenCVを使った基本的な色検出の方法を解説します。コンピュータ上での色の仕組みコンピュータでは、色を「色空間(カラースペース)」や「カラーモデル」と呼ばれる形式で表現します。これは、色の範囲を数値のタプルとして記述する仕組みです。ここでは、最も広く使われている2つの色空間、RGB(赤・緑・青)とHSV(色相・彩度・明度)について見ていきましょう。RGBは、色を3つの成分からなるタプルとして表現します。各成分は0〜255の値を取ることができ、(0, 0, 0)は黒、(255
-
【Python】Tkinterで作るカラーゲーム – 30秒で文字の色を当てるGUIゲーム開発
GUIアプリケーションの開発において、Pythonの標準ライブラリ「Tkinter」は非常に人気が高く、初心者でも扱いやすいツールです。追加のインストール作業なしに使えるため、Tkinterを活用すればシンプルなGUIゲームでも手軽に開発できます。 この記事では、Tkinterを使った「カラーゲーム」の作り方を紹介します。このゲームでは、画面に表示される単語の文字色をプレイヤーが入力し、正解するたびにスコアが1点ずつ加算されます。制限時間は30秒で、使用される色は赤(Red)、青(Blue)、緑(Green)、ピンク(Pink)、黒(Black)、黄(Yellow)、オレンジ(Orange)、