首页 > 其他分享 >20天 hot 100 速通计划-day10

20天 hot 100 速通计划-day10

时间:2023-08-16 17:03:04浏览次数:44  
标签:TreeNode 速通 路径 hot 二叉树 20 null root 节点

二叉树

114. 二叉树展开为链表

给你二叉树的根结点 root ,请你将它展开为一个单链表:

  • 展开后的单链表应该同样使用 TreeNode ,其中 right 子指针指向链表中下一个结点,而左子指针始终为 null
  • 展开后的单链表应该与二叉树 先序遍历 顺序相同。

示例 1:

img

输入:root = [1,2,5,3,4,null,6]
输出:[1,null,2,null,3,null,4,null,5,null,6]

示例 2:

输入:root = []
输出:[]

示例 3:

输入:root = [0]
输出:[0]

提示:

  • 树中结点数在范围 [0, 2000]
  • -100 <= Node.val <= 100
class Solution {
public:
  //参返分析:输入根节点,无需返回值
  //终止条件:根节点为空节点
  //单层逻辑:获取链表化左子树,获取链表化右子树
  //左子树置空,右子树拼接链表化左子树后再拼接链表化右子树,保证顺序为前序遍历的顺序
    void func(TreeNode* root){
        if(!root) return;

      //链表化子树
        func(root->left);
        func(root->right);
      
      //获取链表化子树
        TreeNode* left = root->left;
        TreeNode* right = root->right;

      //左子树置空
        root->left = nullptr;
      //右子树拼接链表化左子树
        root->right =left;
      //右子树拼接链表化右子树
        TreeNode* cur = root;
        while(cur->right){
            cur = cur->right;
        }
        cur->right = right;
    }

    void flatten(TreeNode* root) {
        func(root);
    }
};

105. 从前序与中序遍历序列构造二叉树

给定两个整数数组 preorderinorder ,其中 preorder 是二叉树的先序遍历inorder 是同一棵树的中序遍历,请构造二叉树并返回其根节点。

示例 1:

img

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

示例 2:

输入: preorder = [-1], inorder = [-1]
输出: [-1]

提示:

  • 1 <= preorder.length <= 3000
  • inorder.length == preorder.length
  • -3000 <= preorder[i], inorder[i] <= 3000
  • preorderinorder无重复 元素
  • inorder 均出现在 preorder
  • preorder 保证 为二叉树的前序遍历序列
  • inorder 保证 为二叉树的中序遍历序列

图源自力扣

纯技巧,原子操作,记住就行

class Solution {
public:
  TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
      if (preorder.empty() || inorder.empty()) {
          return nullptr;
      }
      return buildTreeHelper(preorder, 0, preorder.size()-1, inorder, 0, inorder.size()-1);
  }

  //左闭右闭
  TreeNode* buildTreeHelper(vector<int>& preorder, int preorderStart, int preorderEnd,
                            vector<int>& inorder, int inorderStart, int inorderEnd) {
      //左闭右闭终止条件:start > end
      if (preorderStart > preorderEnd || inorderStart > inorderEnd) {
          return nullptr;
      }

      // 前序遍历的第一个节点是根节点,补全中序所丢失的信息
      int rootVal = preorder[preorderStart]; 
      TreeNode* root = new TreeNode(rootVal);

      // 在中序遍历中找到根节点的位置
      int rootPos;
      for (int i = inorderStart; i <= inorderEnd; i++) {
          if (inorder[i] == rootVal) {
              rootPos = i;
              break;
          }
      }

      // 分割中序遍历序列为左子树和右子树部分
    	// 中序遍历:左子树 根节点 右子树,由此可得左子树节点数 和 右子树节点数,补全前序所缺失的信息
    	// 根节点下标为:rootPos,易得 leftSize 和 rightSize
      int leftSize = rootPos - inorderStart;
			int rightSize = inorderEnd - rootPos;

      // 分割前序遍历序列为根节点、左子树和右子树三部分
    	// 前序遍历为:根节点 左子树 右子树
      int preorderLeftEnd = preorderStart + leftSize;
      int preorderRightStart = preorderEnd - rightSize + 1;
    //right - len + 1 是一个表达式,其中 right 代表最右边的索引位置,len 代表列表的长度。这个表达式的结果是将列表中的元素排列在右边时,右边的起始索引位置。
    //为什么要 + 1 呢?这是因为索引是从 0 开始计数的。所以,当计算右边的起始索引位置时,我们需要将列表的长度加上 1。这样,右边的范围将包括最右边的元素,进而保证了左闭右闭

      // 处理左子树和右子树
    	// preStart 已经作为根节点处理 
    	// 故前序被分为 [preStart + 1, preorderLeftEnd] [preorderRightStart, preorderEnd]
    	// rootPos 已经作为根节点处理
    	// 故中序被分为 [inorderStart, rootPos - 1] [rootPos + 1, inorderEnd]
      root->left = buildTreeHelper(preorder, preorderStart + 1, preorderLeftEnd, inorder, inorderStart, rootPos - 1);
      root->right = buildTreeHelper(preorder, preorderRightStart preorderEnd, inorder, rootPos + 1, inorderEnd);

      return root;
  }
};

