1 solutions
-
0
🧠 本題知識點
本題涉及以下幾個資料結構與演算法的知識點:
- 二元樹重建:根據完全先序遍歷(包含
"null")還原原始樹結構。 - 先序遍歷解析:Preorder traversal 的順序為:根節點 → 左子樹 → 右子樹。
- 層序遍歷(BFS):使用佇列(Queue)進行逐層訪問,記錄每層節點總和,保留最後一層的總和作為輸出。
- 字串轉整數:使用
stoi()處理輸入。 - 指標與遞迴:樹的構建使用遞迴實現,並利用引用方式追蹤目前遍歷位置。
🔍 程式碼逐行解析
#include<iostream> #include<vector> #include<queue> #include<cmath> using namespace std;- 引入標準函式庫,包括輸入輸出、動態陣列、佇列、數學。
struct Node { int val; Node* left; Node* right; Node(int v): val(v), left(NULL), right(NULL) {} };- 定義二元樹節點,包含一個整數值
val和左右子樹指標。
Node* buildTrees(vector<string>& preorder, int& i) { if(i >= preorder.size() || preorder[i] == "null") { i += 1; return NULL; }- 遞迴建樹的終止條件:若讀到
"null"或超出邊界,返回空指標。
Node* node = new Node(stoi(preorder[i])); i += 1; node->left = buildTrees(preorder, i); node->right = buildTrees(preorder, i); return node; }- 建立新節點,並遞迴建構左子樹與右子樹。
int main() { int n; cin >> n; vector<string> preorder = {};- 讀取輸入大小,建立字串陣列儲存先序遍歷資料。
for(int i = 0; i < n; i++) { string x; cin >> x; preorder.push_back(x); }- 將每一個字串輸入讀入 vector。
int c = 0; Node* root = buildTrees(preorder, c);- 開始從第 0 個位置建樹。
queue<Node*> qqq = {}; qqq.push(root);- 使用佇列進行層序遍歷。
int deep_size = 0;- 記錄最後一層(最深層)的節點總和。
while(!qqq.empty()) { int level_sum = 0; int size = qqq.size();- 每次進入 while 代表一層。
for(int i = 0; i < size; i++) { Node* node = qqq.front(); qqq.pop(); level_sum += node->val; if(node->left) qqq.push(node->left); if(node->right) qqq.push(node->right); }-
對當前層的每個節點:
- 計算總和
- 加入下一層子節點
deep_size = level_sum; } cout << deep_size << endl; return 0; }- 每層更新
deep_size,直到最深層。最終輸出結果。
🌳 樹形結構示意圖
輸入:
1 2 4 null null 5 null null 3 null 6 null null所還原的二元樹:
1 / \ 2 3 / \ \ 4 5 6層序遍歷(BFS)分層為:
第 1 層:1 第 2 層:2, 3 第 3 層:4, 5, 6 ← 最深層
🔁 程式邏輯流程圖(文字版)
-
讀入
n和先序序列。 -
使用
buildTrees()還原樹。 -
利用 Queue 做 BFS:
- 每層更新節點總和
level_sum - 保留最後一次的
level_sum為deep_size
- 每層更新節點總和
-
輸出
deep_size
✅ 輸出說明
對於輸入:
13 1 2 4 null null 5 null null 3 null 6 null null最深層節點為:4, 5, 6 總和為:
4 + 5 + 6 = 15
💻 完整程式碼
#include<iostream> #include<vector> #include<queue> using namespace std; struct Node { int val; Node* left; Node* right; Node(int v): val(v), left(NULL), right(NULL) {} }; Node* buildTrees(vector<string>& preorder, int& i) { if(i >= preorder.size() || preorder[i] == "null") { i += 1; return NULL; } Node* node = new Node(stoi(preorder[i])); i += 1; node->left = buildTrees(preorder, i); node->right = buildTrees(preorder, i); return node; } int main() { int n; cin >> n; vector<string> preorder(n); for(int i = 0; i < n; i++) { cin >> preorder[i]; } int c = 0; Node* root = buildTrees(preorder, c); queue<Node*> qqq; qqq.push(root); int deep_sum = 0; while(!qqq.empty()) { int size = qqq.size(); int level_sum = 0; for(int i = 0; i < size; i++) { Node* node = qqq.front(); qqq.pop(); level_sum += node->val; if(node->left) qqq.push(node->left); if(node->right) qqq.push(node->right); } deep_sum = level_sum; } cout << deep_sum << endl; return 0; } - 二元樹重建:根據完全先序遍歷(包含
Information
- ID
- 989
- Time
- 256ms
- Memory
- 256MiB
- Difficulty
- 10
- Tags
- (None)
- # Submissions
- 12
- Accepted
- 2
- Uploaded By