本文涉及的基础知识点
C++单调栈
C++记忆化搜索
C++动态规划
LeetCode1130. 叶值的最小代价生成树
给你一个正整数数组 arr,考虑所有满足以下条件的二叉树:
每个节点都有 0 个或是 2 个子节点。
数组 arr 中的值与树的中序遍历中每个叶节点的值一一对应。
每个非叶节点的值等于其左子树和右子树中叶节点的最大值的乘积。
在所有这样的二叉树中,返回每个非叶节点的值的最小可能总和。这个和的值是一个 32 位整数。
如果一个节点有 0 个子节点,那么该节点为叶节点。
示例 1:
输入:arr = [6,2,4]
输出:32
解释:有两种可能的树,第一种的非叶节点的总和为 36 ,第二种非叶节点的总和为 32 。
示例 2:
输入:arr = [4,11]
输出:44
提示:
2 <= arr.length <= 40
1 <= arr[i] <= 15
答案保证是一个 32 位带符号整数,即小于 231 。
记忆化搜索
n = arr.length
数组 arr 中的值与树的中序遍历中每个叶节点的值一一对应。 ⟺ \iff ⟺ 将arr分成左右两部分,arr1,arr2,arr1对应左子树,arr2对应右子树。
如果arr只有一个元素,其最小和为arr[0]。
否则拆分arr1,arr2,递归处理。两这皆不能为空。
动态规划的状态记录
dp[i][j] 记录arr[i…j]对应的子树最小和。空间复杂度:O(nn)
动态规划的状态方程
dp[i][j] = min k = i j − 1 \min_{k=i}^{j-1} mink=ij−1(dp[i][k]+dp[k+1][j]) + arr[i…j]之积。arr[i…j]之积 可以预处理,也可以用前缀和。由于答案在int32范围内,故arr之积也在int32范围内。
单个状态的时间复杂度:O(n)
总时间复杂度:O(nnn) 注意:dp[i][j]的状态记录下来,初始-1,如果是-1则计算,否则查询。
初始调用
Cal(0,arr.lenght-1)
代码
核心代码
class Solution {public:int mctFromLeafValues(vector<int>& arr) {m_arr = arr;m_dp.assign(arr.size(), vector<int>(arr.size(),-1));m_max.assign(arr.size(), vector<int>(arr.size(), 0));for (int i = 0; i < arr.size(); i++) {m_max[i][i] = arr[i];for (int j = i + 1; j < arr.size(); j++) {m_max[i][j] = max(arr[j], m_max[i][j - 1]);}}return Cal(0, arr.size() - 1);}int Cal(int left, int r) {if (-1 != m_dp[left][r]) { return m_dp[left][r]; }if (left == r) {return m_dp[left][r] = 0;}int iMin = INT_MAX; for (int i = left; i < r; i++) {iMin = min(iMin, Cal(left, i) + Cal(i + 1, r)+ m_max[left][i]* m_max[i+1][r]);}return m_dp[left][r] = iMin ;}vector<vector<int>> m_dp,m_max;vector<int> m_arr;};
单元测试
vector<int> arr;TEST_METHOD(TestMethod11){arr = { 6,2,4 };auto res = Solution().mctFromLeafValues(arr);AssertEx(32, res);}TEST_METHOD(TestMethod12){arr = { 4,11 };auto res = Solution().mctFromLeafValues(arr);AssertEx(44, res);}
单调栈
本题就是临项消除:消除成本是两项的乘积,合并后的项是两者的较大者。
证明难度太大,建议暂且放一放。孤立的知识点,难学易忘,效率低得发指。
扩展阅读
我想对大家说的话 |
---|
工作中遇到的问题,可以按类别查阅鄙人的算法文章,请点击《算法与数据汇总》。 |
学习算法:按章节学习《喜缺全书算法册》,大量的题目和测试用例,打包下载。重视操作 |
有效学习:明确的目标 及时的反馈 拉伸区(难度合适) 专注 |
闻缺陷则喜(喜缺)是一个美好的愿望,早发现问题,早修改问题,给老板节约钱。 |
子墨子言之:事无终始,无务多业。也就是我们常说的专业的人做专业的事。 |
如果程序是一条龙,那算法就是他的是睛 |
失败+反思=成功 成功+反思=成功 |
视频课程
先学简单的课程,请移步CSDN学院,听白银讲师(也就是鄙人)的讲解。
https://edu.csdn.net/course/detail/38771
如何你想快速形成战斗了,为老板分忧,请学习C#入职培训、C++入职培训等课程
https://edu.csdn.net/lecturer/6176
测试环境
操作系统:win7 开发环境: VS2019 C++17
或者 操作系统:win10 开发环境: VS2022 C++17
如无特殊说明,本算法用**C++**实现。