2021-01-30 跳水板 判断平衡二叉树 二叉树变单链表

本文介绍了三个关于二叉树的问题:1.如何构建所有可能长度的跳水板;2.如何判断一个二叉树是否为高度平衡的二叉树;3.如何将二叉搜索树转换为有序单链表。解决方案分别涉及递归遍历、深度计算以及后序遍历等算法,对于理解和操作二叉树结构具有重要意义。
摘要由CSDN通过智能技术生成

题目1 跳水板

你正在使用一堆木板建造跳水板。有两种类型的木板,其中长度较短的木板长度为shorter,长度较长的木板长度为longer。你必须正好使用k块木板。编写一个方法,生成跳水板所有可能的长度。

返回的长度需要从小到大排列。
示例 1

输入:
shorter = 1
longer = 2
k = 3
输出: [3,4,5,6]
解释:
可以使用 3 次 shorter,得到结果 3;使用 2 次 shorter 和 1 次 longer,得到结果 4 。以此类推,得到最终结果。

解:

  1. 两个特殊情况
    a. k=0,返回空数组
    b. shorter = longer,只能组成一种长度:shorter*k;
  2. 常规情况。
    可以设木板的长度由 i 块长板和 k-i 块短板组成,那么木板长度则共有k+1种(i从0到k,有k+1个数),总长度为:
    L = longger * i + shorter( k - i)
    L = (longger - shorter)* i + k * shorter
    上式中,(longger - shorter)、k * shorter均为常量,且(longger - shorter)大于0,因此L的长度随 i 的增大而增大。因此从0到k+1遍历i,并将长度存入数组中,即可获取长度从小到大的排序。
class Solution {
public:
    vector<int> divingBoard(int shorter, int longer, int k){
        if(0 == k)
            return (vector<int>(0));
        if(shorter == longer)
            return (vector<int>(1,k*shorter));
        vector<int> num(k+1);
        int i;
        for(i=0; i<=k ; i++)
        {
            num[i] = i*longer+(k-i)*shorter;
        }
        return num;
    }
};

题目2 平衡二叉树

给定一个二叉树,判断它是否是高度平衡的二叉树。

本题中,一棵高度平衡二叉树定义为:

一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1 。

本题目的实际将转化为二叉树的深度问题。

  1. 设置一个全局变量flag,初始化为true
  2. 求取每个结点的左右深度后,判断差值的绝对值是否大于1,大于1则flag置false,并一直返回。
class Solution {
    bool flag;
public:
    bool isBalanced(TreeNode* root) {
    	//初始化变量
        flag = true;
        Judge(root);
        return flag;
    }
    int Judge(TreeNode* root)
    {
    	//flag = false,树不是平衡二叉树,返回。
    	//root为空,开始返回0(递归的结束条件)
        if(false == flag || root == NULL)
            return 0;
        //求左子树深度
        int leftSum = Judge(root->left);
        //求右子树深度
        int rightSum = Judge(root->right);
        //判断该节点左右子树差值是否<1
        if(abs(leftSum - rightSum) > 1)
            flag = false;
        return max(leftSum,rightSum)+1;
    }
};

题目3 二叉树变单链表

二叉树数据结构TreeNode可用来表示单向链表(其中left置空,right为下一个链表节点)。实现一个方法,把二叉搜索树转换为单向链表,要求依然符合二叉搜索树的性质,转换操作应是原址的,也就是在原始的二叉搜索树上直接修改。
返回转换后的单向链表的头节点。

示例:

输入: [4,2,5,1,3,null,6,0]
输出: [0,null,1,null,2,null,3,null,4,null,5,null,6]

解:

根据示例,创建该树为
在这里插入图片描述
链表的顺序是通过后续遍历得到的,因此通过递归后序遍历,并用pNode标记每次遍历结点的上一个结点,根据题目要求设置左右孩子即可。

  1. 设置两个全局变量:
    pNode:标记头节点,pTemp:标记上一节点
  2. 遍历左子树
  3. 处理节点
    a. 若上一节点pTemp为NULL,说明遍历的该节点是头,赋值给pNode
    b. pTemp左孩子为空,右孩子为该节点
    c. pTemp指向该节点
  4. 遍历右子树
class Solution {
    TreeNode* pTemp = NULL;
    TreeNode* pNode = NULL;
public:
    TreeNode* convertBiNode(TreeNode* root) {
        GetAnser(root);
        return pNode;
    }
    void GetAnser(TreeNode* root)
    {
        if(root == NULL) return;
        GetAnser(root->left);
        if(pTemp == NULL)
            pNode = root;
        else
        {
            pTemp->left = NULL;
            pTemp->right = root;
        }
        pTemp = root;
        GetAnser(root->right);
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值