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

Pythonで中央値の絶対差が最小になるように数値リストを分割する方法

数値のリスト nums が与えられたとき、それを同じサイズの2つのグループに分割し、それぞれのグループの中央値の絶対差ができるだけ小さくなるようにすることを考えます。そして、その最小の差を求めるのがこの問題の目的です。なお、リストの長さを2で割った値(len(nums) / 2)は必ず奇数になると仮定します。

問題の例

たとえば、入力が [2, 10, 8, 5, 4, 7] の場合を考えてみましょう。このとき、[2, 5, 10][4, 7, 8] という2つのリストに分割できます。それぞれの中央値は 5 と 7 となるため、出力はその差である 2 になります。

解法のアプローチ

この問題は、一見複雑に思えますが、実は非常にシンプルな手順で解くことができます。鍵となるのは「リストをソートする」という操作です。ソート済みのリストを前半と後半に分けると、それぞれの中央値は必ずリスト全体の中央付近の隣接する2つの要素になります。n/2 が奇数であるため、前半の中央値はインデックス m-1 の要素、後半の中央値はインデックス m の要素に対応します。したがって、求めるべき最小の絶対差は次のように表せます。

  • リスト nums を昇順にソートする
  • m := len(nums) // 2(リストサイズを2で割った商)を計算する
  • |nums[m] - nums[m-1]| を返す

計算量はソートに伴い O(n log n) となり、非常に効率的な解法です。

実装例

より理解を深めるために、以下のPythonコードを見てみましょう。

class Solution:
   def solve(self, nums):
      nums.sort()
      m = len(nums)//2
      return abs(nums[m] - nums[m-1])
ob = Solution()
print(ob.solve([2, 10, 8, 5, 4, 7]))

入力

[2, 10, 8, 5, 4, 7]

出力

2

まとめ

このアルゴリズムのポイントは、ソートによって中央値同士の関係が隣接要素の差に帰着することに気づくことです。ソート後のリストを半分に分ければ、両グループの中央値は必ず中央の隣接ペアになるため、追加の探索や組み合わせの検討は一切不要になります。わずか数行のコードで最適な分割を実現できる、エレガントな問題と言えるでしょう。

  1. Pythonでリスト内の最小値を見つける方法を解説

    この記事では、リストの中から最小の数値を見つける方法について、具体的なサンプルコードとともに詳しく解説します。問題の概要問題: 数値のリストが与えられたとき、その中に含まれる最も小さい数値を画面に表示すること。この問題を解くアプローチは主に2つあります。ひとつは sort() メソッドを使ってリストを昇順に並べ替え、先頭の要素(インデックス0)を取得する方法。もうひとつは、Pythonに標準で用意されている組み込み関数 min() を使う方法です。それぞれ順番に見ていきましょう。方法1:sort()メソッドで並べ替えて最小値を取得するまずはリストを昇順にソートし、先頭の要素を取り出す方法です。

  2. Pythonでリスト内のすべてのペア間の絶対差の合計を求めるプログラム

    本記事では、リスト内のすべてのペア間の絶対差の合計を求める問題の解法とアプローチについて解説します。 問題文 リストが入力として与えられたとき、そのリスト内のすべてのペア間の絶対差の合計を求める必要があります。 解法のアプローチ enumerate() メソッドは、イテラブル(反復可能オブジェクト)にカウンターを付加し、enumerate オブジェクトとして返す組み込み関数です。ループ処理の中でインデックスと要素を同時に取得したい場合に非常に便利です。 この手法では、まず絶対差を格納するためのリスト「diffs」を用意します。 次に、2つの変数を持つ二重ループを使用します。片方はカウンター(イ