【动态规划】LeetCode2111:使数组 K 递增的最少操作次数

作者推荐

[二分查找]LeetCode2040:两个有序数组的第 K 小乘积

本文涉及的基础知识点

二分查找算法合集
分组 动态规划

题目

给你一个下标从 0 开始包含 n 个正整数的数组 arr ,和一个正整数 k 。
如果对于每个满足 k <= i <= n-1 的下标 i ,都有 arr[i-k] <= arr[i] ,那么我们称 arr 是 K 递增 的。
比方说,arr = [4, 1, 5, 2, 6, 2] 对于 k = 2 是 K 递增的,因为:
arr[0] <= arr[2] (4 <= 5)
arr[1] <= arr[3] (1 <= 2)
arr[2] <= arr[4] (5 <= 6)
arr[3] <= arr[5] (2 <= 2)
但是,相同的数组 arr 对于 k = 1 不是 K 递增的(因为 arr[0] > arr[1]),对于 k = 3 也不是 K 递增的(因为 arr[0] > arr[3] )。
每一次 操作 中,你可以选择一个下标 i 并将 arr[i] 改成任意 正整数。
请你返回对于给定的 k ,使数组变成 K 递增的 最少操作次数 。
示例 1:
输入:arr = [5,4,3,2,1], k = 1
输出:4
解释:
对于 k = 1 ,数组最终必须变成非递减的。
可行的 K 递增结果数组为 [5,6,7,8,9],[1,1,1,1,1],[2,2,3,4,4] 。它们都需要 4 次操作。
次优解是将数组变成比方说 [6,7,8,9,10] ,因为需要 5 次操作。
显然我们无法使用少于 4 次操作将数组变成 K 递增的。
示例 2:
输入:arr = [4,1,5,2,6,2], k = 2
输出:0
解释:
这是题目描述中的例子。
对于每个满足 2 <= i <= 5 的下标 i ,有 arr[i-2] <= arr[i] 。
由于给定数组已经是 K 递增的,我们不需要进行任何操作。
示例 3:
输入:arr = [4,1,5,2,6,2], k = 3
输出:2
解释:
下标 3 和 5 是仅有的 3 <= i <= 5 且不满足 arr[i-3] <= arr[i] 的下标。
将数组变成 K 递增的方法之一是将 arr[3] 变为 4 ,且将 arr[5] 变成 5 。
数组变为 [4,1,5,4,6,5] 。
可能有其他方法将数组变为 K 递增的,但没有任何一种方法需要的操作次数小于 2 次。
提示:
1 <= arr.length <= 105
1 <= arr[i], k <= arr.length

分析

时间复杂度

O(nlogn),枚举每个元素,时间复杂度O(n),每个元素二分查找O(logn)。

代码

原理

一,有多少对不符合递增,则至少需要多少次操作。arr[i]和arr[i+1]不符合,需要修改arr[i]或arr[i+1]。能否一次修改,同时解决两个数对,假定arr[i-1] > arr[i] > arr[i+1],由于arr[i-1]>arr[i+1],所以arr[i]无论如何都不可能大于等于arr[i-1],同时小于等于arr[i+1]。
二,需要的操作数,可能大于非递增的对数。比如:4 1 3 ,4 1非递增,1 3递增。
三,操作次数等于=总元素数-最长递增序列的长度。假定最长子系列为:newNew[0]…newNew[n]。
四,第三只能说明是一个解,现在来证明是最优解: 假定arr2最优解,删掉修改过的元素,那么它一定是arr的子序列,且是递增的。此子系列越长,删除(操作)的元素越少。

newNew[0]之前的元素全部改成newNew[0]
newNew[n]之后的元素全部改成newNew[n]
newNew[i]和newNew[i+1]的元素全改成newNew[i]

变量解释

vLenMinEndvLenMinEnd[i]=x,在长度为i的子序列中,结尾的最小值为x

核心代码

class Solution {
public:int kIncreasing(vector<int>& arr, int k) {int iMaxLen = 0;for (int i = 0; i < k; i++){vector<int> vLenMinEnd = { 0,arr[i] };for (int j = i + k; j < arr.size(); j += k){auto index = std::upper_bound(vLenMinEnd.begin(), vLenMinEnd.end(), arr[j])- vLenMinEnd.begin();if (index >= vLenMinEnd.size()){vLenMinEnd.emplace_back(arr[j]);continue;}vLenMinEnd[index] = min(vLenMinEnd[index], arr[j]);		}iMaxLen += vLenMinEnd.size() - 1;}return arr.size()-iMaxLen;}
};

