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);
      } 
      
      • 语法逻辑需注意学习: 在执行此段代码之前 将多个节点值存在vector path中》》》》用string sPath把vector path中所有值记录成一个字符串 sPath +=to_string(path[i])》》》》》》》把string sPath赋值给vector result的一个元素 result.push_back(sPath)
    • 三部曲之第三步 子循环

      		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 原因涉及语法解释 默认初值
  • 递归法 简化版本 很有必要再看看练练

  • 迭代法-----过过过 下次看

【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= 这样会影响递归的值累计传递的
posted @ 2022-12-10 19:34  跬步瑶  阅读(23)  评论(0)    收藏  举报