ホームページ > バックエンド開発 > PHPチュートリアル > K で割り切れる成分の最大数

K で割り切れる成分の最大数

DDD
リリース: 2024-12-26 18:31:30
オリジナル
483 人が閲覧しました

2872。 K で割り切れる成分の最大数

難易度: 難しい

トピック: ツリー、深さ優先検索

0 から n - 1 までのラベルが付けられた n 個のノードを持つ無向ツリーがあります。整数 n と lengthn - 1 の 2D 整数配列エッジが与えられます。ここで、edges[i] = [ai, bi] は、ノード ai とノードの間にエッジがあることを示します。 bi がツリーにいます。

長さ n の 0 インデックス付き 整数配列値も与えられます。ここで、values[i] は i 番目 ノードに関連付けられた値、および整数 k です。

ツリーの有効な分割は、結果として得られるコンポーネントがすべて k で割り切れる値を持つように、ツリーから任意のエッジのセット (空の可能性があります) を削除することによって取得されます。ここで、 の値接続コンポーネントのノードの値の合計です。

有効な分割内のコンポーネントの最大数返します。

例 1:

Maximum Number of K-Divisible Components

  • 入力: n = 5、エッジ = [[0,2],[1,2],[1,3],[2,4]]、値 = [1,8,1,4 ,4]、k = 6
  • 出力: 2
  • 説明: ノード 1 と 2 を接続するエッジを削除します。結果の分割は次の理由から有効です。
    • ノード 1 と 3 を含むコンポーネントの値は、values[1] value[3] = 12 です。
    • ノード 0、2、および 4 を含むコンポーネントの値は、values[0]、values[2]、values[4] = 6 です。
    • 他の有効な分割には 2 つを超える連結成分がないことがわかります。

例 2:

Maximum Number of K-Divisible Components

  • 入力: n = 7、エッジ = [[0,1],[0,2],[1,3],[1,4],[2,5],[2,6] ]、値 = [3,0,6,1,5,2,1]、k = 3
  • 出力: 3
  • 説明: ノード 0 を 2 に接続するエッジと、ノード 0 を 1 に接続するエッジを削除します。結果の分割は次の理由から有効です。
    • ノード 0 を含むコンポーネントの値は、values[0] = 3 です。
    • ノード 2、5、6 を含むコンポーネントの値は、values[2]、values[5]、values[6] = 9 です。
    • ノード 1、3、4 を含むコンポーネントの値は、values[1]、values[3]、values[4] = 6 です。
    • 他の有効な分割には 3 つを超える連結成分がないことがわかります。

制約:

  • 1 4
  • edges.length == n - 1
  • edges[i].length == 2
  • 0 n
  • values.length == n
  • 0 9
  • 1 9
  • 値の合計は k で割り切れます。
  • エッジが有効なツリーを表すように入力が生成されます。

ヒント:

  1. ノード 0 でツリーをルートします。
  2. リーフ ノードが k で割り切れない場合は、親ノードと同じコンポーネント内にある必要があるため、リーフ ノードを親ノードとマージします。
  3. リーフ ノードが k で割り切れる場合、それは独自のコンポーネント内にあるため、親ノードから分離します。
  4. 各ステップで、リーフ ノードを切り取るか、リーフ ノードをマージします。ツリー上のノードの数は 1 つ減ります。ノードが 1 つだけ残るまで、このプロセスを繰り返します。

解決策:

深さ優先検索 (DFS) アプローチを実装して、ツリーを探索し、コンポーネントの値を追跡し、有効な分割の最大数を見つけることができます。

重要なポイント:

  • ツリー構造: 各ノードが関連する値を持つ無向ツリーを操作しています。各コンポーネントの値の合計が k で割り切れるようにツリーを分割することで取得できる接続コンポーネントの最大数を見つける必要があります。
  • DFS トラバーサル: 深さ優先検索 (DFS) を使用してツリーをトラバースし、サブツリーの合計を計算します。
  • 割り算チェック: サブツリーの合計を計算した後、それが k で割り切れる場合、そのサブツリーはそれ自体で有効なコンポーネントとみなせることを意味します。
  • エッジの削除: サブツリーの合計が k で割り切れないノードを接続するエッジを削除することで、有効なコンポーネントの数を最大化できます。

アプローチ:

  1. ツリー表現: エッジ リストを隣接リストに変換してツリーを表現します。
  2. DFS Traversal: ノード 0 から開始して、各サブツリーの値の合計を再帰的に計算します。合計が k で割り切れる場合、そのサブツリーを親から切り離し、有効なコンポーネントを効果的に形成できます。
  3. グローバル カウント: 刃先によって形成された有効なコンポーネントの数を追跡するグローバル カウンタ (結果) を維持します。
  4. 最終チェック: DFS トラバーサルの最後に、ルートのサブツリーの合計が k で割り切れる場合、有効なコンポーネントとしてカウントされることを確認します。

プラン:

  1. 入力解析: 入力を使用可能な形式に変換します。具体的には、ツリーの隣接リスト表現を作成します。
  2. DFS 関数: ノードをルートとするサブツリー内の値の合計を計算する再帰関数 dfs(node) を作成します。この合計が k で割り切れる場合は、結果カウンターをインクリメントし、親にマージして戻らないように 0 を返してエッジを「カット」します。
  3. ルートから DFS を開始します: dfs(0) を呼び出し、結果の最終値を確認します。

