Python
 Computer >> コンピューター >  >> プログラミング >> Python

Pythonで列を並べ替えた後に最大の「1」だけの部分行列の面積を求めるプログラム

問題概要

0と1だけで構成される2値行列が与えられます。まず、列を好きな回数だけ自由に並べ替えることができ、その後、「1」のみで構成される最大の部分行列の面積を求めて返します。

たとえば、入力が次のような行列だった場合を考えてみましょう。

100
111
101

この場合の出力は 4 になります。列を並べ替えることで、次のように2行目と3行目に「1」を集めることができ、2×2の部分行列が作れるからです。

100
111
110

解法のアプローチ

この問題を解くには、以下の手順に従います。

  • n := 行列の行数
  • m := 行列の列数
  • ans := 0(答えを格納する変数)
  • i を 1 から n-1 まで繰り返す:
    • j を 0 から m-1 まで繰り返す:
      • matrix[i, j] が 1 の場合:
        • matrix[i, j] := matrix[i, j] + matrix[i-1, j](上の行の値を加算)
  • 行列の各行に対して:
    • その行をソートする
    • j を m-1 から 0 まで 1 ずつ減らしながら繰り返す:
      • ans := ans と row[j] × (m - j) のうち大きい方
  • ans を返す

考え方のポイント

まず各行について、そのセルから真上方向へ連続する「1」の個数を累積的に計算します。これにより、各行はヒストグラムの高さのように扱えるようになります。列は自由に並べ替えられるため、各行内で高さを昇順にソートすると、右端から見たときに「row[j] 以上の高さを持つ列が (m - j) 本存在する」ことになります。したがって、row[j] × (m - j) がその時点で作れる最大の長方形の面積となり、すべての場合の中での最大値が答えになります。

実装例

理解を深めるために、以下の実装を見てみましょう。

def solve(matrix):
    n, m = len(matrix), len(matrix[0])
    ans = 0
    for i in range(1, n):
        for j in range(m):
            if matrix[i][j]:
                matrix[i][j] += matrix[i-1][j]
    for row in matrix:
        row.sort()
        for j in range(m-1, -1, -1):
            ans = max(ans, row[j] * (m - j))
    return ans

matrix = [
[1, 0, 0],
[1, 1, 1],
[1, 0, 1]
]
print(solve(matrix))

入力

[
[1, 0, 0],
[1, 1, 1],
[1, 0, 1]
]

出力

4
  1. 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] # ドライ

  2. Pythonで配列内の最大要素を見つける方法【初心者向け解説】

    本記事では、配列の中から最大の要素を見つけるための解法とアプローチについて詳しく解説します。 問題の概要 配列が入力として与えられたとき、その中から最も大きい要素を見つけ出すことが課題となります。 アプローチ この問題は「線形探索」と呼ばれるシンプルな手法で解決できます。手順は以下の通りです。 まず、変数 max を配列の最初の要素で初期化します。 次に、2番目の要素から配列の末尾まで順番に走査していきます。 走査中の各要素について、現在の max の値と比較します。 要素が max より大きければ、max の値をその要素で更新します。 そうでなければ、そのまま次の要素へ進みます。 この処