【力扣每日一题】力扣2865美丽塔I

题目来源

力扣2865美丽塔I

题目概述

给你一个长度为 n 下标从 0 开始的整数数组 maxHeights

你的任务是在坐标轴上建 n 座塔。第 i 座塔的下标为 i ,高度为 heights[i]

如果以下条件满足,我们称这些塔是 美丽 的:

1 <= heights[i] <= maxHeights[i] heights 是一个 山脉 数组。

解题思路

思路一:遍历一遍数组,假设每个位置为顶峰,分别计算该位置为顶峰时的山脉高度,并记录最大值; 思路二:使用两个数组(栈或者双端队列都行,最好是栈,方便编码)一个记录从左到右递增序列在某个位置的最大高度和,另一个记录从右到左递增序列在某个位置的最大高度和,同一个位置的最大高度和相加就是该位置为顶峰的结果。

代码实现

java实现

java 复制代码
public class Solution {
    public long maximumSumOfHeights(List<Integer> maxHeights) {
        // 长度
        int length = maxHeights.size();
        // 构造一座从左到右逐渐增高的山脉数组
        int[] rightMaxMountain = new int[length];
        rightMaxMountain[0] = maxHeights.get(0);
        // 表示记某个位置为顶峰,从左递增山脉的累计高度
        long[] rightMaxMountainHeightSum = new long[length];
        rightMaxMountainHeightSum[0] = rightMaxMountain[0];
        // 表示已构造山脉长度
        for (int i = 1; i < length; i++) {
            // 当前高度
            int current = maxHeights.get(i);
            long temp = rightMaxMountainHeightSum[i - 1];
            // 如果当前高度比已经构造的山高度低,已构造高的部分销毁
            int tempCount = i ;
            while (tempCount != 0 && rightMaxMountain[tempCount - 1] > current) {
                temp -= (rightMaxMountain[tempCount - 1] - current);
                rightMaxMountain[tempCount - 1] = current;
                tempCount--;
            }
            // 记录最大高度
            rightMaxMountainHeightSum[i] = temp + (rightMaxMountain[i] = current);
        }
        // 构造一座从右到左逐渐增高的山脉数组
        int[] leftMaxMountain = new int[length];
        leftMaxMountain[length - 1] = maxHeights.get(length - 1);
        // 表示记某个位置为顶峰,从右递增山脉的累计高度
        long[] leftMaxMountainHeightSum = new long[length];
        leftMaxMountainHeightSum[length - 1] = leftMaxMountain[length - 1];
        // 结果
        long result = rightMaxMountainHeightSum[length - 1] + leftMaxMountainHeightSum[length - 1] - maxHeights.get(length - 1);
        for (int i = length - 2; i >= 0; i--) {
            // 当前高度
            int current = maxHeights.get(i);
            long temp = leftMaxMountainHeightSum[i + 1];
            // 如果已构造山脉比当前高度高,销毁已构造高的部分
            int tempCount = i;
            while (tempCount != length - 1 && current < leftMaxMountain[tempCount + 1]){
                temp -= (leftMaxMountain[tempCount + 1] - current);
                leftMaxMountain[tempCount + 1] = current;
                tempCount++;
            }
            // 记录最大高度
            leftMaxMountainHeightSum[i] = temp + (leftMaxMountain[i] = current);
            result = Math.max(result, leftMaxMountainHeightSum[i] + rightMaxMountainHeightSum[i] - current);
        }
        return result;
    }
}

c++实现

cpp 复制代码
class Solution {
public:
    long long maximumSumOfHeights(vector<int>& maxHeights) {
        // 长度
        int length = maxHeights.size();
        // 构造一座从左到右逐渐增高的山脉数组
        int* rightMaxMountain = new int[length];
        rightMaxMountain[0] = maxHeights[0];
        // 表示记某个位置为顶峰,从左递增山脉的累计高度
        long long* rightMaxMountainHeightSum = new long long[length];
        rightMaxMountainHeightSum[0] = rightMaxMountain[0];
        // 表示已构造山脉长度
        for (int i = 1; i < length; i++) {
            // 当前高度
            int current = maxHeights[i];
            long temp = rightMaxMountainHeightSum[i - 1];
            // 如果当前高度比已经构造的山高度低,已构造高的部分销毁
            int tempCount = i;
            while (tempCount != 0 && rightMaxMountain[tempCount - 1] > current) {
                temp -= (rightMaxMountain[tempCount - 1] - current);
                rightMaxMountain[tempCount - 1] = current;
                tempCount--;
            }
            // 记录最大高度
            rightMaxMountainHeightSum[i] = temp + (rightMaxMountain[i] = current);
        }
        // 构造一座从右到左逐渐增高的山脉数组
        int* leftMaxMountain = new int[length];
        leftMaxMountain[length - 1] = maxHeights[length - 1];
        // 表示记某个位置为顶峰,从右递增山脉的累计高度
        long long* leftMaxMountainHeightSum = new long long[length];
        leftMaxMountainHeightSum[length - 1] = leftMaxMountain[length - 1];
        // 结果
        long long result = rightMaxMountainHeightSum[length - 1] + leftMaxMountainHeightSum[length - 1] - maxHeights[length - 1];
        for (int i = length - 2; i >= 0; i--) {
            // 当前高度
            int current = maxHeights[i];
            long temp = leftMaxMountainHeightSum[i + 1];
            // 如果已构造山脉比当前高度高,销毁已构造高的部分
            int tempCount = i;
            while (tempCount != length - 1 && current < leftMaxMountain[tempCount + 1]) {
                temp -= (leftMaxMountain[tempCount + 1] - current);
                leftMaxMountain[tempCount + 1] = current;
                tempCount++;
            }
            // 记录最大高度
            leftMaxMountainHeightSum[i] = temp + (leftMaxMountain[i] = current);
            long long newResult = leftMaxMountainHeightSum[i] + rightMaxMountainHeightSum[i] - current;
            result = result > newResult ? result : newResult;
        }
        return result;
    }
};

算法题记录

相关推荐
猫头虎8 分钟前
HAMi 2.7.0 发布:全面拓展异构芯片支持,优化GPU资源调度与智能管理
嵌入式硬件·算法·prompt·aigc·embedding·gpu算力·ai-native
漫漫不慢.11 分钟前
算法练习-二分查找
java·开发语言·算法
还是鼠鼠19 分钟前
《黑马商城》Elasticsearch基础-详细介绍【简单易懂注释版】
java·spring boot·spring·elasticsearch·搜索引擎·spring cloud·全文检索
如竟没有火炬30 分钟前
LRU缓存——双向链表+哈希表
数据结构·python·算法·leetcode·链表·缓存
Greedy Alg33 分钟前
LeetCode 236. 二叉树的最近公共祖先
算法
牧羊人_myr34 分钟前
Maven核心功能与项目构建详解
java·maven
Maple_land1 小时前
Linux进程第八讲——进程状态全景解析(二):从阻塞到消亡的完整生命周期
linux·运维·服务器·c++·centos
爱吃生蚝的于勒1 小时前
【Linux】零基础学会Linux之权限
linux·运维·服务器·数据结构·git·算法·github
量子物理学1 小时前
Eclipse Mosquitto 在小内存下怎么修改配置文件
java·服务器·eclipse
ajassi20001 小时前
开源 C++ QT QML 开发(十一)通讯--TCP服务器端
c++·qt·开源