【0257.二叉树的所有路径】
- 我的迭代法 运行不成功
/**
* 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:
vector<string> binaryTreePaths(TreeNode* root) {
stack<TreeNode*> st1;
vector<string> result;
if (root != NULL) st1.push(root);
int i = 0;
while (!st1.empty()) {
TreeNode* node1 = st1.top();
st1.pop();
result[i].push_back(node1->val);
result[i].push_back('->');
if (node1->right) {
st1.push(node1->right);
result[i].push_back(node1->right->val);
result[i].push_back('->');
}
if (node1->left) {
st1.push(node1->left);
result[i].push_back(node1->left->val);
result[i].push_back('->');
}
}
return result;
}
};
- 我的递归法 运行不成功
/**
* 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:
vector<string> path(TreeNode* root) {
vector<string> result;
int i = 0;
if (root->left == NULL && root->right == NULL) {
result[i].push_back(root->val);
i++;
}
if (root->left != NULL) {
result[i].push_back(root->left->val);
result[i].push_back('->');
}
if (root->right != NULL) {
result[i].push_back(root->right->val);
result[i].push_back('->');
}
}
vector<string> binaryTreePaths(TreeNode* root) {
vector<string> result;
return result;
}
};
-
递归法 看了思路后
-
三部曲之第一步 输入输出参数
void traversal(TreeNode* cur, vector<int>& path, vector<string>& result)
- 为什么这个亚子 好像懂了又好像没懂。。。
- 别忘了& 否则就只是值传递
-
三部曲之第二步 结束条件
if (cur->left == NULL && cur->right == NULL) { //叶子节点 string sPath; for (int i = 0; i < path.size()-1; i++) { sPath += to_string(path[i]); sPath += "->"; } sPath += to_string(path[path.size()-1]); result.push_back(sPath); }
- 语法逻辑需注意学习: 在执行此段代码之前 将多个节点值存在vector
path中》》》》用string sPath把vector path中所有值记录成一个字符串 sPath +=to_string(path[i])》》》》》》》把string sPath赋值给vector result的一个元素 result.push_back(sPath)
- 语法逻辑需注意学习: 在执行此段代码之前 将多个节点值存在vector
-
三部曲之第三步 子循环
if (cur->left != NULL) { path.push_back(cur->left->val); traversal(cur->left, path, result); } if (cur->right != NULL) { path.push_back(cur->right->val); traversal(cur->right, path, result); }
- 我写的一塌糊涂 看了代码提示后
path.push_back(cur->val) if (cur->left != NULL) { traversal(cur->left, path, result); } path.pop_back(); if (cur->right != NULL) { traversal(cur->right, path, result); }
- 上面代码还是错误地 卡哥说递归和回溯最遥远的距离是你在花括号里而我在花括号外 代码更改如下
path.push_back(cur->val) //中,中为什么写在这里,因为最后一个节点也要加入到path中 if (cur->left != NULL) { //左 traversal(cur->left, path, result); path.pop_back(); } if (cur->right != NULL) { //右 traversal(cur->right, path, result); path.pop_back(); }
- 注意注意 对中的处理 不代表就是放在if(cur->left != NULL)的上一行 注意位置 虽然没太懂。。。。
-
主函数 一塌糊涂,too
vector<string> binaryTreePaths(TreeNode* root) { vector<string> result; vector<int> path; if (root == NULL) return NULL; traversal(root, path, result); return result; }
-
更改如下
vector<string> binaryTreePaths(TreeNode* root) { vector<string> result; vector<int> path; if (root == NULL) return result; traversal(root, path, result); return result; }
- 注意注意 当结点为空时返回值 不是NULL 而是result 为什们 这取决于主函数的返回值是什么类型 -----是vector
类型而不是指针类型 就算没给result赋值 也可返回result 原因涉及语法解释 默认初值
- 注意注意 当结点为空时返回值 不是NULL 而是result 为什们 这取决于主函数的返回值是什么类型 -----是vector
-
-
递归法 简化版本 很有必要再看看练练
-
迭代法-----过过过 下次看
【0404.左叶子之和】
-
还以为自己能一遍ac 不曾想
/** * 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: int sumOfLeftLeaves(TreeNode* root) { queue<TreeNode*> que1; int result = 0; if (root != NULL) que1.push(root); while(!que1.empty()) { int size = que1.size(); for (int i = 0; i < size; i++) { TreeNode* node = que1.front(); que1.pop(); if (i == 0 && node->left == NULL && node->right == NULL) result += node->val; if (node->left) que1.push(node->left); if (node->right) que1.push(node->right); } } return result; } };
-
看了思路提示 问题在于 如何判断该节点是否为左节点 也就是说 上面的代码部分for循环里的第一个if判断的语句逻辑是错误的 更改正确版本见下
class Solution { public: int sumOfLeftLeaves(TreeNode* root) { queue<TreeNode*> que1; int result = 0; if (root != NULL) que1.push(root); if (root->left == NULL && root->right == NULL) return result; while(!que1.empty()) { int size = que1.size(); for (int i = 0; i < size; i++) { TreeNode* node = que1.front(); que1.pop(); if (node->left != NULL && node->left->left == NULL && node->left->right == NULL) result += node->left->val; if (node->left) que1.push(node->left); if (node->right) que1.push(node->right); } } return result; } };
-
以上是我的答案 层次遍历迭代法 最后一段代码是可以ac的
-
以下是卡哥提供的方案 包括 三种深度遍历迭代法 深度遍历递归法 我先自己写写代码
-
深度遍历迭代法
class Solution { public: int sumOfLeftLeaves(TreeNode* root) { stack<TreeNode*> st1; int result = 0; if (root != NULL) st1.push(root); if (root->left == NULL && root->right == NULL) return result; while(!st1.empty()) { TreeNode* node = st1.top(); st1.pop(); if (node->left != NULL && node->left->left == NULL && node->left->right == NULL) result += node->left->val; if (node->right) st1.push(node->right); if (node->left) st1.push(node->left); } return result; } };
- 一遍ac 其实就是相比于层次遍历 除了把queue换成stack外 改了几行代码而已
- 另外注意 每次遍历都不提前考虑用前中后哪种遍历方式更好---默认都写成了前序遍历 虽然很多题三种遍历方式均可 但还是要自己提前清楚是用的哪种方式 这个习惯要养成 为了防止个别题目对某种遍历方式不友好
-
深度遍历递归法
- 前序(先根) 其余方式省略
class Solution { public: void sumLeftNode(TreeNode* cur, int result) { if (cur->left != NULL && cur->left->left == NULL && cur->left->right == NULL) result += cur->left->val; if (cur->left) sumLeftNode(cur->left, result); if (cur->right) sumLeftNode(cur->right, result); } int sumOfLeftLeaves(TreeNode* root) { int result = 0; if (root == NULL || (root->left == NULL && root->right == NULL)) return result; sumLeftNode(root, result); return result; } };
- 其实 我不太明白的 就是递归三部曲中第一步 什么时候需要返回值 什么时候可以把返回值放在输入参数里面一起带走 下面是我 调整返回值后的代码 Ac!!!
class Solution { public: int sumLeftNode(TreeNode* cur) { int result = 0; if (cur->left != NULL && cur->left->left == NULL && cur->left->right == NULL){ result += cur->left->val; } if (cur->left) result += sumLeftNode(cur->left); if (cur->right) result += sumLeftNode(cur->right); return result; } int sumOfLeftLeaves(TreeNode* root) { int result = 0; if (root == NULL || (root->left == NULL && root->right == NULL)) return result; result = sumLeftNode(root); return result; } };
- 因为 我还是对上面提到的问题 ----- 什么时候写返回值什么时候不写而是放输入参数里 我觉得放在输入参数里的--也就是上面这段代码貌似逻辑比上上面--用返回值 逻辑更清晰? 、
- 需要注意的是 result+= 每次都是这样 而不应该出现result= 这样会影响递归的值累计传递的