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

力扣单调栈算法专题训练

目录

  • 1 专题说明
  • 2 训练

1 专题说明

本博客用来计算力扣上的单调栈题目、解题思路和代码。

在这里插入图片描述

2 训练

题目1:2866美丽塔II。

解题思路:先计算出prefix[i],表示0~i满足递增情况下,0~i上的元素之和最大值。然后计算出suffix[i],表示i~n-1满足递增情况下,i~n-1上的元素之和最大值。那么以i为峰顶的美丽塔的元素之和的最大值为prefix[i] + suffix[i] - nums[i],遍历i,获得答案即可。

本质上,还是可以归类为:找到i左边,并且<=nums[i]的元素值。

C++代码如下,

class Solution {
public:long long maximumSumOfHeights(vector<int>& maxHeights) {int n = maxHeights.size();vector<long long> prefix(n, 0); //prefix[i]表示0~i是递增的情况下,0~i的元素之和stack<int> stk;for (int i = 0; i < n; ++i) {while (!stk.empty() && maxHeights[stk.top()] > maxHeights[i]) {stk.pop();}if (stk.empty()) {prefix[i] = (long long)(i + 1) * maxHeights[i];} else {prefix[i] = prefix[stk.top()] + (long long)(i - stk.top()) * maxHeights[i];}stk.push(i);}while (!stk.empty()) {stk.pop();}vector<long long> suffix(n, 0); //suffix[i]表示i~n-1是递减的情况下,i~n-1的元素之和for (int i = n - 1; i >= 0; --i) {while (!stk.empty() && maxHeights[stk.top()] > maxHeights[i]) {stk.pop();}if (stk.empty()) {suffix[i] = (long long)(n - i) * maxHeights[i];} else {suffix[i] = suffix[stk.top()] + (long long)(stk.top() - i) * maxHeights[i];}stk.push(i);}long long res = 0;for (int i = 0; i < n; ++i) {res = max(res, prefix[i] + suffix[i] - maxHeights[i]);}return res;}
};

python3代码如下,

class Solution:def maximumSumOfHeights(self, maxHeights: List[int]) -> int:n = len(maxHeights)prefix = [0 for i in range(n)] #0~i的递增数组的和的最大值stk = []for i in range(n):while len(stk) and maxHeights[stk[-1]] > maxHeights[i]:del stk[-1]if len(stk) == 0:prefix[i] = (i + 1) * maxHeights[i]else:prefix[i] = prefix[stk[-1]] + (i - stk[-1]) * maxHeights[i]stk.append(i)stk.clear()suffix = [0 for i in range(n)] #i~n-1的递减数组的和的最大值for i in range(n-1,-1,-1):while len(stk) and maxHeights[stk[-1]] > maxHeights[i]:del stk[-1]if len(stk) == 0:suffix[i] = (n - i) * maxHeights[i]else:suffix[i] = suffix[stk[-1]] + (stk[-1] - i) * maxHeights[i]stk.append(i)res = 0for i in range(n):#print(f"i = {i}, prefix[i] = {prefix[i]}, suffix[i] = {suffix[i]}.")res = max(res, prefix[i] + suffix[i] - maxHeights[i])return res

题目2:496下一个更大元素I。

解题思路:直接找右边首次大于它的元素即可。

C++代码如下,

class Solution {
public:vector<int> nextGreaterElement(vector<int>& nums1, vector<int>& nums2) {unordered_map<int,int> mp; //mp[x]表示nums2中元素x的右边,第一个比它大的元素stack<int> stk;for (int i = nums2.size() - 1; i >= 0; --i) {while (!stk.empty() && stk.top() <= nums2[i]) {stk.pop();}if (!stk.empty()) {mp[nums2[i]] = stk.top();} else {mp[nums2[i]] = -1;}stk.push(nums2[i]);}vector<int> res;for (auto x : nums1) {res.emplace_back(mp[x]);}return res;}
};

python3代码如下,

class Solution:def nextGreaterElement(self, nums1: List[int], nums2: List[int]) -> List[int]:n = len(nums2)mp = collections.defaultdict(int)stk = []for i in range(n - 1, -1, -1):while len(stk) and stk[-1] <= nums2[i]:del stk[-1]if len(stk):mp[nums2[i]] = stk[-1]else:mp[nums2[i]] = -1stk.append(nums2[i])res = []for x in nums1:res.append(mp[x])return res 

题目3:503下一个更大元素II。

解题思路:环形问题,扩展两倍原数组即可,接下来就是找右侧首次大于它的元素。

C++代码如下,

class Solution {
public:vector<int> nextGreaterElements(vector<int>& nums) {int n = nums.size();vector<int> a(2 * n, 0);for (int i = 0; i < n; ++i) {a[i] = a[i + n] = nums[i];}vector<int> ans(2 * n, -1);stack<int> stk;for (int i = 2 * n - 1; i >= 0; --i) {while (!stk.empty() && stk.top() <= a[i]) {stk.pop();}if (!stk.empty()) {ans[i] = stk.top();}stk.push(a[i]);}vector<int> res(n, -1);for (int i = 0; i < n; ++i) {res[i] = ans[i];}return res;}
};

python3代码如下,

class Solution:def nextGreaterElements(self, nums: List[int]) -> List[int]:n = len(nums)a = [-1 for i in range(2 * n)]for i in range(n):a[i] = a[i + n] = nums[i]ans = [-1 for i in range(2 * n)]stk = []for i in range(2 * n - 1, -1, -1):while len(stk) and stk[-1] <= a[i]:del stk[-1]if len(stk):ans[i] = stk[-1]stk.append(a[i])res = [-1 for i in range(n)]for i in range(n):res[i] = ans[i]return res 

题目4

相关文章:

