チャレンジ一覧に戻る
中級 0件解決済み 正答率0%

コンポジットでフォルダーサイズ

フォルダがファイルや他のフォルダを含む木構造で、すべてのフォルダの合計サイズを計算します。

このチャレンジで学べること

  • 単体とグループを同じように扱う
  • 子の合計を親に足し込む
  • 葉から根に向かって木をたどる

問題

原文(英語)を表示

コンポジット パターンは、単一のオブジェクトとオブジェクトのグループを同じように扱います。フォルダのサイズは、自分自身のファイルサイズに、その中にあるすべてのサイズを、どれだけ深く入っていても足し合わせたものです。

n 個のアイテムが 0 から n − 1 まで番号付けされており、木構造を形成しています。parents[i] はアイテム i を含むフォルダで、ルートの場合は -1 です(ルートはちょうど 1 つ)。sizes[i] はアイテム i 自身の内容のサイズです。

composite_folder_sizes(parents, sizes) を実装してください。

Input

parents: 各アイテムの親。

sizes: 各アイテムの自身のサイズ。

Output

各アイテムについて、その合計サイズを返してください: 自身のサイズに、すべての子の合計を足したものです。

制約

1 ≤ n ≤ 100,000

0 ≤ sizes[i] ≤ 10^9; parents は 1 本の木を表す

例

例 1
入力:
sizes = [1, 2, 3, 4]
parents = [-1, 0, 0, 1]

期待される出力:
expected = [10, 6, 3, 4]
入力:
std::vector<long long> sizes = {1, 2, 3, 4};
std::vector<long long> parents = {-1, 0, 0, 1};

期待される出力:
std::vector<long long> expected = {10, 6, 3, 4};
入力:
long[] sizes = new long[] {1, 2, 3, 4};
long[] parents = new long[] {-1, 0, 0, 1};

期待される出力:
long[] expected = new long[] {10, 6, 3, 4};

解説

Item 3 (size 4) は item 1 の中にあるので、item 1 の合計は 2 + 4 = 6 です。ルートは item 1 と item 2 を持ちます: 1 + 6 + 3 = 10. 結果: [10, 6, 3, 4].

例 2
入力:
sizes = [5, 0, 7]
parents = [1, -1, 1]

期待される出力:
expected = [5, 12, 7]
入力:
std::vector<long long> sizes = {5, 0, 7};
std::vector<long long> parents = {1, -1, 1};

期待される出力:
std::vector<long long> expected = {5, 12, 7};
入力:
long[] sizes = new long[] {5, 0, 7};
long[] parents = new long[] {1, -1, 1};

期待される出力:
long[] expected = new long[] {5, 12, 7};

解説

ルートは item 1 で、自身の内容はありません; そこには item 0 と item 2 が含まれます: 0 + 5 + 7 = 12.

解き方のヒント

まずは自分で考えてから、ヒントを 1 つずつ開いてみましょう。

ヒント 1

フォルダーの合計は自身のサイズと子の合計の和です。

ヒント 2

子を親より先に処理します。たとえば深い順に処理します。

ヒント 3

長い連鎖で深い再帰は避けましょう。明示的なスタックや順序のほうが安全です。

目安の計算量

時間 O(n)、追加メモリ O(n)

参考資料

この課題はCodeUtility用に調整されています。上記の説明と制約に従ってください。

他の人の解答から学ぶ

コミュニティの解答

まだ公開された解答がありません。この課題を解いて最初の解答を共有しましょう。