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

Pythonで解く細胞融合問題 ― heapqを使った効率的なアルゴリズム実装

問題の概要

数値のリスト cells があるとします。このリストは、さまざまな細胞のサイズを表しています。

各反復処理において、最も大きい2つの細胞 ab が次のルールに従って相互作用します。

  • a = b の場合: 両方の細胞は死滅します。
  • a ≠ b の場合: 2つの細胞は融合し、新しいサイズは floor((a + b) / 3)(小数点以下切り捨て)になります。

最終的に残った細胞のサイズを求めてください。すべての細胞が消滅した場合は -1 を返します。

具体例

入力が [20, 40, 40, 30] の場合、出力は 16 になります。

  1. 1回目の反復:最大の2つである 4040 は等しいため、両方とも死滅します。
  2. 2回目の反復:残った 2030 が融合し、floor((20 + 30) / 3) = floor(50 / 3) = 16 となります。

結果として、最後の細胞のサイズは 16 です。

解決のためのアプローチ

この問題を解くには、以下の手順に従います。

  1. cells の各値を負の値に変換します。
  2. 変換したリストでヒープを構築します。
  3. ヒープに要素が2つ以上残っている間、以下を繰り返します。
    • ヒープから2つの要素を取り出し、符号を元に戻してそれぞれ first(最大値)、second(2番目に大きい値)とします。
  4. firstsecond が等しくない場合は、floor((first + second) / 3) を再び負にしてヒープへ挿入します。
  5. 処理終了後、ヒープに要素が残っていれば -cells[0] を返し、空であれば -1 を返します。

ポイント: Python標準ライブラリの heapq は最小ヒープのみをサポートしています。そこで、値をあらかじめ負に変換しておくことで、最大の要素を先頭に取り出せる「最大ヒープ」として利用できます。

実装例

from heapq import heapify, heappop, heappush

class Solution:
    def solve(self, cells):
        # 各値を負に変換することで最大ヒープとして扱う
        cells = [-x for x in cells]
        heapify(cells)

        while len(cells) > 1:
            # 最大の2つの細胞を取り出す
            first, second = -heappop(cells), -heappop(cells)

            if first != second:
                # 融合後のサイズを計算してヒープに戻す
                heappush(cells, -((first + second) // 3))

        return -cells[0] if cells else -1


ob = Solution()
cells = [20, 40, 40, 30]
print(ob.solve(cells))

入力

[20, 40, 40, 30]

出力

16

計算量について

このアルゴリズムでは、各反復ごとにヒープへの挿入・削除を行います。ヒープ操作の計算量は O(log n) であるため、全体の時間計算量は O(n log n)、空間計算量は O(n) となります。これにより、大量のデータに対しても効率的に処理できます。

  1. 【初心者向け】Pythonのissuperset()メソッドの使い方をわかりやすく解説

    はじめにこの記事では、Pythonのissuperset()メソッドについて、基本的な仕組みから実際のコード例まで詳しく解説します。issuperset()は、セット(集合)に対して使用できるメソッドで、引数として渡されたセットのすべての要素が、呼び出し元のセットに含まれているかどうかを判定します。呼び出し元のセットBが、引数のセットAのすべての要素を含んでいる場合 → True を返すセットAの要素がすべてBに含まれていない場合 → False を返すつまり、「BがAの上位集合(スーパーセット)であるかどうか」を判定するためのメソッドです。基本構文B.issuperset(A)この式は、Bが

  2. Microsoft Excelでセルを分割する3つの方法|初心者向け完全ガイド

    Excelでは、1つのセルに複数のデータが入ってしまうことがあります。これは、複数のスプレッドシートを統合したり、外部からデータをインポートしたりする際によく発生します。そのまま我慢して使うこともできますが、Microsoft Excelにはセルを分割する機能が備わっています。ただし、単純な「分割」ボタンがあるわけではなく、目的に応じていくつかの異なる方法を使い分ける必要があります。方法1:「区切り位置」機能を使うMicrosoftが公式に推奨しているのは、「区切り位置」ウィザードを使う方法です。この方法では、分割対象のセルのすぐ右隣にあるセルの内容が上書きされるため、データを失わないよう、あ