1. 首页

LeetCode 154. 寻找旋转排序数组中的最小值 II

题目描述

难度:Hard

给定一个二叉树,其中所有的右节点要么是具有兄弟节点(拥有相同父节点的左节点)的叶节点,要么为空
将此二叉树上下翻转并将它变成一棵树, 原来的右节点将转换成左叶节点。返回新的根。

例子:

输入: [1,2,3,4,5]

    1
   / \
  2   3
 / \
4   5

输出: 返回二叉树的根 [4,5,2,#,#,3,1]

   4
  / \
 5   2
    / \
   3   1
说明:

对 [4,5,2,#,#,3,1] 感到困惑? 下面详细介绍请查看 二叉树是如何被序列化的。

二叉树的序列化遵循层次遍历规则,当没有节点存在时,'#' 表示路径终止符。

这里有一个例子:

   1
  / \
 2   3
    /
   4
    \
     5
上面的二叉树则被序列化为 [1,2,3,#,#,4,#,#,5].

说明:

  • 这道题是寻找旋转排序数组中的最小值
    的延伸题目。

  • 允许重复会影响算法的时间复杂度吗?会如何影响,为什么?

  • 先自底向上,翻转二叉树,把子节点的 left,指向父节点
  • 同时记录父节点有多少个子节点(0,1,2,)
  • 把叶子节点加入队列
  • 开始BFS,出队一个,就把该节点的 left (原来的父节点的子节点计数 -1)
  • 当节点的子节点计数为0时,它就变成了叶子节点,可以入队了
/**
 * @param {number[]} nums
 * @return {number}
 */
class Solution {
    vector<vector<int>> ans;
    queue<TreeNode*> q;
    unordered_map<TreeNode*, int> map;//父节点底下挂着几个子节点
public:
    vector<vector<int>> findLeaves(TreeNode* root) {
        reverse(root);//上下翻转二叉树
        while(!q.empty())
        {
            int size = q.size(), i = 0;
            vector<int> lv(size);
            while(size--)
            {
                TreeNode *cur = q.front();
                q.pop();
                map[cur->left]--;//原父节点的子节点计数-1
                lv[i++] = cur->val;//当前值写入答案
                if(cur->left && map[cur->left]==0)//父节点计数为0,可以入队
                    q.push(cur->left);
            }
            ans.push_back(lv);
        }
        return ans;
    }
    TreeNode* reverse(TreeNode* root)
    {
        if(!root) return NULL;
        auto l = root->left;
        auto r = root->right;
        if(!l && !r)
            q.push(root);//叶子节点加入队列
        map[root] += (l?1:0) + (r?1:0);//记得加括号,子节点个数
        root->left = NULL;//断开子节点
        root->right = NULL;
        auto lc = reverse(l);
        auto rc = reverse(r);
        if(lc)
            lc->left = root;//子节点的left指向父节点
        if(rc)
            rc->left = root;
        return root;
    }
};

看完两件小事

如果你觉得这篇文章对你挺有启发,我想请你帮我两个小忙:

  1. 关注我们的 GitHub 博客,让我们成为长期关系
  2. 把这篇文章分享给你的朋友 / 交流群,让更多的人看到,一起进步,一起成长!
  3. 关注公众号 「画漫画的程序员」,公众号后台回复「资源」 免费领取我精心整理的前端进阶资源教程

JS中文网是中国领先的新一代开发者社区和专业的技术媒体,一个帮助开发者成长的社区,目前已经覆盖和服务了超过 300 万开发者,你每天都可以在这里找到技术世界的头条内容。欢迎热爱技术的你一起加入交流与学习,JS中文网的使命是帮助开发者用代码改变世界

本文著作权归作者所有,如若转载,请注明出处

转载请注明:文章转载自「 Js中文网 · 前端进阶资源教程 」https://www.javascriptc.com

标题:LeetCode 154. 寻找旋转排序数组中的最小值 II

链接:https://www.javascriptc.com/4519.html

« LeetCode 155. 最小栈
LeetCode 153. 寻找旋转排序数组中的最小值»
Flutter 中文教程资源

相关推荐

QR code