Pythonで「値がk以上の要素がちょうどk個」成立するkを見つける方法
非負の整数のみを含むリスト nums が与えられます。この中から、「k 以上の値を持つ要素がちょうど k 個存在する」ような整数 k を見つけて返すことを考えます。条件を満たす k が存在しない場合は -1 を返します。
たとえば、入力が nums = [6, 4, 0, 8, 2, 9] の場合を考えてみましょう。4 以上の値を持つ要素は [6, 4, 8, 9] のちょうど 4 個であるため、答えは 4 になります。
解法の考え方
この問題は、リストを降順にソートすることで効率的に解けます。降順ソート後のリストでは、インデックス i より前にある要素はすべて nums[i - 1] 以上の値を持つため、「先頭から i 個の要素が i 以上になっているか」という判定が容易になります。
アルゴリズムの手順
- リスト nums を降順にソートする
- i を 1 からリストの長さ - 1 まで繰り返し処理する
- i > nums[i - 1] の場合:それ以降に条件を満たす値は存在しないため、ループを抜ける
- そうでなく、i > nums[i] の場合:「i 以上の要素がちょうど i 個」を満たすので、i を返す
- ループが完了しても見つからなければ、-1 を返す
実装例
実際のPythonコードは次のようになります。
def solve(nums):
nums.sort(reverse=True)
for i in range(1, len(nums)):
if i > nums[i - 1]:
break
elif i > nums[i]:
return i
return -1
nums = [6, 4, 0, 8, 2, 9]
print(solve(nums))
入力
[6, 4, 0, 8, 2, 9]
出力
4
計算量について
ソートに O(n log n)、ソート後のリスト走査に O(n) の時間がかかるため、全体の時間計算量は O(n log n) です。追加のデータ構造を必要としないシンプルな解法であり、実用性の高いアプローチといえます。
-
Pythonでリストの隣接しない要素の最大合計を求めるプログラム
数値のリスト nums が与えられたとき、互いに隣接しない要素だけを選んだ場合の最大合計を返す関数を作ることを考えます。リストには 0 や負の数が含まれている場合もあります。 たとえば、入力が [3, 5, 7, 3, 6] のとき、出力は 16 になります。これは、3・7・6 を選ぶことで要素同士が隣接せず、合計 16 を達成できるためです。 解き方の手順 この問題は動的計画法(DP)の考え方を使うと、O(n) の計算量で効率よく解けます。手順は次のとおりです。 リストの長さが 2 以下の場合は、max(nums) をそのまま返す noTake(現在の要素を選ばない場合の最大合計)を 0
-
Pythonでサイズkの各ウィンドウに含まれる一意な要素の数を求めるプログラム
数値のリスト nums と整数 k が与えられたとき、サイズ k の各ウィンドウ(連続する k 個の要素)に含まれる異なる数値(ユニークな要素)の個数を順番に求める問題です。問題の例たとえば、入力が nums = [2, 2, 3, 3, 4]、k = 2 の場合を考えてみましょう。このとき、各ウィンドウは次のようになります。[2, 2] → 一意な要素数は 1(2のみ)[2, 3] → 一意な要素数は 2(2と3)[3, 3] → 一意な要素数は 1(3のみ)[3, 4] → 一意な要素数は 2(3と4)したがって、出力は [1, 2, 1, 2] となります。解き方のアプローチこの問題は「