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

Pythonでnums[i] + nums[j] + (i - j)を最大化するペア(i, j)を見つけるプログラム

問題の概要

数値のリスト nums が与えられたとき、i < j を満たすペア (i, j) の中から、nums[i] + nums[j] + (i - j) の値が最大になるものを見つけることを考えます。

例として、入力が nums = [6, 6, 2, 2, 2, 8] の場合、出力は 11 になります。インデックス 0 と 1 の2つの「6」を選ぶと、スコアは 6 + 6 + (0 - 1) = 11 となり、これが最大値となるためです。

解法のアプローチ

この式は次のように変形できます。

nums[i] + nums[j] + (i - j) = (nums[i] + i) + (nums[j] - j)

つまり、各 j について「それより前の位置における nums[i] + i の最大値」が分かれば、全体の最大値を一度の走査で求められます。変数 large にこれまで見てきた nums[i] + i の最大値を保持し、ループのたびに 1 を引いて位置の差分(距離のペナルティ)を調整しながら更新していきます。

アルゴリズムの手順

  • large := nums[0]、maxi := 0 で初期化する

  • i を 1 から nums のサイズまで順に処理する

    • large から 1 を引く

    • maxi を max(large + nums[i], maxi) で更新する

    • large を max(large, nums[i]) で更新する

  • 最後に maxi を返す

実装例(Python)

class Solution:
    def solve(self, nums):
        large = nums[0]

        maxi = 0
        for i in range(1, len(nums)):
            large -= 1
            maxi = max(large + nums[i], maxi)
            large = max(large, nums[i])

        return maxi

ob = Solution()
nums = [6, 6, 2, 2, 2, 8]
print(ob.solve(nums))

入力

[6, 6, 2, 2, 2, 8]

出力

11

計算量

配列を一度だけ走査するため、時間計算量は O(n)、追加のメモリ使用量は O(1) で済みます。すべてのペアを総当たりする O(n²) の方法と比べて大幅に効率的であり、大規模なデータにも対応できます。

  1. Pythonで多角形の外周(周囲長)を求めるプログラム

    問題の概要2次元平面上にある単純な多角形(自己交差しないポリゴン)の頂点が、順序付きの点のリストとして与えられているとします。このとき、その多角形の外周(周囲長)を求めることが目的です。例として、入力が points = [(0, 0), (0,5), (3, 5), (3,0)] の場合を考えてみましょう。このときの出力は 16 になります。これは、図からも分かるように、長さ3の辺が2本、長さ5の辺が2本存在するためです。したがって、2×5 + 2×3 = 16 となります。アルゴリズムの考え方この問題は、「隣接する2つの頂点間の距離をすべて計算して合計する」というシンプルなアプローチで解く

  2. Pythonでグリッド内のボールの着地位置を求めるプログラム

    問題概要 m × n のグリッドボックスを考えます。各セルには、左上から右下、もしくは右上から左下へ向けて斜めの板が設置されています。グリッドの上端からボールを落とし、それぞれのボールが底まで到達できるか、そしてどの列に着地するのかを求めるのがこの問題です。 グリッドは行列として与えられ、各セルの値は板の向きを表します。 1: 左上から右下へ下る斜めの板 -1: 右上から左下へ下る斜めの板 n 個のボールを上端の各列から順に落としたとき、底に到達したボールの着地列を答えとして返します。途中で側面の壁に当たったり、V字型の溝にはまって動けなくなったボールについては -1 を出力します。 3