【动态规划】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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

ReactJS和VueJS的简介以及它们之间的区别

本文主要介绍ReactJS和VueJS的简介以及它们之间的区别。 目录 ReactJS简介ReactJS的优缺点ReactJS的应用场景VueJS简介VueJS的优缺点VueJS的应用场景ReactJS和VueJS的区别 ReactJS简介 ReactJS是一个由Facebook开发的基于JavaScript的前端框架。它是一个用于构建用户界面的库&…

windows建立软链 报 无法将“mklink”项识别为 cmdlet、函数、脚本文件或可运行程序的名称

当我执行网上提供的mklink 的时候&#xff0c;出现 mklink : 无法将“mklink”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。怎么回事&#xff0c;原来&#xff0c;要在执行的签名加 cmd /c 当我执行建立软链接时&#xff0c;提示 没有足够的权限&#xff0c;要用管理…

pytest使用allure测试报告

最近通过群友了解到了allure这个报告&#xff0c;开始还不以为然&#xff0c;但还是逃不过真香定律。 经过试用之后&#xff0c;发现这个报告真的很好&#xff0c;很适合自动化测试结果的展示。下面说说我的探索历程吧。 选用的项目为Selenium自动化测试Pytest框架实战&#…

物料做出库的时候提交,提示 【即时成本为0】

【财务会计】——【出库核算】——【材料出库核算】

HarmonyOS学习--TypeScript语言学习(二)

本章目录如下&#xff1a; 一、基础类型 二、运算符 三、变量声明 四、类型断言 五、类型推断 TypeScript支持一些基础的数据类型&#xff0c;如布尔型、数组、字符串等&#xff0c;下文举例几个较为常用的数据类型&#xff0c;我们来了解下他们的基本使用。 关于let 我们…

MYSQL数据库中运行SQL文件报错

报错显示 当使用mysql数据库运行SQL文件报错时 [Err] 1273 - Unknown collation: utf8mb4_0900_ai_ci 报错原因 版本高低问题&#xff0c;一个是5.7版本&#xff0c;一个是8.0版本生成转储文件的数据库版本为8.0,要导入sql文件的数据库版本为5.7,因为是高版本导入到低版本&a…

首次超越1000量子比特大关!量子前哨详解IBM突破性进展

&#xff08;图片来源&#xff1a;网络&#xff09; 本周&#xff0c;IBM在其年度量子峰会上宣布&#xff0c;公司已在量子计算领域取得重要突破。其中包括备受期待的1121量子比特Condor QPU&#xff0c;以及一个较小的133量子比特Heron QPU&#xff0c;这些QPU能够与其他QPU组…

0-1背包问题

二维版: import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader;public class Main {static int N 1010;static int[][] dp new int[N][N]; //dp[i][j] 只选前i件物品,体积 < j的最优解static int[] w new int[N]; //存储价…

Unity渲染Stats分析

文章目录 前言一、Stats二、我们主要看渲染状态分析1、FPS2、其他状态信息3、DrawCall4、Batch5、Setpass Call6、在Unity中弱化了DrawCall的概念&#xff0c;我们主要看 Batch 和 Setpass Call 三、使用 Batching&#xff08;合批&#xff09; 降低 Batch &#xff08;渲染批次…

【C++】:set和map

朋友们、伙计们&#xff0c;我们又见面了&#xff0c;本期来给大家解读一下有关多态的知识点&#xff0c;如果看完之后对你有一定的启发&#xff0c;那么请留下你的三连&#xff0c;祝大家心想事成&#xff01; C 语 言 专 栏&#xff1a;C语言&#xff1a;从入门到精通 数据结…

k8s 安装部署

一&#xff0c;准备3台机器&#xff0c;安装docker&#xff0c;kubelet、kubeadm、kubectl firewall-cmd --state 使用下面命令改hostname的值&#xff1a;(改为k8s-master01)另外两台改为相应的名字。 172.188.32.43 hostnamectl set-hostname k8s-master01 172.188.32.4…

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

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

PWM控制器电路D9741,定时闩锁、短路保护电路,输出基准电压(2.5V) 采用SOP16封装形式

D9741是一块脉宽调制方三用于也收路像机和笔记本电的等设备上的直流转换器。在便携式的仪器设备上。 主要特点&#xff1a;● 高精度基准电路 ● 定时闩锁、短路保护电路 ● 低电压输入时误操作保护电路 ● 输出基准电…

2023年美赛获奖结果分析(附中英文版赛题)

023年美国大学生数学建模竞赛&#xff08;MCM/ICM&#xff09;成绩已经公布&#xff0c;现在就请跟随着忠哥一起通过Python 进行大数据分析吧&#xff01; 美赛成绩分析 2023年美国大学生数学建模竞赛MCM参赛队伍总数为11296支&#xff0c;ICM参赛队伍总数为9562支&#xff0…

智慧校园:TSINGSEE青犀智能视频监控系统,AI助力优化校园管理

随着科技的飞速发展和信息化社会的到来&#xff0c;智慧校园已经成为教育领域的一种新型发展模式。智慧校园的需求和发展趋势日益显现&#xff0c;其建设已成为当今教育信息化发展的重要方向。 TSINGSEE青犀结合高可靠、高性能的云计算、人工智能、大数据、物联网等技术&#…

css实现最简单的3d透视效果,通过旋转可以直观感受到

css的3d效果还是非常复杂的&#xff0c;我今天简单学习了一下入门&#xff0c;实现了一个超级简单的效果&#xff0c;帮助我自己理解这个3d的过程&#xff0c;实现的效果动画如下&#xff1a;可以通过调整父元素旋转的角度&#xff0c;更加直观的感受这个3d效果&#xff1a; 实…

Android中在google Map 上绘制历史路径

很多的App都会有这种需求&#xff0c;需要把自己的轨迹绘制在地图上来加标一段行踪&#xff0c;使得自己的行程展现出来&#xff0c;通过地图的展示&#xff0c;自己的行程也就一目了然了。 这里利用Google Map 把自己的行程展现出来&#xff0c;注意这里用到了上一章的基础&a…

男士化妆品市场分析:全球市场规模将达到786亿美元

男士化妆品是针对男性肤质特点而研制的化妆品。男士化妆护肤品基本上集中在洗发水、香水、须后水、剃须膏、洁面乳、面霜、爽肤水以及润唇膏几类,。男性和女性化妆品 需求的发展都历经了3个阶段&#xff1a;清洁、护理和美容。中国市场上男士护理品在过去很长一段时期都集中在基…

java封装类Number

1、概念 在实际开发过程中&#xff0c;我们经常会遇到需要使用对象&#xff0c;而不是内置数据类型的情形。为了解决这个问题&#xff0c;Java 语言为每一个内置数据类型提供了对应的包装类。 所有的包装类&#xff08;Integer、Long、Byte、Double、Float、Short&…

1. Appflowy 之 Bloc和freezed,理解Bloc和模式匹配

Talk is cheap, Show me the code Bloc是什么&#xff1f; Bloc 全称Business Logic Component, 核心思想是将界面和业务逻辑分离&#xff0c;并通过单项数据流的方式来管理状态。 Flutter 提供了StatelessWidget 处理无状态的UI&#xff0c;StatefulWidget处理有状态的数据&…