437. 路径总和 III

给定一个二叉树的根节点 root ,和一个整数 targetSum ,求该二叉树里节点值之和等于 targetSum路径 的数目。

路径 不需要从根节点开始,也不需要在叶子节点结束,但是路径方向必须是向下的(只能从父节点到子节点)。

示例 1:

img

输入:root = [10,5,-3,3,2,null,11,3,-2,null,1], targetSum = 8
输出:3
解释:和等于 8 的路径有 3 条,如图所示。

示例 2:

输入:root = [5,4,8,11,null,13,4,7,2,null,null,5,1], targetSum = 22
输出:3

提示:

  • 二叉树的节点个数的范围是 [0,1000]
  • -109 <= Node.val <= 109
  • -1000 <= targetSum <= 1000
class Solution {
public:
    int count=0;    
  //参返分析:输入根节点、当前和 & 目标和
  //终止条件:根节点为空,返回路径数为 0
  //单层逻辑:如果加入当前节点后值为 target,证明找到了目标路径,count++
    void dfs(TreeNode* root, long targetSum,long sum){
        if(!root) return;
        sum+=root->val;
        if(sum==targetSum) count++;
        dfs(root->left,targetSum,sum);
        dfs(root->right,targetSum,sum);
    }
    int pathSum(TreeNode* root, long targetSum) {
        if(!root) return 0;
      //使用dfs来遍历二叉树,并计算从根节点到当前节点的路径之和。当我们遍历到某个节点时,我们检查当前路径之和是否等于目标和,如果是,则计数器加1。
        dfs(root,targetSum,0);
      //然而,当前节点到根节点的路径可能不止一条。我们需要通过再次调用pathSum函数来遍历当前节点的左子树和右子树,以计算所有可能的路径。这样,我们就能将路径不仅仅限制在根节点到当前节点上,而是可以从任意节点开始。
        pathSum(root->left,targetSum);
        pathSum(root->right,targetSum);
        
        return count;
    
    }
};

236. 二叉树的最近公共祖先

给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。

百度百科中最近公共祖先的定义为:“对于有根树 T 的两个节点 p、q,最近公共祖先表示为一个节点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”

示例 1:

img

输入:root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1
输出:3
解释:节点 5 和节点 1 的最近公共祖先是节点 3 。

示例 2:

img

输入:root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4
输出:5
解释:节点 5 和节点 4 的最近公共祖先是节点 5 。因为根据定义最近公共祖先节点可以为节点本身。

示例 3:

输入:root = [1,2], p = 1, q = 2
输出:1

提示:

  • 树中节点数目在范围 [2, 105] 内。
  • -109 <= Node.val <= 109
  • 所有 Node.val 互不相同
  • p != q
  • pq 均存在于给定的二叉树中。
class Solution {
public:
  //参返分析:输入根节点,待查找公共祖先的节点 p、q,返回最近公共祖先
  //终止条件:
  //当根节点为空时,直接返回 nullptr,即返回 root
  //当根节点非空时,若根节点为待查找公共祖先的任意节点,则最近公共祖先节点为节点本身,即返回 root
  //单层逻辑:
  //如果左子树和右子树分别包含p和q,则当前节点为最近公共祖先
  //如果左(右)子树只包含p或q,则返回包含了节点p或q的子树
  	TreeNode* func(TreeNode* root, TreeNode* p, TreeNode* q){
      // 如果当前节点为空或等于p或q,则返回该节点(归并)
      if(!root || root == p || root == q){
        return root;
      }
      
       // 递归查找左子树和右子树
       TreeNode* left = func(root->left, p, q);
       TreeNode* right = func(root->right, p, q);
       // 如果左子树和右子树分别包含p和q,则当前节点为最近公共祖先
       if (left != nullptr && right != nullptr) {
           return root;
       }
       // 如果左子树只包含p或q,则返回包含了节点p或q的子树
       if (left != nullptr) {
           return left;
       }
       // 如果右子树只包含p或q,则返回包含了节点p或q的子树
       if (right != nullptr) {
           return right;
       }
       return nullptr;
      
    }
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
		return func(root, p, q);
    }
};

124. 二叉树中的最大路径和

二叉树中的 路径 被定义为一条节点序列,序列中每对相邻节点之间都存在一条边。同一个节点在一条路径序列中 至多出现一次 。该路径 至少包含一个 节点,且不一定经过根节点。

路径和 是路径中各节点值的总和。

给你一个二叉树的根节点 root ,返回其 最大路径和

示例 1:

img

输入:root = [1,2,3]
输出:6
解释:最优路径是 2 -> 1 -> 3 ,路径和为 2 + 1 + 3 = 6

示例 2:

img

输入:root = [-10,9,20,null,null,15,7]
输出:42
解释:最优路径是 15 -> 20 -> 7 ,路径和为 15 + 20 + 7 = 42

提示:

  • 树中节点数目范围是 [1, 3 * 104]
  • -1000 <= Node.val <= 1000
