2865. 美丽塔 I

简介: 2865. 美丽塔 I

说在前面

🎈不知道大家对于算法的学习是一个怎样的心态呢?为了面试还是因为兴趣?不管是出于什么原因,算法学习需要持续保持。

题目描述

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

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

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

1 <= heights[i] <= maxHeights[i]

heights 是一个 山脉 数组。

如果存在下标 i 满足以下条件,那么我们称数组 heights 是一个 山脉 数组:

对于所有 0 < j <= i ,都有 heights[j - 1] <= heights[j]

对于所有 i <= k < n - 1 ,都有 heights[k + 1] <= heights[k]

请你返回满足 美丽塔 要求的方案中,高度和的最大值 。

示例 1:

输入:maxHeights = [5,3,4,1,1]
输出:13
解释:和最大的美丽塔方案为 heights = [5,3,3,1,1] ,这是一个美丽塔方案,因为:
- 1 <= heights[i] <= maxHeights[i]  
- heights 是个山脉数组,峰值在 i = 0 处。
13 是所有美丽塔方案中的最大高度和。

示例 2:

输入:maxHeights = [6,5,3,9,2,7]
输出:22
解释: 和最大的美丽塔方案为 heights = [3,3,3,9,2,2] ,这是一个美丽塔方案,因为:
- 1 <= heights[i] <= maxHeights[i]
- heights 是个山脉数组,峰值在 i = 3 处。
22 是所有美丽塔方案中的最大高度和。

示例 3:

输入:maxHeights = [3,2,5,5,2,3]
输出:18
解释:和最大的美丽塔方案为 heights = [2,2,5,5,2,2] ,这是一个美丽塔方案,因为:
- 1 <= heights[i] <= maxHeights[i]
- heights 是个山脉数组,最大值在 i = 2 处。
注意,在这个方案中,i = 3 也是一个峰值。
18 是所有美丽塔方案中的最大高度和。

提示:

  • 1 <= n == maxHeights <= 10^3
  • 1 <= maxHeights[i] <= 10^9

解题思路

这题目数据规模比较小,我们可以直接使用前缀和+后缀和来解题。

const arr1 = new Array(maxHeights.length).fill(0);
const len = maxHeights.length;
map[maxHeights[0]] = 1;
for (let i = 1; i < len; i++) {
  const n = map[maxHeights[i]] || 0;
  map[maxHeights[i]] = n + 1;
  let appendNum = 0;
  if (maxHeights[i] < maxHeights[i - 1]) {
    appendNum = checkMap(maxHeights[i]);
  }
  arr1[i] = arr1[i - 1] + appendNum;
}

从左往右计算最大高度差的部分。首先创建一个长度为 maxHeights 的数组 arr1,用于记录从左边开始的最大高度差。然后使用一个 map 对象记录当前高度出现的次数。接下来遍历给定的高度数组 maxHeights,对于当前高度,如果其比前一个高度要低,则调用 checkMap 函数计算当前位置之前的最大高度差并将结果保存在 appendNum 中。最后将 appendNum 加到 arr1 数组中,更新 arr1 的值。

值得注意的是,由于第一个元素没有前面的元素与其比较,因此在初始化 map 对象时将 maxHeights[0] 的值设为 1 以表示该高度出现了一次。

其中 n 变量表示当前高度在 map 对象中出现的次数。如果 n 不存在,则默认为 0。

const arr2 = new Array(maxHeights.length).fill(0);
const len = maxHeights.length;
map = {};
map[maxHeights[len - 1]] = 1;
let res = arr1[len - 1] + arr2[len - 1];
let sum = maxHeights[len - 1];
for (let i = len - 2; i >= 0; i--) {
  const n = map[maxHeights[i]] || 0;
  map[maxHeights[i]] = n + 1;
  let appendNum = 0;
  if (maxHeights[i] < maxHeights[i + 1]) {
    appendNum = checkMap(maxHeights[i]);
  }
  arr2[i] = arr2[i + 1] + appendNum;
  res = Math.min(arr1[i] + arr2[i], res);
  sum += maxHeights[i];
}

