原题链接

暴力做法 (时间复杂度 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. C#调用HTTP POST请求上传图片

    public static string UploadImage(string uploadUrl, string imgPath, string fileparameter = "file ...

  2. Linux编写Shell脚本获取指定目录下所有文件并处理

    Linux编写Shell脚本获取指定目录下所有文件进行处理并保存到新目录 #!/bin/bash app_name="shell" path="/dir" #原 ...

  3. KingbaseES数据库适配Activiti7 didn't put process definition问题处理过程

    一.Activiti介绍 Activiti是一个轻量级的java开源BPMN 2工作流引擎.目前以升级至7.x,支持与springboot2.x集成. 二.项目环境 Spring Boot版本2.2. ...

  4. MyBatis 简介、优缺点

    40)谈谈 MyBatis Mybatis 是一个半自动化的 ORM 框架,它对 jdbc 的操作数据库的过程进行封装,使得开发者只需要专注于 SQL 语句本身,而不用去关心注册驱动,创建 conne ...

  5. C++设计模式 - 职责链模式(Chain of Resposibility)

    数据结构模式 常常有一-些组件在内部具有特定的数据结构,如果让客户程序依赖这些特定的数据结构,将极大地破坏组件的复用.这时候,将这些特定数据结构封装在内部,在外部提供统一的接口,来实现与特定数据结构无 ...

  6. #对偶图最短路,网络流#洛谷 4001 [ICPC-Beijing 2006]狼抓兔子

    题目 网格图最小割\((n,m\leq 1000)\) 分析 首先网络流可以过,但是由于无向图,所以残量网络容量也为\(w\),\(Dinic\)玄学AC,代码就不贴了 那有没有其它方法呢,网格图显然 ...

  7. Java 包装类:原始数据类型与迭代器

    Java Iterator Iterator 接口提供了一种迭代集合的方法,即顺序访问集合中的每个元素.它支持 hasNext() 和 next() 方法,用于检查是否存在下一个元素以及获取下一个元素 ...

  8. 了解 Spring MVC 架构、Dispatcher Servlet 和 JSP 文件的关键作用

    Spring MVC 是 Spring 框架的一部分,是一个 Web 应用程序框架.它旨在使用 Model-View-Controller(MVC) 设计模式轻松构建Web应用程序. Spring M ...

  9. 可视化库 pygal 生成png中文乱码

    解决方法:设置style,style中设置中文字体 代码如下: import pygal from pygal.style import Style import cairosvg style = S ...

  10. openGauss2.1.0新特性-账本数据库实验

    openGauss2.1.0 新特性-账本数据库实验 账本数据库融合了区块链思想,将用户操作记录至两种历史表中:用户历史表和全局区块表.当用户创建防篡改用户表时,系统将自动为该表添加一个 hash 列 ...