得到山形数组的最少删除次数(LeetCode日记)

LeetCode-1671-得到山形数组的最少删除次数

题目信息:

我们定义 a r r arr arr山形数组 当且仅当它满足:

  • a r r . l e n g t h > = 3 arr.length >= 3 arr.length>=3
  • 存在某个下标 i i i (从 0 开始) 满足 0 < i < a r r . l e n g t h − 1 0 < i < arr.length - 1 0<i<arr.length1 且:
    • a r r [ 0 ] < a r r [ 1 ] < . . . < a r r [ i − 1 ] < a r r [ i ] arr[0] < arr[1] < ... < arr[i - 1] < arr[i] arr[0]<arr[1]<...<arr[i1]<arr[i]
    • a r r [ i ] > a r r [ i + 1 ] > . . . > a r r [ a r r . l e n g t h − 1 ] arr[i] > arr[i + 1] > ... > arr[arr.length - 1] arr[i]>arr[i+1]>...>arr[arr.length1]

给你整数数组 n u m s nums nums​ ,请你返回将 n u m s nums nums 变成 山形状数组 的​ 最少 删除次数。

  • 示例1:

输入:nums = [1,3,1]
输出:0
解释:数组本身就是山形数组,所以我们不需要删除任何元素。

  • 示例2:

输入:nums = [2,1,1,5,6,2,3,1]
输出:3
解释:一种方法是将下标为 0,1 和 5 的元素删除,剩余元素为[1,5,6,3,1] ,是山形数组。

提示:

  • 3 <= nums.length <= 1000
  • 1 <= nums[i] <= 109
  • 题目保证 nums 删除一些元素后一定能得到山形数组。

相关标签 :动态规划,二分查找

题解

这道题实际上是 Leetcode 第300题 最长递增子序列 的 扩展问题。建议大家在做这道题之前可以先去了解一下上面这道题的思路和代码。下面我们开始分析本题。

方法 : 动态规划
根据题目的要求,我们需要使用最少的删除次数,使得给定的数组 n u m s nums nums 成为 山形状数组。这等价于,我们需要找出数组 n u m s nums nums 的一个最长的子序列,并且这个子序列是一个山形状数组
因此,我们可以考虑枚举山形状数组的最高点。记数组 n u m s nums nums 的长度为 n n n,并且枚举第 i i i 个元素 n u m s [ i ] nums[i] nums[i] 作为最高点,那么:

  • ( 1 ) (1) (1)在数组的前缀部分 n u m s [ 0.. i ] nums[0..i] nums[0..i] ,找出一个严格递增的子序列,并且以 n u m s [ i ] nums[i] nums[i]结束,对应着山形状数组的上升部分;
  • ( 2 ) (2) (2)在数组的后缀部分 n u m s [ i . . n − 1 ] nums[i..n−1] nums[i..n1] ,找出一个严格递减的子序列,并且以 n u m s [ i ] nums[i] nums[i]开始,对应着山形状数组的下降部分。

由于我们需要找出最长的山形状数组,并且 n u m s [ 0.. i ] nums[0..i] nums[0..i] n u m s [ i . . n − 1 ] nums[i..n−1] nums[i..n1] 这两部分是互相独立的,那么我们只需要找出 n u m s [ 0.. i ] nums[0..i] nums[0..i] 中以 n u m s [ i ] nums[i] nums[i] 结束的最长严格递增子序列,以及 n u m s [ i . . n − 1 ] nums[i..n−1] nums[i..n1] 中以 n u m s [ i ] nums[i] nums[i] 开始的最长严格递减子序列即可。

求解最长严格递增/递减子序列是一个非常经典的问题,即我们上文提到的 Leetcode 第300题 最长递增子序列 问题,使用动态规划或贪心算法的方法,可以在 O ( n 2 ) O(n^2) O(n2) 或者 O ( n l o g ⁡ n ) O(nlog⁡n) O(nlogn) 的时间内求出给定数组中,以每一个元素结尾的最长严格递增子序列的长度。
最长递增子序列问题的动态规划解法的状态转移方程如下,如果有需要的话,我可以在下一篇更新该问题。
d p [ i ] = max ⁡ 0 ≤ j < i , n u m s [ j ] < n u m s [ i ] d p [ j ] + 1 d p[i]=\max _{0 \leq j<i, n u m s[j]<n u m s[i]} d p[j]+1 dp[i]=0j<i,nums[j]<nums[i]maxdp[j]+1

对于严格递减子序列的部分,我们可以把数组 n u m s nums nums 进行反转,这样就从求解后缀的最长严格递减子序列,变成求解前缀的最长严格递增子序列了。

