二叉树动态规划算法基础

动态规划理解

需要使用到动态规划算法的问题都是原问题可以拆分为小问题,而大的问题是受小问题影响的。

树型动态规划通用公式

1.首先分析出要满足当前要求需要从左右孩子获取到什么信息。

2.将需要用到的信息进行封装(如果只有单条数据就不用封装了)

3.编写递归函数 函数的返回值就是2中封装的信息体

3.1在递归函数中首先写出最小问题的信息体并返回

3.2从左右子树获取它们的信息体

3.3通过左右子树获得的信息体来推算出自己的信息体并将其返回即可

题1:判断二叉树是否是满二叉树

分析:

1.首先分析出要满足当前要求需要从左右孩子获取到说明信息。

需要知道当前树的高度和树的总节点数(2的height次方 - 1与总节点相等就是满二叉树)

2.将需要用到的信息进行封装(如果只有单条数据就不用封装了)

封装树的高度和总节点数

3.编写递归函数 函数的返回值就是2中封装的信息体

3.1在递归函数中首先写出最小问题的信息体并返回

最小问题:树为空  ==> 树的高度为0  数的总节点数为0

3.2从左右子树获取它们的信息体

直接调用递归函数获取

3.3通过左右子树获得的信息体来推算出自己的信息体并将其返回即可

1.高度:当前节点的高度 = 左右孩子节点的高度较大的那一个高度 + 1

2.总节点数:当前节点的总节点数 = 左右孩子的节点数之和

    public boolean isFullTree(Nodes root){
        if (root == null)
            return true;
        //写递归函数
        Data result = process(root);
        return result.nodeNum == (1 << result.height) - 1;
    }
    //封装信息体
    public static class Data{
        int height;
        int nodeNum;

        public Data(int height, int nodeNum) {
            this.height = height;
            this.nodeNum = nodeNum;
        }
    }
    //递归函数
    public Data process(Nodes nodes){
        if (nodes == null)
            return new Data(0, 0);

        Data leftData = process(nodes.getLeft());//左树返给我的信息
        Data rightData = process(nodes.getRight());//右树返给我的信息
        //从左右树返给我的信息进行处理从而得到自己的信息
        int height = Math.max(leftData.height, rightData.height) + 1;
        int nodeNum = leftData.nodeNum + rightData.nodeNum + 1;
        return new Data(height, nodeNum);
    }

题2:判断二叉树是否是平衡二叉树

分析:

1.首先分析出要满足当前要求需要从左右孩子获取到说明信息。

需要知道当前树的左右孩子是否是平衡二叉树 左右孩子的高度(左右孩子都是平衡二叉树并且左右孩子的高度差的绝对值小于等于1就是平衡二叉树)

2.将需要用到的信息进行封装(如果只有单条数据就不用封装了)

封装是否是平衡二叉树 和 树的高度

3.编写递归函数 函数的返回值就是2中封装的信息体

3.1在递归函数中首先写出最小问题的信息体并返回

最小问题:树为空  ==> 是平衡二叉树  高度为0

3.2从左右子树获取它们的信息体

直接调用递归函数获取

3.3通过左右子树获得的信息体来推算出自己的信息体并将其返回即可

1.是否是平衡二叉树:左右孩子都是平衡二叉树并且左右孩子的高度差的绝对值小于等于1就是平衡二叉树

2.树的高度:左右孩子中高度较高的高度 + 1

    public boolean isBalanceTree(Nodes root){
        if (root == null)
            return true;
        Data result = process(root);
        return result.is;
    }

    //封装信息
    public static class Data{
        boolean is;
        int height;

        public Data(boolean is, int height) {
            this.is = is;
            this.height = height;
        }
    }

    public Data process(Nodes node){
        if (node == null)
            return new Data(true, 0);

        //获取左右子树的信息
        Data leftData = process(node.getLeft());
        Data rightData = process(node.getRight());

        //处理自己的信息
        boolean is = false;
        int height;
        //is为true的条件是 左右子树的is都为true  并且  它们的高度差小于等于1
        if (leftData.is && rightData.is && Math.abs(leftData.height - rightData.height) <= 1)
            is = true;
        height = Math.max(leftData.height, rightData.height) + 1;
        return new Data(is,height);
    }

题3:判断二叉树是否是搜索二叉树

分析:

1.首先分析出要满足当前要求需要从左右孩子获取到说明信息。

需要知道当前树的左右孩子是否是搜索二叉树 左孩子的最大值 右孩子的最小值

2.将需要用到的信息进行封装(如果只有单条数据就不用封装了)

封装是否是搜索二叉树 和 树的最大最小值(由于递归的原因所有递归的参数要一致 所以左右孩子的最大最小值都要有)

3.编写递归函数 函数的返回值就是2中封装的信息体

3.1在递归函数中首先写出最小问题的信息体并返回

最小问题:树为空  ==> 由于最大最小值不好给出  所有直接返回null后面再做判断

