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

【1130. 叶值的最小代价生成树】

来源:力扣(LeetCode)

描述:

给你一个正整数数组 arr,考虑所有满足以下条件的二叉树:

  • 每个节点都有 0 个或是 2 个子节点。
  • 数组 arr 中的值与树的中序遍历中每个叶节点的值一一对应。
  • 每个非叶节点的值等于其左子树和右子树中叶节点的最大值的乘积。

在所有这样的二叉树中,返回每个非叶节点的值的最小可能总和。这个和的值是一个 32 位整数。

如果一个节点有 0 个子节点,那么该节点为叶节点。

示例 1:

1

输入:arr = [6,2,4]
输出:32
解释:有两种可能的树,第一种的非叶节点的总和为 36 ,第二种非叶节点的总和为 32

示例 2:

2

输入:arr = [4,11]
输出:44

提示:

  • 2 <= arr.length <= 40
  • 1 <= arr[i] <= 15
  • 答案保证是一个 32 位带符号整数,即小于 231

方法一:动态规划

已知数组 arr 与二叉树的中序遍历的所有叶子节点对应,并且二叉树的每个节点都有 0 个节点或 2 个节点。考虑数组 arr 可以生成的所有二叉树,我们可以将 arr 切分成任意两个非空子数组,分别对应左子树和右子树,然后递归地对两个非空子树组执行相同的操作,直到子数组大小等于 1,即叶子节点,那么一种切分方案对应一个合法的二叉树。

使用 dp[i][j] 表示子数组 [i, j] (i ≤ j) 对应的子树所有非叶子节点的最小总和,那么 dp[i][j] 可以通过切分子树求得,状态转移方程如下:

方法一

其中 mik 表示子数组 [i,k] 的最大值,可以预先计算并保存下来。

代码:

class Solution {
public:int mctFromLeafValues(vector<int>& arr) {int n = arr.size();vector<vector<int>> dp(n, vector<int>(n, INT_MAX / 4)), mval(n, vector<int>(n));for (int j = 0; j < n; j++) {mval[j][j] = arr[j];dp[j][j] = 0;for (int i = j - 1; i >= 0; i--) {mval[i][j] = max(arr[i], mval[i + 1][j]);for (int k = i; k < j; k++) {dp[i][j] = min(dp[i][j], dp[i][k] + dp[k + 1][j] + mval[i][k] * mval[k + 1][j]);}}}return dp[0][n - 1];}
};

执行用时:4 ms, 在所有 C++ 提交中击败了77.21%的用户
内存消耗:9 MB, 在所有 C++ 提交中击败了25.58%的用户
复杂度分析
时间复杂度:O(n3),其中 n 是数组 arr 的长度。三重循环需要 O(n3) 的空间。
空间复杂度:O(n2)。保存 dp 和 mval 需要 O(n2) 的空间。

方法二:单调栈

方法一的思路是自上而下构建二叉树,这里我们可以尝试自下而上构建二叉树:

  1. 选择 arr 两个相邻的值,即两个节点,将它们作为一个新节点的左子节点和右子节点;
  2. 将这个新节点在数组 arr 替代这两个节点;
  3. 如果 arr 剩余的元素数目大于 1,执行步骤 1,否则终止,那么剩余的节点就是构建的二叉树的根节点。

问题可以转化为:给定一个数组 arr,不断地合并相邻的数,合并代价为两个数的乘积,合并之后的数为两个数的最大值,直到数组只剩一个数,求最小合并代价和。

假设一个数 arr[i] (0 < i < n − 1),满足 arr[i−1] ≥ arr[i] 且 arr[i] ≤ arr[i+1],如果 arr[i−1] ≤ arr[i+1],那么优先将 arr[i] 与 arr[i−1] 合并是最优的,反之如果 arr[i−1] > arr[i+1],那么优先将 arr[i] 与 arr[i+1] 合并是最优的。

按照这种思路,套用单调栈算法(栈元素从底到顶是严格递减的),我们遍历数组 arr,记当前遍历的值为 x。

如果栈非空且栈顶元素小于等于 x,那么说明栈顶元素(类似于 arr[i])是符合前面所说的最优合并的条件,将栈顶元素 y 出栈:

  • 如果栈空或栈顶元素大于 x,那么将 y 与 x 合并,合并代价为 x × y,合并之后的值为 x;
  • 否则将 y 与栈顶元素合并,合并代价为 y 与栈顶元素的乘积,合并之后的值为栈顶元素。

