[模版总结] - 树的基本算法3 - 结构转化

news2024/11/30 12:48:44

二叉树结构转化

  • 通常将二叉树根据某些要求进行结构重构,比如线性结构转化(链表,数组),序列化等。

常见题型

注:这类题目最基本的解题思路是利用递归分治 (也可以使用迭代方法),在构建树结构的时候,我们通常会使用前序遍历的思路自上而下,进行建树,每一次递归中,得到左右子树的值进行连接。

链表类

Leetcode 114 - Flatten Binary Tree to LinkedList

LeetCode 426 - Convert BST to Sorted Doubly Linked List

线性数组或字符类

Leetcode 297. 序列化和反序列化二叉树

Leetcode 106. Construct Binary Tree from Inorder and Postorder Traversal

Leetcode 105. Construct Binary Tree from Preorder and Inorder Traversal

Leetcode 536. Construct Binary Tree from String

Leetcode 606. Construct String from Binary Tree

Leetcode 889. Construct Binary Tree from Preorder and Postorder Traversal

二叉搜索树

Leetcode 449. Serialize and Deserialize BST

题目思路

Leetcode 114 - Flatten Binary Tree to LinkedList

将二叉树以前序遍历的顺序转化成连接结构,要求in-place即不占用额外空间存储新的链表结构。基本思路是递归分治,这里我们使用后序遍历的思路,先拿到左右结点然后转化成链表结构,在每一次递归中:

  1. 拿到左右子结点
  2. 如果左子树为空则直接返回右子树
  3. 如果左子树不为空,将左子树的最右边的结点与当前节点右子树连接,然后将当前节点右边连接到该左子树,然后将当前节点左子树置空。

代码如下:

class Solution {
    public void flatten(TreeNode root) {
        dfs(root);
    }

    private void dfs(TreeNode root) {
        if (root==null) return;
        if (root.left==null && root.right==null) return;

        dfs(root.left);
        dfs(root.right);

        if (root.left==null) return;
        else {
            TreeNode dum = root.left;
            while (dum.right!=null) {
                dum = dum.right;
            }
            dum.right = root.right;
            root.right = root.left;
            root.left = null;
        }
    }
}

Leetcode 606. Construct String from Binary Tree

二叉树序列化问题,根据二叉树前序遍历顺序将各节点按照继承关系打印出来

例子:[1,2,3,4] -> "1(2(4))(3)"

二叉树序列化,通常思路就是前序遍历依次打印各个节点,按照分治的思路,我们在每一次递归任务中,需要做以下步骤:

  1. 打印当前节点
  2. 打印左括号
  3. 遍历左子树
  4. 打印右括号
  5. 判断右子树是否为空,如果不为空重复 2,3(打印右子树),4。

代码如下:

时间复杂度:O(N) ; 空间复杂度:O(h) , h代表递归深度。

class Solution {
    StringBuilder str = new StringBuilder();
    public String tree2str(TreeNode root) {
        dfs(root);
        return str.toString();
    }

    private void dfs(TreeNode root) {
        if (root==null) return;

        str.append(root.val+"");

        if (root.left==null && root.right==null) return;

        str.append('(');
        dfs(root.left);
        str.append(')');

        // skip if right == null
        if (root.right!=null) {
            str.append('(');
            dfs(root.right);
            str.append(')');
        }
    }
}

 

Leetcode 536. Construct Binary Tree from String

这道题目则是上面LC.606的反序列化,通过给定序列化字符串构造原始的树结构,由于序列化后可以通过"()" 来判断节点的父子关系,这道题思路有一些类似Leetcode基础计算器或者表达式计算的问题,我们需要维护一个栈结构,在遍历字符串过程中:

  1. 如果遇到左括号,继续循环
  2. 如果遇到数字或者负号,读取数字位,创建结点并加入Stack中
  3. 如果遇到右括号,即需要开始处理结点父子关系,将最近结点pop出来,pop后栈中最顶上的结点一定是pop出结点的父亲结点,将当前节点连接到该父亲结点上,左优先如果左边不为空则连接到右子树。

代码如下:

时间复杂度:O(N) ; 空间复杂度:O(h) , h代表递归深度。

class Solution {
    public TreeNode str2tree(String s) {
        if (s==null || s.length()==0) return null;
        Stack<TreeNode> stk = new Stack<>();

        for (int i=0; i<s.length();) {
            if (s.charAt(i)=='(') {
                i++;
                continue;
            } else if (s.charAt(i)==')') {
                if (!stk.isEmpty()) {
                    TreeNode node = stk.pop();
                    TreeNode parent = stk.peek();
                    if (parent.left==null) parent.left = node;
                    else parent.right = node;
                }
                i++;
            } else {
                String num = "";
                while (i<s.length() && ((s.charAt(i)>='0' && s.charAt(i)<='9') || s.charAt(i)=='-')) {
                    num+=s.charAt(i);
                    i++;
                }

                TreeNode node = new TreeNode(Integer.parseInt(num));
                stk.push(node);
            }
        }

        return stk.pop();
    }
}