3.2从左右子树获取它们的信息体

直接调用递归函数获取

3.3通过左右子树获得的信息体来推算出自己的信息体并将其返回即可

1.是否是搜索二叉树:满足一下条件就不是搜索二叉树

1.1.有左孩子 并且 左孩子的最大值大于等于了当前节点的value

1.2.有右孩子 并且 右孩子的最小值小于等于了当前节点的value

2.max:左孩子最大值、右孩子最大值、以及当前值中最大的

3.min:左孩子最小值、右孩子最小值、以及当前值中最小的

    public boolean isSearchTree(Nodes root){
        if (root == null)
            return true;
        //递归函数
        Data data = process(root);
        return data.is;
    }

    //封装信息
    public static class Data{
        boolean is;
        int max;
        int min;

        public Data(boolean is, int max, int min) {
            this.is = is;
            this.max = max;
            this.min = min;
        }
    }

    public Data process(Nodes node){
        if (node == null)
            return null;//因为这里的最大最小值不好确定 所有先暂且返回null 但是后面就要进行判断了
        //获取左右子树的信息
        Data leftData = process(node.getLeft());
        Data rightData = process(node.getRight());
        //根据左右子树的信息加工自己的信息
        int max = node.getValue();
        int min = node.getValue();
        if (node.getLeft() != null){
            max = Math.max(leftData.max, max);
            min = Math.min(leftData.min, min);
        }
        if (node.getRight() != null){
            max = Math.max(rightData.max, max);
            min = Math.min(rightData.min, min);
        }
        boolean is = true;
        //说明情况下导致is变false       1.有左孩子  &&  左孩子的最大值大于等于了node.value
        //                           2.有右孩子 && 右孩子的最小值小于等于了node.value
        if (leftData != null && (leftData.max >= node.getValue()))
            is = false;
        if (rightData != null && (rightData.min <= node.getValue()))
            is = false;
        return new Data(is, max, min);
    }

题1:给出一颗二叉树的两个节点(n1和n2),找到它们的第一个父节点

分析:

采用递归的方式从下向上的返回信息最后根节点返回的信息就是题解

制定边界:

1.如果自己是null  那么就返回null

2.如果自己是n1或者n2就返回自己   

注:

1.其实1、2可以合并为  如果自己是null或者n1或者n2就返回自己

2.为什么要有第二条  因为当前节点的返回值不仅受左右孩子信息的影响  有时候还会受自己的信息影响比如说当自己的信息是n1或者n2的时候。

制定自己返回信息的规则:

1.如果左右孩子给我的信息都不为null  那就返回我自己   此时说明自己就是第一个公共的父节点 把自己返回后根据3就会一路返回到根

2.如果左右孩子都为null就返回null

3.如果左右孩子有一个为null有一个不为null 那就返回不为null的那个

    public Nodes process(Nodes head,Nodes o1,Nodes o2){
        if (head == null || head == o1 || head == o2)
            return head;
        //接收左右孩子返回的信息
        Nodes leftData = process(head.getLeft(), o1, o2);
        Nodes rightData = process(head.getRight(), o1, o2);
        if (leftData != null && rightData != null)
            return head;
        return leftData != null ? leftData : rightData;
    }

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
很高兴回答你关于数据结构和算法的问题!在Java中,有许多基础的数据结构和算法可以使用。下面是一些常见的数据结构和算法的介绍: 1. 数组(Array):数组是一种线性数据结构,可以存储相同类型的元素。它们在内存中是连续存储的,并且可以通过索引来访问元素。 2. 链表(Linked List):链表是另一种常见的线性数据结构,它由节点组成,每个节点都包含一个数据项和一个指向下一个节点的指针。 3. 栈(Stack):栈是一种后进先出(LIFO)的数据结构。它支持两个基本操作:push(将元素放入栈顶)和pop(从栈顶删除元素)。 4. 队列(Queue):队列是一种先进先出(FIFO)的数据结构。它支持两个基本操作:enqueue(将元素放入队尾)和dequeue(从队头删除元素)。 5. 树(Tree):树是一种非线性数据结构,它由节点和边组成。每个节点可以有零个或多个子节点。常见的树包括二叉树、二叉搜索树和平衡二叉树。 6. 图(Graph):图是由节点和边组成的非线性数据结构。节点表示对象,边表示节点之间的关系。图可以是有向的或无向的。 在Java中,还有一些常见的算法,包括但不限于以下几种: 1. 排序算法:例如冒泡排序、选择排序、插入排序、快速排序和归并排序等。 2. 查找算法:例如线性查找和二分查找等。 3. 图算法:例如广度优先搜索(BFS)和深度优先搜索(DFS)等。 4. 动态规划:一种通过将问题分解成子问题来解决复杂问题的算法。 这只是数据结构和算法的一小部分基础知识,希望对你有所帮助!如果你还有其他问题,请随时提问。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值