【动态规划-最长递增子序列(LIS)】【hard】力扣1671. 得到山形数组的最少删除次数

news2024/10/10 0:32:07

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

arr.length >= 3
存在某个下标 i (从 0 开始) 满足 0 < i < arr.length - 1 且:
arr[0] < arr[1] < … < arr[i - 1] < arr[i]
arr[i] > arr[i + 1] > … > arr[arr.length - 1]
给你整数数组 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] ,是山形数组。

在这里插入图片描述

二分查找

class Solution {
public:
    int minimumMountainRemovals(vector<int>& nums) {
        int n = nums.size();

        vector<int> lis(n, 1), lds(n, 1);

        vector<int> inc; 

        for (int i = 0; i < n; ++i) {
            auto it = lower_bound(inc.begin(), inc.end(), nums[i]);
            if (it == inc.end()) {
                inc.push_back(nums[i]);
            } else {
                *it = nums[i];
            }
            lis[i] = inc.size();
        }

        vector<int> dec; 

        // 计算从右到左的最长递减子序列 (LDS) 长度,使用二分查找
        for (int i = n - 1; i >= 0; --i) {
            auto it = lower_bound(dec.begin(), dec.end(), nums[i]);
            if (it == dec.end()) {
                dec.push_back(nums[i]);
            } else {
                *it = nums[i];
            }
            lds[i] = dec.size();
        }


        int minRemovals = n;
        for (int i = 1; i < n - 1; ++i) {
            if (lis[i] > 1 && lds[i] > 1) {
                // 山峰的长度是 lis[i] + lds[i] - 1
                minRemovals = min(minRemovals, n - (lis[i] + lds[i] - 1));
            }
        }

        return minRemovals;
    }
};

时间复杂度:O(nlogn),其中 n 是数组 nums 的长度。

空间复杂度:O(n)。

这道题的思路就是构建一个最长递增子序列LIS和最长递减子序列LDS。
开始,我们定义vector<int> lis(n, 1), lds(n, 1);来储存以nums[i]结尾的最长递增/递减子序列长度。

我们定义一个迭代器it,指向通过二分查找找到的inc数组中的大于等于nums[i]的元素。
需要注意是
由于 upper_bound 查找的是严格大于当前值的元素,它确保了序列是非严格递增的,即允许相同的元素出现在序列中。例如,如果当前序列为 1, 2, 3,新加入的元素也是 3,upper_bound 会找到序列末尾并在适当位置插入新的 3,从而维持非严格递增的性质。

而lower_bound查找的是大于等于nums[i]的元素,所以nums[i]如果有与inc中相等的元素,会替换而不是推入,这保证了最长递增子序列是严格递增的。

我们还定义了lis和lds来储存不同nums[i]结尾的最长递增。递减子序列的长度。我们遍历每个元素结尾的最长递增子序列和最长递减子序列的长度。·然后通过minRemovals来记录山峰数组的最少删除次数。

最后返回minRemovals。

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

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

相关文章

【hot100-java】二叉搜索树中第 K 小的元素