Leetcode 297. 序列化和反序列化二叉树

上面两道题目的合并版,比起使用上述括号形式进行序列化编码,这道题目我们可以对于序列化的格式进行简化,对于缺失的左右叶子结点我们用NULL来表示,每一个结点以逗号隔开。

对于反序列化的步骤,由于序列化是以前序遍历的顺序,所以反序列化也利用前序遍历的顺序,每一次递归过程中进行如下操作:

  1. 根据当前遍历的结点创建二叉树结点,并从列表中移除该结点
  2. 向下遍历左右子树,得到左右子树
  3. 将当前节点连接到左右子树,并返回当前节点

前序遍历的特性是根-左-右,是比较适合构建二叉树这类问题

代码如下:

public class Codec {
    StringBuilder str;
    // Encodes a tree to a single string.
    public String serialize(TreeNode root) {
        str = new StringBuilder();
        helper(root);

        return str.toString().substring(0, str.length()-1);
    }

    private void helper(TreeNode root) {
        if (root==null) {
            str.append("null,");
            return;
        }

        str.append(root.val+",");
        helper(root.left);
        helper(root.right);
    }

    // Decodes your encoded data to tree.
    public TreeNode deserialize(String data) {
        List<String> nodes = new LinkedList<String>(Arrays.asList(data.split(",")));
        return deshelper(nodes);
    }

