Pythonで最大k回の増加操作後に最も頻出する数を求めるプログラム
問題の概要
数値のリスト nums と整数 k が与えられます。「リスト内の任意の要素を1つ選び、その値を1だけ増やす」という操作を最大 k 回まで行えるとき、操作後に最も多く出現することになる数の値を求めてください。候補が複数ある場合は、そのうち最も小さい値を返します。
たとえば nums = [1, 0, 0, 0, 8, 8, 8, 8]、k = 8 の入力を考えてみます。値 1 を7回増やして 8 にすれば、残りの1回で 0 のいずれかを 1 にできます。結果は [8, 1, 0, 0, 8, 8, 8, 8] となり、8 が5個並ぶため、答えは 8 になります。
アプローチ:スライディングウィンドウ
この問題は、リストをソートしたうえでスライディングウィンドウ(二ポインタ法)を使うと効率的に解けます。ウィンドウ [low, high) は、含まれる各要素をウィンドウ内の最大値 nums[high - 1] まで引き上げるのに必要な増分の合計が k 以内に収まる範囲を表します。
具体的な手順は次のとおりです。
- リスト
numsをソートします。 low := 0、high := 0で初期化します。dist := 0(ウィンドウ内の要素を右端の値に揃えるために必要な増分の合計)、best := 0(これまでに見つかった最大の出現数)、ret := -1(答えとなる値)を用意します。highがリストの長さ未満である間、次を繰り返します。high > 0かつnums[high] != nums[high - 1]のとき、dist += (high - low) * (nums[high] - nums[high - 1])で必要コストを更新します。highを1つ進めます。dist > kの間、dist -= nums[high - 1] - nums[low]としてlowを1つ進め、予算オーバーになった分だけウィンドウを左側から縮めます。high - low > bestなら、best := high - low、ret := nums[high - 1]として答えを更新します。
- 最後に
retを返します。
リストは昇順にソートされているため、出現数が同じ候補が複数あっても、先に記録されるのはより小さい値を持つウィンドウです。したがって「同数なら最小の値を選ぶ」という条件も自然に満たされます。
実装例(Python)
class Solution: def solve(self, nums, k): nums.sort() low, high = 0, 0 dist = 0 best = 0 ret = -1 while high < len(nums): if high > 0 and nums[high] != nums[high - 1]: dist += (high - low) * (nums[high] - nums[high - 1]) high += 1 while dist > k: dist -= nums[high - 1] - nums[low] low += 1 if high - low > best: best = high - low ret = nums[high - 1] return ret ob = Solution() nums = [1, 0, 0, 0, 8, 8, 8, 8] k = 8 print(ob.solve(nums, k))
入力
[1, 0, 0, 0, 8, 8, 8, 8], 8
出力
8
計算量について
ソートに O(n log n)、その後のウィンドウ処理は左右のポインタが各要素を高々1回ずつ通過するだけなので O(n) で済みます。全体の計算量は O(n log n) となり、全ペアを総当たりで調べる O(n²) の素朴な手法と比べて、大きな入力でも高速に動作します。追加のメモリも定数程度で済む点が魅力です。
-
Pythonで色のマージ後に残る最小個数を求めるプログラム
問題概要 赤(R)、緑(G)、青(B)の3種類の色からなるリストを考えます。隣り合う異なる2つの色は、残りの「第3の色」1個に変換(マージ)できます。この変換を好きな順序で何度でも繰り返してよいとき、最終的に残る要素数の最小値を求めるのがこの問題です。 たとえば入力が colors = [G, R, G, B, R] の場合、次のように変換を進めることで最終的に1個まで減らせます。したがって出力は 1 となります。 解き方のアプローチ 一見すると状態探索が必要そうな問題ですが、実はXOR(排他的論理和)を使ったシンプルな判定だけで答えが求まります。手順は以下の通りです。 n := 色リス
-
Pythonでリスト内の最大値を見つける方法|sort()とmax()の2つのアプローチ
この記事では、リストの中から最大の数値を見つけるための解決策とアプローチについて詳しく解説します。問題の概要数値のリストが与えられたとき、その中から最大の要素を見つけ出す必要があります。Pythonでは、主に以下の2つの方法でこれを実現できます。ソート(並べ替え)を利用する方法組み込み関数 max() を利用する方法アプローチ1:sort() 関数を使う方法リストを sort() メソッドで昇順に並べ替えると、リストの最後の要素(インデックス -1)が必ず最大値になります。サンプルコードlist1 = [18, 65, 78, 89, 90] list1.sort() # メイン処理 prin