测试用例

template
void Assert(const vector& v1, const vector& v2)
{
if (v1.size() != v2.size())
{
assert(false);
return;
}
for (int i = 0; i < v1.size(); i++)
{
assert(v1[i] == v2[i]);
}
}

template
void Assert(const T& t1, const T& t2)
{
assert(t1 == t2);
}

int main()
{
vector arr;
int k, res;
{
Solution slu;
arr = { 12, 6, 12, 6, 14, 2, 13, 17, 3, 8, 11, 7, 4, 11, 18, 8, 8, 3 }, k = 1;
auto res = slu.kIncreasing(arr, k);
Assert(12, res);
}
{
Solution slu;
arr = { 5, 4, 3, 2, 1 }, k = 1;
auto res = slu.kIncreasing(arr,k);
Assert(4, res);
}
{
Solution slu;
arr = { 4,1,5,2,6,2 }, k = 2;
auto res = slu.kIncreasing(arr, k);
Assert(0, res);
}
{
Solution slu;
arr = { 4,1,5,2,6,2 }, k = 3;
auto res = slu.kIncreasing(arr, k);
Assert(2, res);
}

//CConsole::Out(res);

}

2023年9月旧代码

class Solution {
public:
int kIncreasing(vector& arr, int k) {
vector<vector> vSubArr(k);
for (int i = 0; i < arr.size(); i++)
{
vSubArr[i%k].push_back(arr[i]);
}
int iRet = 0;
for ( auto& v : vSubArr)
{
iRet += NeedChange(v, 0, v.size() );
}
return iRet;
}
int NeedChange(vector& arr,int iLeft,int iRight)
{
std::map<int, int> mValueNums;
for (const auto& a : arr)
{
auto it = mValueNums.upper_bound(a);
auto itTmp = it;
const int iValue = ((mValueNums.begin() == it) ? 0 : (–itTmp)->second) + 1;
if ((mValueNums.end() != it) && (it->second <= iValue))
{
mValueNums.erase(it);
}
mValueNums[a] = iValue;
}
return arr.size() - mValueNums.rbegin()->second;
}
int m_iK;
};

2023年9月第一版

class Solution {
public:
int kIncreasing(vector& arr, int k) {
int iRet = 0;
for (int turn = 0; turn < k; turn++)
{
std::map<int, int> mEndLen;
mEndLen[0] = 0;
int iMaxLen = 0;
for (int index = turn; index < arr.size(); index += k)
{
auto it = mEndLen.upper_bound(arr[index]);
const int iLen = std::prev(it)->second+1;
it = mEndLen.lower_bound(arr[index]);
auto ij = it;
for (; (ij != mEndLen.end()) && (ij->second <= iLen); ij++);
mEndLen.erase(it, ij);
mEndLen[arr[index]] = iLen;
iMaxLen = max(iMaxLen, iLen);
}
iRet += iMaxLen;
}
return arr.size()- iRet;
}
};

2023年9月第二版

class Solution {
public:
int kIncreasing(vector& arr, int k) {
int iRet = 0;
for (int turn = 0; turn < k; turn++)
{
vector vValue;
for (int index = turn; index < arr.size(); index += k)
{
auto it = std::upper_bound(vValue.begin(), vValue.end(),arr[index]);
if (vValue.end() == it)
{
vValue.emplace_back(arr[index]);
}
else
{
*it = arr[index];
}
}
iRet += vValue.size();
}
return arr.size()- iRet;
}
};

扩展阅读

视频课程

有效学习:明确的目标 及时的反馈 拉伸区(难度合适),可以先学简单的课程,请移步CSDN学院,听白银讲师(也就是鄙人)的讲解。
https://edu.csdn.net/course/detail/38771

如何你想快

速形成战斗了,为老板分忧,请学习C#入职培训、C++入职培训等课程
https://edu.csdn.net/lecturer/6176

相关下载

想高屋建瓴的学习算法,请下载《喜缺全书算法册》doc版
https://download.csdn.net/download/he_zhidan/88348653

我想对大家说的话
闻缺陷则喜是一个美好的愿望,早发现问题,早修改问题,给老板节约钱。
子墨子言之:事无终始,无务多业

