DFS_牛客网(一)

163 阅读3分钟
  • 牛客NC62:判断是不是平衡二叉树

    • 题目描述:

      image-20211124194837324

      image-20211124194900334

    • 知识铺垫:

    • 算法思路:

      • 深搜每一个节点,记录下每个节点对应的树的高度

             map<TreeNode*, int>hs;
             int depth(TreeNode* root){
                 if(!root)    return 0;//当这个树为空的时候;
                 if(hs.find(root) != hs.end())    return hs[root];//查找到这个节点
                 int ldep = depth(root->left);
                 int rdep = depth(root->right);
                 return hs[root] = max(ldep,rdep) + 1;
             }
        
      • 验证每一个节点(看节点是否为空以及节点的左右子树的高度差小于1)

           bool judge(TreeNode* root){
                 if(!root)    return true;
                 return abs(hs[root->left] - hs[root->right]) <=1 
                     &&judge(root->left) && judge(root->right);
             }
        
      • 主函数:调用两个函数 (传入树根,验证每一个节点)

             bool IsBalanced_Solution(TreeNode* pRoot) {
                 depth(pRoot);
                 return judge(pRoot);
             }
        
      • 完整代码:

         class Solution {
         public:
             /*定义map,
                  1.map:小写
                  2.在指定Key与Value的时候仅需要指定出这个数据类型就行了
             */
             map<TreeNode*, int>hs;
             int depth(TreeNode* root){
                 if(!root)    return 0;//当这个树为空的时候;
                 if(hs.find(root) != hs.end())    return hs[root];//查找到这个节点
                 int ldep = depth(root->left);
                 int rdep = depth(root->right);
                 return hs[root] = max(ldep,rdep) + 1;
             }
             bool judge(TreeNode* root){
                 if(!root)    return true;
                 return abs(hs[root->left] - hs[root->right]) <=1
                     && judge(root->left) && judge(root->right);
             }
             bool IsBalanced_Solution(TreeNode* pRoot) {
                 depth(pRoot);
                 return judge(pRoot);
             }
         };
        
    • 实现细节:

      • map的使用

        • map需要小写,并且对于键值,首字母小写,仅需写出数据类型即可

        • 二级结论(在map中查找一个节点,查找成功就返回对应的值)

           //当map中含有root这个节点,返回hs[root]
           if(hs.find(root) != hs.end())    return hs[root];
          
    • 刷题总结:

      • 内置头文件:

        • 需要使用内置函数,STL容器等,不需要手动导入头文件
      • 编程思路:

        • 暴力为主导,先处理最简单的思路,再优化
        • 采用面向过程编程,将思路拆分成多个函数;在main中以调用不同函数的方式进行处理
      • 编程细节:

        • 对于给出的形参,就不要去改它,直接用就行了
        • 当实参为TreeNode* root时,不用自己去建树,只写核心代码
  • 牛客NC6 二叉树中的最大路径和

    • 题目描述:

      image-20211124195010023

      image-20211124194950088

    • 知识铺垫:

      • C++中声明最小值

         int ans = -0X3f3f3f;
        
      • java声明最小值

         int ans = Integer.MIN_VALUE;
        
      • max函数(返回两个实参中较大的按一个)

         int a=4,b=6;
         int ans = max(a,b)//ans = 6
        
    • 算法思路:

      • 概述:采用DFS遍历整颗树,

      • DFS细节:

        • 先判断此树是否为空;

           if(!root)    return 0;//搜索到根节点时退出
          
        • 递归形式拿到左右两个子树的最大路径和;

           int left = dfs(root->left);
           int right = dfs(root->right);//递归处理左右节点
          
        • 拿到本节点权值;

           int tempSum = root->val;//拿到本节点
          
        • 根据左右子树的状态更新本节点状态;

           if(left > 0)    tempSum += left;
           if(right > 0)    tempSum += right;//判断负值
          
        • 再次更新最终答案状态;

           ans = max(ans,tempSum);//更新答案
          
        • 递归返回

           return max(root->val,max(left,right)+root->val);
          
      • 递归出口

        • 出口一:当此树为空,即根节点为空

        • 出口二:返回当前节点权值,与 左子树右子树同当前节点权值之和的较大值

           return max(root->val,max(left,right)+root->val);
          
      • 搜索细节:

        image-20211124194539429

    • 完整代码

       /**
        * struct TreeNode {
        *  int val;
        *  struct TreeNode *left;
        *  struct TreeNode *right;
        * };
        */
       ​
       class Solution {
       public:
           /**
            * 
            * @param root TreeNode类 
            * @return int整型
            */
           int ans = -0X3f3f3f;//将ans初始值设置为负无穷,避免那种节点值全部为负值的树
           int dfs(TreeNode* root){
               if(!root)    return 0;//搜索到根节点时退出
               
               int left = dfs(root->left);
               int right = dfs(root->right);//递归处理左右节点
               
               int tempSum = root->val;//拿到本节点
               
               if(left > 0)    tempSum += left;
               if(right > 0)    tempSum += right;//判断负值
               
               ans = max(ans,tempSum);//更新答案
               
               return max(root->val,max(left,right)+root->val);
           }
           int maxPathSum(TreeNode* root) {
               // write code here
               ans = max(ans,dfs(root));
               
               return ans;
               
                
           }
       };
      

    \