513 找树左下角的值
题目链接:513. 找树左下角的值 - 力扣(LeetCode)
给定一个二叉树的 根节点 root
,请找出该二叉树的 最底层 最左边 节点的值。
假设二叉树中至少有一个节点。
方法1 递归
思路:
获取每个节点的深度,当每次超过maxdepth,则更新答案,最终得到的必定是最底层最左边的,因为它右边的和它高度一致,不会被更新。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
void dfs(TreeNode* cur, int& ans, int depth, int& maxdepth)
{
if(cur == nullptr) return;
if(cur->left == nullptr && cur->right == nullptr)
{
depth++;
if(depth > maxdepth)
{
maxdepth = depth;
ans = cur->val;
}
}
depth++;
dfs(cur->left, ans, depth, maxdepth);
dfs(cur->right, ans, depth, maxdepth);
}
int findBottomLeftValue(TreeNode* root) {
int ans = 0;
int maxdepth = 0;
dfs(root, ans, 0, maxdepth);
return ans;
}
};
方法2 迭代
使用层序遍历,将每行的第一个赋值给ans,最终ans为最底层最左边。
class Solution {
public:
int findBottomLeftValue(TreeNode* root) {
queue<TreeNode*> q;
int ans;
if(root != nullptr)
q.push(root);
while(!q.empty())
{
int qSize = q.size();
ans = (q.front())->val;
for(int i = 0; i < qSize; i++)
{
TreeNode* cur = q.front();
q.pop();
if(cur->left) q.push(cur->left);
if(cur->right) q.push(cur->right);
}
}
return ans;
}
};
112 路径总和
给你二叉树的根节点 root
和一个表示目标和的整数 targetSum
。判断该树中是否存在 根节点到叶子节点 的路径,这条路径上所有节点值相加等于目标和 targetSum
。如果存在,返回 true
;否则,返回 false
。
叶子节点 是指没有子节点的节点。
思路:
对每个节点累加,若存在满足条件的,则修改ans为true。
class Solution {
public:
void dfs(TreeNode* cur, int targetSum, int sum, bool& ans)
{
if(cur == nullptr) return;
if(cur->left == nullptr && cur->right == nullptr) //叶子节点
{
sum += cur->val;
if(sum == targetSum)
{
ans = true;
}
return;
}
sum += cur->val;
dfs(cur->left, targetSum, sum, ans);
dfs(cur->right, targetSum, sum, ans);
}
bool hasPathSum(TreeNode* root, int targetSum) {
bool ans = false;
dfs(root, targetSum, 0, ans);
return ans;
}
};
113 路径总和Ⅱ
题目链接:
113. 路径总和 II - 力扣(LeetCode)
给你二叉树的根节点 root
和一个整数目标和 targetSum
,找出所有 从根节点到叶子节点 路径总和等于给定目标和的路径。
叶子节点 是指没有子节点的节点。
思路:
对上述代码稍作修改即可。
class Solution {
public:
void dfs(TreeNode* cur, int targetSum, int sum, vector<int> path, vector<vector<int>>& ans)
{
if(cur == nullptr) return;
if(cur->left == nullptr && cur->right == nullptr)
{
sum += cur->val;
path.push_back(cur->val);
if(sum == targetSum)
{
ans.push_back(path);
}
return;
}
sum += cur->val;
path.push_back(cur->val);
dfs(cur->left, targetSum, sum, path, ans);
dfs(cur->right, targetSum, sum, path, ans);
}
vector<vector<int>> pathSum(TreeNode* root, int targetSum) {
vector<vector<int>> ans;
vector<int> path;
dfs(root, targetSum, 0, path, ans);
return ans;
}
};
106 从中序与后序遍历序列构造二叉树
题目链接:
106. 从中序与后序遍历序列构造二叉树 - 力扣(LeetCode)
给定两个整数数组 inorder
和 postorder
,其中 inorder
是二叉树的中序遍历, postorder
是同一棵树的后序遍历,请你构造并返回这颗 二叉树 。
思路:
使用hashmap存储inorder元素与下标值,使用helper函数递归创建二叉树,helper函数只需要弄清楚inorder和postorder中左右子树范围即可。
class Solution {
public:
TreeNode* helper(vector<int>& inorder, vector<int>& postorder,
int inStart, int inEnd,
int postStart, int postEnd,
unordered_map<int, int>& map)
{
if (inStart > inEnd || postStart > postEnd) {
return nullptr;
}
TreeNode* root = new TreeNode(postorder[postEnd]);
int rootIndex = map[postorder[postEnd]];
root->left = helper(inorder, postorder,
inStart, rootIndex - 1,
postStart, postStart + rootIndex - inStart - 1,
map);
root->right = helper(inorder, postorder,
rootIndex + 1, inEnd,
postStart + rootIndex - inStart, postEnd - 1,
map);
return root;
}
TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
if (inorder.empty() || postorder.empty() || inorder.size() != postorder.size()) return nullptr;
unordered_map<int, int> map;
for (int i = 0; i < inorder.size(); ++i)
{
map[inorder[i]] = i;
}
return helper(inorder, postorder, 0, inorder.size() - 1, 0, postorder.size() - 1, map);
}
};
参考题解:
LeetCode 106. Construct Binary Tree from Inorder and Postorder Traversal | JIAKAOBO
105 从前序与中序遍历序列构造二叉树
题目链接:105. 从前序与中序遍历序列构造二叉树 - 力扣(LeetCode)
给定两个整数数组 preorder
和 inorder
,其中 preorder
是二叉树的先序遍历, inorder
是同一棵树的中序遍历,请构造二叉树并返回其根节点。
思路:
本题与上题方法类似,但对于preorder,只需要靠preStart即可确定左右子树。
class Solution {
public:
TreeNode* helper(vector<int>& preorder, vector<int>& inorder,
int preStart,
int inStart, int inEnd,
unordered_map<int, int>& map)
{
if (preStart >= preorder.size() || inStart > inEnd) {
return nullptr;
}
TreeNode* root = new TreeNode(preorder[preStart]);
int rootIndex = map[preorder[preStart]];
root->left = helper(preorder, inorder, preStart + 1, inStart, rootIndex - 1, map);
root->right = helper(preorder, inorder, preStart + rootIndex - inStart + 1, rootIndex + 1, inEnd, map);
return root;
}
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
if (inorder.empty() || preorder.empty() || inorder.size() != preorder.size()) return nullptr;
unordered_map<int, int> map;
for (int i = 0; i < inorder.size(); ++i)
{
map[inorder[i]] = i;
}
return helper(preorder, inorder, 0, 0, inorder.size() - 1, map);
}
};