。也就是我们常说的专业的人做专业的事。 |
|如果程序是一条龙,那算法就是他的是睛|

测试环境

操作系统:win7 开发环境: VS2019 C++17
或者 操作系统:win10 开发环境:

VS2022 C++17

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

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

相关文章

Qt + MySQL(简单的增删改查)

Qt编译MySql插件教程 QSqlDatabase 静态函数 1.drivers()&#xff0c;得到可以使用的数据库驱动名字的集合 [static] QStringList QSqlDatabase::drivers();2.addDatabase()&#xff0c;添加一个数据库实例 [static] QSqlDatabase QSqlDatabase::addDatabase(const QStrin…

ROS小练习——话题发布

目录 一、话题与消息获取 1、话题 2、消息 二、代码编写 1、C 2、python 三、编译运行 一、话题与消息获取 打开小乌龟案例 1、话题 rqt_graph rostopic list 2、消息 获取消息类型: rostopic type /turtle1/cmd_vel 获取消息格式: rosmsg info geometry_msgs/Twi…

PieCloudDB Database 自研全新向量化执行器,带来性能的数量级提升

数据分析和应用的重要性日益增长&#xff0c;对于数据平台和数据计算系统来说&#xff0c;极致的性能是关键需求之一。为实现更高效的数据并行计算&#xff0c;一款优秀的执行器需要能够充分利用硬件资源&#xff0c;如 CPU 的并行计算能力和 SIMD 指令集。此外&#xff0c;优化…

【用unity实现100个游戏之18】从零开始制作一个类CSGO/CS2、CF第一人称FPS射击游戏——基础篇1(附项目源码)

文章目录 本节最终效果前言搭建环境玩家移动控制摄像机跟随和视角人物奔跑实现跳跃斜坡顿挫感人物卡墙问题源码完结 本节最终效果 前言 生存和射击游戏一直是我的最爱&#xff0c;说起3D最普遍的应该就是射击系统了&#xff0c;你可以在任何情况下加入射击功能&#xff0c;所以…

软件工程之架构设计

从公众号转载&#xff0c;关注微信公众号掌握更多技术动态 --------------------------------------------------------------- 一、架构设计的目的 1.什么是复杂的软件项目 复杂的软件项目通常有两个特点&#xff1a; 需求不确定 技术复杂 技术的复杂性主要体现在四个方面…

Ubuntu防止休眠和挂起(笔记)

目录 1 动机2 禁用休眠3 解除休眠 1 动机 我要将 饿啊人制作成 noah-mp 的区域运行强迫&#xff0c;但是跑的慢&#xff0c;一晚上两天。后来发现是因为电脑自动 supend 了。Ubuntu 在电源那里最多只能设置 2 小时的防止休眠&#xff0c;2小时候又自动休眠&#xff0c;严重影响…

论在武汉考一个安全员B证能有多难?谁曾想

论在武汉考一个安全员B证能有多难&#xff1f;谁曾想 在武汉考一个安全员B证的考试难度&#xff0c;硬考&#xff08;自己练习系统题库备考&#xff09;还是有一定难度的。毕竟考试范围比较宽泛&#xff0c;里边涉及日常工作内容、法规知识、建筑管理知识等等。即使你考过了二…

AOP记录操作日志

创建数据库表 -- 操作日志 create table operate_log (id int unsigned primary key auto_increment commentid,operate_user int unsigned comment 操作人员Id,operate_time datetime comment 操作时间,class_name varchar(100)comment 操作类,method_name varchar(100)comme…

鸿蒙4.0开发笔记之ArkTS语法基础的UI描述、基础组件的使用与如何查看组件是否有参数(八)

文章目录 一、声明式UI描述1、无/有参数组件2、如何查看组件是否有参数 二、Image组件的使用三、组件的属性设置四、补充1、使用组件的成员函数配置组件的事件方法2、配置子组件3、多组件嵌套 一、声明式UI描述 在HarmonyOS的ArkTS语法中&#xff0c;万物皆组件。ArkTS以声明方…

【Verilog】 FPGA程序设计---Verilog基础知识

目录 Verilog 和 VHDL 区别 Verilog 和 C 的区别 Verilog 基础知识 1 Verilog 的逻辑值 2 Verilog 的标识符 3 Verilog 的数字进制格式 4 Verilog 的数据类型 1) 寄存器类型 2) 线网类型 3) 参数类型 5 Verilog 的运算符 1) 算术运算符 2) 关系运算…

