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

Pythonで行列内の「ラッキーナンバー」(行と列の両方で最大の数)を数える方法

問題の概要

ある行列(マトリックス)が与えられたとき、「その行においても、その列においても最も大きい値になっている整数」がいくつあるかを求める問題です。このような数字は「ラッキーナンバー(Lucky Number)」とも呼ばれます。

例として、次のような入力を考えてみましょう。

132
465
157

この場合、答えは 2 になります。条件を満たすのは 6 と 7 の2つだけだからです。

  • 6: 2行目(4, 6, 5)の最大値であり、同時に2列目(3, 6, 5)の最大値でもある
  • 7: 3行目(1, 5, 7)の最大値であり、同時に3列目(2, 5, 7)の最大値でもある

解き方のアプローチ

この問題は、以下の手順で効率よく解くことができます。

  1. 各行の最大値をまとめたリスト r_maxes を作成する。
  2. 各列の最大値をまとめたリスト c_maxes を作成する。
  3. すべてのセルを走査し、その値が「行の最大値」かつ「列の最大値」と一致する場合に、結果リストへ追加する。
  4. 最後に、結果リストの要素数を返す。

実装例(Python)

class Solution:
    def solve(self, matrix):
        mat = matrix
        trans_mat = list(zip(*matrix))
        print(mat, trans_mat)
        r_maxes = [max(row) for row in mat]
        c_maxes = [max(t_row) for t_row in trans_mat]
        a = []
        for r in range(len(mat)):
            for c in range(len(trans_mat)):
                v = mat[r][c]
                if (r_maxes[r], c_maxes[c]) == (v, v):
                    a.append(v)
        return len(a)

ob = Solution()
matrix = [
    [1, 3, 2],
    [4, 6, 5],
    [1, 5, 7]
]
print(ob.solve(matrix))

入力

[[1, 3, 2], [4, 6, 5], [1, 5, 7]]

出力

2

コードのポイント

転置行列で列を簡単に扱う

Pythonでは zip(*matrix) を使うことで、行列をワンラインで転置できます。これにより「列ごとの最大値」も、行の場合とまったく同じように max() で求められるのが大きなポイントです。

計算量

  • 時間計算量: O(m × n)(m:行数、n:列数)— 全セルを一度ずつ確認します。
  • 空間計算量: O(m + n)— 行・列それぞれの最大値リストを保持します。

シンプルながら効率的なこの手法は、競技プログラミングやコーディング面接で頻出の定番パターンです。ぜひ覚えておきましょう。

  1. Pythonで2つの数値を加算するプログラム:ビット演算による実装方法

    この記事では、2つの数値を加算するという問題に対する解法とアプローチについて詳しく解説します。 問題の概要 2つの大きな数値が与えられ、それらを加算した結果を出力することが求められます。 最も単純なアプローチは、オペランド同士を「+」演算子で結ぶ方法です。また、2つの数値をリストなどのイテラブルに格納し、Python標準ライブラリに用意されている組み込み関数 sum() を利用する方法もあります。 しかし、これらのアプローチでは10進数に対して直接演算を行うため、計算コストが増大するという課題があります。 ビット演算を用いた別のアプローチ そこで次に、数値をビット単位で操作する別のアプローチを

  2. 【Python入門】数値を範囲内に制限するクランプ関数の自作方法

    クランプ(clamp)関数とは?クランプ関数とは、ある値を指定された最小値と最大値の範囲内に制限する関数です。値が範囲を下回れば最小値に、上回れば最大値に丸められます。残念ながら、Pythonの標準機能には組み込みのクランプ関数が用意されていません。しかし、max() と min() を組み合わせることで、わずか数行で簡単に自作できます。クランプ関数の実装例def clamp(num, min_value, max_value): return max(min(num, max_value), min_value) print(clamp(5, 1, 20)) print(clamp