重复以上过程直到栈空或栈顶元素大于 x,然后将 x 入栈。

经过以上合并过程后,栈中的元素从底到顶是严格递减的,因此可以不断地将栈顶的两个元素出栈,合并,再入栈,直到栈元素数目小于 2。返回最终合并代价和即可。

代码:

class Solution {
public:int mctFromLeafValues(vector<int>& arr) {int res = 0;stack<int> stk;for (int x : arr) {while (!stk.empty() && stk.top() <= x) {int y = stk.top();stk.pop();if (stk.empty() || stk.top() > x) {res += y * x;} else {res += stk.top() * y;}}stk.push(x);}while (stk.size() >= 2) {int x = stk.top();stk.pop();res += stk.top() * x;}return res;}
};

执行用时:0 ms, 在所有 C++ 提交中击败了100.00%的用户
内存消耗:8.1 MB, 在所有 C++ 提交中击败了76.28%的用户
复杂度分析
时间复杂度:O(n),其中 n 为数组 arr 的长度。每次循环都有入栈或出栈操作,总次数不超过 2 × n,因此时间复杂度为 O(n)。
空间复杂度:O(n)。栈 stk 需要 O(n) 的空间。
author:LeetCode-Solution

相关文章:

【1130. 叶值的最小代价生成树】

来源&#xff1a;力扣&#xff08;LeetCode&#xff09; 描述&#xff1a; 给你一个正整数数组 arr&#xff0c;考虑所有满足以下条件的二叉树&#xff1a; 每个节点都有 0 个或是 2 个子节点。数组 arr 中的值与树的中序遍历中每个叶节点的值一一对应。每个非叶节点的值等于…...

Linux各个目录的全称及含义

/ 根目录&#xff0c;包含整个文件系统的根节点。 /bin : Binary Directory 二进制文件目录&#xff0c;包含一些基本的可执行程序。 /boot : Boot Directory 包含启动系统所需的文件&#xff0c;如内核和引导程序。 /dev : Device Directory 设备文件目录&#xff0c;…...

Cookie和Session原理详解

目录 前言 Cookie Session 会话机制 Cookie和Session的区别 Servlet中对Session和Cookie的封装 代码实例&#xff1a;实现用户登录 约定前后端交互的接口 前端页面&#xff1a; 后端实现 login index 总结 前言 在web的发展史中&#xff0c;我们知道浏览器和服务…...

小程序自动化测试

背景 近期团队打算做一个小程序自动化测试的工具&#xff0c;期望能够做到业务人员操作一遍小程序后&#xff0c;自动还原之前的操作路径&#xff0c;并且捕获操作过程中发生的异常&#xff0c;以此来判断这次发布是否会影响小程序的基础功能。 上述描述看似简单&#xff0c;…...

【linux系统操作】 - 技术一览

文章目录 1. 用户管理2. 文件管理3. 文件系统4. 字符处理5. 网络管理6. 进程管理7. 软件安装8. vi和vim编辑器9. 正则表达式 1. 用户管理 1.用户和用户组 2.账号管理 新增和删除用户、组&#xff1b;检查用户信息切换用户信息、用其他用户身份执行例行任务管理 : 周期性执行任…...

yield和sleep 区别

yield和sleep对比 sleepyieldsleep会导致当前线程暂停指定的时间&#xff0c;没有CPU时间片的消耗。yield只是对CPU调度器的一个提示&#xff0c;如果CPU调度器没有忽略这个提示&#xff0c;它会导致线程上下文的切换。sleep会使线程短暂block&#xff0c;会在给定的时间内释放…...

Redis 注册服务,自动启动

通常情况下我们可以通过 redis-server.exe 和配置文件启动redis服务 : 命令&#xff1a; redis-server.exe redis.windows.conf 另外开启一个命令行窗口 redis-cli.exe 即可做一些简单的操作命令行 但如果我们关闭控制台&#xff0c;那么Redis服务也跟随着一起关闭了&#x…...

华为OD机试真题 Java 实现【字符统计】【2023 B卷 100分】

一、题目描述 输入一个只包含小写英文字母和数字的字符串,按照不同字符统计个数由多到少输出统计结果,如果统计的个数相同,则按照ASCII码由小到大排序输出。 数据范围:字符串长度满足 1≤len(str)≤1000 。 二、输入描述 一个只包含小写英文字母和数字的字符串。 三、…...