从右往左计算最大高度差的部分。首先创建一个长度为 maxHeights 的数组 arr2,用于记录从右边开始的最大高度差。然后初始化 map 对象,将最后一个元素的值设为 1 表示该高度出现了一次。然后初始化 res 变量为 arr1[len - 1] + arr2[len - 1],表示当前的最小值。

接下来倒序遍历给定的高度数组 maxHeights,对于当前高度,如果其比后一个高度要低,则调用 checkMap 函数计算当前位置之后的最大高度差并将结果保存在 appendNum 中。然后将 appendNum 加到 arr2 数组中,更新 arr2 的值。

同时,在每次遍历时,计算当前位置的最小值并将其与 res 取最小值,并将结果存储在 res 变量中。最后计算所有高度的和并存储在 sum 变量中。

值得注意的是,在处理完最后一个元素后,下一次循环中的 i 值为 len - 2,所以需要在循环中进行一次判断。另外,在初始化 map 对象时需要将之前的对象清空,否则会影响计算结果。

const checkMap = (maxNum) => {
  let sum = 0;
  for (let k in map) {
    if (Number(k) > Number(maxNum)) {
      sum += (k - maxNum) * map[k];
      let n = map[maxNum] || 0;
      map[maxNum] = n + map[k];
      delete map[k];
    }
  }
  return sum;
};

计算高度差总和。

AC代码

/**
 * @param {number[]} maxHeights
 * @return {number}
 */
var maximumSumOfHeights = function (maxHeights) {
  const arr1 = new Array(maxHeights.length).fill(0);
  const arr2 = new Array(maxHeights.length).fill(0);
  const len = maxHeights.length;
  let map = {};
  const checkMap = (maxNum) => {
    let sum = 0;
    for (let k in map) {
      if (Number(k) > Number(maxNum)) {
        sum += (k - maxNum) * map[k];
        let n = map[maxNum] || 0;
        map[maxNum] = n + map[k];
        delete map[k];
      }
    }
    return sum;
  };
  map[maxHeights[0]] = 1;
  for (let i = 1; i < len; i++) {
    const n = map[maxHeights[i]] || 0;
    map[maxHeights[i]] = n + 1;
    let appendNum = 0;
    if (maxHeights[i] < maxHeights[i - 1]) {
      appendNum = checkMap(maxHeights[i]);
    }
    arr1[i] = arr1[i - 1] + appendNum;
  }
  map = {};
  map[maxHeights[len - 1]] = 1;
  let res = arr1[len - 1] + arr2[len - 1];
  let sum = maxHeights[len - 1];
  for (let i = len - 2; i >= 0; i--) {
    const n = map[maxHeights[i]] || 0;
    map[maxHeights[i]] = n + 1;
    let appendNum = 0;
    if (maxHeights[i] < maxHeights[i + 1]) {
      appendNum = checkMap(maxHeights[i]);
    }
    arr2[i] = arr2[i + 1] + appendNum;
    res = Math.min(arr1[i] + arr2[i], res);
    sum += maxHeights[i];
  }
  return sum - res;
};

公众号

关注公众号『前端也能这么有趣』,获取更多有趣内容。

说在后面

🎉 这里是 JYeontu,现在是一名前端工程师,有空会刷刷算法题,平时喜欢打羽毛球 🏸 ,平时也喜欢写些东西,既为自己记录 📋,也希望可以对大家有那么一丢丢的帮助,写的不好望多多谅解 🙇,写错的地方望指出,定会认真改进 😊,偶尔也会在自己的公众号『前端也能这么有趣』发一些比较有趣的文章,有兴趣的也可以关注下。在此谢谢大家的支持,我们下文再见 🙌。

