leetcode 1187. Make Array Strictly Increasing

探讨了如何通过最少的操作使两个整数数组中的第一个数组变为严格递增序列的问题。在一次操作中,可以选择两个数组的任意元素进行替换。文章详细解析了算法思路,包括使用vector和map来记录修改次数及修改后的最大值,以及如何遍历和更新这些值以找到最少的操作次数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Given two integer arrays arr1 and arr2, return the minimum number of operations (possibly zero) needed to make arr1 strictly increasing.

In one operation, you can choose two indices 0 <= i < arr1.length and 0 <= j < arr2.length and do the assignment arr1[i] = arr2[j].

If there is no way to make arr1 strictly increasing, return -1.

 

Example 1:

Input: arr1 = [1,5,3,6,7], arr2 = [1,3,2,4]
Output: 1
Explanation: Replace 5 with 2, then arr1 = [1, 2, 3, 6, 7].

Example 2:

Input: arr1 = [1,5,3,6,7], arr2 = [4,3,1]
Output: 2
Explanation: Replace 5 with 3 and then replace 3 with 4. arr1 = [1, 3, 4, 6, 7].

Example 3:

Input: arr1 = [1,5,3,6,7], arr2 = [1,6,3,3]
Output: -1
Explanation: You can't make arr1 strictly increasing.

 

Constraints:

  • 1 <= arr1.length, arr2.length <= 2000
  • 0 <= arr1[i], arr2[i] <= 10^9

解题思路:

对于arr1的第 i - 1 位,这位可以改,也可以不改。但是都要保证前i- 1位严格递增 ;

设置了一个vector<map<int,int>> cnt_max ;

cnt_max[i]中存的是<修改的次数 , 修改后的最大值> 。

第i位,遍历cnt_max[i - 1]中的每对元素

for(auto ele : cnt_max[i - 1])

{

         //不改

         if(arr1[i - 1] > ele.second) //可以不改;

         //要改

         auto it = arr2_num.upper_bound(ele.second) ;

         if(it != arr2_num.end())//在arr2_num中可以找到一个比ele.second大的数,可以改

}

如果cnt_max[i].empty(),就直接返回-1 ;

最后返回cnt_max[arr1.size()].begin()->first ;//这个是判断arr1[arr1.size()-1]位改还是不改后的最少修改次数 ;

class Solution {
public:
    int makeArrayIncreasing(vector<int>& arr1, vector<int>& arr2) 
    {
        int n1 = arr1.size() ;
        vector<map<int , int>> cnt_max(n1 + 1) ;
        cnt_max[0][0] = -1 ;
        set<int> arr2_num ;
        for(int i = 0 ; i < arr2.size() ; ++i)
            arr2_num.insert(arr2[i]) ;
        for(int i = 1 ; i <= n1 ; ++i)
        {
            for(auto ele : cnt_max[i - 1])
            {
                if(arr1[i - 1] > ele.second)
                {
                    if(cnt_max[i].count(ele.first))
                    {
                        cnt_max[i][ele.first] = min(cnt_max[i][ele.first] , arr1[i - 1]) ;
                    }
                    else
                    {
                        cnt_max[i][ele.first] = arr1[i - 1] ;
                    }
                }
                auto it = arr2_num.upper_bound(ele.second) ;
                if(it != arr2_num.end())
                {
                    if(cnt_max[i].count(ele.first + 1))
                    {
                        cnt_max[i][ele.first + 1] = min(cnt_max[i][ele.first + 1] , *it) ;
                    }
                    else
                    {
                        cnt_max[i][ele.first + 1] = *it ;
                    }
                }
            }
            if(cnt_max[i].empty()) return -1 ;
        }
        
        return cnt_max[n1].begin()->first ;
    }
};

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值