代码随想录算法训练营 Day 15 | 层序遍历,226.翻转二叉树,101.对称二叉树

层序遍历

102.二叉树的层序遍历

题目链接:二叉树的层序遍历

迭代法:

public List<List<Integer>> levelOrder(TreeNode root) {
    List<List<Integer>> result = new ArrayList<>();
    if (root == null) {
        return result;
    }
    Queue<TreeNode> queue = new LinkedList<>();
    int deep = 0;
    queue.offer(root);
    while (!queue.isEmpty()) {
        List<Integer> list = new ArrayList<>();
        int len = queue.size();
        for (int i = 0; i < len; i++) {
            TreeNode temp = queue.poll();
            list.add(temp.val);
            if (temp.left != null) queue.offer(temp.left);
            if (temp.right != null) queue.offer(temp.right);
        }
        result.add(list);
    }
    return result;
}

递归法:

public List<List<Integer>> levelOrder(TreeNode root) {
    List<List<Integer>> result = new ArrayList<>();
    checkFun(root, 0, result);
    return result;
}

void checkFun(TreeNode cur, int deep, List<List<Integer>> result) {
    if (cur == null) return;
    deep++;

    if (result.size() < deep) {
        List<Integer> list = new ArrayList<>();
        result.add(list);
    }
    result.get(deep - 1).add(cur.val);
    checkFun(cur.left, deep, result);
    checkFun(cur.right, deep, result);
}

107.二叉树的层次遍历 II

最简单的思路就是直接把 102 的结果给反转一下,不过也可通过修改一部分代码,把每层列表添加在开头来解决。

迭代法

public List<List<Integer>> levelOrderBottom(TreeNode root) {
    List<List<Integer>> result = new ArrayList<>();
    if (root == null) return result;
    Queue<TreeNode> queue = new LinkedList<>();
    queue.offer(root);
    while (!queue.isEmpty()) {
        List<Integer> list = new ArrayList<>();
        int len = queue.size();
        for (int i = 0; i < len; i++) {
            TreeNode temp = queue.poll();
            list.add(temp.val);
            if (temp.left != null) queue.offer(temp.left);
            if (temp.right != null) queue.offer(temp.right);
        }
        // 每层加在开头
        result.add(0, list);
    }

    return result;
}

递归法

public List<List<Integer>> levelOrderBottom(TreeNode root) {
    List<List<Integer>> result = new ArrayList<>();
    if (root == null) return result;
    checkFun(root, 0, result);
    return result;
}

void checkFun(TreeNode cur, int deep, List<List<Integer>> result) {
    if (cur == null) {
        return;
    }
    deep++;
    if (result.size() < deep) {
        // 反序,所以每次插入新数组在开头位置
        result.add(0, new ArrayList<>());
    }
    // 添加值时也要计算一下索引
    result.get(result.size() - deep).add(cur.val);
    checkFun(cur.left, deep, result);
    checkFun(cur.right, deep, result);
}

199.二叉树的右视图

迭代法,添加结果的时候判断是否到每层的最后一个。

public List<Integer> rightSideView(TreeNode root) {
    List<Integer> result = new ArrayList<>();
    if (root == null) return result;
    Queue<TreeNode> queue = new LinkedList<>();
    queue.offer(root);
    while (!queue.isEmpty()) {
        int len = queue.size();
        for (int i = 0; i < len; i++) {
            TreeNode temp = queue.poll();
            if (i == len - 1) {
                result.add(temp.val);
            }
            if (temp.left != null) queue.offer(temp.left);
            if (temp.right != null) queue.offer(temp.right);
        }
    }

    return result;
}

637.二叉树的层平均值

太简单啦。

public List<Double> averageOfLevels(TreeNode root) {
    List<Double> result = new ArrayList<>();
    if (root == null) {
        return result;
    }
    Queue<TreeNode> queue = new LinkedList<>();
    queue.offer(root);
    while (!queue.isEmpty()) {
        int len = queue.size();
        double sum = 0;
        for (int i = 0; i < len; i++) {
            TreeNode temp = queue.poll();
            sum += temp.val;
            if (temp.left != null) queue.offer(temp.left);
            if (temp.right != null) queue.offer(temp.right);
        }
        result.add(sum / len);
    }
    return result;
}

429.N 叉树的层序遍历

乱杀

public List<List<Integer>> levelOrder(Node root) {
    List<List<Integer>> result = new ArrayList<>();
    if (root == null) return result;
    Queue<Node> queue = new LinkedList<>();
    queue.offer(root);
    while (!queue.isEmpty()) {
        List<Integer> list = new ArrayList<>();
        int len = queue.size();
        for (int i = 0; i < len; i++) {
            Node temp = queue.poll();
            if (temp == null) continue;
            list.add(temp.val);
            queue.addAll(temp.children);
        }
        result.add(list);
    }
    return result;
}

515.在每个树行中找最大值

就这

public List<Integer> largestValues(TreeNode root) {
    List<Integer> result = new ArrayList<>();
    if (root == null) return result;
    Queue<TreeNode> queue = new LinkedList<>();
    queue.offer(root);
    while (!queue.isEmpty()) {
        Integer maxVal = Integer.MIN_VALUE;
        int len = queue.size();
        for (int i = 0; i < len; i++) {
            TreeNode temp = queue.poll();
            maxVal = Math.max(temp.val, maxVal);
            if (temp.left != null) queue.offer(temp.left);
            if (temp.right != null) queue.offer(temp.right);
        }
        result.add(maxVal);
    }

    return result;
}

116.填充每个节点的下一个右侧节点指针

层序遍历,每层定义一个 Node next 变量,默认为空。重在在于入队列顺序改为从右开始,然后循环当前层节点的 next 进行赋值,同时吧 next 指向当前节点。

public Node connect(Node root) {
    if (root == null) {
        return root;
    }
    Queue<Node> queue = new LinkedList<>();
    queue.offer(root);
    while (!queue.isEmpty()) {
        int len = queue.size();
        Node next = null;
        for (int i = 0; i < len; i++) {
            Node temp = queue.poll();
            if (temp.right != null) queue.offer(temp.right);
            if (temp.left != null) queue.offer(temp.left);
            temp.next = next;
            next = temp;
        }
    }
    return root;
}

117.填充每个节点的下一个右侧节点指针 II

额,同 116.填充每个节点的下一个右侧节点指针

104.二叉树的最大深度

public int maxDepth(TreeNode root) {
    int depth = 0;
    if (root == null)
        return depth;
    Queue<TreeNode> queue = new LinkedList<>();
    queue.offer(root);
    while (!queue.isEmpty()) {
        int len = queue.size();
        for (int i = 0; i < len; i++) {
            TreeNode temp = queue.poll();
            if (temp.left != null) queue.offer(temp.left);
            if (temp.right != null) queue.offer(temp.right);
        }
        depth++;
    }
    return depth;
}

111.二叉树的最小深度

‍子节点两边为空就结束。

public int minDepth(TreeNode root) {
    int depth = 0;
    if (root == null) return depth;
    Queue<TreeNode> queue = new LinkedList<>();
    queue.offer(root);
    while (!queue.isEmpty()) {
        depth++;
        int len = queue.size();
        for (int i = 0; i < len; i++) {
            TreeNode temp = queue.poll();
            if (temp.left == null && temp.right == null) {
                return depth;
            }
            if (temp.left != null) queue.offer(temp.left);
            if (temp.right != null) queue.offer(temp.right);
        }
    }
    return depth;
}

226.翻转二叉树

题目链接:力扣

这道题用前序遍历和后续遍历很好解,要注意中序遍历,容易让部分节点旋转两次,不推荐使用。

递归法:

public TreeNode invertTree(TreeNode root) {
    if (root == null) {
        return root;
    }
    swapChild(root);
    invertTree(root.left);
    invertTree(root.right);
    return root;
}

void swapChild(TreeNode node) {
    TreeNode temp = node.left;
    node.left = node.right;
    node.right = temp;
}

迭代法:

public TreeNode invertTree(TreeNode root) {
    if (root == null) {
        return root;
    }
    Queue<TreeNode> queue = new LinkedList<>();
    queue.offer(root);
    while (!queue.isEmpty()) {
        int len = queue.size();
        for (int i = 0; i < len; i++) {
            TreeNode temp = queue.poll();
            if (temp.left != null) queue.offer(temp.left);
            if (temp.right != null) queue.offer(temp.right);
            swapChild(temp);
        }
    }

    return root;
}

void swapChild(TreeNode node) {
    TreeNode temp = node.left;
    node.left = node.right;
    node.right = temp;
}

101.对称二叉树

题目链接:力扣

这道题重点要知道哪些节点进行比较,我们可以区分为两类,一个是外侧节点,一个是内测节点。

 

递归解法:

public boolean isSymmetric(TreeNode root) {

    return compare(root.left, root.right);
}

private boolean compare(TreeNode left, TreeNode right) {
    if (left == null && right == null) {
        return true;
    }
    if (left == null || right == null || left.val != right.val) {
        return false;
    }

    boolean compareOutside = compare(left.left, right.right);
    boolean compareInside = compare(left.right, right.left);

    return compareOutside && compareInside;
}

递归法:

使用队列,一次性保存两对节点,然后每次比较也取出两对节点,如图所示:

 

public boolean isSymmetric(TreeNode root) {
    Queue<TreeNode> queue = new LinkedList<>();
    queue.offer(root.left);
    queue.offer(root.right);
    while (!queue.isEmpty()) {
        TreeNode left = queue.poll();
        TreeNode right = queue.poll();
        if (left == null && right == null) {
            continue;
        }
        if (left == null || right == null || left.val != right.val) {
            return false;
        }
        // 保存外侧
        queue.offer(left.left);
        queue.offer(right.right);
        // 保存内测
        queue.offer(left.right);
        queue.offer(right.left);
    }
    return true;
}

总结

唯一的想法就是多复习。。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值