题目链接:513. 找树左下角的值
层序迭代法:将遍历最深一层之前队列第一个值取出来就是结果。
class Solution {
public:
int findBottomLeftValue(TreeNode* root) {
queue<TreeNode*> que;
que.push(root);
int result = root->val;
while(!que.empty()) {
size_t size = que.size();
result = que.front()->val;
while(size--) {
if(que.front()->left)
que.push(que.front()->left);
if(que.front()->right)
que.push(que.front()->right);
que.pop();
}
}
return result;
}
};
递归法:
为什么在max_depth更新时取节点的值,最终就是结果?
左右子树遍历顺序决定,先遍历左子树,保证每层在遍历时第一个元素为每层最右侧的值。
class Solution {
public:
int findBottomLeftValue(TreeNode* root) {
int max_depth = 1;
int result = root->val;
backtracking(root, max_depth, result, 1);
return result;
}
void backtracking(TreeNode* node, int& max_depth, int& result, int depth){
if(node->right == nullptr && node->left == nullptr){
if(depth > max_depth) {
result = node->val;
max_depth = depth;
}
}
if(node->left) backtracking(node->left, max_depth, result, depth + 1);
if(node->right) backtracking(node->right, max_depth, result, depth + 1);
}
};
题目链接:112. 路径总和
自己写的代码没看视频,选用中序遍历,每次第一个取到当前节点的值
class Solution {
public:
bool hasPathSum(TreeNode* root, int targetSum) {
if(root == nullptr) return false;
targetSum = targetSum - root->val;
if(root->left == nullptr && root->right == nullptr && targetSum == 0) return true;
bool right = false, left = false;
if(root->left) left = hasPathSum(root->left, targetSum);
if(left) return left;
if(root->right) right = hasPathSum(root->right, targetSum);
return right;
}
};
题目链接:113. 路径总和 II
与上题思路相同
class Solution {
public:
vector<vector<int>> pathSum(TreeNode* root, int targetSum) {
vector<int> vec;
vector<vector<int>> result;
frontReaversal(root, targetSum, vec, result);
return result;
}
void frontReaversal(TreeNode* node, int targetSum, vector<int>& vec, vector<vector<int>>& result) {
if(node == nullptr) return;
targetSum -= node->val;
vec.push_back(node->val);
if(node->left == nullptr && node->right == nullptr && targetSum == 0){
result.push_back(vec);
}
if(node->left) frontReaversal(node->left, targetSum, vec, result);
if(node->right) frontReaversal(node->right, targetSum, vec, result);
vec.pop_back();
}
};
题目链接:106. 从中序与后序遍历序列构造二叉树
题目前提:数组中元素各不相同。
思路:后续遍历数组取最后一个元素为根节点,找到中序遍历数组中根节点的位置,该位置左右两侧为左右子树各元素,以及元素数量。在后续遍历数组中划分左右子树,递归。
class Solution {
public:
TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
if(postorder.empty()) return nullptr;
TreeNode* curr = new TreeNode(*(postorder.end() - 1));
vector<int>::iterator iter;
iter = inorder.begin();
while(*iter != curr->val) iter++;
vector<int> left_tree_inorder(inorder.begin(), iter);
vector<int> left_tree_postorder(postorder.begin(), postorder.begin() + (iter - inorder.begin()));
curr->left = buildTree(left_tree_inorder, left_tree_postorder);
vector<int> right_tree_inorder(iter + 1, inorder.end());
vector<int> right_tree_postorder(postorder.begin() + (iter - inorder.begin()), postorder.end() - 1);
curr->right = buildTree(right_tree_inorder, right_tree_postorder);
return curr;
}
};
题目链接:105. 从前序与中序遍历序列构造二叉树
思路与上题类似
class Solution {
public:
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
if(preorder.empty()) return nullptr;
TreeNode* curr = new TreeNode(preorder[0]);
int mid_idx = 0;
while(inorder[mid_idx] != curr->val) mid_idx++;
vector<int> left_preorder(preorder.begin() + 1, preorder.begin() + 1 + mid_idx);
vector<int> left_inorder(inorder.begin(), inorder.begin() + mid_idx);
curr->left = buildTree(left_preorder, left_inorder);
vector<int> right_preorder(preorder.begin() + 1 + mid_idx, preorder.end());
vector<int> right_inorder(inorder.begin() + mid_idx + 1, inorder.end());
curr->right = buildTree(right_preorder, right_inorder);
return curr;
}
};