ASP.NET Core MVC 从入门到精通之自动映射(一)

随着技术的发展&#xff0c;ASP.NET Core MVC也推出了好长时间&#xff0c;经过不断的版本更新迭代&#xff0c;已经越来越完善&#xff0c;本系列文章主要讲解ASP.NET Core MVC开发B/S系统过程中所涉及到的相关内容&#xff0c;适用于初学者&#xff0c;在校毕业生&#xff0c…...

4. WebGPU 存储缓冲区 (WebGPU Storage Buffers)

这篇文章是关于存储缓冲区的&#xff0c;我们从上一篇文章暂停的地方继续。 存储缓冲区在许多方面类似于统一缓冲区。如果我们所做的只是将 JavaScript 中的 UNIFORM 更改为 STORAGE 并将 WGSL 中的 var 更改为 var<storage, read> &#xff0c;那么上一页中的示例就可以…...

ChatGPT 插件功能深度解析:acquire、scholarai、form

引言 在我们的日常工作中&#xff0c;插件扮演着重要的角色&#xff0c;它们可以帮助我们提高工作效率&#xff0c;简化复杂的任务。在这篇文章中&#xff0c;我将详细介绍三个非常实用的插件&#xff1a;acquire、scholarai和form。 1、acquire 插件详解 acquire插件是一个…...

【面试集锦 - 汽车电子 - ASPICE]

ASPICE ASPICE&#xff08;Automotive Software Performance Improvement and Capability dEtermination&#xff09;是一种针对汽车电子行业的软件过程评估和改进模型。它是一种国际标准&#xff0c;旨在帮助汽车制造商和供应商评估和改进其软件开发过程的能力&#xff0c;以…...

深入探索Vue.js响应式原理及其实现机制

导语&#xff1a;Vue.js的核心特性之一是其强大的响应式系统&#xff0c;它使得数据和视图能够自动保持同步。在本文中&#xff0c;我们将深入探索Vue.js的响应式原理及其实现机制&#xff0c;帮助您更好地理解Vue.js的工作方式。 数据劫持&#xff1a;Vue.js的响应式系统通过数…...

Spark SQL概述、数据帧与数据集

文章目录 一、准备工作1、准备数据文件2、启动Spark Shell 二、加载数据为Dataset1、读文件得数据集 三、给数据集添加元数据信息1、定义学生样例类2、导入隐式转换3、将数据集转换成学生数据集4、对学生数据集进行操作&#xff08;1&#xff09;显示数据集内容&#xff08;2&a…...

c# cad 二次开发 类库 CAD表格的操作,给CAD添加一个表格

c# cad 二次开发 类库 CAD表格的操作&#xff0c;给CAD添加一个表格 using Autodesk.AutoCAD.ApplicationServices; using Autodesk.AutoCAD.Colors; using Autodesk.AutoCAD.DatabaseServices; using Autodesk.AutoCAD.EditorInput; using Autodesk.AutoCAD.Geometry; using A…...

单点登录的两种实现方式,分别有啥优缺点?

单点登录&#xff08;Single Sign-On&#xff0c;简称SSO&#xff09;是指在多个应用系统中&#xff0c;用户只需要登录一次&#xff0c;就可以访问所有已授权的系统资源的一种身份认证技术。SSO可以提升用户体验&#xff0c;减少用户密码管理工作量&#xff0c;并加强安全管理…...

opencv_c++学习(二十七)

一、单目相机模型 上图为针孔相机成像原理&#xff0c;蓝色坐标中的O即为镜头光心。成像原理与小孔成像相同。 单目相机映射关系如下&#xff1a; 将上式进行变换&#xff0c;就可以从三位空间映射到2维平面的公式。 相机的畸变公式如下&#xff1a; 二、模型投影函数 vo…...

探查chatGPT插件:Outschool,resume,webhooks

引言 在我们的日常工作和学习中&#xff0c;插件扮演着重要的角色。它们可以帮助我们提高效率&#xff0c;简化复杂的任务。在这篇文章中&#xff0c;我将介绍三个非常有用的插件&#xff1a;Outschool&#xff0c;resume&#xff0c;和webhooks&#xff0c;并通过具体的例子来…...