  • ArcGIS基础:便捷查看外业照片及识别举证照片方位角
  • 案例125:基于微信小程序的个人健康数据管理系统的设计与实现
  • StringBuilder和StringBuffer区别是什么?
  • 2.3_2 进程互斥的软件实现方法
  • java类和对象的思想概述
  • .net core webapi 大文件上传到wwwroot文件夹
  • 微服务之配置中心与服务跟踪
  • 【Grafana】Grafana匿名访问以及与LDAP连接
  • Git常用命令分享
  • 论文笔记 | ICLR 2023 WikiWhy:回答和解释因果问题
  • Sentinel 流量治理组件教程
  • 用C#也能做机器学习?
  • 在MongoDB中使用数组字段和子文档字段进行索引
  • SQL---Zeppeline前驱记录与后驱记录查询
  • 测试理论知识三:测试用例、测试策略
  • Google 是如何开发 Web 框架的
  • 《深入 React 技术栈》
  • 【React系列】如何构建React应用程序
  • Angular 4.x 动态创建组件
  • Apache的基本使用
  • avalon2.2的VM生成过程
  • CSS 三角实现
  • Docker 1.12实践:Docker Service、Stack与分布式应用捆绑包
  • Elasticsearch 参考指南(升级前重新索引)
  • java小心机(3)| 浅析finalize()
  • Java应用性能调优
  • Laravel 中的一个后期静态绑定
  • Magento 1.x 中文订单打印乱码
  • mockjs让前端开发独立于后端
  • passportjs 源码分析
  • Promise面试题2实现异步串行执行
  • Python 反序列化安全问题(二)
  • unity如何实现一个固定宽度的orthagraphic相机
  • vue-loader 源码解析系列之 selector
  • vuex 学习笔记 01
  • 阿里云容器服务区块链解决方案全新升级 支持Hyperledger Fabric v1.1
  • 纯 javascript 半自动式下滑一定高度,导航栏固定
  • 构建二叉树进行数值数组的去重及优化
  • 前端相关框架总和
  • 如何优雅的使用vue+Dcloud(Hbuild)开发混合app
  • 使用 Xcode 的 Target 区分开发和生产环境
  • 微信开放平台全网发布【失败】的几点排查方法
  • 微信开源mars源码分析1—上层samples分析
  • 智能网联汽车信息安全
  • Python 之网络式编程
  • python最赚钱的4个方向,你最心动的是哪个?
  • Salesforce和SAP Netweaver里数据库表的元数据设计
  • 阿里云ACE认证之理解CDN技术
  • ​插件化DPI在商用WIFI中的价值
  • #{}和${}的区别?
  • $分析了六十多年间100万字的政府工作报告,我看到了这样的变迁
  • %3cli%3e连接html页面,html+canvas实现屏幕截取
  • (Demo分享)利用原生JavaScript-随机数-实现做一个烟花案例
  • (二)JAVA使用POI操作excel
  • (分享)自己整理的一些简单awk实用语句