Pythonで配列の減少・再配置後に取得できる最大要素を求める方法
問題概要
配列 arr が与えられたとします。この配列に対していくつかの操作を行い、次の条件を満たすようにする必要があります。
arrの最初の要素は必ず 1 であること。隣接する任意の 2 つの要素の絶対差が 1 以内であること。
使用できる操作は次の 2 種類で、それぞれ何度でも実行できます。
arr内の任意の値を、それより小さい正の整数へ減らす。arrの要素を任意の順序に並べ替える。
これらの操作を実行して上記の条件を満たしたとき、arr 内に残せる最大の値を求めるのが目的です。
入力例
たとえば arr = [3,3,2,3,2] の場合、出力は 3 になります。これは、最後の要素を 1 に減らし、その後 [1,2,3,3,3] のように並べ替えることで条件を満たせるためです。このときの最大値は 3 となります。
解法アプローチ
この問題は、以下の手順で解くことができます。
- リスト
arrを昇順にソートする。 arr[0]を 1 に設定する。- i を 1 から配列の長さ − 1 までループさせ、各要素に対して
arr[i] = min(arr[i-1] + 1, arr[i])を適用する。 - 最後に
arrの最大値を返す。
このアルゴリズムのポイントは、まず配列をソートすることで、小さい値から順に制約を確認できる点にあります。先頭を 1 に固定した後、「前の要素 + 1」と元の値のうち小さい方を各要素に代入していくことで、隣接要素間の差が 1 以内になるように制御します。これにより、各位置で可能な限り大きな値を維持しながら条件を満たすことができます。
実装例
理解を深めるために、以下の Python コードをご覧ください。
def solve(arr): arr.sort() arr[0] = 1 for i in range(1, len(arr)): arr[i] = min(arr[i - 1] + 1, arr[i]) return max(arr) arr = [3,3,2,3,2] print(solve(arr))
入力
[3,3,2,3,2]
出力
3
計算量について
この解法の時間計算量は O(n log n) であり、その大部分はソート処理によるものです。ソート後の線形走査は O(n) で完了します。また、入力配列をそのまま書き換えるインプレース処理のため、追加の空間計算量は O(1) で済みます(ソートアルゴリズム内部で使用されるメモリを除く)。
-
【Python】リストから最大値・最小値・2番目に大きい値・2番目に小さい値を求める方法
この記事では、Pythonを使ってリスト(配列)の中から最大値、最小値、2番目に大きい値(second largest)、2番目に小さい値(second smallest)を一度に見つけるプログラムを解説します。ソートを行わずに1回のループで処理できるのがポイントです。アルゴリズム全体の流れは以下の3ステップです。ステップ1:リストの要素を入力する ステップ2:各要素を取り出し、リスト内の他の数値と順に比較する ステップ3:最大値・最小値・2番目に大きい値・2番目に小さい値を取得して表示するサンプルコード# リスト内の最大値・最小値・2番目に大きい値・2番目に小さい値を求める def maxm
-
Pythonでリスト内の最大値・最小値の位置を見つける方法
Pythonでは、リスト内の最大値や最小値を求めるのが非常に簡単で、それらの位置(インデックス)も簡単に取得できます。Pythonには便利な組み込み関数が用意されており、min()はリスト内の最小値を求め、max()はリスト内の最大値を求めます。さらに、index()を使えば特定の要素のインデックス(位置)を調べることができます。 アルゴリズム maxminposition(A, n) /* Aはユーザーが入力したリスト、nはリストのサイズ */ ステップ1:組み込み関数を使って最小要素の位置を求める A.index(min(A)) ステップ2:組み込み関数を使って最