图解LeetCode——623. 在二叉树中增加一行(难度:中等)

一、题目

给定一个二叉树的根 root 和两个整数 valdepth ,在给定的深度 depth 处添加一个值为 val 的节点行。

注意,根节点 root 位于深度 1

加法规则如下:

  • 给定整数 depth,对于深度为 depth - 1 的每个非空树节点 cur ,创建两个值为 val 的树节点作为 cur 的左子树根和右子树根。
  • cur 原来的左子树应该是新的左子树根的左子树。
  • cur 原来的右子树应该是新的右子树根的右子树。
  • 如果 depth == 1 意味着 depth - 1 根本没有深度,那么创建一个树节点,值 val 作为整个原始树的新根,而原始树就是新根的左子树。

二、示例

2.1> 示例 1:

【输入】 root = [4,2,6,3,1,5], val = 1, depth = 2
【输出】 [4,1,1,2,null,null,6,3,1,5]

2.2> 示例 2:

【输入】 root = [4,2,null,3,1], val = 1, depth = 3
【输出】 [4,2,null,1,1,3,null,null,1]

提示:

  • 节点数在 [1, 104] 范围内
  • 树的深度在 [1, 104]范围内
  • -100 <= Node.val <= 100
  • -105 <= val <= 105
  • 1 <= depth <= the depth of tree + 1

三、解题思路

3.1> 思路1:广度优先算法

根据题意,我们要在指定的某一层depth中添加一行指定的val值节点,那么很容易想到的解题思路就是广度优先算法。通过广度优先算法+队列,我们可以确定当前所遍历的层数,因为题意是要在depth层中添加一行val节点,其实主要修改节点之间的关系是在depth-1这一层中,所以,当我们遍历到depth-1这层的是,执行新节点的创建并维护到depth-1这层节点即可。

当然,在这个过程中,我们还需要针对一些特殊情况做特殊的处理,比如depth如果传值为1,那么意思就是,新的节点要替换老的root节点了。此时我们只需要在创建的新节点的左子节点维护原root节点即可。那么,另一种情况就是,当depth值时大于1的情况下,那么这种情况就可以使用通用的算法逻辑去处理了。依然是首先将root节点放入到队列Queue中,此时队列size等于1,那么我们通过for循环遍历这个size长度的节点,每当从队列中取到节点之后,都要再向Queue中放入自己的左右子节点,当然,如果左节点或者右节点有一个为null的话,就不用放入到Queue中了

那么,每当遍历完一层节点之后,层数都要加1,当我们发现,当前遍历的层数等于depth-1的话,那么,就可以开始执行新建节点操作了

下面我们以root = [4,2,6,3,1,5],val = 1,depth = 3为例。首先,将root节点放入到队列Queue中,此时元素size=1,通过poll()方法遍历每个元素,由于此时层级是1,不满足depth-1,所以不需要创建新节点。具体操作如下所示:

随着我们对Node(4)的遍历,随着我们将其子节点Node(2)和Node(6)也放入到队列Queue中,此时队列 size=2,通过poll()方法遍历每个元素。

由于此时层级是2,满足了depth-1的条件,那么我们开始着手创建新的节点。根据题意,val值等于1,所以我们分别为Node(2)和Node(6)创建一共4个Node(1),区别在于,这四个Node(1)的左右子节点是不同的,即:其中一个Node(1)的左子节点是Node(3);另一个Node(1)的右子节点是Node(1);第三个Node(1)的左子节点是Node(5);最后一个Node(1)的左右子节点都为null。具体操作如下图所示:

通过对depth-1这层节点的操作,也就完成了我们整个业务逻辑了,我们将根节点进行返回即可。具体的代码实现,请参照:4.1> 实现1:广度优先算法

3.2> 思路2:深度优先算法

除了可以采用广度优先算法之外,我们也可以采用深度优先算法。那么当深度遍历到达depth-1这层的时候,我们就开始进行新节点的创建。此处与广度优先算法的区别就是,我们不再需要Queue这个队列结构了,而是通过对depth的计算,来确定是否到达了我们要操作的那一层。怎么计算呢?这里面其实会有一些绕。因为深度优先是从root根节点向下遍历的。而入参depth我们获得之后,要通过每次的减1操作,来计算是否满足我们要操作的那一层。他们之间别扭的点就在于,一个是从上往下,另一个是从下往上。那么问题来了,depth要减到什么情况下,才说明到达了我们要操作的那一层呢。其实是这样的:首先我们要操作的那层其实就是depth - 1这层。那么如果从根节点到达这层是需要往下走 (depth) - 1 - 1 = depth - 2 次 ,那么随着每次遍历,depth都会执行减1操作,也就是说,当depth - (depth - 2) = 2的时候,就到达了我们期望要操作的那一层了。即:if (depth == 2) 执行创建新节点的操作

通过深度优先算法,可以全面提高代码执行效率和降低内存消耗。具体的代码实现,请参照:4.2> 实现2:深度优先算法

四、代码实现

4.1> 实现1:广度优先算法

class Solution {
    public TreeNode addOneRow(TreeNode root, int val, int depth) {
        if (depth == 1) {
            return new TreeNode(val, root, null);
        }

        Queue<TreeNode> queue = new ArrayDeque();
        queue.add(root);
        int searchDepth = 1;
        while(!queue.isEmpty() && searchDepth != depth) {
            // 因为下面else中会向queue中添加元素,所以,此处应该先计算出来循环的size大小,以免受到影响
            int levelNodeSize = queue.size();
            for (int i = 0; i < levelNodeSize; i++) {
                TreeNode node = queue.poll();
                if (searchDepth == (depth - 1)) {
                    node.left = new TreeNode(val, node.left, null);
                    node.right = new TreeNode(val, null, node.right);
                } else {
                    if (node.left != null) queue.add(node.left);
                    if (node.right != null) queue.add(node.right);
                }
            }
            searchDepth++;
        }
        return root;
    }
}

4.2> 实现2:深度优先算法

class Solution {
    public TreeNode addOneRow(TreeNode root, int val, int depth) {
        if (root == null) return null;

        if (depth == 1) return new TreeNode(val, root, null);
        
        if (depth == 2) {
            root.left = new TreeNode(val, root.left, null);
            root.right = new TreeNode(val, null, root.right);
        } else {
            addOneRow(root.left, val, depth - 1);
            addOneRow(root.right, val, depth - 1);
        }

        return root;
    }
}

今天的文章内容就这些了:

写作不易,笔者几个小时甚至数天完成的一篇文章,只愿换来您几秒钟的 点赞 & 分享

更多技术干货,欢迎大家关注公众号“爪哇缪斯” ~ \(o)/ ~ 「干货分享,每天更新」

题目来源:力扣(LeetCode)

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,402评论 6 499
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,377评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,483评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,165评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,176评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,146评论 1 297
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,032评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,896评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,311评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,536评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,696评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,413评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,008评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,659评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,815评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,698评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,592评论 2 353

推荐阅读更多精彩内容