513 层序遍历注意先放右边再放左边 这样queue里面最后一个数才是要找的
递归法 还是要多练习 找终止条件已经终止后处理方式是最重要的,这里终止条件即子叶,再加判断此时是否在最深处,如果是,更新maxDepth和result。
1.我用了隐藏回溯,隐藏回溯其实就是不要改变传递的值在本函数的值 但是传参的时候又对应更新了。(这里是传depth)
2.这里是先左后右,因为到子叶的时候maxDepth已经被更新了 判断条件是depth>maxDepth。没有等于号 所以同深度的右边叶子不会刷新数值,跟迭代会刷新不一样。
3.maxDepth在这边传递的时候要用&,不然会出bug。解释如下:(但我还是没太看明白为什么)
(cr to chatGPT)
在你的代码中,`depth` 参数并没有像 `maxDepth` 那样在函数内部被修改并期望这个修改能反映到函数外部。当你对 `depth` 参数进行加法运算并将结果传递给下一级的 `traversal` 函数调用时,你实际上创建了一个新的 `depth` 值。原始的 `depth` 值并没有被改变,你只是基于它计算出了一个新的值并传递给了下一级的函数调用。
在你的 `traversal` 函数中,`depth` 参数在每一级的函数调用中都是独立的。对于任何特定的函数调用,`depth` 参数只代表从根节点到当前节点的深度,它并不需要被修改并反映到函数外部。因此,你可以按值传递 `depth` 参数,而不需要像 `maxDepth` 和 `result` 那样按引用传递。
请注意,按值传递和按引用传递在C++中是非常重要的概念,理解它们之间的差别对于写出正确的C++代码是至关重要的。
/* //层序遍历
class Solution {
public:
int findBottomLeftValue(TreeNode* root) {
queue<TreeNode*>que;
int result;
if (root!=nullptr) que.push(root);
while (!que.empty()) {
TreeNode* curr = que.front();
result = curr->val;
que.pop();
if (curr->right) que.push(curr->right);
if (curr->left) que.push(curr->left);
}
return result;
}
}; */
//递归
class Solution {
void traversal(TreeNode* root, int depth, int& maxDepth, int& result) {
if (root->left==nullptr && root->right==nullptr) {
if (depth>maxDepth) {
maxDepth = depth;
result = root->val;
}
}
cout<<endl;
if (root->left){
traversal(root->left, depth+1, maxDepth, result);
}
if (root->right) {
traversal(root->right, depth+1, maxDepth, result);
}
}
public:
int findBottomLeftValue(TreeNode* root) {
int result;
int maxDepth = INT_MIN;
if (root == nullptr) return result;
traversal(root, 0, maxDepth, result);
return result;
}
};
112
/* //递归
class Solution {
void traversal(TreeNode* root, int& remain, bool& found) {
remain-=root->val;
if (root->left==nullptr && root->right == nullptr) {
if (remain==0) {
found = true;
}
return;
}
if (root->left) {
traversal(root->left, remain, found);
remain+=root->left->val;
}
if (root->right) {
traversal(root->right, remain, found);
remain+=root->right->val;
}
}
public:
bool hasPathSum(TreeNode* root, int targetSum) {
if (root==nullptr) return false;
bool found = false;
traversal(root, targetSum, found);
return found;
}
}; */
//简化之后
/* class Solution {
public:
bool hasPathSum(TreeNode* root, int targetSum) {
if (root==nullptr) return false;
if (root->left==nullptr && root->right==nullptr && targetSum==root->val) return true;
return hasPathSum(root->left, targetSum-root->val)||hasPathSum(root->right, targetSum-root->val);
}
}; */
//迭代
class Solution {
public:
bool hasPathSum(TreeNode* root, int targetSum) {
stack<pair<TreeNode*, int>> stack;
if (root!=nullptr) {
pair<TreeNode*, int> p;
p.first = root;
p.second = root->val;
stack.push(p);
}
while (!stack.empty()) {
pair<TreeNode*, int> curr_p = stack.top();
if (curr_p.first->left==nullptr && curr_p.first->right==nullptr && curr_p.second==targetSum) return true;
stack.pop();
if (curr_p.first->left!=nullptr) {
pair<TreeNode*, int> left;
left.first=curr_p.first->left;
left.second=curr_p.second+left.first->val;
stack.push(left);
}
if (curr_p.first->right!=nullptr) {
pair<TreeNode*, int> right;
right.first=curr_p.first->right;
right.first=curr_p.first->right;
right.second=curr_p.second+right.first->val;
stack.push(right);
}
}
return false;
}
};
113
//递归
class Solution {
vector<vector<int>> paths;
void traversal (TreeNode* root, int sum, vector<int>& path) {
if (!root->left && !root->right && root->val == sum) {
path.push_back(root->val);
paths.push_back(path);
path.pop_back();
return;
}
if (root->left) {
path.push_back(root->val);
traversal(root->left, sum-root->val, path);
path.pop_back();
}
if (root->right) {
path.push_back(root->val);
traversal(root->right, sum-root->val, path);
path.pop_back();
}
}
public:
vector<vector<int>> pathSum(TreeNode* root, int targetSum) {
if (root==nullptr) return paths;
vector<int> path;
traversal(root, targetSum, path);
return paths;
}
};
106
class Solution {
TreeNode* traversal(vector<int>& inorder, vector<int>& postorder) {
if (inorder.size()==0) return nullptr;
int val = postorder[postorder.size()-1];
vector<int> left_inorder;
int i;
for (i=0; i<inorder.size(); i++) {
if (inorder[i]==val){
break;
}
left_inorder.push_back(inorder[i]);
}
vector<int> right_inorder;
right_inorder.insert(right_inorder.end(), inorder.begin()+i+1, inorder.end());
vector<int> left_postorder;
left_postorder.insert(left_postorder.end(), postorder.begin(), postorder.begin()+i);
vector<int> right_postorder;
right_postorder.insert(right_postorder.end(), postorder.begin()+i, postorder.end()-1);
TreeNode* root = new TreeNode(val);
root->left = traversal(left_inorder, left_postorder);
root->right = traversal(right_inorder, right_postorder);
return root;
}
public:
TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
return traversal(inorder, postorder);
}
};
cr to 代码随想录 ,这种定义vector的方式比我简单,要学习。我用的是insert。 都是左闭右开。
vector<int> leftPostorder(postorder.begin(), postorder.begin() + leftInorder.size());
105 递归的时候传递头尾的index,这样可以节约空间,不用每次递归都新建两个vector
class Solution {
TreeNode* traversal(vector<int>& preorder, vector<int>& inorder, int pre_s, int pre_e, int in_s, int in_e){
if (pre_e-pre_s==0) return nullptr;
int val = preorder[pre_s];
int index;
for (index=0; index<in_e-in_s; index++){
if (inorder[index+in_s]==val) break;
}
//用左闭右开
TreeNode* root = new TreeNode(val);
root->left = traversal(preorder, inorder, pre_s+1, pre_s+index+1, in_s, in_s+index);
root->right = traversal(preorder, inorder, pre_s+index+1, pre_e, in_s+index+1, in_e);
return root;
}
public:
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
return traversal(preorder, inorder, 0, preorder.size(), 0, inorder.size());
}
};