新聞中心
本文轉(zhuǎn)載自微信公眾號(hào)「代碼隨想錄」,作者程序員Carl 。轉(zhuǎn)載本文請(qǐng)聯(lián)系代碼隨想錄公眾號(hào)。

左葉子之和
題目地址:https://leetcode-cn.com/problems/sum-of-left-leaves/
計(jì)算給定二叉樹的所有左葉子之和。
示例:
思路
首先要注意是判斷左葉子,不是二叉樹左側(cè)節(jié)點(diǎn),所以不要上來(lái)想著層序遍歷。
因?yàn)轭}目中其實(shí)沒(méi)有說(shuō)清楚左葉子究竟是什么節(jié)點(diǎn),那么我來(lái)給出左葉子的明確定義:如果左節(jié)點(diǎn)不為空,且左節(jié)點(diǎn)沒(méi)有左右孩子,那么這個(gè)節(jié)點(diǎn)就是左葉子
大家思考一下如下圖中二叉樹,左葉子之和究竟是多少?
其實(shí)是0,因?yàn)檫@棵樹根本沒(méi)有左葉子!
那么判斷當(dāng)前節(jié)點(diǎn)是不是左葉子是無(wú)法判斷的,必須要通過(guò)節(jié)點(diǎn)的父節(jié)點(diǎn)來(lái)判斷其左孩子是不是左葉子。
如果該節(jié)點(diǎn)的左節(jié)點(diǎn)不為空,該節(jié)點(diǎn)的左節(jié)點(diǎn)的左節(jié)點(diǎn)為空,該節(jié)點(diǎn)的左節(jié)點(diǎn)的右節(jié)點(diǎn)為空,則找到了一個(gè)左葉子,判斷代碼如下:
- if (node->left != NULL && node->left->left == NULL && node->left->right == NULL) {
- 左葉子節(jié)點(diǎn)處理邏輯
- }
遞歸法
遞歸的遍歷順序?yàn)楹笮虮闅v(左右中),是因?yàn)橐ㄟ^(guò)遞歸函數(shù)的返回值來(lái)累加求取左葉子數(shù)值之和。。
遞歸三部曲:
1.確定遞歸函數(shù)的參數(shù)和返回值
判斷一個(gè)樹的左葉子節(jié)點(diǎn)之和,那么一定要傳入樹的根節(jié)點(diǎn),遞歸函數(shù)的返回值為數(shù)值之和,所以為int
使用題目中給出的函數(shù)就可以了。
2.確定終止條件
依然是
- if (root == NULL) return 0;
3.確定單層遞歸的邏輯
當(dāng)遇到左葉子節(jié)點(diǎn)的時(shí)候,記錄數(shù)值,然后通過(guò)遞歸求取左子樹左葉子之和,和 右子樹左葉子之和,相加便是整個(gè)樹的左葉子之和。
代碼如下:
- int leftValue = sumOfLeftLeaves(root->left); // 左
- int rightValue = sumOfLeftLeaves(root->right); // 右
- // 中
- int midValue = 0;
- if (root->left && !root->left->left && !root->left->right) {
- midValue = root->left->val;
- }
- int sum = midValue + leftValue + rightValue;
- return sum;
整體遞歸代碼如下:
- class Solution {
- public:
- int sumOfLeftLeaves(TreeNode* root) {
- if (root == NULL) return 0;
- int leftValue = sumOfLeftLeaves(root->left); // 左
- int rightValue = sumOfLeftLeaves(root->right); // 右
- // 中
- int midValue = 0;
- if (root->left && !root->left->left && !root->left->right) { // 中
- midValue = root->left->val;
- }
- int sum = midValue + leftValue + rightValue;
- return sum;
- }
- };
以上代碼精簡(jiǎn)之后如下:
- class Solution {
- public:
- int sumOfLeftLeaves(TreeNode* root) {
- if (root == NULL) return 0;
- int midValue = 0;
- if (root->left != NULL && root->left->left == NULL && root->left->right == NULL) {
- midValue = root->left->val;
- }
- return midValue + sumOfLeftLeaves(root->left) + sumOfLeftLeaves(root->right);
- }
- };
迭代法
本題迭代法使用前中后序都是可以的,只要把左葉子節(jié)點(diǎn)統(tǒng)計(jì)出來(lái),就可以了,那么參考文章 二叉樹:聽說(shuō)遞歸能做的,棧也能做!和二叉樹:迭代法統(tǒng)一寫法中的寫法,可以寫出一個(gè)前序遍歷的迭代法。
判斷條件都是一樣的,代碼如下:
- class Solution {
- public:
- int sumOfLeftLeaves(TreeNode* root) {
- stack
st; - if (root == NULL) return 0;
- st.push(root);
- int result = 0;
- while (!st.empty()) {
- TreeNode* node = st.top();
- st.pop();
- if (node->left != NULL && node->left->left == NULL && node->left->right == NULL) {
- result += node->left->val;
- }
- if (node->right) st.push(node->right);
- if (node->left) st.push(node->left);
- }
- return result;
- }
- };
總結(jié)
這道題目要求左葉子之和,其實(shí)是比較繞的,因?yàn)椴荒芘袛啾竟?jié)點(diǎn)是不是左葉子節(jié)點(diǎn)。
此時(shí)就要通過(guò)節(jié)點(diǎn)的父節(jié)點(diǎn)來(lái)判斷其左孩子是不是左葉子了。
平時(shí)我們解二叉樹的題目時(shí),已經(jīng)習(xí)慣了通過(guò)節(jié)點(diǎn)的左右孩子判斷本節(jié)點(diǎn)的屬性,而本題我們要通過(guò)節(jié)點(diǎn)的父節(jié)點(diǎn)判斷本節(jié)點(diǎn)的屬性。
希望通過(guò)這道題目,可以擴(kuò)展大家對(duì)二叉樹的解題思路。
其他語(yǔ)言版本
Java
遞歸
- class Solution {
- public int sumOfLeftLeaves(TreeNode root) {
- if (root == null) return 0;
- int leftValue = sumOfLeftLeaves(root.left); // 左
- int rightValue = sumOfLeftLeaves(root.right); // 右
- int midValue = 0;
- if (root.left != null && root.left.left == null && root.left.right == null) { // 中
- midValue = root.left.val;
- }
- int sum = midValue + leftValue + rightValue;
- return sum;
- }
- }
迭代
- class Solution {
- public int sumOfLeftLeaves(TreeNode root) {
- if (root == null) return 0;
- Stack
stack = new Stack<> (); - stack.add(root);
- int result = 0;
- while (!stack.isEmpty()) {
- TreeNode node = stack.pop();
- if (node.left != null && node.left.left == null && node.left.right == null) {
- result += node.left.val;
- }
- if (node.right != null) stack.add(node.right);
- if (node.left != null) stack.add(node.left);
- }
- return result;
- }
- }
Python
遞歸
- class Solution:
- def sumOfLeftLeaves(self, root: TreeNode) -> int:
- if not root:
- return 0
- left_left_leaves_sum = self.sumOfLeftLeaves(root.left) # 左
- right_left_leaves_sum = self.sumOfLeftLeaves(root.right) # 右
- cur_left_leaf_val = 0
- if root.left and not root.left.left and not root.left.right:
- cur_left_leaf_val = root.left.val # 中
- return cur_left_leaf_val + left_left_leaves_sum + right_left_leaves_sum
迭代
- class Solution:
- def sumOfLeftLeaves(self, root: TreeNode) -> int:
- """
- Idea: Each time check current node's left node.
- If current node don't have one, skip it.
- """
- stack = []
- if root:
- stack.append(root)
- res = 0
- while stack:
- # 每次都把當(dāng)前節(jié)點(diǎn)的左節(jié)點(diǎn)加進(jìn)去.
- cur_node = stack.pop()
- if cur_node.left and not cur_node.left.left and not cur_node.left.right:
- res += cur_node.left.val
- if cur_node.left:
- stack.append(cur_node.left)
- if cur_node.right:
- stack.append(cur_node.right)
- return res
新聞標(biāo)題:做了這么多題目了,會(huì)求左葉子之和么?
瀏覽地址:http://www.5511xx.com/article/djiicgi.html


咨詢
建站咨詢
