原题链接

暴力做法 (时间复杂度 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的更多相关文章

  1. 刷题-力扣-剑指 Offer II 055. 二叉搜索树迭代器

    剑指 Offer II 055. 二叉搜索树迭代器 题目链接 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/kTOapQ 著作权归领扣网络所有 ...

  2. 刷题-力扣-541. 反转字符串 II

    541. 反转字符串 II 题目链接 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/reverse-string-ii 著作权归领扣网络所有. ...

  3. 刷题-力扣-113. 路径总和 II

    113. 路径总和 II 题目链接 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/path-sum-ii 著作权归领扣网络所有.商业转载请联系 ...

  4. 刷题-力扣-518. 零钱兑换 II

    518. 零钱兑换 II 题目链接 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/coin-change-2/ 著作权归领扣网络所有.商业转载 ...

  5. 刷题-力扣-63. 不同路径 II

    63. 不同路径 II 题目链接 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/unique-paths-ii/ 著作权归领扣网络所有.商业转 ...

  6. 刷题-力扣-264. 丑数 II

    264. 丑数 II 题目链接 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/ugly-number-ii/ 著作权归领扣网络所有.商业转载请 ...

  7. 力扣---45. 跳跃游戏 II

    给定一个长度为 n 的 0 索引整数数组 nums.初始位置为 nums[0].每个元素 nums[i] 表示从索引 i 向前跳转的最大长度.换句话说,如果你在 nums[i] 处,你可以跳转到任意 ...

  8. 力扣 ——Linked List Cycle II(环形链表 II) python实现

    题目描述: 中文: 给定一个链表,返回链表开始入环的第一个节点. 如果链表无环,则返回 null. 为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始). ...

  9. Leetcode力扣45题 跳跃游戏 II

    原题目: 跳跃游戏 II 给定一个非负整数数组,你最初位于数组的第一个位置. 数组中的每个元素代表你在该位置可以跳跃的最大长度. 你的目标是使用最少的跳跃次数到达数组的最后一个位置. 示例: 输入: ...

  10. Leetcode(力扣) 整数反转

    Leetcode 7.整数反转 给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转. 示例: 输入: -123 输出: -321 注意: 假设我们的环境只能存储得下 32 位的有符 ...

随机推荐

  1. GPT-SoVITS教程,接入酒馆AI,SillyTavern-1.11.5,让AI女友声若幽兰

    本次分享一下如何将GPT-SoVITS接入SillyTavern-1.11.5项目,让让AI女友声若幽兰,首先明确一下,SillyTavern-1.11.5只是一个前端项目,它没有任何大模型文本生成能 ...

  2. 【Spring注解驱动开发】面试官再问你BeanPostProcessor的执行流程,就把这篇文章甩给他!

    写在前面 在前面的文章中,我们讲述了BeanPostProcessor的postProcessBeforeInitialization()方法和postProcessAfterInitializati ...

  3. Oracle 获取月初、月末时间,获取上一月月初、月末时间

    select trunc(sysdate, 'mm'), last_day(trunc(sysdate)), trunc(add_months(trunc(sysdate), -1), 'mm'), ...

  4. KingbaseES V8R6 中unlogged表

    前言 KingbaseESV8R6有一种表称为unlogged,在该表新建的索引也属于unlogged.和普通表的区别是,对该表进行DML操作时候不将该表的变更记录变更写入到wal文件中.在数据库异常 ...

  5. DevSecOps 中的漏洞管理(下)

    建立漏洞管理程序以支持DevSecOps 在讨论DevSecOps及DevOps模型中包含安全性的重要性时,建立有效的漏洞管理实践是非常重要的.这可以通过将漏洞管理设置为程序来实现. 我们可以开始对I ...

  6. #floyd,分治#D 路径之和

    题目 对于每个\(y\),求除了\(y\)之外,其余的所有点组成的有序点对\((x,z)\) 不经过\(y\)的最短路长度之和(不存在即为-1).\(n\leq 320\) 分析 太妙了,首先用flo ...

  7. 深入了解 Python MongoDB 查询:find 和 find_one 方法完全解析

    在 MongoDB 中,我们使用 find() 和 find_one() 方法来在集合中查找数据,就像在MySQL数据库中使用 SELECT 语句来在表中查找数据一样 查找单个文档 要从MongoDB ...

  8. HarmonyOS元服务开发实践:桌面卡片字典

     本文转载分享自华为开发者论坛<HarmonyOS元服务开发实践:桌面卡片字典>,作者:蛟龙腾飞   一.项目说明 1.DEMO创意为卡片字典. 2.不同卡片显示不同内容:微卡.小卡.中卡 ...

  9. sql 语句系列(删库跑路系列)[八百章之第七章]

    前言 最开心的章节,没有之一. 删除违反参照完整性的记录 EMP 是员工表,DEPT 是部门表 DEPTNO是部门编号 delete from EMP where not exists ( selec ...

  10. 鸿蒙HarmonyOS实战-ArkUI组件(Tabs)

    一.Tabs Tabs组件是一种常见的用户界面(UI)组件,它是一个可以容纳多个选项卡的容器组件.每个选项卡通常包含一个面板和一个标签,用户可以通过点击标签来切换面板.Tabs组件通常用于展示多个相关 ...