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

Pythonのリーフ値からの最小コストツリー


正の整数の配列arrがあると仮定し、次のようなすべての二分木を検討します-

  • 各ノードには0個または2個の子があります。
  • arr配列の値は、ツリーを順番にトラバースする際の各リーフの値に対応します。
  • 各非リーフノードの値は、それぞれその左サブツリーと右サブツリーの最大リーフ値の積に等しくなります。

考慮されるすべての可能な二分木の中で、各非リーフノードの値の可能な最小の合計を見つける必要があります。したがって、入力arrが[6,2,4]の場合、2つのツリーが存在する可能性があるため、出力は32になります-

Pythonのリーフ値からの最小コストツリー

これを解決するには、次の手順に従います-

  • メモと呼ばれる地図を作成する
  • メソッドdp()を定義します。これは、パラメーターとしてiとjを取ります。これは次のように機能します-
  • j <=iの場合、0を返します
  • メモに(i、j)が含まれている場合は、メモを返します[(i、j)]
  • res:=無限大
  • 範囲iからj–1のkの場合
    • res:=resの最小値、dp(i、k)+ dp(k + 1、j)+(インデックスiからk + 1までのarrのサブ配列の最大値)* k+1からのarrのサブ配列の最大値to j + 1
  • メモ[(i、j)]:=res
  • メモを返す[(i、j)]
  • メインメソッドは、このdp()メソッドを次のように呼び出します-call dp(0、length of arr-1)

理解を深めるために、次の実装を見てみましょう-

class Solution(object):
   def mctFromLeafValues(self, arr):
      """
      :type arr: List[int]
      :rtype: int
      """
      self. memo = {}
      def dp(i,j):
         if j<=i:
            return 0
         if (i,j) in self.memo:
            return self.memo[(i,j)]
         res = float('inf')
         for k in range(i,j):
            res = min(res,dp(i,k) + dp(k+1,j) + (max(arr[i:k+1])*max(arr[k+1:j+1])))
         self.memo[(i,j)]=res
         return self.memo[(i,j)]
      return dp(0,len(arr)-1)

入力

[6,2,4]

出力

32

  1. Pythonで最小コストで都市を接続する

    1からNまでの番号が付けられたN個の都市があるとします。接続があります。各接続[i]は[city1、city2、cost]で、これはcity1とcity2を接続するためのコストを表します。 。都市のすべてのペアに対して、これら2つの都市を接続する接続パス(おそらく長さ1)が存在するように、最小コストを見つける必要があります。コストは、使用された接続コストの合計です。タスクが不可能な場合は、-1を返します。 したがって、グラフが次のような場合- その場合、出力は6になります。任意の2つの都市を選択すると、すべての都市が接続されるため、最小の2、[1、5]を選択します。 これを解決する

  2. Pythonのリーフから始まる最小の文字列

    二分木のルートがあり、各ノードに0から25までの値が含まれているとします。これらの値は、文字「a」から「z」を表します。値0は「a」を表し、値1は「b」を表します。 、 等々。このツリーの葉で始まり、ルートで終わる辞書式順序で最小の文字列を検索する必要があります。したがって、ツリーが次のような場合- シーケンスが[0,3,25]であるため、出力は「adz」になります。 これを解決するには、次の手順に従います- 次のようにdfsトラバーサルメソッドを定義します ノードがnullでない場合、 ノード値を文字としてAに挿入します ノードに左右の子がない場合、