Day16|| ● 513.找树左下角的值● 112. 路径总和 113.路径总和ii● 106.从中序与后序遍历序列构造二叉树 105.从前序与中序遍历序列构造二叉树

513.找树左下角的值

这样的是递归的写法。在递归写法中我们一定要注意回溯,保证在遍历右子树的时候我们的depth的值没有改变。其实在栈低的每一个函数体内部都会有这样一个过程,所以我们每次只用回溯1。

class Solution {
public:
int result;
int maxdepth=-1;

void traversal(TreeNode *node,int depth)
{
  if(node->left==nullptr&&node->right==nullptr)
  {
      if(depth>maxdepth)
      {
          maxdepth=depth;
          result=node->val;
      }
      return;
  }
  if(node->left)
  {
      depth++;
      traversal(node->left,depth);
      depth--;
  }
  if(node->right)
  {
      depth++;
      traversal(node->right,depth);
      depth--;
  }
  
}


    int findBottomLeftValue(TreeNode* root) {
        traversal(root,0);
        return result;

    }
};

class Solution {
public:
    int findBottomLeftValue(TreeNode* root) {
         int result;
         queue<TreeNode*> que;

         if(root!=nullptr)
         que.push(root);
         int size=1;
         while(!que.empty())
         {
            
            size=que.size();
            for(int i=0;i<size;i++)
            {
                TreeNode *node=que.front();
                 que.pop();
                if(node->left) que.push(node->left);
                if(node->right) que.push(node->right);
                if(i==0)
                result=node->val;
                
                
                 
            }

            
            
         }
         return result;

    }
};

这是迭代法,更好理解,就是层序遍历!

112. 路径总和 113.路径总和ii

112.路径总和

深度遍历,可以理解为前中后序遍历都可以,因为对中没有操作。其实这里也有一个控制循环不变量的想法,就是我们保证每次函数传入前我们都已经对传入节点的值进行过处理,就是减去传入节点的val。所以在根节点的时候也要先减去再传入。一定要记得根节点的判空操作。

class Solution {
public:
    bool hasPathSum(TreeNode* root, int targetSum) {
       if(root!=nullptr)
       return traveral(root,targetSum-root->val);
       else return false;


    }
    bool traveral(TreeNode *node,int count)
    {
        
        if(node==nullptr&&count!=0) return false;
        if(node->left==nullptr&&node->right==nullptr)
        {
           if(count==0) return true;
           else return false;
        }


        if(node->left)
        {
           if(traveral(node->left,count-node->left->val))
           return true ;
        }
        if(node->right)
        {
          if(traveral(node->right,count-node->right->val))
          return true;
        }
        
        return false;
    }
};

113.路径总和ii

思路和上道题一样,但是需要传回路径,所以需要在终止条件的时候push一下,注意回溯操作!

class Solution {
private:
    vector<vector<int>> result;
    vector<int> path;
    void traversal(TreeNode* cur, int count) {
        if (!cur->left && !cur->right && count == 0) { 
            result.push_back(path);
            return;
        }

        if (!cur->left && !cur->right) return ; // 

        if (cur->left) { 
            path.push_back(cur->left->val);
            count -= cur->left->val;
            traversal(cur->left, count);    
            count += cur->left->val;        
            path.pop_back();                
        }
        if (cur->right) {
            path.push_back(cur->right->val);
            count -= cur->right->val;
            traversal(cur->right, count);   
            count += cur->right->val;       
            path.pop_back();                
        }
        return ;
    }

public:
    vector<vector<int>> pathSum(TreeNode* root, int sum) {
        result.clear();
        path.clear();
        if (root == nullptr) retur
        traversal(root, sum - root->val);
        return result;
    }
};

106.从中序与后序遍历序列构造二叉树 105.从前序与中序遍历序列构造二叉树

106.从中序与后序遍历序列构造二叉树

第一遍写其实应该做日志,这样来方便debug。

class Solution {
public:
    TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
    if(inorder.size()==0||postorder.size()==0)
    return nullptr;

    return traversal(inorder,postorder);


    }
    TreeNode *traversal(vector<int>& inorder, vector<int>& postorder)
    {
        if(postorder.size()==0) return nullptr;

        int rootval=postorder[postorder.size()-1];
        TreeNode *root=new TreeNode(rootval);
        if(postorder.size()==1) return root;

        int index=0;
        for(index=0;index<inorder.size();index++)
        {
            if(rootval==inorder[index]) break;


        }

        vector<int> left_inorder(inorder.begin(),inorder.begin()+index);
        vector<int> right_inorder(inorder.begin()+index+1,inorder.end());//左闭右开//

        postorder.resize(postorder.size()-1);

        vector<int> left_postorder(postorder.begin(),postorder.begin()+left_inorder.size());
        vector<int> right_postorder(postorder.begin()+left_inorder.size(),postorder.end());

        root->left=traversal(left_inorder,left_postorder);
        root->right=traversal(right_inorder,right_postorder);

        return root;



    }
};

105.从前序与中序遍历序列构造二叉树

有一个很容易错的点就是在分割数组的时候忘记➕1,因为我们的前序数组的头是无用的数

class Solution {
public:
    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
        if(preorder.size()==0)
        return nullptr;

        return traversal(preorder,inorder);

    }
TreeNode *traversal(vector<int>& preorder, vector<int>& inorder)
{
       if(preorder.size()==0) return nullptr;

        int rootval=*preorder.begin();
        TreeNode *root=new TreeNode(rootval);
        if(preorder.size()==1) return root;

        int index=0;
        for(index=0;index<inorder.size();index++)
        {
            if(rootval==inorder[index]) break;

        }
        vector<int> left_inorder(inorder.begin(),inorder.begin()+index);
        vector<int> right_inorder(inorder.begin()+index+1,inorder.end());
        vector<int> left_preorder(preorder.begin()+1,preorder.begin()+left_inorder.size()+1);
        vector<int> right_preorder(preorder.begin()+left_inorder.size()+1,preorder.end());
        
        root->left=traversal(left_preorder,left_inorder);
        root->right=traversal(right_preorder,right_inorder);
    
       return root;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值