【二分算法】1187:使数组严格递增

【二分算法】1187:使数组严格递增给你两个整数数组 arr1 和 arr2 返回使 arr1 严格递增所需要的最小 操作 数 可能为 0

大家好,欢迎来到IT知识分享网。

涉及知识点

动态规划 二分查找

LeetCode1187:使数组严格递增

分析

时间复杂度

O(nnlogn)。两层循环,第一层枚举结尾O(n),第二层枚举前值O(n),寻找第一个大于nums[i]的值O(logn)。

注意

arr2中的值可以重复取,所以arr2中重复的值可以删除。直接用有序集合记录就可以了。dp和pre的key都是记录前值,value记录操作次数。如果preValue0<=preValue1且iNum0<=iNum1,那preValue1被淘汰。能选择preValue1则一定能选择preValue0,而iNum0更小。淘汰后,dp和pre的key是升序,value是降序。

处理思路

对于每个前值(前一个元素的值),有两种操作方式:

如果前者<当前值 不替换
setHas中存在大于前值的数 用符合条件的最小值替换

代码

核心代码

class Solution { 
    public: int makeArrayIncreasing(vector<int>& arr1, vector<int>& arr2) { 
    std::set<int> setHas(arr2.begin(), arr2.end()); auto Add = [](map<int, int>&dp,int iValue, int iNum) { 
    //如果iValue和iNum都大,则被淘汰。淘汰后,iVaule升序,iNum降序 auto it = dp.upper_bound(iValue); if ((dp.begin() != it) && (std::prev(it)->second <= iNum)) { 
    return;//被淘汰 } auto ij = it; for (; (dp.end() != ij) && (ij->second >= iNum); ++ij); dp.erase(it, ij); dp[iValue] = iNum; }; map<int, int> pre; Add(pre, arr1.front(), 0); Add(pre, *setHas.begin(), 1); for (int i = 1; i < arr1.size(); i++) { 
    map<int, int> dp; for (const auto& [preValue, iNum] : pre) { 
    if (preValue < arr1[i]) { 
    //不换 Add(dp,arr1[i], iNum); } auto it = setHas.upper_bound(preValue); if (setHas.end()!= it ) { 
    //换 Add(dp,*it, iNum + 1); } } dp.swap(pre); } return pre.empty() ? -1 : pre.rbegin()->second; } }; 

测试用例

//CConsole::Out(res); 

}

优化

Add(pre, -1, 0); for (int i = 0; i < arr1.size(); i++) 

2023年1月旧版

扩展阅读

视频课程

如何你想快

相关下载

洒家想对大家说的话
闻缺陷则喜是一个美好的愿望,早发现问题,早修改问题,给老板节约钱。
墨家名称的来源:有所得以墨记之。
如果程序是一条龙,那算法就是他的是睛

测试环境

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

VS2022 C++17

【二分算法】1187:使数组严格递增

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/134379.html

(0)
上一篇 2025-07-12 19:45
下一篇 2025-07-12 20:10

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信