二叉树 二叉搜索树的中序遍历是递增序列。 /*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeNode right;* TreeNode() {}* TreeNode(int val) { this.val val; }* TreeNode(int val, TreeNode lef…

【C++】面向对象之继承

不要否定过去&#xff0c;也不要用过去牵扯未来。不是因为有希望才去努力&#xff0c;而是努力了&#xff0c;才能看到希望。&#x1f493;&#x1f493;&#x1f493; 目录 ✨说在前面 &#x1f34b;知识点一&#xff1a;继承的概念及定义 •&#x1f330;1.继承的概念 •&…

ECCV24高分论文:MVSplat稀疏视图下的高效的前馈三维重建模型

目录 一、概述 二、相关工作 1、稀疏视角场景重建 2、前馈NeRF 3、前馈3DGS 4、多视角立体视觉 三、MVSplat 1、多视角Transformer 一、概述 本文提出了一个MVSplat高效的前馈三维重建模型&#xff0c;可以从稀疏的多视图图像中预测3D高斯分布&#xff0c;并且相较于p…

三角形面积 python

题目&#xff1a; 计算三角形面积 代码&#xff1a; a int(input("请输入三角形的第一个边长&#xff1a;")) b int(input("请输入三角形的第二个边长&#xff1a;")) c int(input("请输入三角形的第三个边长&#xff1a;")) s (abc) / 2 #…

我谈均值平滑模板——给均值平滑模板上升理论高度

均值平滑&#xff08;Mean Smoothing&#xff09;&#xff0c;也称为盒状滤波&#xff08;Box Filter&#xff09;&#xff0c;通过计算一个像素及其周围像素的平均值来替换该像素的原始值&#xff0c;从而达到平滑图像的效果。 均值平滑通常使用一个模板&#xff08;或称为卷…

ISCC认证是什么?ISCC认证的申请流程有哪些注意事项?

ISCC认证&#xff0c;即国际可持续发展与碳认证&#xff08;International Sustainability & Carbon Certification&#xff09;&#xff0c;是一个全球通用的可持续发展认证体系。以下是对ISCC认证的详细介绍&#xff1a; 一、起源与背景 ISCC认证体系起源于德国&#x…

如何使用pymysql和psycopg2执行SQL语句

在Python中&#xff0c;pymysql和psycopg2是两个非常流行的库&#xff0c;用于与MySQL和PostgreSQL数据库进行交互。本文将详细介绍如何使用这两个库来执行SQL查询、插入、更新和删除操作。 1. 准备工作 首先&#xff0c;确保已经安装了pymysql和psycopg2库。如果尚未安装&a…

Linux驱动---光电开关、火焰传感器、人体红外传感器

文章目录 一、电路连接二、设备树三、驱动代码 一、电路连接 人体红外 – PF12 检测到人体时会产生一个上升沿 光电开关 – PE15 有遮挡物时会产生一个上升沿 火焰传感器 – PF5 有火焰时会产生一个上升沿 二、设备树 /{ //人体红外PF12human{ compatible "zyx,huma…

电池大师 2.3.9 | 专业电池管理,延长寿命优化性能

Battery Guru 显示电池使用情况信息&#xff0c;测量电池容量&#xff08;mAh&#xff09;&#xff0c;并通过有用技巧帮助用户改变充电习惯&#xff0c;延长电池寿命。支持显示电池健康状况&#xff0c;优化电池性能。 大小&#xff1a;9.6M 百度网盘&#xff1a;https://pan…

数据库软题7-数据库设计

一、概念结构设计 题1-ER图的属性分类 题2-局部ER图的冲突分类 1.命名冲突 命名冲突有同名异义&#xff0c;异名同义2.结构冲突 结构冲突分为&#xff1a;统一实体不同属性&#xff0c;同一对象在不同关系里可能为属性或者实体 教师其实就是职工&#xff0c;他们有不同的属性…

基于Arduino的超声波测距模块HC-SR04

一. HC-SR04超声波模块简介 HC-SR04超声波模块是一种常用的测距模块&#xff0c;通过不断检测超声波发射后遇到障碍物所反射的回波&#xff0c;从而测出发射和接收回波的时间差&#xff0c;并据此求出距离。它主要由两个‌压电陶瓷超声传感器和一个外围信号处理电路构成&#…

重生之我在代码随想录刷算法第十九天 | 第77题. 组合、216.组合总和III、 17.电话号码的字母组合

参考文献链接&#xff1a;代码随想录 本人代码是Java版本的&#xff0c;如有别的版本需要请上代码随想录网站查看。 第77题. 组合 力扣题目链接 解题思路 这道题目乍一看可以用暴力解法解决&#xff0c;但如果k的数量增加那就需要套特别多的循环&#xff0c;所以这种组合类…

植物大战僵尸修改器-MFC

创建项目 创建mfc应用 基于对话框 打开资源视图下的 IDD_MFCAPPLICTION2_DIALOG 限制对话框大小 将属性中Border的值改为对话框外框 删除对话框中原有的控件 属性-外观-Caption 设置对话框标题 工具箱中拖放一个按钮 修改按钮名称 将按钮ID改为IDC_COURSE 在MFCApplication2…

django(二):定义第一个函数及url介绍

1.定义index函数 """ django里的第一个函数必须是request,不写会报错 """def index(request):return HttpResponse("Hello, world. Youre at the index of djangoProject.")注意&#xff01; ①.index函数里的形参必须为request ②.r…

STM32输入捕获模式详解(上篇):原理、测频法与测周法

1. 前言 在嵌入式系统的开发过程中&#xff0c;常常需要对外部信号进行精确的时间测量&#xff0c;如测量脉冲信号的周期、频率以及占空比等。STM32系列微控制器提供了丰富的定时器资源&#xff0c;其中的输入捕获&#xff08;Input Capture, IC&#xff09;模式能实现对信号的…

【测试】BUG篇——BUG

bug的概念 定义&#xff1a;⼀个计算机bug指在计算机程序中存在的⼀个错误(error)、缺陷(flaw)、疏忽(mistake)或者故障(fault)&#xff0c;这些bug使程序⽆法正确的运⾏。Bug产⽣于程序的源代码或者程序设计阶段的疏忽或者错误。 准确的来说&#xff1a; 当且仅当规格说明&am…

网站集群批量管理-Ansible(ad-hoc)

1. 概述 1. 自动化运维: 批量管理,批量分发,批量执行,维护 2. 无客户端,基于ssh进行管理与维护 2. 环境准备 环境主机ansible10.0.0.7(管理节点)nfs01 10.0.0.31(被管理节点)backup10.0.0.41(被管理节点) 2.1 创建密钥认证 安装sshpass yum install -y sshpass #!/bin/bash ##…

SpringBoot整合MyBatis记录

整体目录结构 创建数据库 创建一个MySQL的表&#xff0c;表名是student。 create table student (id int auto_increment comment 唯一标识idprimary key,name varchar(30) not null comment 姓名,age int not null comment 年龄 ) 插入一条数据记录到数据库当中去…

【数据结构与算法-高阶】并查集

【数据结构与算法-高阶】并查集 &#x1f955;个人主页&#xff1a;开敲&#x1f349; &#x1f525;所属专栏&#xff1a;数据结构与算法&#x1f345; &#x1f33c;文章目录&#x1f33c; 1. 并查集原理 2. 并查集实现 3. 并查集应用 1. 并查集原理 在一些应用问题中&…

Matlab|基于遗传粒子群算法的无人机路径规划【遗传算法|基本粒子群|遗传粒子群三种方法对比】

目录 主要内容 模型研究 部分代码 结果一览 下载链接 主要内容 为了更高效地完成复杂未知环境下的无人机快速探索任务&#xff0c;很多智能算法被应用于无人机路径规划方面的研究&#xff0c;但是传统粒子群算法存在粒子更新思路单一、随机性受限、收敛速度慢…