目录
相关文章
|
5天前
|
人工智能 安全 API
CoPaw:5分钟部署你的 AI助理
源自阿里巴巴开源生态的个人 AI 助理——CoPaw。作为阿里倾力打造的开源力作,CoPaw 完美打通钉钉、飞书、Discord 等多平台对话通道,支持定时任务自动化。内置 PDF/Office 深度处理、新闻摘要等强大技能,更开放自定义扩展接口。坚持数据全程私有化部署,绝不上传云端,让每一位用户都能在大厂技术加持下,拥有安全、专属的智能助手。
|
8天前
|
人工智能 自然语言处理 JavaScript
2026年Windows+Ollama本地部署OpenClaw保姆级教程:本地AI Agent+阿里云上快速搭建
2026年OpenClaw凭借本地部署、私有化运行的特性,成为打造个人智能体的核心工具,而Ollama作为轻量级本地大模型管理工具,能让OpenClaw摆脱对云端大模型的依赖,实现**本地推理、数据不泄露、全流程私有化**的智能体验。本文基于Windows 11系统,从硬件环境准备、Ollama安装与模型定制、OpenClaw部署配置、技能扩展到常见问题排查,打造保姆级本地部署教程,同时补充阿里云OpenClaw(Clawdbot)快速部署步骤,兼顾本地私有化需求与云端7×24小时运行需求,文中所有代码命令均可直接复制执行,确保零基础用户也能快速搭建属于自己的本地智能体。
9513 76
|
6天前
|
人工智能 安全 JavaScript
阿里云上+本地部署OpenClaw(小龙虾)新手攻略:解锁10大必备Skills,零基础也能玩转AI助手
2026年,开源AI代理工具OpenClaw(昵称“小龙虾”)凭借“能实际做事”的核心优势,在GitHub斩获25万+星标,成为现象级AI工具。它最强大的魅力在于可扩展的Skills(技能包)系统——通过ClawHub插件市场的数百个技能,能让AI助手从简单聊天升级为处理办公、学习、日常事务的全能帮手。
4895 13
|
7天前
|
人工智能 自然语言处理 机器人
保姆级教程:Mac本地搭建OpenClaw及阿里云上1分钟部署OpenClaw+飞书集成实战指南
OpenClaw(曾用名Clawdbot、Moltbot)作为2026年最热门的开源个人AI助手平台,以“自然语言驱动自动化”为核心,支持对接飞书、Telegram等主流通讯工具,可替代人工完成文件操作、日历管理、邮件处理等重复性工作。其模块化架构适配多系统环境,既可以在Mac上本地化部署打造私人助手,也能通过阿里云实现7×24小时稳定运行,完美兼顾隐私性与便捷性。
5031 12
|
9天前
|
人工智能 JSON JavaScript
手把手教你用 OpenClaw + 飞书,打造专属 AI 机器人
手把手教你用 OpenClaw(v2026.2.22-2)+ 飞书,10分钟零代码搭建专属AI机器人!内置飞书插件,无需额外安装;支持Claude等主流模型,命令行一键配置。告别复杂开发,像聊同事一样自然对话。
5325 13
手把手教你用 OpenClaw + 飞书,打造专属 AI 机器人
|
8天前
|
人工智能 监控 机器人
2026年零门槛部署 OpenClaw(Clawdbot)接入A股数据,实现24小时股票分析保姆级教程
在AI赋能金融分析的浪潮中,OpenClaw(原Clawdbot/Moltbot)凭借开源灵活的架构,成为个人投资者打造专属智能分析助手的首选。通过接入A股实时数据,它能实现24小时市场监控、涨跌预警、潜力股推荐等核心功能,彻底解放人工盯盘的繁琐。而阿里云的稳定部署环境,更让这套系统实现全天候不间断运行,成为真正的“金融AI助手”。 本文基于OpenClaw v2026.1.25稳定版与QVeris免费A股数据接口,详细拆解阿里云OpenClaw部署步骤、A股数据接入流程、高级分析功能配置及多平台联动技巧,所有代码命令均可直接复制复用,即使无技术基础也能在1小时内完成从部署到实战的全流程。
3709 12
|
4天前
|
人工智能 JavaScript Ubuntu
5分钟上手龙虾AI!OpenClaw部署(阿里云+本地)+ 免费多模型配置保姆级教程(MiniMax、Claude、阿里云百炼)
OpenClaw(昵称“龙虾AI”)作为2026年热门的开源个人AI助手,由PSPDFKit创始人Peter Steinberger开发,核心优势在于“真正执行任务”——不仅能聊天互动,还能自动处理邮件、管理日程、订机票、写代码等,且所有数据本地处理,隐私完全可控。它支持接入MiniMax、Claude、GPT等多类大模型,兼容微信、Telegram、飞书等主流聊天工具,搭配100+可扩展技能,成为兼顾实用性与隐私性的AI工具首选。
2401 6

热门文章

最新文章