首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >LeetCode 897. Increasing Order Search Tree

LeetCode 897. Increasing Order Search Tree

原创
作者头像
大学里的混子
修改于 2018-10-29 09:10:01
修改于 2018-10-29 09:10:01
66900
代码可运行
举报
文章被收录于专栏:LeetCodeLeetCode
运行总次数:0
代码可运行

897. Increasing Order Search Tree

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制

Given a tree, rearrange the tree in in-order so that the leftmost node in the tree is now the 
root of the tree, and every node has no left child and only 1 right child.

Example 1:
Input: [5,3,6,2,4,null,8,1,null,null,null,7,9]

           5
          / \
         3    6
        / \    \
       2   4    8
      /        / \
     1        7   9

Output: [1,null,2,null,3,null,4,null,5,null,6,null,7,null,8,null,9]

        1
          \
           2
             \
              3
               \
                 4
                   \
                    5
                      \
                       6
                        \
                          7
                            \
                              8
                               \
                                9

题目大意:将一个BST,转化为一个只有右孩子的树,并且,这个树从根节点到叶子节点是从小到大排列的。

错误解法:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    TreeNode prev1 ;
    TreeNode dunny = prev1;
    public TreeNode increasingBST(TreeNode root) {
        increasingBST_helper(root);
        return dunny;
    }

    public void increasingBST_helper(TreeNode root) {
        if (root == null) return;
        increasingBST_helper(root.left);
        if (prev1!=null) {
            prev1.right = root;
            root.left = null;
        }
        prev1 = root;
        increasingBST_helper(root.right);
    }

这个解法思路没有什么错误,但是最终的结果总是返回null?是什么原因呢?

解法一:

个人觉得解法一较为容易理解,既然最后的树从根节点到叶子节点是从小到大排列的,我们知道,BST采用中序遍历就是从小到大依次遍历树。于是我们采用prev1节点来记录上一个遍历的节点,用dunny来记录最终树的根节点,于是可以很容易的写出一下程序,个人觉得算法的效率一般,至少不会很差吧,属于一个中规中矩的树的递归。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
TreeNode prev1 ;
TreeNode dunny = prev1;
public TreeNode increasingBST(TreeNode root) {
    increasingBST_helper(root);
    return dunny;
}

public void increasingBST_helper(TreeNode root) {
    if (root == null) return;
    increasingBST_helper(root.left);
    if (prev1!=null) {
        prev1.right = root;
        root.left = null;
    }else {
        dunny = root;
    }
    prev1 = root;
    increasingBST_helper(root.right);
}

需要注意的是,什么时候给dunny赋值呢?这种错误是我经常犯的错误,如果再定义dunny的时候让dunny指向一个没有初始化的prev1,后面不再对dunny做其他赋值操作的话,这样的返回结果是为null的,因为dunny指向prev1的时候,prevd1还没有初始化,所以,这个时候prev1并没有指向一个地址,prev1仍然指向null,即使后面对prev1进行了赋值操作,但是这个时候并不会影响到dunny,因此,这就是为什么之前一直返回为null的原因。

解法二:

解法二的思路与解法一,并没有原理上本质的区别,对错误的解法进行了思考后,可以采用虚拟投节点的方式更好的处理标记头结点的问题,我们采用dunny做为虚拟头结点,这节点不包含于最终的结果,这样就省去了一个解法一中的判断条件,不需要考虑何时给最终结果的投节点做标记的情况。实际上,虚拟头结点(英文:dunny)在链表中的使用更加广泛,这样的好处是很好的处理头结点的问题。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
TreeNode prev1 = new TreeNode(0);
TreeNode dunny = prev1;
public TreeNode increasingBST(TreeNode root) {
    increasingBST_helper(root);
    return dunny.right;
}

public void increasingBST_helper(TreeNode root) {
    if (root == null) return;
    increasingBST_helper(root.left);
    prev1.right = root;
    root.left = null;
    prev1 = root;
    increasingBST_helper(root.right);
}

如果你觉得采用global variable 不爽,那也可以很容易改为函数变量。

解法三:

解法三的思路是我在讨论区看到的别人的解法,这个递归的思路,个人感觉并没有之前的好理解,但是代码量比上面的要少。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public TreeNode increasingBST(TreeNode root) {
    return helper(root, null);
}

public TreeNode helper(TreeNode root, TreeNode tail) {
    if (root == null) return tail;
    TreeNode res = helper(root.left, root);
    root.left = null;
    root.right = helper(root.right, tail);
    return res;
}

