day33
【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); }- 语法逻辑需注意学习:   在执行此段代码之前 将多个节点值存在vectorpath中》》》》用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= 这样会影响递归的值累计传递的
 
本文来自博客园,作者:跬步瑶,转载请注明原文链接:https://www.cnblogs.com/deservee/p/16972168.html
 
                    
                
 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号