五个简单题熟悉二叉树

四月十九号—leetcode刷题总结

题目一:108. 将有序数组转换为二叉搜索树

给你一个整数数组 nums ,其中元素已经按 升序 排列,请你将其转换为一棵 高度平衡 二叉搜索树。

高度平衡 二叉树是一棵满足「每个节点的左右两个子树的高度差的绝对值不超过 1 」的二叉树。

该日题集主要是熟悉二叉树的基础知识。通过递归取实现节点的遍历。

示例 1:

输入:nums = [-10,-3,0,5,9]
输出:[0,-3,9,-10,null,5]
解释:[0,-10,5,null,-3,null,9] 也将被视为正确答案:
在这里插入图片描述
在这里插入图片描述

示例 2:

输入:nums = [1,3]
输出:[3,1]
解释:[1,null,3] 和 [3,1] 都是高度平衡二叉搜索树。

在这里插入图片描述

提示:

1 <= nums.length <= 104
-104 <= nums[i] <= 104
nums 按 严格递增 顺序排列

思路

nums严格单调递增,而我们所要构造的二叉树需要高度平衡,因此以数组的中点为数的根便满足题意,
以这棵树的根开始,不断向下延展,采用递归的方式.

public:
    TreeNode* sortedArrayToBST(vector<int>& nums) {
        return helper(nums,0,nums.size()-1);
    }
    TreeNode* helper(vector<int>&nums,int left,int right)
    {
        if(left>right)
        {
            return nullptr;
        }
        int mid=(left+right)/2;
        TreeNode *root=new TreeNode(nums[mid]);
        root->left=helper(nums,left,mid-1);
        root->right=helper(nums,mid+1,right);
        return root;
    }
};

题目二

144.二叉树的前序遍历
链接二叉树的前序遍历
此题为数据结构二叉树的遍历的入门题,其遍历共有三种方式,前序,后序,中序,其在代码上的区别无非是几个语句的顺序不一样。
前序,先存储根节点,再左节点,右节点。
使用递归一次遍历,root为空时返回。
使用c++中的vector存储更便利,直接push_back().

class Solution {
public:
    vector<int> preorderTraversal(TreeNode* root) {
        vector<int>nums;
        find(root,nums);
        return nums;
    }
    void find(TreeNode *root,vector<int>&nums)
    {
        if(!root)
        return ;
        nums.push_back(root->val);
        find(root->left,nums);
        find(root->right,nums);
    }
};

中序遍历

二叉树的中序遍历
理解了前一道题,接下了便势如破竹

class Solution {
public:
    vector<int> inorderTraversal(TreeNode* root) {
        vector<int>nums;
        find(root,nums);
        return nums;
    }
    void find(TreeNode* root,vector<int>&nums)
    {
        if(!root)
        return ;
        find(root->left,nums);
        nums.push_back(root->val);
        find(root->right,nums);

    }
};

题目三

后序遍历
额~~后序遍历

class Solution {
public:
    vector<int> postorderTraversal(TreeNode* root) {
        vector<int>nums;
        find(root,nums);
        return nums;
    }
    void find(TreeNode* root,vector<int>&nums)
    {
        if(!root)
        return ;
        find(root->left,nums);
        find(root->right,nums);
        nums.push_back(root->val);
    }
};

题目四: 二叉树的最大深度

104求二叉树的最大深度
思路
因为是二叉树,顾每个节点只有两条路,只需选节点最多的路即可。

class Solution {
public:
    int maxDepth(TreeNode* root) {
        int ans=0;
        ans=get(root);
        return ans;
    }
    int get(TreeNode* root)
    {
        if(!root)
        return 0;
        int ans=1+max(get(root->left),get(root->right));
        return ans;
    }
};

题目五:验证二叉树的前序列化

验证二叉树的前序列化
序列化二叉树的一种方法是使用 前序遍历 。当我们遇到一个非空节点时,我们可以记录下这个节点的值。如果它是一个空节点,我们可以使用一个标记值记录,例如 #。

在这里插入图片描述

例如,上面的二叉树可以被序列化为字符串 “9,3,4,#,#,1,#,#,2,#,6,#,#”,其中 # 代表一个空节点。

给定一串以逗号分隔的序列,验证它是否是正确的二叉树的前序序列化。编写一个在不重构树的条件下的可行算法。

保证 每个以逗号分隔的字符或为一个整数或为一个表示 null 指针的 ‘#’ 。

你可以认为输入格式总是有效的

例如它永远不会包含两个连续的逗号,比如 “1,3” 。
注意:不允许重建树。

示例 1:

输入: preorder = “9,3,4,#,#,1,#,#,2,#,6,#,#”
输出: true
示例 2:

输入: preorder = “1,#”
输出: false
示例 3:

输入: preorder = “9,#,#,1”
输出: false
思路
当一个节点为空,输入了‘#’,则说明每个非空的节点都将带两节点(不论是否为空),为空便不带节点。那么当我们遍历完string时,节点也遍历完,若string以遍历完,但还空着节点,不能前序列化
第二,因其为前序遍历,我们先访问左子树,
因此采用栈来标记每一次的状态,即还可存几个节点(最多两个)
因为只需考虑此树的合法性,则只有数据的空与非空对操作有影响,而题目给的存储类型为string型,当其数字时,需一并读掉。
当一个非空节点已有两便出栈,不再进行考虑,
此时便出现了一个问题,当我们把栈弹空时,说明以所有数据已经满足1对2的条件,如果之后还有数据,则定不满足题意的二叉树
将两种错误用黄色标记
代码

class Solution {
public:
    bool isValidSerialization(string preorder) {
        int n=preorder.length();
        int i=0;
        stack<int>stk;
        stk.push(1);
        while(i<n)
        {
            if(stk.empty())
            {
                return false;
            }
            if(preorder[i]==',')
            {
                i++;
            }
            else if(preorder[i]=='#')
            {
                stk.top()-=1;
                if(stk.top()==0)
                {
                    stk.pop();
                }
                i++;
            }
            else 
            {
                while(i<n&&preorder[i]!=',')
                {
                    i++;
                }
                stk.top()-=1;
                if(stk.top()==0)
                {
                    stk.pop();
                }
                stk.push(2);
            }
        }
        return stk.empty();
    }
};

好了,刷题结束。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值