首页 > 其他分享 >(nice!!!)LeetCode 2865. 美丽塔 I(数组、单调栈)

(nice!!!)LeetCode 2865. 美丽塔 I(数组、单调栈)

时间:2024-06-12 17:33:07浏览次数:11  
标签:f1 2865 int sum long st heights LeetCode nice

2865. 美丽塔 I

在这里插入图片描述
在这里插入图片描述

思路:方法一,时间复杂度0(n^2)。枚举每一个点i作为当前山脉数组的最高点。然后我们通过预处理遍历其前面和后面,来更新两个数组f1、f2。
数组f1[i]:表示在满足非递减的情况下,区间0~i,以点i的高度heighs[i]为最高点所能形成的最大高度和。
数组f2[i]:表示在满足非递减的情况下,区间i~n-1,以点i的高度heighs[i]为最高点所能形成的最大高度和。
具体细节看注释。

class Solution {
public:
    long long maximumSumOfHeights(vector<int>& heights) {
        int n=heights.size();
        vector<long long > f1(n,0),f2(n,0);
        f1[0]=heights[0];
        for(int i=1;i<heights.size();i++){
            f1[i]+=heights[i];
            for(int j=i-1;j>=0;j--){
            	//遇到前面的一个点j的heights[j]<=heights[i],那么直接就可以跳出
                if(heights[j]<=heights[i]){
                     f1[i]+=f1[j];
                     break;
                }else{
                	//没遇到之前,这些比heights[i]点高的高度都为heights[i];
                    f1[i]+=heights[i];
                }
                
            }
        }
        f2[n-1]=heights[n-1];
        for(int i=n-2;i>=0;i--){
            f2[i]+=heights[i];
            for(int j=i+1;j<n;j++){
          	  	//遇到后面的一个点j的heights[j]<=heights[i],那么直接就可以跳出
                if(heights[j]<=heights[i]){
                     f2[i]+=f2[j];
                     break;
                }else{
                	//没遇到之前,这些比heights[i]点高的高度都为heights[i];
                    f2[i]+=heights[i];
                }
            }
        }
        long long mx=0;
        for(int i=0;i<n;i++){
            mx=max(mx,f1[i]+f2[i]-heights[i]);
        }
        return mx;
    }
};

思路:方法二,时间复杂度0(n)。观察方法一会发现,在预处理时,我们每次都要再遍历一遍已遍历过的元素,只有当heights[j]<=heights[i]时才停下,那么我们直接维护一个非递减序列即可。细节看注释

class Solution {
public:
    long long maximumSumOfHeights(vector<int>& heights) {
        int n=heights.size();
        vector<long long > f(n,0);
        //维护一个非递减序列,记录的是下标
        stack<int> st;
        //哨兵,方便计算
        st.push(n);
        //保存到目前点i,所能形成的最大高度和
        long long sum=0;
        for(int i=n-1;i>=0;i--){
        	//栈中比点i还高的点,就需要从sum当中删掉,
            while(st.size()>1&&heights[i]<heights[st.top()]){
                int tmp=st.top();
                st.pop();
                //这个点的高度太高了,我们需要把区间[tmp,st.top())的高度都减掉;
                sum-=(long long)heights[tmp]*(st.top()-tmp);
            }
            //剔除比点i的高度heights[i]高的点后,需要将[i,st.top())这段区间的高度都置为heights[i]
            sum+=(long long)heights[i]*(st.top()-i);
            f[i]=sum;
            st.push(i);
        }
        st=stack<int>();
        st.push(-1);
        long long mx=0;
        sum=0;
        for(int i=0;i<n;i++){
            while(st.size()>1&&heights[i]<heights[st.top()]){
                int tmp=st.top();
                st.pop();
                sum-=(long long)heights[tmp]*(tmp-st.top());
            }
            sum+=(long long)heights[i]*(i-st.top());
            mx=max(mx,sum+f[i]-heights[i]);
            st.push(i);
        }
        return mx;
    }
};

标签:f1,2865,int,sum,long,st,heights,LeetCode,nice
From: https://blog.csdn.net/weixin_46028214/article/details/139628410

相关文章

  • LeetCode 300. 最长递增子序列
    更多题解尽在https://sugar.matrixlab.dev/algorithm每日更新。组队打卡,更多解法等你一起来参与哦!LeetCode300.最长递增子序列,难度中等。动态规划解题思路:遍历数组,对于每个nums[i],检查其之前的所有元素nums[j]0......
  • LeetCode刷题之HOT100之单词搜索
    2024/6/12这两天天气只能用闷、潮、热来描述。整个人像被罩在为了饭菜保温的盖子里,喘气困难、粘稠的空气一次又一次打湿我。唯有空调救我,夏天来了。Anyway,昨天只做了一题,今天早点来做一题。1、题目描述2、逻辑分析给定一个二维字符矩阵和一个单词,求单词是否在这个二维......
  • 代码随想录 算法训练营 d6 哈希表 Leetcode242 有效的字母异位词 Leetcode349 两个数
    哈希表很重要哈希表哈希表场景一般哈希表都是用来快速判断一个元素是否出现集合里一般来说数组模拟哈希set 哈希map不同的场景 当我们遇到了要快速判断一个元素是否出现集合里的时候,就要考虑哈希法。但是哈希法也是牺牲了空间换取了时间,因为我们要使用额外的数组,se......
  • leetcode刷题-归纳总结
    框架思维124.求⼆叉树中最⼤路径和后序遍历最大路径转换为为求单边最大路径105.根据前序和中序遍历构造二叉树前序遍历,找到根节点构建root,得到左右子树区间,左右子树递归构建注意:1.终止条件2.构建unordered_map230.寻找⼆叉搜索树中的第k⼩的元素⼆叉搜索树即左支树所有......
  • LeetCode 419. 甲板上的战舰(深度优先搜索dfs、数组)
    419.甲板上的战舰思路:方法一,深度优先搜索dfs,遇到‘X’,就dfs一次,并在board中将其变为‘.’。classSolution{public:voiddfs(intx,inty,vector<vector<char>>&board){if(board[x][y]!='X')return;board[x][y]='.';if(x+1......
  • Leetcode419 甲板上的战舰
    最近以来,我在力扣上坚持完成每天一题,今天系统推的题目为《甲板上的战舰》,在此记录一下。题目描述如下:给你一个大小为mxn的矩阵board表示甲板,其中,每个单元格可以是一艘战舰'X'或者是一个空位'.',返回在甲板board上放置的战舰的数量。战舰只能水平或者垂直放置在......
  • LeetCode 409 Longest Palindrome All In One
    LeetCode409LongestPalindromeAllInOneLeetCode409最长回文算法题解Solutions//MapfunctionlongestPalindrome(s:string):number{constmap=newMap();letlen=0;for(leti=0;i<s.length;i++){if(map.has(s[i])){//配对,消元......
  • LeetCode 算法:缺失的第一个正数c++
    原题链接......
  • Q25 LeetCode49 字母异位词分组
    难好好看看  1classSolution{2publicList<List<String>>groupAnagrams(String[]strs){3if(strs==null||strs.length==0)4returnnewArrayList<>();5//map中key存储的是字符串中字母排序后新的字符串6Map<Stri......
  • 第一篇 LeetCode(42)接雨水
    LeetCode(42)接雨水力扣官网题目描述:给定n个非负整数表示每个宽度为1的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。输入:height=[0,1,0,2,1,0,1,3,2,1,2,1]输出:6解释:上面是由数组[0,1,0,2,1,0,1,3,2,1,2,1]表示的高度图,在这种情况下,可以接6个单位的雨水......