代码随想录-算法训练---day14

day14

lc226.翻转二叉树

本题一定要理清遍历顺序, 翻转二叉树也就是 两两交换左右孩子 这个交换是指交换指针指向 并不是交换数字

本题可以使用递归和非递归 但 优先掌握递归解法 使用前序和后续解

既然是写递归 那必须明白递归三部曲

  1. 递归函数的返回值和参数

返回翻转之后的根节点 参数就是要传入节点的指针

  1. 终止条件

if(root == null) return root;

  1. 处理逻辑

先处理前序便利 跟--- 左----右

在根节点的处理逻辑就是 进行交换左右

左 右 就是正常便利

sweap();

root.l;

root.r;

这个是前序便利 但是把sweap交换函数放在下面呢?

root.l;

root.r;

sweap();

这种便利就是左右跟 也就是后续便利

**但是能放在中间变成中序吗 不可的 **

因为先左孩子交换孩子,再根交换孩子(做完后,右孩子已经变成了原来的左孩子),再右孩子交换孩子(此时其实是对原来的左孩子做交换)


public TreeNode invertTree(Node root) {
    if(root == null) return root;
    sweap(root);
    invertTree(root.l);
    invertTree(root.r);
    return root;
}
public void sweap(Node root){
    Node temp = root.l;
    root.l = root.r;
    root.r = temp;
}

lc101对称二叉树

本质上对称二叉树也就是判断根节点的左子树和右子树是否可以相互翻转

比较的话 是比较/\这种 外侧的节点是否相等 同时还有比较内侧节点是否相等 左的左 比较 右边的右

但是 便利顺序如何确定呢?

lc101对称二叉树这道题 只能采用后续便利 左 ---- 右 ---- 跟

因为要不断的收集左右孩子的信息返回给上一个节点 然后再左右 返回给上面

如果是前序 跟左右 这种便利一上来就处理根节点 那么怎么找到左右孩子是否相互翻转呢 所以不能

按照递归三部曲

  1. **确定递归函数 参数 返回值 **

返回值是布尔类型 参数要传入左右孩子

  1. 终止条件

情况一: 左边是空或者不为空 右边不是空或者是空 说明节点个数都不对 肯定不相同

情况二: 左右都空了 但是值不相同 说明个数对上了 但是值不一样 也是false

  1. 处理逻辑

外侧比较: 左节点的左孩子 比较右节点的右孩子

外侧: 左节点的右孩子 比较 右节点的左孩子

如果内侧和外侧 都是true的情况

public boolean isSymmetric(Node root) {
    return compare(root.l, root.r);

}
public boolean compare(Node l, Node r) {
    if(l != null && r == null) return false;
    if(l == null && r != null) return false;
    if(l == null && r == null) return true;
    if(l.v != r.v) return false;

    boolean out = compare(l.l, r.r);
    boolean in = compare(l.r, r.l);
    return out && in;

}

lc104_二叉树最大深度

给定一个二叉树,找出其最大深度。

深度: 二叉树任意一个节点到根节点的距离 (取决于深度是0开始还是1开始)

高度: 任意一个节点 到叶子节点的距离 (看高度0开始还是1开始)

确定便利顺序

求高度 用后续 求深度 用前序便利 而根节点的高度就是二叉树的最大深度 最大深度 肯定是根节点开始

所以本题使用后续便利求二叉树最大深度 后续: 左---右----跟

递归三部曲

返回值int 参数跟节点 便利的节点遇到空了就终止

逻辑 按照后续便利 求左节点高度 有节点高度 在根节点 取左右的最大值 最后返回这个最大值再加一

public int maxDepth(Node root){

    if(root == null) return 0;
    int lDepth = maxDepth(root.l);
    int rDepth = maxDepth(root.r);
    return Math.max(lDepth, rDepth) + 1;
}

**本题也可以使用一行代码搞定 但是那种并不利于新手理解 也看不出来是使用的后续便利 **


lc111二叉树的最小深度

给定一个二叉树,找出其最小深度。

本题的最小深度是: 根节点到 最近的叶子节点


本题的坑在于 如果左子树 或者右子树 有一个是空的话 那么就要算非空子树的最小深度


public int minDepth(Node root){

    if(root == null) return 0;

    int lDepth = minDepth(root.l);
    int rDepth = minDepth(root.r);

    if(root.l == null) return rDepth + 1;
    if(root.r == null) return rDepth + 1;

    return Math,min(l, r) + 1;


}
posted @ 2024-11-13 16:33  小杭呀  阅读(11)  评论(0)    收藏  举报