下面添加两行输出,把每次的递归参数打印出来,也许会更好理解。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public TreeNode increasingBST(TreeNode root) {
    return helper(root, null);
}

public TreeNode helper(TreeNode root, TreeNode tail) {

///////////////////////////////////////////////////////////////////////////////
    if (root!=null)System.out.print(root.val); else System.out.print("null");
    System.out.print("  ");
    if (tail!=null)System.out.println(tail.val); else System.out.println("null");
///////////////////////////////////////////////////////////////////////////////

    if (root == null) return tail;
    TreeNode res = helper(root.left, root);
    root.left = null;
    root.right = helper(root.right, tail);
    return res;
}
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
           5
          / \
         3    6
        / \    \
       2   4    8
      /         / \
     1         7   9

输出为:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
root  tail:
5    null
3    5
2    3
1    2
null    1
null    2
null    3
4    5
null    4
null    5
6    null
null    6
8    null
7    8
null    7
null    8
9    null
null    9
null    null

总结,关于BST的问题,考察中序遍历的问题较为常见,也会存在各种变形,需要你仔细思考,将问题转化为我们熟知的那些树的特性上去求解。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
一文了解Mongodb使用的语法
在使用数据库之前,我们需要先了解下其基本的数据结构类型。防止我们出现类型不匹配的问题。 支持的数据类型补充的是本人在开发中经常使用的。还有更多的数据类型可以参考官方文档。
用户2196435
2018/11/08
6350
了解 MongoDB 看这一篇就够了
MongoDB 是一款流行的开源文档型数据库,从它的命名来看,确实是有一定野心的。MongoDB 的原名一开始来自于 英文单词"Humongous", 中文含义是指"庞大",即命名者的意图是可以处理大规模的数据。
美码师
2019/10/18
1.4K0
了解 MongoDB 看这一篇就够了
MongoDB学习整理
MongoDB 是介于关系数据库和非关系数据库之间的产品,是非关系数据库中功能最丰富,最像关系数据库的,语法类似javascript面向对象的查询语言,是一个面向集合的、模式自由的文档型数据库。
CS逍遥剑仙
2019/01/01
9150
mongodb概念
https://www.runoob.com/mongodb/mongodb-databases-documents-collections.html
用户10325771
2023/03/01
4870
mongodb概念
2020最新MongoDB规范你应该了解一下
MongoDB是非关系型数据库的典型代表,DB-Engines Ranking 数据显示,近年来,MongoDB在 NoSQL领域一直独占鳌头。MongoDB是为快速开发互联网应用 而设计的数据库系统,其数据模型和持 久化策略就是为了构建高读/写的性能,并且可以方面的弹性拓展。随着MongoDB的普及和使用量的快 速增长,为了规范使用,便于管理和获取更高的性能,整理此文档。我们从 数据库设计规范、集合设计 规范、索引设计规范、文档设计规范、API使用规范、连接规范等方面进行阐述和要求。
MongoDB中文社区
2020/06/24
2K0
mac系统下安装、启动、停止mongodb
MongoDB 下载地址: https://www.mongodb.com/download-center?jmp=nav#community nodejs下载地址: https://nodejs.o
极客教程
2018/03/01
2.5K0
mac系统下安装、启动、停止mongodb
MongoDB分片集群原理、搭建及测试详解
随着技术的发展,目前数据库系统对于海量数据的存储和高效访问海量数据要求越来越高,MongoDB分片机制就是为了解决海量数据的存储和高效海量数据访问而生。 MongoDB分片集群由mongos路由进程(轻量级且非持久化进程)、复制集组成的片shards(分片一般基于复制集故障转移和冗余备份功能)、一组配置服务器(存储元数据信息,一般冗余3台)构成。
用户7353950
2022/06/23
1.5K0
MongoDB Change Stream之一——上手及初体验
Change Stream可以直译为"变更流",也就是说会将数据库中的所有变更以流式的方式呈现出来。用户可以很方便地对数据库建立一个监听(订阅)进程,一旦数据库发生变更,使用change stream的客户端都可以收到相应的通知。使用场景可以包括但不限于以下几种:
phoenix、
2020/10/10
10.8K0
MongoDB Change Stream之一——上手及初体验
MongoDB删数据---一个无聊的测试
上周五的时候,线上的一个MongoDB集群需要删除部分数据,这个MongoDB集群本身是个分片集群,包含10个分片,架构如下:
AsiaYe
2021/11/09
8560
MongoDB删数据---一个无聊的测试
MongoDB入门实操《中篇》
首先我们来了解几个概念,虽然MongoDB入门实操《上篇》这篇文章已经提到过,这里再次加深印象: 集合:Mongo 中的集合就是mysql 的表的表现形式 文档:文档的数据结构和JSON 基本一样,它就是集合(表)中的一条记录,相当于mysql 的行row 字段:Mongo 中的field 相当于mysql 中的column 索引:Mongo 中的index 与mysql 的index 一样 主键:Mongo 中的primary key 与mysql 的一样,其中Mongo 中将_id 自动设置为主键
Wu_Candy
2022/07/04
2550
都 2020了,你该知道MongoDB优化策略了~
MongoDB 是高性能数据,但是在使用的过程中,大家偶尔还会碰到一些性能问题。MongoDB和其它关系型数据库相比,例如 SQL Server 、MySQL 、Oracle 相比来说,相对较新,很多人对其不是很熟悉,所以很多开发、DBA往往是注重功能的实现,而忽视了性能的要求。其实,MongoDB和 SQL Server 、MySQL 、Oracle 一样,一个 数据库对象的设计调整、索引的创建、语句的优化,都会对性能产生巨大的影响。
JavaEdge
2020/05/27
2.2K0
MongoDB 从4.4到7.0各个版本特性概览
在数据库技术日新月异的今天,MongoDB作为领先的NoSQL数据库之一,持续地推出新版本以满足不断变化的企业需求和技术挑战。从MongoDB 4.4至7.0,每一版都融入了创新特性,旨在提升性能、扩展性、安全性和易用性,同时也反映了行业趋势和用户反馈。本文旨在全面剖析这些版本中的关键新特性,不仅是为了记录技术演进的历史,更是为了赋能数据库管理员、开发者和架构师,使他们能够充分理解并利用这些新功能,从而优化数据管理和应用性能。
DBA实战
2024/09/06
4940
MongoDB 从4.4到7.0各个版本特性概览
MongoDB后台shell语句(一)
1.连接数据库 ./mongo 2.创建数据库 (如果数据库不存在,则创建数据库,否则切换到指定数据库。)
六月的雨在Tencent
2024/03/28
2170
MongoDB使用小结:一些常用操作分享
本文整理了一年多以来我常用的MongoDB操作,涉及mongo-shell、pymongo,既有运维层面也有应用层面,内容有浅有深,这也就是我从零到熟练的历程。
拓荒者
2019/09/06
2.2K0
mongodb11天之屠龙宝刀(三)基本操作:增删改查与mysql对比
mongodb11天之屠龙宝刀(三)基本操作:增删改查与mysql对比 基本概念_id和ObjectId: 1._id   MongoDB 中存储的文档必有一”_id” 键。这个键的值可以是任何类型的,默认是个ObjectId 对象。在一个集合里面,每个文档都有唯一的”_id” 值,来确保集合里面每个文档都能被唯一标识。如果有两个集合的话,两个集合可以都有一个值为123 的”_id” 键,但是每个集合里面只能有一个”_id” 是123 的文档。 2. ObjectId   ObjectId 是”
学到老
2018/03/19
7090
mongodb11天之屠龙宝刀(三)基本操作:增删改查与mysql对比
为MongoDB添加分片副本集
MongoDB分片相关的知识,之前介绍过了,今天我们来看如何为一个已经分片好的集群添加一个新的分片副本集。
AsiaYe
2021/01/24
1.5K0
MongoDB索引使用总结
MongoDB 提供范围广泛的索引类型和功能以及特定于语言的排序顺序,以支持对数据的复杂访问模式。 MongoDB 索引可以按需创建和删除来适应不断变化的应用程序需求和查询模式,并且可以在文档中的任何字段上声明,包括嵌套在数组中的字段。本文介绍一下 MongoDB 中的索引底层结构、索引遍历过程、建索引以及如何使用。
腾讯技术工程官方号
2024/04/18
1.1K1
MongoDB索引使用总结
MongoDB急速入门
前面我们已经介绍过缓存k-v数据库Redis,华为的OpenGauss关系型数据库,今天我们继续介绍一款NoSQL数据库MongoDB。
Python研究所
2022/09/01
6560
MongoDB数据库(二)
# _id是指定用什么字段分组,需要写成$sex, $sum:1表示此行数据计算为1
不断折腾
2019/09/23
1.6K0
MongoDB Capped Collection
MongoDB Collection可以理解为关系型数据库的表,当第一次在Collection存储数据或者创建索引时,如果该Collection不存在,则会首先创建该Collection,如下:
shysh95
2024/06/03
2190
MongoDB Capped Collection
相关推荐
一文了解Mongodb使用的语法
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档