class Solution {
public:
    int maxPath = INT_MIN;
    int func(TreeNode* root) {
        if (root == nullptr) return 0;
        //获取左子树最大路径和
        int leftMax = max(0, func(root->left));
        //获取右子树最大路径和
        int rightMax = max(0, func(root->right));
        //获取最大路径和
        int pathSum = root->val + leftMax + rightMax;
        //更新最大路径和
        maxPath = max(maxPath, pathSum);

        //返回经过当前节点的最大路径和
        return root->val + max(leftMax, rightMax);
	}
    int maxPathSum(TreeNode* root) {
        func(root);
        return maxPath;
    }
};

标签:TreeNode,速通,路径,hot,二叉树,20,null,root,节点
From: https://www.cnblogs.com/ba11ooner/p/17635572.html

相关文章

  • vite打包报错:ERROR: Top-level await is not available in the configured target env
    在开发时,vita打包报错如下: 原因:ECMAScript提案Top-levelawait由MylesBorins提出,它可以让你在模块的最高层中使用await操作符。在这之前,你只能通过在async函数或asyncgenerators中使用await操作符。Top-levelawait是个新特性,打包不支持此特性。解决方案:1.......
  • Autodesk Navisworks Manage 2024 (建筑工程项目模拟和协作软件)中文永久使用
    AutodeskNavisworksManage2024是一款强大的协同项目管理软件,旨在帮助建筑、工程和施工行业的专业人士更高效地进行项目协调和冲突检测。下面将详细介绍NavisworksManage2024的功能和特点。点击获取AutodeskNavisworksManage2024 模拟和可视化:NavisworksManage......
  • 海泰密码全能力 赋能业务全场景|2023年商密大会海泰方圆完美收官
    2023商用密码大会8月11日,为期三天的2023年商用密码大会圆满举办。作为密码界万众瞩目的一场盛会,此次商密大会吸引了300多家业内主流的密码厂商参展、四万多人次参观创历史新高。海泰方圆重磅亮相,全面展示了公司前沿技术、拳头产品、精品方案,充分展现了海泰方圆在百行百业数字化转型......
  • 2023商用密码大会|海泰方圆发布密境新品牌及多款重磅产品
    8月10日,在北京商用密码行业协会展区-展中展活动上,海泰方圆重磅发布了数据安全品牌“密境”,并隆重推出了密境隐私计算服务平台、密境数据安全沙箱、红莲花云浏览器三款拳头产品。海泰密境:以密码之力,守护您的安全之境海泰方圆产品总监Peter孙发表了《密码技术驱动隐私计算要素流通服......
  • 2023/08/16
    练习题:生成一个顺序数组,将这个数组的元素打乱顺序后输出package练习;importjava.util.Arrays;importjava.util.Random;publicclassShuffleArray{publicstaticvoidmain(String[]args){int[]a=f();for(inti=0;i<a.length;i++){......
  • P2034题解
    P2034题解题目描述给定一行\(n\)个非负整数\(a_1\cdotsa_n\)。现在你可以选择其中若干个数,但不能有超过\(k\)个连续的数字被选择。你的任务是使得选出的数字的和最大。题解正难则反,考虑将原问题转化为从\(a\)中选若干数使得,任意两数差不大于\(k\),求答案最小。观察......
  • 【专题】2021 年中国电力行业经济运行报告PDF合集分享(附原数据表)
    原文链接:https://tecdat.cn/?p=33446报告合集根据实践创新,我们提出了“云上新型电力系统”,该系统将加速电力流、信息流和价值流的融通流动,通过更灵活高效的能源资源优化配置平台,支持大规模的新能源开发和利用。这一系统将为电力业务创新、电力行业发展以及全社会的绿色生产和生活......
  • 【专题】2022年中国电力行业分析报告PDF合集分享(附原数据表)
    原文链接:https://tecdat.cn/?p=33446报告合集根据实践创新,我们提出了“云上新型电力系统”,该系统将加速电力流、信息流和价值流的融通流动,通过更灵活高效的能源资源优化配置平台,支持大规模的新能源开发和利用。这一系统将为电力业务创新、电力行业发展以及全社会的绿色生产和生活......
  • 【专题】2022年中国电力数字化产业研究报告PDF合集分享(附原数据表)
    原文链接:https://tecdat.cn/?p=33446报告合集根据实践创新,我们提出了“云上新型电力系统”,该系统将加速电力流、信息流和价值流的融通流动,通过更灵活高效的能源资源优化配置平台,支持大规模的新能源开发和利用。这一系统将为电力业务创新、电力行业发展以及全社会的绿色生产和生活......
  • 【专题】2022年中国电力行业经济运行报告PDF合集分享(附原数据表)
    原文链接:https://tecdat.cn/?p=33446报告合集根据实践创新,我们提出了“云上新型电力系统”,该系统将加速电力流、信息流和价值流的融通流动,通过更灵活高效的能源资源优化配置平台,支持大规模的新能源开发和利用。这一系统将为电力业务创新、电力行业发展以及全社会的绿色生产和生活......