【LeetCode】每日一題129:求根到葉子節點數字之和
129.求根到葉子節點數字之和
給定一個二叉樹,它的每個結點都存放一個 0-9 的數字,每條從根到葉子節點的路徑都代表一個數字。
例如,從根到葉子節點路徑 1->2->3 代表數字 123。
計算從根到葉子節點生成的所有數字之和。
說明: 葉子節點是指沒有子節點的節點。
示例 1:
- 輸入: [1,2,3]
1
/ \
2 3 - 輸出: 25
- 解釋:
從根到葉子節點路徑 1->2 代表數字 12.
從根到葉子節點路徑 1->3 代表數字 13.
因此,數字總和 = 12 + 13 = 25.
示例 2:
- 輸入: [4,9,0,5,1]
4
/ \
9 0
/ \
5 1 - 輸出: 1026
- 解釋:
從根到葉子節點路徑 4->9->5 代表數字 495.
從根到葉子節點路徑 4->9->1 代表數字 491.
從根到葉子節點路徑 4->0 代表數字 40.
因此,數字總和 = 495 + 491 + 40 = 1026.
節點類如下:
public class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) { val = x; }
}
思考:
題目是計算「根節點」到每個「葉子節點」對應的數字之和,必然需要遍歷二叉樹的每個「葉子節點」,首先想到「深度優先遍歷」。當然,「廣度優先遍歷」也能解決問題,稍微複雜一些。
「深度優先遍歷」:沿著一條路一直走到底,然後從這條路盡頭的節點回退到上一個節點,再從另一條路開始走到底…,不斷遞迴重複此過程。
「廣度優先遍歷」:指的是從圖的一個未遍歷的節點出發,先遍歷這個節點的相鄰節點,再依次遍歷每個相鄰節點的相鄰節點。
「葉子節點」:沒有兒子的節點。
關於兩種遍歷的詳解,可以參考此文章,講得非常好:https://developer.51cto.com/art/202004/614590.htm
方法一:深度優先遍歷
摘自官方解答:從根節點開始,遍歷每個節點,如果遇到葉子節點,則將葉子節點對應的數字加到數字之和。如果當前節點不是葉子節點,則計算其子節點對應的數字,然後對子節點遞迴遍歷。
這裡用了一個巧妙的方式:當前節點的計算值 = 父節點的計算值 × 10 + 當前節點的值
對應程式碼中 sum = sum * 10 + root.val
public int sumNumbers(TreeNode root) {
int sum = 0;
return sum(root, sum);
}
public int sum(TreeNode root, int sum){
if (root == null) {
return 0;
}
sum = sum * 10 + root.val;
if (root.left == null && root.right == null) {
return sum;
}
return sum(root.left, sum) + sum(root.right, sum);
}
方法二:廣度優先遍歷
同樣摘自官方解答:使用廣度優先搜尋,需要維護兩個佇列,分別儲存節點和節點對應的數字。
初始時,將根節點和根節點的值分別加入兩個佇列。每次從兩個佇列分別取出一個節點和一個數字,進行如下操作:
1.如果當前節點是葉子節點,則將該節點對應的數字加到數字之和;
2.如果當前節點不是葉子節點,則獲得當前節點的非空子節點,並根據當前節點對應的數字和子節點的值計運算元節點對應的數字,然後將子節點和子節點對應的數字分別加入兩個佇列。
public int sumNumbers2(TreeNode root) {
if (root == null) {
return 0;
}
Queue<Integer> numQueue = new LinkedList<>();
Queue<TreeNode> nodeQueue = new LinkedList<>();
// 初始化
numQueue.offer(root.val);
nodeQueue.offer(root);
int sum = 0;
while (!nodeQueue.isEmpty()) {
TreeNode cur = nodeQueue.poll();
int num = numQueue.poll();
if (cur.left == null && cur.right == null) {
sum += num;
} else {
if (cur.left != null) {
nodeQueue.offer(cur.left);
numQueue.offer(num * 10 + cur.left.val);
}
if (cur.right != null) {
nodeQueue.offer(cur.right);
numQueue.offer(num * 10 + cur.right.val);
}
}
}
return sum;
}
執行結果:深度優先遍歷
相關文章
- leetcode129. 求根到葉子節點數字之和LeetCode
- 129 - 求根到葉子節點數字之和 - PythonPython
- LeetCode-129-求根節點到葉節點數字之和LeetCode
- LeetCode每日一題:兩數之和(No.1)LeetCode每日一題
- 【js】Leetcode每日一題-葉子相似的樹JSLeetCode每日一題
- LeetCode每日一題 (32)1. 兩數之和LeetCode每日一題
- LeetCode-404-左葉子之和LeetCode
- leetcode------給定一個二叉樹和一個值sum,判斷是否有從根節點到葉子節點的節點值之和等於sum 的路徑,LeetCode二叉樹
- 每日一道 LeetCode (1):兩數之和LeetCode
- 404. 左葉子之和
- 10.5 每日一題 18. 四數之和每日一題
- 【10月打卡~Leetcode每日一題】18. 四數之和(難度:中等)LeetCode每日一題
- LeetCode 每日一題,用 Go 實現兩數之和的非暴力解法LeetCode每日一題Go
- MySQL:非葉子節點指標MySql指標
- 二叉樹節點個數,葉子個數,第K層個數,最低公共節點二叉樹
- LeetCode每日一題: 猜數字大小(No.374)LeetCode每日一題
- 每日一道演算法題:1.兩數之和演算法
- LeetCode每日一題:只出現一次的數字(No.136)LeetCode每日一題
- Leetcode第一題:兩數之和(3種語言)LeetCode
- 為什麼二叉樹中葉子節點個數等於度為2的節點個數+1二叉樹
- 每日一道 LeetCode (4):羅馬數字轉整數LeetCode
- 一句話查詢出指定節點的葉子記錄
- 每日一題:五 特別的數字每日一題
- [LeetCode 刷題] 1. 兩數之和LeetCode
- LeetCode題集-1- 兩數之和LeetCode
- 每日一道演算法, 《兩數之和》演算法
- [每日一題] 第十三題:連結串列中倒數第k個節點每日一題
- LeetCode 之 JavaScript 解答第一題 —— 兩數之和(Two Sum)LeetCodeJavaScript
- LeetCode每日一題:刪除連結串列中的節點(No.237)LeetCode每日一題
- LeetCode每日一題:自除數(No.728)LeetCode每日一題
- LeetCode每日一題:迴文數(No.9)LeetCode每日一題
- leetcode每日一題LeetCode每日一題
- LeetCode:兩數之和LeetCode
- LeetCode - 兩數之和LeetCode
- #leetcode刷題之路1-兩數之和LeetCode
- leetCode解題記錄1 - 兩數之和LeetCode
- leetcode----給定一個二叉樹,返回該二叉樹由底層到頂層的層序遍歷,(從左向右,從葉子節點到根節點,一層一層的遍歷)LeetCode二叉樹
- LeetCode每日一題:整數反轉(No.7)LeetCode每日一題