Find the sum of all left leaves in a given binary tree.
Example:
3 / \ 9 20 / \ 15 7 There are two left leaves in the binary tree, with values 9 and 15 respectively. Return 24.
這道題讓我們求一棵二叉樹的所有左子葉的和,那么看到這道題我們知道這肯定是考二叉樹的遍歷問題,那么最簡潔的寫法肯定是用遞歸,由於我們只需要累加左子葉之和,那么我們在進入遞歸函數的時候需要知道當前結點是否是左子節點,如果是左子節點,而且該左子節點再沒有子節點了說明其是左子葉,那么我們將其值加入結果res中,我們用一個bool型的變量,如果為true說明當前結點是左子節點,若為false則說明是右子節點,不做特殊處理,整個來說就是個遞歸的先序遍歷的寫法,參見代碼如下:
解法一:
class Solution { public: int sumOfLeftLeaves(TreeNode* root) { if (!root || (!root->left && !root->right)) return 0; int res = 0; helper(root->left, true, res); helper(root->right, false, res); return res; } void helper(TreeNode* node, bool left, int& res) { if (!node) return; if (!node->left && !node->right && left) res += node->val; helper(node->left, true, res); helper(node->right, false, res); } };
我們還可以寫的更簡潔一些,不需要寫其他的函數,直接在原函數中檢查當前節點的左子節點是否是左子葉,如果是的話,則返回左子葉的值加上對當前結點的右子節點調用遞歸的結果;如果不是的話,我們對左右子節點分別調用遞歸函數,返回二者之和,參見代碼如下:
解法二:
class Solution { public: int sumOfLeftLeaves(TreeNode* root) { if (!root) return 0; if (root->left && !root->left->left && !root->left->right) { return root->left->val + sumOfLeftLeaves(root->right); } return sumOfLeftLeaves(root->left) + sumOfLeftLeaves(root->right); } };
我們也可以使用迭代來解,因為這道題的本質是遍歷二叉樹,所以我們可以用層序遍歷的迭代寫法,利用queue來輔助,注意對左子葉的判斷和處理,參見代碼如下:
解法三:
class Solution { public: int sumOfLeftLeaves(TreeNode* root) { if (!root || (!root->left && !root->right)) return 0; int res = 0; queue<TreeNode*> q; q.push(root); while (!q.empty()) { TreeNode *t = q.front(); q.pop(); if (t->left && !t->left->left && !t->left->right) res += t->left->val; if (t->left) q.push(t->left); if (t->right) q.push(t->right); } return res; } };
我們也可以用stack來輔助,對比上面的解法,我們發現幾乎一模一樣,只是把queue換成了stack,但實際上遍歷的順序不同,這種方法是先序遍歷的迭代寫法,參見代碼如下:
解法四:
class Solution { public: int sumOfLeftLeaves(TreeNode* root) { if (!root || (!root->left && !root->right)) return 0; int res = 0; stack<TreeNode*> s; s.push(root); while (!s.empty()) { TreeNode *t = s.top(); s.pop(); if (t->left && !t->left->left && !t->left->right) res += t->left->val; if (t->left) s.push(t->left); if (t->right) s.push(t->right); } return res; } };
參考資料:
https://discuss.leetcode.com/topic/60467/3-line-c-solution
https://discuss.leetcode.com/topic/60381/java-solution-using-bfs
https://discuss.leetcode.com/topic/60415/java-solution-with-stack