leetcode(力扣) 2866. 美丽塔 II
暴力做法 (时间复杂度 O(n^2))
每次选取下标 i 为峰值, 进行 n 次,对每次取max就可以找到答案
对于 i 左边的序列: 需要满足序列是非递减的, 同时每个值尽可能大
所以满足: j 的位置上的数 <= (j, i] 上的最小的值 (等于时取得最大值) , 同时需要保证 j 位置上的数要小于heights[j] (题目中的要求,美丽塔的要求); 即 t = min(pre, heights[j]) pre表示的是 下标是 (j, i] 的最小的值
对于 i 右边的序列: 需要满足序列是非递增的,同时每个值尽可能大
所以满足:j 的位置上的数 <= [i, j) 上的最小的值 (等于时取得最大值), 同时需要保证 j 位置上的数要小于heights[j]; 即 t = min(pre, heights[j]) pre表示的是 下标是 [i, j) 的最小的值
class Solution {
public:
long long maximumSumOfHeights(vector<int>& heights) {
int n = heights.size();
long long res = 0;
for (int i = 0; i < n; i ++ )
{
int pre = heights[i];
long long sum = heights[i] * 1LL;
for (int j = i - 1; j >= 0; j --) // pre表示的是下标 (j, i] 中heights中的最小值
{
sum += min(pre, heights[j]); // 下标从i - 1开始, 每次取min,可以保证当下标为 j 时 pre 表示的就是 [j + 1, i] 的最小值
pre = min(pre, heights[j]);
}
pre = heights[i];
for (int j = i + 1; j < n; j ++) // pre表示的是下标 [i, j) 中heights中的最小值
{
sum += min(pre, heights[j]);
pre = min(pre, heights[j]);
}
res = max(sum, res);
}
return res;
}
};
单调栈做法 (时间复杂度 O(n)) (tag: 单调栈、 动态规划)
st1 和 st2 存的都是下标
下面图片模拟的是 第一个 for循环, 标红的是 进入 if(st1.empty()) 这个分支的
p1[4] 为什么加的是 2 x heights[4]呢, 因为此时st1中还有 元素1的下标2, 此时 下标3 和 下标4 的高度应该都为heights[4]