p r e [ i ] pre[i] pre[i] s u f [ i ] suf[i] suf[i] 分别表示上文 (1)、(2) 中找出的最长子序列的长度,只要 p r e [ i ] pre[i] pre[i] s u f [ i ] suf[i] suf[i]均大于 1,就可以拼接成一个以 n u m s [ i ] nums[i] nums[i] 为最高点的山形状数组,长度为 L = p r e [ i ] + s u f [ i ] − 1 L=pre[i]+suf[i]−1 L=pre[i]+suf[i]1,需要的删除次数为 n − L n−L nL

下面给出的代码使用了 上文提到的 最长递增子序列 问题的代码, 并将其中的代码封装成函数 g e t L I S A r r a y getLISArray getLISArray,用于求解所有的 p r e [ i ] pre[i] pre[i] ,并枚举 i i i 以得出最终的答案。

实现代码(Python)

class Solution:def minimumMountainRemovals(self, nums: List[int]) -> int:pre = self.getLISArray(nums)suf = self.getLISArray(nums[::-1])[::-1]ans = 0for pre_i, suf_i in zip(pre, suf):if pre_i > 1 and suf_i > 1:ans = max(ans, pre_i + suf_i - 1)return len(nums) - ansdef getLISArray(self, nums: List[int]) -> List[int]:n = len(nums)dp = [1] * nfor i in range(n):for j in range(i):if nums[j] < nums[i]:dp[i] = max(dp[i], dp[j] + 1)return dp
复杂度分析:
  • 时间复杂度: O ( n 2 ) O(n^2) O(n2) ,其中 n n n 是数组 n u m s nums nums 的长度。
  • 空间复杂度: O ( n ) O(n) O(n)

题记:


  • 研究生在读,我会尽量保持LeetCode每日一题的思路和代码输出。希望大家多多支持。
  • 水平有限,希望各位大佬能够批评指正。您的教诲是我进步的船帆。
  • 希望各位跟我一样的小白能跟我一起参与到做题和讨论中来。共同进步是我所能期盼的最高愿想。
  • 您的点赞和关注是我坚持分享的动力泉源,希望能将这件简单平凡的事一直做下去。感谢大家。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/240405.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Google推出Gemini AI开发——10年工作经验的Android开发要被2年工作经验的淘汰了?

应用程序中利用 Gemini 前言&#xff08;可略过&#xff09;、使用 Gemini Pro 开发应用程序正文、Android Studio 中构建Gemini API Starter 应用第 1 步&#xff1a;在 AI 的新项目模板的基础上进行构建第 2 步&#xff1a;生成 API 密钥第 3 步&#xff1a;开始原型设计 正文…

Mybatis之增删改查

目录 一、引言 二、Mybatis——增 举例&#xff1a;添加用户 三、Mybatis——删 举例&#xff1a;删除用户 四、Mybatis——改 举例&#xff1a;修改用户 五、Mybatis——查 六、注意 END&#xff1a; 一、引言 书接上回&#xff0c;我们在了解完mybatis之后&#xff0c;肯…

STM32F4 HAL流水灯Proteus仿真

源码下载&#xff1a;https://download.csdn.net/download/zlkk00/88654405

CSS基础小练习

<!DOCTYPE html> <html><head><meta charset"UTF-8"><title>圣诞节快乐</title><style>/*设置背景色*/body{background-image:linear-gradient(green 50%,red 50%);background-size:100% 30px;}/*让div在页面居中*/#text{…

ubuntu 18/20/22 安装 mysql 数据库

这里写自定义目录标题 ubuntu 18/20/22 安装 mysql 数据库1. 准备2. 安装 mysql3. 配置4. 测试 demo 用户5 服务管理5.1 查看服务状态5.2 启动服务5.3 停止服务5.4 重启服务 ubuntu 18/20/22 安装 mysql 数据库 1. 准备 安装前需要知道 root 用户的密码 假如不知道 root 用户…

20231223使用Rockchip原厂的Android11调通Firefly的AIO-3399J开发板上的AP6356S

20231223使用Rockchip原厂的Android11调通Firefly的AIO-3399J开发板上的AP6356S 2023/12/23 14:14 开发板&#xff1a;Firefly的AIO-3399J【RK3399】 SDK&#xff1a;rk3399-android-11-r20211216.tar.xz【Android11】 Android11.0.tar.bz2.aa【ToyBrick】 Android11.0.tar.bz2…

C# Onnx yolov8n csgo player detection

目录 效果 模型信息 项目 代码 下载 C# Onnx yolov8n csgo player detection 效果 模型信息 Model Properties ------------------------- date&#xff1a;2023-12-22T15:01:08.014205 author&#xff1a;Ultralytics task&#xff1a;detect license&#xff1a;AGPL-…

学会这套Pytest接口自动化测试框架,击败99%的人

