当前位置: 首页 > article >正文

剑指offer 二叉树 持续更新中...

文章目录

  • 1. 重建二叉树
    • 1.1 题目描述
    • 1.2 方法1,分治
  • 2. 二叉树的下一个节点
    • 2.1 题目描述
    • 2.2 方法1,模拟

1. 重建二叉树

105. 从前序与中序遍历序列构造二叉树 - 力扣(LeetCode)

1.1 题目描述

题目描述:输入某二叉树的前序遍历和中序遍历结果,请重建二叉树。假设输入的前序遍历和中序遍历结果中不包含重复元素

示例 1:

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

1.2 方法1,分治

二叉树的前序遍历中:第一个数字总是树的根节点的值。当我们确立了根节点后,根据中序遍历确定左子树和右子树。一直递归下去,注意这里的区间全部是前闭后开

class Solution {
    vector<int> _preorder, _inorder;
    int _length;
public:
    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
        _preorder = preorder, _inorder = inorder, _length = preorder.size();
        return buildTreeCore(0, _length, 0, _length);
    }
    TreeNode* buildTreeCore(int startPreOrder, int endPreOrder, 
                            int startInOrder, int endInorder)
    {
        if(startPreOrder >= endPreOrder || startInOrder >= endInorder) {
            return nullptr;
        }
        TreeNode* root = new TreeNode(_preorder[startPreOrder]);
        // 在中序遍历序列中找到根节点的值, 可以确定下一次左子树的长度
        int rootInOrder = startInOrder;
        while(rootInOrder < endInorder && _inorder[rootInOrder] != root->val)
            rootInOrder++;
        int leftLength = rootInOrder - startInOrder;        // 左子树的长度
        // 构建左子树
        root->left = buildTreeCore(startPreOrder+1, startPreOrder + leftLength + 1,
                                      startInOrder, rootInOrder);
        // 构建右子树
        root->right = buildTreeCore(startPreOrder + leftLength + 1, endPreOrder,
                                    rootInOrder+1, endInorder);
        return root;
    }
};

这题与之类似,106. 从中序与后序遍历序列构造二叉树 - 力扣(LeetCode),都是一样的思考过程,下面是解答

class Solution {
    vector<int> _inorder, _postorder;
    int _length;

public:
    TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
        _inorder = inorder, _postorder = postorder, _length = inorder.size();
        _length = inorder.size();
        return buildTreeCore(0, _length, 0, _length);
    }
    TreeNode* buildTreeCore(int startInorder, int endInorder,
                            int startPostorder, int endPostorder) {
        if (startInorder >= endInorder || startPostorder >= endPostorder)
            return nullptr;
        TreeNode* root = new TreeNode(_postorder[endPostorder - 1]);
        // 在中序序列中找到根
        int rootInorder = startInorder;
        while (rootInorder < endInorder && _inorder[rootInorder] != root->val)
            rootInorder++;
        int leftLength = rootInorder - startInorder; // 左子树的长度
        root->left = buildTreeCore(startInorder, rootInorder, startPostorder,
                                   startPostorder + leftLength);
        root->right =
            buildTreeCore(rootInorder + 1, endInorder,
                          startPostorder + leftLength, endPostorder - 1);
        return root;
    }
};

2. 二叉树的下一个节点

二叉树的下一个结点_牛客题霸_牛客网

2.1 题目描述

题目描述:给定一个二叉树其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。

示例1:

输入:{8,6,10,5,7,9,11}, 8
返回:9

2.2 方法1,模拟

  1. 如果一个节点有右子树,那么它的下一个节点就是它的右子树的最左节点
  2. 如果一个节点没有右子树
    1. 如果该节点是父节点的左孩子节点,那么下一个节点就是该节点的父节点
    2. 如果该节点是父节点的右孩子节点,那么就一直向上找它的父节点,直到找到一个节点,是父节点的左孩子节点,此时下一个该节点的下一个节点就是该节点的父节点。如果找到根节点了,就证明到最后了,没有下一个节点了。
class Solution 
{
public:
    TreeLinkNode* GetNext(TreeLinkNode* pNode) 
    {
        // 1.一个节点有右子树
        if(pNode->right != nullptr) {
            pNode = pNode->right;
            while(pNode->left != nullptr)
                pNode = pNode->left;
            return pNode;
        }
        auto parent = pNode->next;
        // 2.1没有右子树, 该节点是父节点的左孩子节点
        if(parent != nullptr && parent->left == pNode)
            return parent;
        // 2.2没有右子树, 该节点是父节点的右孩子节点
        while(parent != nullptr) {
            pNode = parent;
            parent = pNode->next;
            if(parent == nullptr)    break;
            if(pNode == parent->left)
                return parent;
        }
        return nullptr;
    }
};

http://www.kler.cn/a/533193.html

相关文章:

  • 【大数据技术】用户行为日志分析(python+hadoop+mapreduce+yarn+hive)
  • Windows图形界面(GUI)-QT-C/C++ - QT Tab Widget
  • 进阶数据结构——双向循环链表
  • SQL优化
  • 深度学习之“缺失数据处理”
  • 物联网 STM32【源代码形式-ESP8266透传】连接OneNet IOT从云产品开发到底层MQTT实现,APP控制 【保姆级零基础搭建】
  • FastPlanner论文解读(一)——前端路径搜索
  • 「全网最细 + 实战源码案例」设计模式——模板方法模式
  • JavaScript语言的面向对象编程
  • 代码随想录算法训练营Day36
  • 深入理解 Rust 模块中的路径与公开性:绝对路径、相对路径和 `pub` 的应用
  • mysql 学习8 函数,字符串函数,数值函数,日期函数,流程函数
  • 18.[前端开发]Day18-王者荣耀项目实战(一)
  • Scheme语言的正则表达式
  • 传输层协议——TCP协议
  • LeetCode 0922.按奇偶排序数组 II:O(1)空间复杂度-一次遍历双指针
  • 青少年编程与数学 02-008 Pyhon语言编程基础 19课题、外部模块
  • 【数据采集】基于Selenium采集豆瓣电影Top250的详细数据
  • 【Day29 LeetCode】动态规划DP
  • Rust中变量【引用】与【借用】规则
  • Markdown转换器中间件
  • AI协助探索AI新构型自动化创新的技术实现
  • 【现代深度学习技术】深度学习计算 | 延后初始化自定义层
  • 决策规划概述
  • C# 数组、索引器与集合介绍
  • 面向智慧农业的物联网监测系统设计(论文+源码+实物)