Pythonで2次元バイナリ行列の最も左にある「1」の列インデックスを効率的に求める方法
問題の概要
2次元のバイナリ行列(0と1のみで構成される行列)が与えられます。ここで、各行は昇順にソートされており、すべての0が1よりも先に並んでいるものとします。この条件のもとで、行列全体の中で最も左側に存在する「1」の列インデックスを見つけるプログラムを作成します。該当する「1」が存在しない場合は -1 を返します。
例えば、次のような入力が与えられたとします。
| 0 | 0 | 0 | 1 |
| 0 | 0 | 1 | 1 |
| 0 | 0 | 1 | 1 |
| 0 | 0 | 1 | 0 |
この場合、出力は 2 となります。なぜなら、3列目(インデックス2)に、行列全体で最も左に位置する「1」が存在するからです。
解法のアプローチ
この問題は、右上の角から探索を開始し、条件に応じて左または下へ移動するという効率的な手法で解くことができます。各行がソート済みであるという性質を利用することで、全要素を走査する必要がなくなります。
具体的な手順は以下の通りです。
- 行列が空の場合は、-1 を返します。
- N を行数、M を列数とします。
- 探索位置 i = 0(先頭行)、j = M - 1(最終列)からスタートします。
- 答えを格納する変数 leftmost を -1 で初期化します。
- i < N かつ j >= 0 の間、以下を繰り返します。
- matrix[i][j] が 0 の場合:その行にはそれより右に「1」しか存在しないため、下の行へ移動します(i += 1)。
- matrix[i][j] が 1 の場合:これが現在わかっている中で最も左の「1」なので、leftmost を j で更新し、さらに左へ移動します(j -= 1)。
- ループ終了後、leftmost の値を返します。
このアルゴリズムの計算量は O(N + M) であり、行列のサイズに対して非常に効率的です。各ステップで必ず行または列のどちらかが減少していくためです。
実装例(Pythonコード)
class Solution:
def solve(self, matrix):
if not matrix or not matrix[0]:
return -1
N = len(matrix)
M = len(matrix[0])
i = 0
j = M - 1
leftmost = -1
while i < N and j >= 0:
if matrix[i][j] == 0:
i += 1
else:
leftmost = j
j -= 1
return leftmost
ob = Solution()
matrix = [
[0, 0, 0, 1],
[0, 0, 1, 1],
[0, 0, 1, 1],
[0, 0, 1, 0]
]
print(ob.solve(matrix))入力
[ [0, 0, 0, 1], [0, 0, 1, 1], [0, 0, 1, 1], [0, 0, 1, 0] ]
出力
2
まとめ
ソート済みバイナリ行列の特性を活かしたこの手法では、右上からスタートして「0なら下へ、1なら左へ」と移動するだけで、最短 O(N + M) の時間で答えを導き出せます。全マスを走査する O(N × M) の素朴な方法と比べ、大規模な行列でも高速に動作する点が大きなメリットです。
-
Pythonで二分木内の長さkの一意なパスを数えるプログラム
問題概要 一意な値を持つ二分木と整数 k が与えられます。このとき、木の中に存在する「長さ k の一意なパス」の総数を求めます。パスは親ノードから子ノードへ向かう方向でも、子ノードから親ノードへ向かう方向でも構いません。また、あるノードが片方のパスにのみ含まれる場合、その2つのパスは互いに異なるものとして扱います。 入力例と出力例 たとえば、次のような二分木が与えられたとします。 k = 3 の場合、出力は 4 になります。該当するパスは次の4本です。 [12, 8, 3] [12, 8, 10] [8, 12, 15] [3, 8, 10] 解き方:深さ優先探索(DFS)によるアプ
-
Pythonで行列の転置を求めるプログラム
この記事では、与えられた問題に対する解法とアプローチについて詳しく解説します。 問題文 ある行列が与えられたとき、その転置を同じ行列に格納し、結果を表示する必要があります。 行列の転置とは、行を列に、列を行に入れ替えたものです。言い換えれば、行列Aの転置は、要素A[i][j]をA[j][i]と入れ替えることで得られます。 実装例 N = 4 def transpose(A): for i in range(N): for j in range(i+1, N): A[i][j], A[j][i] = A[j][i], A[i][j] # ドライ