    private TreeNode deshelper(List<String> nodes) {
        if (nodes==null || nodes.size()==0) return null;

        if (nodes.get(0).equals("null")) {
            nodes.remove(0);
            return null;
        }

        TreeNode curr = new TreeNode(Integer.parseInt(nodes.get(0)));
        nodes.remove(0);
        curr.left = deshelper(nodes);
        curr.right = deshelper(nodes);

        return curr;
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1215533.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

餐厅订座预约小程序的效果如何

市场中无论哪种城市&#xff0c;餐厅非常多&#xff0c;一条不长的商业街&#xff0c;汇聚着数家餐饮品牌&#xff0c;且相互间竞争激烈&#xff0c;并且各个商家都希望用成本低高效率的方法引流及转化。 随着互联网深入各个行业&#xff0c;传统餐饮行业经营痛点不少。 传统餐…

c#正则表达式

using System.Text.RegularExpressions; namespace demo1 {/// <summary>/// 正则表达式&#xff08;Regular Expression&#xff09;是一种文本模式&#xff0c;包括普通字符&#xff08;例如&#xff0c;a&#xff5e;z的字母&#xff09;和特殊字符&#xff08;称为“…

【ArcGIS处理】行政区划与流域区划间转化

【ArcGIS处理】行政区划与流域区划间转化 引言数据准备1、行政区划数据2、流域区划数据 ArcGIS详细处理步骤Step1&#xff1a;统计行政区划下子流域面积1、创建批量处理模型2、添加批量裁剪处理3、添加计算面积 Step2&#xff1a;根据子流域面积占比均化得到各行政区固定值 参考…

Nginx反向代理与负载均衡与504错误

Nginx反向代理与负载均衡概念简介 关于代理 什么是代理 类似中介 在没有代理模式的情况下&#xff0c;客户端和Nginx服务端&#xff0c;都是客户端直接请求服务端&#xff0c;服务端直接响应客户端。 那么在互联网请求里面&#xff0c;客户端往往无法直接向服务端发起请求…

简单的 UDP 网络程序

文章目录&#xff1a; 简单的UDP网络程序服务端创建套接字服务端绑定启动服务器udp客户端本地测试INADDR_ANY 地址转换函数关于 inet_ntoa 简单的UDP网络程序 服务端创建套接字 我们将服务端封装为一个类&#xff0c;当定义一个服务器对象之后&#xff0c;需要立即进行初始化…

态路小课堂丨800G QSFP-DD OSFP VR8光模块简介

TARLUZ态路 近年来&#xff0c;随着IDC数据中心的不断升级&#xff0c;我们可以看到大多数企业已经在不断推出 800G系列光模块。其中&#xff0c;800G QSFP-DD/OSFP VR8&#xff08;以下简称800G VR8&#xff09;采用8通道全双工收发模块&#xff0c;能够满足短距离数据中心和云…

腾讯云服务器可用区是什么意思?可用区选择方法

腾讯云服务器可用区是什么意思&#xff1f;云服务器可用区如何选择&#xff1f;可用区是指在同一个地域内电力和网络相互独立的区域&#xff0c;可用区可以做到故障隔离&#xff0c;所以可用区存在的意义在于构建高可用、高容灾应用&#xff0c;将应用部署在不同可用区内&#…

VB.net WebBrowser网页元素抓取分析方法

在用WebBrowser编程实现网页操作自动化时&#xff0c;常要分析网页Html&#xff0c;例如网页在加载数据时&#xff0c;常会显示“系统处理中&#xff0c;请稍候..”&#xff0c;我们需要在数据加载完成后才能继续下一步操作&#xff0c;如何抓取这个信息的网页html元素变化&…

SpringJDBC模板类JdbcTemplate

Spring JdbcTemplate使用JdbcTemplate完成增删改查环境准备新增修改删除查询一个对象批量添加批量修改和批量删除使用德鲁伊连接池&#xff08;之前数据源是用我们自己写的&#xff09; JdbcTemplate JdbcTemplate是Spring提供的一个JDBC模板类&#xff0c;是对JDBC的封装&…

c语言-浅谈指针(2)

文章目录 1.数组名的理解2.使用指针访问数组3.一维数组传参的本质4.二级指针5.指针数组 本篇文章是关于数组与指针的&#xff0c;在上一篇指针内容的基础上进一步了解指针 1.数组名的理解 我们先来了解一个知识点&#xff1a;在给指针变量赋值时&#xff0c;数组用数组名赋给指…

光伏仪器-1763卫星帆板电源阵列模拟器

01 1763卫星帆板电源阵列模拟器 产品综述&#xff1a; 1763卫星帆板电源阵列模拟器用于解决卫星电源系统研制等帆板电源阵列及二次供电设备的测量和分析&#xff0c;解决电源分系统功能验证、现场试验等无法使用真实的帆板电源等带来的难题&#xff0c;用于卫星或卫星测试系…

顺序理清linux下的环境变量

文章目录 关于环境变量概念&#xff08;了解&#xff09;例引 环境变量 查看环境变量的方法echo && printenv 命令 环境变量的配置.bash_profile 常见 环境变量通过程序获取环境变量本地变量环境变量表 关于环境变量 概念&#xff08;了解&#xff09; 环境变量的概念…

有什么进销存软件,比较适合零售行业日常开单要求及库存记录?

本文将为大家总结一下对于进销存软件要求&#xff1a; 基础功能&#xff1a;可以日常开单、退换货处理、出入库进阶功能&#xff1a;电脑、手机数据同步&#xff0c;保障数据安全&#xff0c;可进行数据分析 其实无论是小型创业公司&#xff0c;还是一家大型企业&#xff0c;…

为什么SSL证书会有序列号

SSL证书中的序列号是为了唯一标识该证书。他是用于识别和跟踪证书的唯一标识符。以确保每个证书都具有唯一的值。 有序列号的原因如下&#xff1a; 唯一性&#xff1a;通过序列号&#xff0c;可以确保每个ssl证书都有一个独特的标识符。这对于区分不同的证书非常重要。 跟踪和…

tsconfig.json无法写入文件“XXXX“因为它会覆盖输入文件

在开发ts项目的时候&#xff0c;包错提示无法写入文件&#xff1a; tsconfig.json无法写入文件"XXXX"因为它会覆盖输入文件 这是tsconfig.json文件配置问题&#xff0c;需要加入下面的配置就好了&#xff1a; {"compilerOptions": {"outDir": …

教育案例分享 | 安全狗云安全体系为高校提升立体化纵深防御能力

一、客户情况 某高校有服务器500台&#xff0c;对外站点200个&#xff0c;核心交换流量20G。 二、客户痛点 校园网系统分类较多&#xff0c;并且每类网站中安全级重要程度又各不相同&#xff0c;同时有多个网络出口(如&#xff1a;教育网、电信网、移动网等)&#xff0c;二级学…

常见JMeter面试题

1、什么是JMeter&#xff1f; JMeter是一种开源的性能测试工具&#xff0c;可以用于测试静态和动态资源&#xff0c;如Web应用程序、数据库、FTP服务器等。 2、JMeter可以测试哪些类型的应用&#xff1f; JMeter可以测试各种类型的应用程序&#xff0c;包括Web应用程序、数…

【知网会议征稿】第三届社会科学与人文艺术国际学术会议 (SSHA 2024)

第三届社会科学与人文艺术国际学术会议 (SSHA 2024) 2024 3rd International Conference on Social Sciences and Humanities and Arts 第三届社会科学与人文艺术国际学术会议 (SSHA 2024)于2024年3月1-3日在中国福州举行。会议旨在为从事“社会科学”与“人文艺术”研究的专…

【C++&数据结构】二叉树(结合C++)的经典oj例题 [ 盘点&全面解析 ](24)

前言 大家好吖&#xff0c;欢迎来到 YY 滴数据结构系列 &#xff0c;热烈欢迎&#xff01; 本章主要内容面向接触过C的老铁 主要内容含&#xff1a; 欢迎订阅 YY滴 数据结构 专栏&#xff01;更多干货持续更新&#xff01;以下是传送门&#xff01; 目录 一.二叉树创建字符串1…

.NET 7 创建Android项目 (拥有原生的界面设计能力,比MAUI更好的性能)

vs2022默认移动开发使用的是maui项目模板&#xff0c;maui确实有很多亮点&#xff0c;就是对比android原生项目性能还需要优化&#xff0c;特别是启动app时无法达到秒开。后来发现vs2022中依然可以直接创建android项目&#xff0c;性能和原生Android基本一致。 1、搜索模板 dot…