数据结构之选择排序

目录 直接选择排序 选择排序的时间复杂度 堆排序 向上调整算法 向下调整算法 向上调整算法建立堆 向下调整算法建立堆 堆排序整体代码 堆排序的时间复杂度 直接选择排序 在之前讲插入排序时&#xff0c;我们讲了这样的一个应用场景&#xff0c;我们在斗地主摸牌时&…

国产智能运维操作系统新选择-浪潮KeyarchOS

1.背景 在CentOS停更&#xff0c;国有企业纷纷摒弃原有的开发与运维工具&#xff0c;全面拥抱国产。我司也顺应号召&#xff0c;更换原有CentOS系统。 在新系统选型上&#xff0c;我司有以下要求&#xff1a; 国产、快速更新迭代、社区活跃&#xff1b;拥有一定知名度&#x…

保障海外业务发展,Coremail提供高效安全的海外通邮服务

11月22日&#xff0c;Coremail举办《全球通邮&#xff1a;如何保障安全、快捷的海外中继服务》直播分享会&#xff0c;直播会上Coremail安全团队和直播嘉宾复旦大学校园信息化办公室徐艺扬老师就海外中继服务进行了深度分享。 ​ 海外通邮困难重重 境外垃圾邮件数量居高不下…

echarts中option个参数的含义

var option {title: {text: ECharts 入门示例},tooltip: {},legend: {data: [数量]},xAxis: {data: [衬衫, 羊毛衫, 雪纺衫, 裤子, 高跟鞋, 袜子]},yAxis: {},series: [{name: 数量,type: bar,data: [5, 20, 36, 10, 10, 20]}] }; title&#xff1a;主要控制图表的标题 legen…

语义分割 LR-ASPP网络学习笔记 (附代码)

论文地址&#xff1a;https://arxiv.org/abs/1905.02244 代码地址&#xff1a;https://github.com/WZMIAOMIAO/deep-learning-for-image-processing/tree/master/pytorch_segmentation/lraspp 1.是什么&#xff1f; LR-ASPP是一个轻量级语义分割网络&#xff0c;它是在Mobil…

【ESP8266】ESP8266集成开发环境对比

当涉及到ESP8266开发环境的选择时&#xff0c;有几个常见的选择可供开发人员使用。在本篇文章中&#xff0c;我们将对比一些目前最流行的ESP8266集成开发环境&#xff08;IDE&#xff09;&#xff0c;以帮助您选择最适合您的需求的开发环境。 总结&#xff1a;Arduino IDE和Pl…

HarmonyOS应用开发——页面

我们将对于多页面以及更多有趣的功能展开叙述&#xff0c;这次我们对于 HarmonyOS 的很多有趣常用组件并引出一些其他概念以及解决方案、页面跳转传值、生命周期、启动模式&#xff08;UiAbility&#xff09;&#xff0c;样式的书写、状态管理以及动画等方面进行探讨 页面之间…

项目进度已经落后了,项目经理该怎么办?

进度管理是项目管理的核心工作之一&#xff0c;通过可续的进度计划与控制管理&#xff0c;最终实现项目按照目标交付。 进度管理的两大核心工作&#xff1a;计划制定、过程管控。 项目管理过程中难免会遇到工作进度和计划不一致的情况&#xff0c;有效管理项目进度&#xff…

Redis安装和使用(基于windows)

Redis是一个使用C语言编写的开源、高性能、非关系型的键值对存储数据库。它支持多种数据结构&#xff0c;包括字符串、列表、集合、有序集合、哈希表等。Redis的内存操作能力极强&#xff0c;其读写性能非常优秀&#xff0c;且支持持久化&#xff0c;可以将数据存储到磁盘上&am…

使用 React 和 ECharts 创建地球模拟扩散和飞线效果

在本博客中&#xff0c;我们将学习如何使用 React 和 ECharts 创建一个酷炫的地球模拟扩散效果。我们将使用 ECharts 作为可视化库&#xff0c;以及 React 来构建我们的应用。地球贴图在文章的结尾。 最终效果 准备工作 首先&#xff0c;确保你已经安装了 React&#xff0c;并…