解決策の手順:

  1. ツリーの構築: トラバースを容易にするために、エッジ リストを隣接リストに変換します。
  2. 訪問先配列の初期化: 訪問先配列を使用して、ノードを再度訪問しないようにします。
  3. DFS Traversal: ノード 0 から開始して DFS を実行します。ノードごとに、そのサブツリーの値の合計を計算します。
  4. 割り算のチェック: サブツリーの合計が k で割り切れる場合、結果をインクリメントし、サブツリーの合計を 0 にリセットします。
  5. 最終コンポーネント チェック: DFS トラバーサル後、ツリー全体 (ノード 0 をルートとする) の合計が k で割り切れるかどうかを確認し、必要に応じて別のコンポーネントとして考慮します。

このソリューションを PHP で実装してみましょう: 2872。 K で割り切れる成分の最大数

<?php
/**
 * @param Integer $n
 * @param Integer[][] $edges
 * @param Integer[] $values
 * @param Integer $k
 * @return Integer
 */
function maxKDivisibleComponents($n, $edges, $values, $k) {
    ...
    ...
    ...
    /**
     * go to ./solution.php
     */
}

/**
 * DFS Function
 *
 * @param $graph
 * @param $node
 * @param $parent
 * @param $values
 * @param $k
 * @param $ans
 * @return array|bool|int|int[]|mixed|null
 */
private function dfs($graph, $node, $parent, &$values, $k, &$ans) {
    ...
    ...
    ...
    /**
     * go to ./solution.php
     */
}

// Example 1
$n = 5;
$edges = [[0,2],[1,2],[1,3],[2,4]];
$values = [1,8,1,4,4];
$k = 6;
echo maxKDivisibleComponents($n, $edges, $values, $k) . "\n"; // Output: 2

// Example 2
$n = 7;
$edges = [[0,1],[0,2],[1,3],[1,4],[2,5],[2,6]];
$values = [3,0,6,1,5,2,1];
$k = 3;
echo maxKDivisibleComponents($n, $edges, $values, $k) . "\n"; // Output: 3
?>
ログイン後にコピー

説明:

  1. ツリーの構築: ツリー構造を表す隣接リストを構築します。各エッジは 2 つのノードを接続し、この隣接リストを使用してツリーを走査します。
  2. DFS Traversal: DFS 関数は、各ノードをルートとするサブツリーの合計を再帰的に計算します。サブツリーの合計が k で割り切れる場合、結果をインクリメントし、サブツリーを別の有効なコンポーネントとみなします。
  3. サブツリーの合計を返す: 各ノードについて、DFS 関数はそのサブツリーの値の合計を返します。サブツリーが k で割り切れる場合は、合計 0 を返すことでエッジを事実上「カット」し、親ノードとのさらなるマージバックを防ぎます。
  4. 最終チェック: DFS の最後に、ツリー全体の合計が k で割り切れる場合、有効なコンポーネントとしてカウントされることを確認します。

チュートリアルの例:

例 1:

入力:

  • n = 5、エッジ = [[0,2]、[1,2]、[1,3]、[2,4]]、値 = [1,8,1,4,4]、k = 6。

DFS はノード 0 から開始します:

  • ノード 0: サブツリーの合計 = 1
  • ノード 2: サブツリーの合計 = 1 1 4 = 6 (6 で割り切れるので、このエッジをカットできます)
  • ノード 1: サブツリーの合計 = 8 4 = 12 (6 で割り切れ、このエッジをカット)
  • コンポーネントの最終的な数 = 2。

例 2:

入力:

  • n = 7、エッジ = [[0,1]、[0,2]、[1,3]、[1,4]、[2,5]、[2,6]]、値 = [3,0] ,6,1,5,2,1]、k = 3.

DFS はノード 0 から開始します:

  • ノード 0: サブツリーの合計 = 3
  • ノード 2: サブツリーの合計 = 6 2 1 = 9 (3 で割り切れ、このエッジをカット)
  • ノード 1: サブツリーの合計 = 0 5 = 5 (3 で割り切れないため、この合計をマージします)
  • コンポーネントの最終的な数 = 3。

時間計算量:

  • DFS 時間計算量: O(n)、n はノードの数です。各ノードを 1 回訪問し、各ノードで定時間操作を実行します。
  • 空間複雑度: 隣接リスト、訪問配列、および再帰スタックの場合は O(n)。

したがって、全体的な時間と空間の複雑さは O(n) となり、このアプローチは特定の問題の制約に対して効率的になります。

連絡先リンク

このシリーズが役立つと思われた場合は、GitHub で リポジトリ にスターを付けるか、お気に入りのソーシャル ネットワークで投稿を共有することを検討してください。あなたのサポートは私にとって大きな意味を持ちます!

このような役立つコンテンツがさらに必要な場合は、お気軽にフォローしてください:

  • LinkedIn
  • GitHub

以上がK で割り切れる成分の最大数の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:dev.to
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート