瑞_力扣LeetCode_二叉搜索树相关题

🙊 前言:本文章为瑞_系列专栏之《刷题》的力扣LeetCode系列,主要以力扣LeetCode网的题进行解析与分享。本文仅供大家交流、学习及研究使用,禁止用于商业用途,违者必究!

在这里插入图片描述

说明

  本文主要是配合《瑞_数据结构与算法_二叉树》对二叉树的知识进行提升和拓展

题目 144. 二叉树的前序遍历

  原题链接:Leetcode144. 二叉树的前序遍历

  给你二叉树的根节点 root ,返回它节点值的前序遍历。

  示例 1:

在这里插入图片描述

输入:root = [1,null,2,3]
输出:[1,2,3]

  示例 2:

输入:root = []
输出:[]

  示例 3:

输入:root = [1]
输出:[1]

  示例 4:

在这里插入图片描述

输入:root = [1,2]
输出:[1,2]

  示例 5:

在这里插入图片描述

输入:root = [1,null,2]
输出:[1,2]

  提示:

  • 树中节点数目在范围 [0, 100] 内
  • -100 <= Node.val <= 100

  进阶:递归算法很简单,你可以通过迭代算法完成吗?

题解

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
   
    public List<Integer> preorderTraversal(TreeNode root) {
   
		/*
         * 栈
         */
        LinkedList<TreeNode> stack = new LinkedList<>();

        /*
         * 代表当前节点
         */
        TreeNode current = root;
        /*
         * 最近一次弹栈的元素
         */
        TreeNode pop = null;

        List<Integer> result = new ArrayList<>();
        while (!stack.isEmpty() || current != null) {
   
            if (current != null) {
   
                stack.push(current);
                // 待处理左子树
                result.add(current.val);
                current = current.left;
            } else {
   
                TreeNode peek = stack.peek();
                // 没有右子树
                if (peek.right == null) {
   
                    // 获取最近一次弹栈的元素
                    pop = stack.pop();
                }
                // 右子树处理完成
                else if (peek.right == pop) {
   
                    // 获取最近一次弹栈的元素
                    pop = stack.pop();
                }
                // 待处理右子树
                else {
   
                    current = peek.right;
                }
            }
        }
        return result;
    }
}

题目 94. 二叉树的中序遍历

  原题链接:Leetcode94. 二叉树的中序遍历

  给定一个二叉树的根节点 root ,返回 它的中序遍历 。

  示例 1:

在这里插入图片描述

输入:root = [1,null,2,3]
输出:[1,3,2]

  示例 2:

输入:root = []
输出:[]

  示例 3:

输入:root = [1]
输出:[1]

  提示:

  • 树中节点数目在范围 [0, 100] 内
  • -100 <= Node.val <= 100

  进阶: 递归算法很简单,你可以通过迭代算法完成吗?

题解

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
   
    public List<Integer> inorderTraversal(TreeNode root) {
   
        /*
         * 栈
         */
        LinkedList<TreeNode> stack = new LinkedList<>();

        /*
         * 代表当前节点
         */
        TreeNode current = root;
        /*
         * 最近一次弹栈的元素
         */
        TreeNode pop = null;

        List<Integer> result = new ArrayList<>();
        while (!stack.isEmpty() || current != null) {
   
            if (current != null) {
   
                stack.push(current);
                // 待处理左子树
                current = current.left;
            } else {
   
                TreeNode peek = stack.peek();
                // 没有右子树
                if (peek.right == null) {
   
                    result.add(peek.val);
                    // 获取最近一次弹栈的元素
                    pop = stack.pop();
                }
                // 右子树处理完成
                else if (peek.right == pop) {
   
                    // 获取最近一次弹栈的元素
                    pop = stack.pop();
                }
                // 待处理右子树
                else {
   
                    result.add(peek.val);
                    current = peek.right;
                }
            }
        }
        return result;
    }
}

题目 145. 二叉树的后序遍历

  原题链接:Leetcode145. 二叉树的后序遍历

  示例 1:
在这里插入图片描述

输入:root = [1,null,2,3]
输出:[3,2,1]

  示例 2:

输入:root = []
输出:[]

  示例 3:

输入:root = [1]
输出:[1]

  说明:

  • 树中节点的数目在范围 [0, 100] 内
  • -100 <= Node.val <= 100

  进阶:递归算法很简单,你可以通过迭代算法完成吗?

题解

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
   
    public List<Integer> postorderTraversal(TreeNode root) {
   
        /*
         * 栈
         */
        LinkedList<TreeNode> stack = new LinkedList<>();
        /*
         * 代表当前节点
         */
        TreeNode current = root;
        /*
         * 最近一次弹栈的元素
         */
        TreeNode pop = null;

        List<Integer> result = new ArrayList<>();
        while (!stack.isEmpty() || current != null) {
   
            if (current != null) {
   
                stack.push(current);
                // 待处理左子树
                current = current.left;
            } else {
   
                TreeNode peek = stack.peek();
                // 没有右子树
                if (peek.right == null) {
   
                    // 获取最近一次弹栈的元素
                    pop = stack.pop();
                    result.add(pop.val);
                }
                // 右子树处理完成
                else if (peek.right == pop) {
   
                    // 获取最近一次弹栈的元素
                    pop = stack.pop();
                    result.add(pop.val);
                }
                // 待处理右子树
                else {
   
                    current = peek.right;
                }
            }
        }
        return result;
    }
}

题目 105. 从前序与中序遍历序列构造二叉树

  原题链接:Leetcode105. 从前序与中序遍历序列构造二叉树

  给定两个整数数组 preorder 和 inorder ,其中 preorder 是二叉树的先序遍历, inorder 是同一棵树的中序遍历,请构造二叉树并返回其根节点。

  示例 1:

在这里插入图片描述

	输入: preorder = [3,9,20,15,7], inorder = [9,3,15,20,7]
	输出: [3,9,20,null,null,15,7]

  示例 2:

	输入: preorder = [-1], inorder = [-1]
	输出: [-1]

  提示:

  • 1 <= preorder.length <= 3000
  • inorder.length == preorder.length
  • -3000 <= preorder[i], inorder[i] <= 3000
  • preorderinorder无重复 元素
  • inorder 均出现在 preorder
  • preorder 保证 为二叉树的前序遍历序列
  • inorder 保证 为二叉树的中序遍历序列

题解

  思路

	1. 前序遍历(preorder)的第一个值肯定是根节点。通过preorder寻找根节点。
	2. 中序遍历(inorder)在根节点之前的值是根节点的左子树部分,而之后的值是根节点的右子树部分。通过inorder区分左右子树部分。
	3. 通过循环inorder使用根节点确定中序遍历的左右子树部分、前序遍历的左右子树部分。
	4. 根据1.2.3.继续分为子问题,递归解决。
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
   
    public TreeNode buildTree(int[] preOrder, int[] inOrder) {
   
        if (preOrder.length == 0) {
   
            return null;
        }
        // 创建根节点
        int rootValue = preOrder[0];
        TreeNode root = new TreeNode(rootValue);
        // 区分左右子树
        for (int i = 0; i < inOrder.length; i++) {
   
            if (inOrder[i] == rootValue) {
   
                // 0 ~ i-1 左子树
                // i+1 ~ inOrder.length -1 右子树
                int[] inLeft = Arrays.copyOfRange(inOrder, 0, i); 
                int[] inRight = Arrays.copyOfRange(inOrder, i + 1, inOrder.length); 

                int[] preLeft = Arrays.copyOfRange(preOrder, 1, i + 1);
                int[] preRight = Arrays.copyOfRange(preOrder, i + 1, preOrder.length); 

                root.left = buildTree(preLeft, inLeft); 
                root.right = buildTree(preRight, inRight); 
                break;
            }
        }
        return root;
    }
}

瑞:可以使用HashMap优化,以及新数组可以通过索引坐标参数传递优化。具体可见本系列HashMap章节(后续更新)

题目 106. 从中序与后序遍历序列构造二叉树

  原题链接:Leetcode106. 从中序与后序遍历序列构造二叉树

  给定两个整数数组 inorder 和 postorder ,其中 inorder 是二叉树的中序遍历, postorder 是同一棵树的后序遍历,请你构造并返回这颗 二叉树 。

  示例1:

在这里插入图片描述

	输入:inorder = [9,3,15,20,7], postorder = [9,15,7,20,3]
	输出:[3,9,20,null,null,15,7]

  示例2:

	输入:inorder = [-1], postorder = [-1]
	输出:[-1]

  提示:

  • 1 <= inorder.length <= 3000
  • postorder.length == inorder.length
  • -3000 <= inorder[i], postorder[i] <= 3000
  • inorderpostorder 都由 不同 的值组成
  • postorder 中每一个值都在 inorder
  • inorder 保证是树的中序遍历
  • postorder 保证是树的后序遍历

题解

  思路

	1. 后序遍历(postorder)的最后一个元素就是根节点。通过postorder寻找根节点。
	2. 中序遍历(inorder)在根节点之前的值是根节点的左子树部分,而之后的值是根节点的右子树部分。通过inorder区分左右子树部分。
	3. 通过循环inorder使用根节点确定中序遍历的左右子树部分、后序遍历的左右子树部分。
	4. 根据1.2.3.继续分为子问题,递归解决。
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
   
    public TreeNode buildTree(int[] inOrder, int[] postOrder) {
   
        if (inOrder.length == 0) {
   
            return null;
        }
        // 根
        int rootValue = postOrder[postOrder.length - 1];
        TreeNode root = new TreeNode(rootValue);
        // 切分左右子树
        for (int i = 0; i < inOrder.length; i++) {
   
            if (inOrder[i] == rootValue) {
   
                int[] inLeft = Arrays.copyOfRange(inOrder, 0, i);
                int[] inRight = Arrays.copyOfRange(inOrder, i + 1, inOrder.length);

                int[] postLeft = Arrays.copyOfRange(postOrder, 0, i);
                int[] postRight = Arrays.copyOfRange(postOrder, i, postOrder.length - 1);

                root.left = buildTree(inLeft, postLeft);
                root.right = buildTree(inRight, postRight);
                break;
            }
        }
        return root;
    }
}



本文是博主的粗浅理解,可能存在一些错误或不完善之处,如有遗漏或错误欢迎各位补充,谢谢

  如果觉得这篇文章对您有所帮助的话,请动动小手点波关注💗,你的点赞👍收藏⭐️转发🔗评论📝都是对博主最好的支持~


相关推荐

  1. 700,搜索中的搜索

    2024-02-07 14:40:04       31 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-02-07 14:40:04       98 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-02-07 14:40:04       106 阅读
  3. 在Django里面运行非项目文件

    2024-02-07 14:40:04       87 阅读
  4. Python语言-面向对象

    2024-02-07 14:40:04       96 阅读

热门阅读

  1. 渗透测试工具库总结(全网最全)

    2024-02-07 14:40:04       80 阅读
  2. redis相关问题

    2024-02-07 14:40:04       44 阅读
  3. UI自动化之Poco常用断言方式

    2024-02-07 14:40:04       54 阅读
  4. 踩坑实录(Second Day)

    2024-02-07 14:40:04       51 阅读
  5. 蓝桥杯(Web大学组)2022国赛真题:新鲜的蔬菜

    2024-02-07 14:40:04       52 阅读
  6. 51单片机 温度传感器得数据,传到上位机

    2024-02-07 14:40:04       51 阅读
  7. docker学习

    2024-02-07 14:40:04       50 阅读
  8. C++类模板实例:数组类封装

    2024-02-07 14:40:04       47 阅读
  9. Synchronized 和 ReentrantLock 的区别

    2024-02-07 14:40:04       56 阅读
  10. Dockerfile和.gitlab-ci.yml文件模板

    2024-02-07 14:40:04       57 阅读
  11. 什么是可解释AI

    2024-02-07 14:40:04       48 阅读
  12. 详解Non-ASCII character ‘\xe6‘

    2024-02-07 14:40:04       51 阅读
  13. Spring Cloud Netflix Eureka的参数调优

    2024-02-07 14:40:04       44 阅读
  14. 融转通与转融通

    2024-02-07 14:40:04       53 阅读
  15. 数据分析之数据预处理、分析建模、可视化

    2024-02-07 14:40:04       46 阅读