补day18--二叉树part5

第0题:二叉树--层序遍历

用一个队列保存节点,然后将节点的值一层一层的放进vec中,然后将vec放进result中

class Solution {
public:
    vector<vector<int>> levelOrder(TreeNode* root) {
        queue<TreeNode*>  que;
        if(root!=NULL) que.push(root);
        vector<vector<int>> result;    //将vec按行信息放进去
        while(!que.empty())
        {
            int size=que.size();
            vector<int> vec;   //将每行的值放进去
            for(int i=0;i<size;i++)
            {
                TreeNode *node=que.front();
                que.pop();
                vec.push_back(node->val);
                if(node->left) que.push(node->left);
                if(node->right) que.push(node->right);

            }
            result.push_back(vec);

        }
        return result;

    }
};

第一题:找树左下角的值

也就是给定一个二叉树,在树的最后一行找到最左边的值。

注意左下角不是最左边,所以本题适合用迭代法层序遍历,只需要记录最后一行第一个节点就可以

1.相比原来的层序遍历,本题不需要记录所有结点的值,只需要一个result记录一个结点的值就可以了。

第二题:路径总和

给定一个二叉树和一个目标和,判断该树中是否存在根节点到叶子节点的路径,这条路径上所有节点值相加等于目标和。

递归三部曲:

(1)确定递归函数的参数和返回类型

bool traversal(treenode * cur,int count)

//返回的类型是在说明是否找到了符合要求的路径

(2)确定终止条件

计数器可以往上增,累和,也可以往下减,如果最后为0 ,则说找到了满足条件的路径;

if(!cur->left && !cur->right &&count==0) return true;

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

(3) 确定单层递归的逻辑

空节点不遍历,找到合适的路径,立刻返回;

if(cur->left){

 if(traversal(cur->left,count-cur->left->val))  return ture;

}

if(cur->right){

if(traversal(cur->right,count-cur->right->val)) return true;

}

return false;

2. 回溯是什么

就是发现第一条路径不满足条件,回到刚刚最后一个叶子节点的父亲结点的右孩子

第三题 从中序和后序遍历序列构造二叉树

0.首先中序:左根右;后序:左右根

  • 第一步:如果数组大小为零的话,说明是空节点了。

  • 第二步:如果不为空,那么取后序数组最后一个元素作为节点元素。

  • 第三步:找到后序数组最后一个元素在中序数组的位置,作为切割点

  • 第四步:切割中序数组,切成中序左数组和中序右数组 (顺序别搞反了,一定是先切中序数组)

  • 第五步:切割后序数组,切成后序左数组和后序右数组

  • 第六步:递归处理左区间和右区间

 TreeNode* traversal(vector<int>& inorder, vector<int>& postorder) 
    {
        //第一步
        if(postorder.size()==0) return NULL;

        //第二步 后序遍历最后一个元素就是当前的根节点
        int rootValue=postorder[postorder.size()-1];
        TreeNode* root=new TreeNode(rootValue);

        //叶子节点
        if(postorder.size()==1) return root;
        
        //第三步,找切割点
        int delimiterIndex;
        for(delimiterIndex=0;delimiterIndex<inorder.size();delimiterIndex++)
        {
            if(inorder[delimiterIndex]==rootValue) break;
        }

        //第四步:切割中序数组 得到 中序左数组和中序右数组 
        //左闭右开区间:[0,delimiterIndex)
        vector<int> leftInorder(inorder.begin(),inorder.begin()+delimiterIndex);
        //[delimiterIndex+1,end)
        vector<int> rightInorder(inorder.begin()+delimiterIndex+1,inorder.end());

        //舍弃末尾元素
        postorder.resize(postorder.size()-1);



        //第五步:切割后序数组,得到 后序左数组和后序右数组
        //[0,leftInorder.size)
        vector<int> leftPostorder(postorder.begin(),postorder.begin()+leftInorder.size());
        //[leftInorder.size(),en)
        vector<int> rightPostorder(postorder.begin()+leftInorder.size(),postorder.end());


        //第六步
        root->left=traversal(leftInorder,leftPostorder);
        root->right=traversal(rightInorder,rightPostorder);

        return root;

    }

第四题 从前序与中序遍历序列构造二叉树

思路:本题和上一题思路一样,步骤也一样,前序遍历可以确定根节点,然后在中序遍历中切割成两个数组。多次迭代

非要说有什么不同,本题前序遍历的方向不一样:根左右,所以确定根节点值的时候,直接放前序数组的第一个值;以及将上一题中求数组长度的值直接用参数表示;

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值