● 513.找树左下角的值
● 112. 路径总和 113.路径总和ii
● 106.从中序与后序遍历序列构造二叉树 105.从前序与中序遍历序列构造二叉树
513. 找树左下角的值
先迭代法水一下
class Solution {
public:
int findBottomLeftValue(TreeNode* root) {
queue<TreeNode*> q;
q.push(root);
int res = 0;
while(!q.empty()) {
int size = q.size();
for(int i = 0; i < size; ++i) {
TreeNode* node = q.front();
q.pop();
if(!i) res = node->val;
if(node->left != nullptr) q.push(node->left);
if(node->right != nullptr) q.push(node->right);
}
}
return res;
}
};
递归的话……应该还是得DFS
一遍过,很容易
递归主要是还是判断边界条件,叶子结点自然是 【左右孩子为 nullptr】
然后还要最大深度
先搜索左边且depth > maxDepth 保证了永远都是最左边那个子结点才判断,正好符合题意
class Solution {
int maxDepth{};
int res{};
void DFS(TreeNode* node, int depth) {
if(node->left == nullptr && node->right == nullptr) {
if(depth > maxDepth) {
res = node->val;
maxDepth = depth;
}
return;
}
if(node->left != nullptr) {
depth++;
DFS(node->left, depth);
depth--;
}
if(node->right != nullptr) {
depth++;
DFS(node->right, depth);
depth--;
}
}
public:
int findBottomLeftValue(TreeNode* root) {
DFS(root, 1);
return res;
}
};
112. 路径总和
看题目都知道是回溯
class Solution {
bool hasPath {};
void DFS(TreeNode* node, int target, int sum) {
if(node->left == nullptr && node->right == nullptr) {
if(sum == target) {
hasPath = true;
}
return;
}
if(node->left != nullptr) {
sum += node->left->val;
DFS(node->left, target, sum);
sum -= node->left->val;
}
if(node->right != nullptr) {
sum += node->right->val;
DFS(node->right, target, sum);
sum -= node->right->val;
}
}
public:
bool hasPathSum(TreeNode* root, int targetSum) {
if(root == nullptr) return false;
DFS(root, targetSum, root->val);
return hasPath;
}
};
113. 路径总和II
上一题的改改就行
class Solution {
vector<vector<int>> res;
void DFS(TreeNode* node, int target, int sum, vector<int>& path) {
if(node->left == nullptr && node->right == nullptr) {
if(sum == target) {
res.push_back(path);
}
return;
}
if(node->left != nullptr) {
sum += node->left->val;
path.push_back(node->left->val);
DFS(node->left, target, sum, path);
sum -= node->left->val;
path.pop_back();
}
if(node->right != nullptr) {
sum += node->right->val;
path.push_back(node->right->val);
DFS(node->right, target, sum, path);
sum -= node->right->val;
path.pop_back();
}
}
public:
vector<vector<int>> pathSum(TreeNode* root, int targetSum) {
if(root == nullptr) return {};
vector<int> path{root->val};
DFS(root, targetSum, root->val, path);
return res;
}
};
106.从中序与后序遍历序列构造二叉树
这种题型只学过理论,还真没写过码
依稀记得当年没有搞熟练结果考试时候卡了好久...
首先,后序遍历最后一个是根节点,这个都懂
然后直接看随想录...真忘却了
看了下随想录大概懂了(原来当年好像确实没学会这个,只是以为自己会了 抽象)
注意就是切割数组时候
中序数组可以按照元素索引切割,后序数组则是按照中序数组的大小。
优化的话,就是不用构造vector,只传一次引用,然后传索引。
class Solution {
TreeNode* Traversal(vector<int>& inorder, vector<int>& postorder) {
if(postorder.size() == 0) return nullptr;
TreeNode* root = new TreeNode(postorder.back());
int idx = 0;
for(; idx < inorder.size(); ++idx) {
if(inorder[idx] == root->val) {
break;
}
}
vector<int> lInorder( inorder.begin(), inorder.begin() + idx );
vector<int> rInorder( inorder.begin() + idx + 1, inorder.end() );
vector<int> lPostorder( postorder.begin(), postorder.begin() + lInorder.size() );
vector<int> rPostorder( postorder.begin() + lInorder.size(), postorder.end() - 1 );
root->left = Traversal(lInorder, lPostorder);
root->right = Traversal(rInorder, rPostorder);
return root;
}
public:
TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
return Traversal(inorder, postorder);
}
};
105. 从前序与中序遍历序列构造二叉树
基本上是一样
class Solution {
TreeNode* Tarversal(vector<int>& preorder, vector<int>& inorder) {
if(!preorder.size() || !inorder.size()) return nullptr;
TreeNode* root = new TreeNode(preorder[0]);
int idx = 0;
for(; idx < inorder.size(); ++idx) {
if(inorder[idx] == root->val) {
break;
}
}
vector<int> lInorder(inorder.begin(), inorder.begin() + idx + 1);
vector<int> rInorder(inorder.begin() + idx + 1, inorder.end() );
vector<int> lPreorder(preorder.begin() + 1, preorder.begin() + 1 + idx);
vector<int> rPreorder(preorder.begin() + 1 + idx, preorder.end());
root->left = Tarversal(lPreorder, lInorder);
root->right = Tarversal(rPreorder, rInorder);
return root;
}
public:
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
return Tarversal(preorder, inorder);
}
};