Pytest 的下载安装 1、Python3 使用 pip install -U pytest 安装 2、查看 pytest 版本信息 pytest --version 3、pytest 用例的执行规则&#xff1a; ①测试文件以 test_xx.py 命名需要以 test_开头&#xff08;或_test 结尾&#xff09; ②测试类以 Test_开头&#xff0…

QtRO(Qt Remote Objects)分布式对象远程通信

一、什么是QtRO Qt Remote Objects&#xff08;QRO&#xff09;是Qt提供的一种用于实现远程对象通信的机制。 QtRO支持两种类型的通信&#xff1a;RPC&#xff08;远程过程调用&#xff09;和LPC&#xff08;本地进程通信&#xff09;。 RPC&#xff08;远程过程调用&#xf…

智能优化算法应用:基于骑手优化算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于骑手优化算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于骑手优化算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.骑手优化算法4.实验参数设定5.算法结果6.…

跨平台应用程序开发软件,携RAD Studio 12新版上线

RAD Studio 是一款专为程序员而准备的跨平台应用程序开发软件&#xff0c;内置Delphi和CBuilder这两种开发工具&#xff0c;另外还提供了新的C功能&#xff0c;扩展了对ExtJS的RAD服务器支持&#xff0c;增强了对vcL的高dpi支持&#xff0c;提高了firemonk (FMX)的质量等等&…

C++结合OpenCV:掌握图像基础与处理

本文详细介绍了使用 OpenCV4 进行图像处理的基础知识和操作。内容包括图像的基础概念、色彩空间理解、以及如何在 C 中进行图像读取、显示和基础操作。 1.图像的基本概念与术语 图像表示 在计算机视觉中&#xff0c;图像通常表示为一个二维或三维的数组。二维数组表示灰度图像&…

vue3.0 通用管理页面封装

bmTable使用方法 <BmTable url"/project/list":columns"columns":formItem"formItem":formConfig"formConfig":isPagination"true"postData"postData"preData"preData"ref"bmTable">&…

[SQL]实验 视图和索引的应用

实验目的&#xff1a; [实验目的和要求] 1、掌握视图的创建、修改和重命名的方法 2、掌握视图中数据的操作 3、了解索引的作用 4、掌握索引的创建方法 实验步骤&#xff1a; 1、在销售管理数据库中&#xff0c;创建一个女职工视图&#xff0c;包括员工的编号、姓名、性别、雇佣…

JavaScript 数组去重 ES6 方法总结

JavaScript 数组去重 ES6 方法 方法一 new Set()生成出来的数据是Set数据结构&#xff0c;需要自行转换成对应结构 let array [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 2, 3, 3, 3, 9, 8, 9, s, o, o]; Array.from(new Set(array));方法二 let array [0, 1, 2, 3, 4, 5, 6, 7, 8,…

网站怎么才能做好SEO?网站SEO指引!!

在当今互联网的激烈竞争中&#xff0c;SEO&#xff08;搜索引擎优化&#xff09;已成为提升网站流量和吸引更多用户的关键手段。为了帮助您更好地掌握SEO网站优化技巧&#xff0c;本文将深入探讨以下几个方面&#xff1a; 一、关键词策略 关键词策略是SEO优化的基石。正确选择…

【WPF.NET开发】创建样式

本文内容 创建样式隐式应用样式显式应用样式以编程方式应用样式扩展样式TargetType 属性与 x:Key 属性之间的关系 使用 Windows Presentation Foundation (WPF)&#xff0c;可以使用自己的可重用样式自定义现有控件的外观。 可以对应用、窗口和页面全局应用样式&#xff0c;也…

linux同步文件到百度云盘

背景 由于个人项目预算有限&#xff0c;把mysql和应用程序都跑在同一台阿里云ECS机器上面&#xff0c;就在昨天(2023年12月21日) &#xff0c;服务器突然出现问题 进程全部挂掉了&#xff0c;服务器也无法重启&#xff0c;找工程师排查后发现是系统磁盘挂载出现了问题&#xf…

Ansible的脚本---Playbook剧本编写

playbook的组成部分 1、 tasks&#xff1a;任务 在目标主机上需要执行的操作。使用模块定义这些操作。每个任务都是一个模块的调用。 2、 variables&#xff1a;变量 用于存储和传递数据。类似于shell脚本中的变量。变量可以自定义。可以在playbook当中定义为全局变量&…

基于Vite+Vue3 给项目引入Axios

基于ViteVue3 给项目引入Axios,方便与后端进行通信。 系列文章指路&#x1f449; 系列文章-基于Vue3创建前端项目并引入、配置常用的库和工具类 文章目录 安装依赖新建src/config/config.js 用于存放常用配置进行简单封装解决跨域问题调用尝试 安装依赖 npm install axios …