文章目录
介绍
二叉树的遍历可参考 二叉树的非递归遍历【前序|中序|后序】-解释非常清晰
下面介绍几道关于二叉树遍历的题目。
Leetcode 面试题34. 二叉树中和为某一值的路径
问题描述
输入一棵二叉树和一个整数,打印出二叉树中节点值的和为输入整数的所有路径。从树的根节点开始往下一直到叶节点所经过的节点形成一条路径。
示例:
给定如下二叉树,以及目标和 sum = 22,
返回:
[
[5,4,11,2],
[5,8,4,5]
]
实现代码
class Solution {
public:
vector<vector<int>> pathSum(TreeNode* root, int sum) {
vector<vector<int>> ans; vector<int> path;
stack<TreeNode *> stk;
TreeNode *p = root, *prev = nullptr;
while (p || !stk.empty()) {
while (p) {
path.push_back(p->val);
sum -= p->val;
stk.push(p);
p = p->left; // 一直往左
}
p = stk.top(); //不能再左了,取得右拐点(根结点)
// 这里的!p->left不能漏
if (!p->left && !p->right && !sum) ans.push_back(path); // 找到一组解
if (!p->right || p->right == prev) {
sum += p->val;
path.pop_back();
stk.pop();
prev = p; // 标记已经使用
p = nullptr; // 回溯
} else {
p = p->right; // 处理右子树
}
}
return ans;
}
};
Leetcode 257. 二叉树的所有路径
问题描述
给定一个二叉树,返回所有从根节点到叶子节点的路径。
说明: 叶子节点是指没有子节点的节点。
输入:
输出: [“1->2->5”, “1->3”]
解释: 所有根节点到叶子节点的路径为: 1->2->5, 1->3
解题报告
这道题使用非递归后序遍历时,关键点在于箭头的输出
。
第一点:输出指向左孩子的箭头时,要确保左孩子存在;
第二点:在转向右孩子时【右孩子存在】,在路径加上箭头;
第三点:回溯时,不仅将节点弹出,还要讲箭头弹出,当然我们需要确保路径中有这两个元素。
实现代码
代码源自题解区 Victor
。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
vector<string> binaryTreePaths(TreeNode* root) {
vector<string> ans;
vector<string> path;
stack<TreeNode *> stk;
TreeNode *p = root, *prev = nullptr;
while (p || !stk.empty()) {
while (p) {
path.push_back(to_string(p->val));
if(p->left!=NULL) path.push_back("->");
stk.push(p);
p = p->left; // 一直往左
}
p = stk.top(); //不能再左了,取得右拐点(根结点)
if (!p->left && !p->right){
string tmp="";
for(int i=0;i<path.size();i++){
tmp+=path[i];
}
ans.push_back(tmp);
};
if(p->right&&p->right!=prev){
p = p->right; // 处理右子树
path.push_back("->");
}
else{
if(path.size()>=2){
path.pop_back();
path.pop_back();
}
stk.pop();
prev = p;
p = nullptr;
}
}
return ans;
}
};
Leetcode 129. 求根到叶子节点数字之和
问题描述
给定一个二叉树,它的每个结点都存放一个 0-9 的数字,每条从根到叶子节点的路径都代表一个数字。
例如,从根到叶子节点路径 1->2->3 代表数字 123。
计算从根到叶子节点生成的所有数字之和。
说明: 叶子节点是指没有子节点的节点。
输入: [4,9,0,5,1]
输出: 1026
解释:
从根到叶子节点路径 4->9->5 代表数字 495.
从根到叶子节点路径 4->9->1 代表数字 491.
从根到叶子节点路径 4->0 代表数字 40.
因此,数字总和 = 495 + 491 + 40 = 1026.
解题报告
略。具体参考代码。
实现代码
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
int sumNumbers(TreeNode* root) {
int ans=0,sum=0;
stack<TreeNode *> stk;
TreeNode *p = root, *prev = nullptr;
while (p || !stk.empty()) {
while (p) {
sum=sum*10+p->val;
stk.push(p);
p = p->left; // 一直往左
}
p = stk.top(); //不能再左了,取得右拐点(根结点)
if (!p->left && !p->right) ans+=sum;
if(p->right&&p->right!=prev) p=p->right;
else{
sum=(sum-p->val)/10; //或者 sum/=10;因为p->val是个位数。
stk.pop();
prev = p; // 标记已经使用
p = nullptr; // 回溯
}
}
return ans;
}
};
参考资料
[1] Leetcode 面试题34. 二叉树中和为某一值的路径
[2] 题解区:Victor
[3] Leetcode 257. 二叉树的所有路径
[4] Leetcode 129. 求根到叶子节点数字之和