class Solution {
public:
long long maximumSumOfHeights(vector<int>& heights) {
int n = heights.size();
long long res = 0;
stack<int> st1; stack<int> st2; // 栈里面存的是 下标
vector<long long> p1(n); vector<long long> p2(n);
// p1 的状态表示是 下标为 i 的 左侧美丽塔高度之和 (包含i本身,同时满足p1[i]是美丽塔高度和的最大值)
// p2 的状态表示是 下标为 i 的 右侧美丽塔高度之和 (包含i本身,同时满足p1[i]是美丽塔高度和的最大值)
for (int i = 0; i < n; i ++)
{
while (!st1.empty() && heights[i] < heights[st1.top()]) st1.pop(); // 让栈满足 (栈为空 || 栈中元素对应的heights的值是非递减的)
// 栈为空 说明 : i = 0或者 i 前面的山脉高度都比 heights[i] 大, 为了保证序列非递减, 前面的所有数都应该是 heights[i]
if (st1.empty()) p1[i] = (long long)(i + 1) * heights[i];
else p1[i] = p1[st1.top()] + (long long)(i - st1.top()) * heights[i] ;
// 不为空 说明 下标为 (st1.top(), i] 山脉高度 都比 heights[i] 大, 为了保证序列非递减, (st1.top(), i] 之间的山脉高度都应该是 heights[i]
st1.emplace(i);
}
for (int i = n - 1; i >= 0; i --) // 需要保证从后往前是一个非递减序列
{
while (!st2.empty() && heights[i] < heights[st2.top()]) st2.pop();
if (st2.empty()) p2[i] = (long long)(n - i) * heights[i] * 1LL;
else p2[i] = p2[st2.top()] + (long long)(st2.top() - i) * heights[i] ;
st2.emplace(i);
res = max(res, p1[i] + p2[i] - heights[i]); // 看p1和p2的状态表示,都包含的 i,要减去重复的一个
}
return res;
}
};
觉得写的不错的话,点个赞吧!~
leetcode(力扣) 2866. 美丽塔 II的更多相关文章
- 刷题-力扣-剑指 Offer II 055. 二叉搜索树迭代器
剑指 Offer II 055. 二叉搜索树迭代器 题目链接 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/kTOapQ 著作权归领扣网络所有 ...
- 刷题-力扣-541. 反转字符串 II
541. 反转字符串 II 题目链接 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/reverse-string-ii 著作权归领扣网络所有. ...
- 刷题-力扣-113. 路径总和 II
113. 路径总和 II 题目链接 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/path-sum-ii 著作权归领扣网络所有.商业转载请联系 ...
- 刷题-力扣-518. 零钱兑换 II
518. 零钱兑换 II 题目链接 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/coin-change-2/ 著作权归领扣网络所有.商业转载 ...
- 刷题-力扣-63. 不同路径 II
63. 不同路径 II 题目链接 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/unique-paths-ii/ 著作权归领扣网络所有.商业转 ...
- 刷题-力扣-264. 丑数 II
264. 丑数 II 题目链接 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/ugly-number-ii/ 著作权归领扣网络所有.商业转载请 ...
- 力扣---45. 跳跃游戏 II
给定一个长度为 n 的 0 索引整数数组 nums.初始位置为 nums[0].每个元素 nums[i] 表示从索引 i 向前跳转的最大长度.换句话说,如果你在 nums[i] 处,你可以跳转到任意 ...
- 力扣 ——Linked List Cycle II(环形链表 II) python实现
题目描述: 中文: 给定一个链表,返回链表开始入环的第一个节点. 如果链表无环,则返回 null. 为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始). ...
- Leetcode力扣45题 跳跃游戏 II
原题目: 跳跃游戏 II 给定一个非负整数数组,你最初位于数组的第一个位置. 数组中的每个元素代表你在该位置可以跳跃的最大长度. 你的目标是使用最少的跳跃次数到达数组的最后一个位置. 示例: 输入: ...
- Leetcode(力扣) 整数反转
Leetcode 7.整数反转 给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转. 示例: 输入: -123 输出: -321 注意: 假设我们的环境只能存储得下 32 位的有符 ...
随机推荐
- FPGA中的面积优化
FPGA中的面积优化 一.优化的意义 面积优化,就是在实现预定功能的情况下,使用更小的面积.通过优化,可以使设计能够运行在资源较少的平台上,节约成本,也可以为其他设计提供面积资源. 二.操作符平衡 对 ...
- GraphQl in ASP.NET Core
GraphQl in ASP.NET Core https://graphql.cn/ https://graphql-dotnet.github.io/docs/getting-started/ar ...
- 学习Source Generators之从swagger中生成类
前面学习了一些Source Generators的基础只是,接下来就来实践一下,用这个来生成我们所需要的代码. 本文将通过读取swagger.json的内容,解析并生成对应的请求响应类的代码. 创建项 ...
- #状压dp,背包,贪心#洛谷 5997 [PA2014]Pakowanie
题目 你有 \(n\) 个物品和 \(m\) 个包.物品有重量,且不可被分割: 包也有各自的容量.要把所有物品装入包中,至少需要几个包? 分析 考虑物品的数量很小,首先优先选容量大的背包, 设\(f[ ...
- Agent内存马分析
什么是Java Agent 我们知道Java是一种强类型语言,在运行之前必须将其编译成.class字节码,然后再交给JVM处理运行.Java Agent就是一种能在不影响正常编译的前提下,修改Java ...
- Redis 02 基础命令
数据库 Redis 默认有 16 个数据库. 默认使用的是第 0 个数据库. 不同数据库存不同的值. 切换数据库 select 127.0.0.1:6379> select 1 OK 127.0 ...
- HarmonyOS Connect认证测试
原文链接:https://mp.weixin.qq.com/s/zRG97PWPqfDo0vfwQWSUew,点击链接查看更多技术内容: 在HarmonyOS Connect生态产品的认证测试过 ...
- k8s之emptyDir存储卷
一.简介 emptyDir卷是最简单的卷,主要用于存储临时数据,当pod生命周期结束,emptyDir卷也就销毁. emptyDir卷应用场景一般是pod中多个容器共享数据,即在pod中定义一个emp ...
- 什么是ip协议二
前言 续前面一章. 正文 看下ip选项: 看一张图: 这个ip选项一般我们不用看,即使你去搞硬件,那么做c++或者c的人会告诉你填啥,按照他们设置即可. 那么ip是如何传输的呢? 先看这张图,这张图的 ...
- javascript现代编程系列教程之一:区块作用域对VAR不起作用的问题
在JavaScript中,使用var声明的变量具有函数作用域,而不是块级作用域.这意味着在一个函数内部,使用var声明的变量在整个函数范围内都是可见的,包括嵌套的块(如if语句.for循环等).为了避 ...