【学习笔记】Unity基础(七)【uGUI基础、利用render Texture实现小地图功能】

目录 一 Canvas1.1 三种Render Space渲染空间 screen1.2 canvas scaler画布缩放器1.3sprite1.4 sprite packer1.5 unity目录1.6 RuleTile Tilemap1.7 sprite packer1.8 sorting layer 二 rect transform2.1 pivot 中轴 中心点2.2 anchor 锚点2.3 uGUI源代码 三 EventSystem3.1 …...

yolov5配置错误记录

这里是直接没有找到数据集&#xff0c;说明是路径错误。经过设置yaml后&#xff0c; # Train/val/test sets as 1) dir: path/to/imgs, 2) file: path/to/imgs.txt, or 3) list: [path/to/imgs1, path/to/imgs2, ..] path: ../autodl-tmp/datasets/neu # dataset root dir tr…...

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周&#xff0c;有很多同学在写期末Java web作业时&#xff0c;运行tomcat出现乱码问题&#xff0c;经过多次解决与研究&#xff0c;我做了如下整理&#xff1a; 原因&#xff1a; IDEA本身编码与tomcat的编码与Windows编码不同导致&#xff0c;Windows 系统控制台…...

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …...

深入浅出Asp.Net Core MVC应用开发系列-AspNetCore中的日志记录

ASP.NET Core 是一个跨平台的开源框架&#xff0c;用于在 Windows、macOS 或 Linux 上生成基于云的新式 Web 应用。 ASP.NET Core 中的日志记录 .NET 通过 ILogger API 支持高性能结构化日志记录&#xff0c;以帮助监视应用程序行为和诊断问题。 可以通过配置不同的记录提供程…...

调用支付宝接口响应40004 SYSTEM_ERROR问题排查

在对接支付宝API的时候&#xff0c;遇到了一些问题&#xff0c;记录一下排查过程。 Body:{"datadigital_fincloud_generalsaas_face_certify_initialize_response":{"msg":"Business Failed","code":"40004","sub_msg…...

golang循环变量捕获问题​​

在 Go 语言中&#xff0c;当在循环中启动协程&#xff08;goroutine&#xff09;时&#xff0c;如果在协程闭包中直接引用循环变量&#xff0c;可能会遇到一个常见的陷阱 - ​​循环变量捕获问题​​。让我详细解释一下&#xff1a; 问题背景 看这个代码片段&#xff1a; fo…...

FFmpeg 低延迟同屏方案

引言 在实时互动需求激增的当下&#xff0c;无论是在线教育中的师生同屏演示、远程办公的屏幕共享协作&#xff0c;还是游戏直播的画面实时传输&#xff0c;低延迟同屏已成为保障用户体验的核心指标。FFmpeg 作为一款功能强大的多媒体框架&#xff0c;凭借其灵活的编解码、数据…...

STM32F4基本定时器使用和原理详解

STM32F4基本定时器使用和原理详解 前言如何确定定时器挂载在哪条时钟线上配置及使用方法参数配置PrescalerCounter ModeCounter Periodauto-reload preloadTrigger Event Selection 中断配置生成的代码及使用方法初始化代码基本定时器触发DCA或者ADC的代码讲解中断代码定时启动…...

React19源码系列之 事件插件系统

事件类别 事件类型 定义 文档 Event Event 接口表示在 EventTarget 上出现的事件。 Event - Web API | MDN UIEvent UIEvent 接口表示简单的用户界面事件。 UIEvent - Web API | MDN KeyboardEvent KeyboardEvent 对象描述了用户与键盘的交互。 KeyboardEvent - Web…...

2025 后端自学UNIAPP【项目实战:旅游项目】6、我的收藏页面

代码框架视图 1、先添加一个获取收藏景点的列表请求 【在文件my_api.js文件中添加】 // 引入公共的请求封装 import http from ./my_http.js// 登录接口&#xff08;适配服务端返回 Token&#xff09; export const login async (code, avatar) > {const res await http…...

Android15默认授权浮窗权限

我们经常有那种需求&#xff0c;客户需要定制的apk集成在ROM中&#xff0c;并且默认授予其【显示在其他应用的上层】权限&#xff0c;也就是我们常说的浮窗权限&#xff0c;那么我们就可以通过以下方法在wms、ams等系统服务的systemReady()方法中调用即可实现预置应用默认授权浮…...