【leetcode】1187. Make Array Strictly Increasing

題目以下:spa

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

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].blog

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

Example 1:it

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

Example 2:io

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

Example 3:class

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

Constraints:im

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

解題思路:若是arr1[i]個元素須要交換的話,那麼必定是和arr2中大於arr1[i-1]的全部值中最小的那個交換。在這個前提下,能夠利用動態規劃的思想來解決這個問題。首先對arr2去重排序,記dp[i][j] = v 表示使得arr1在0~i區間遞增須要的最小交換次數爲v,而且最後一個交換的操做是 arr1[i] 與 arr2[j]交換,因爲存在不須要交換的狀況,因此令 dp[i][len(arr2)]爲arr1[i]爲不須要交換。由於題目要保證遞增,因此只須要關注arr1[i-1]與arr[i]的值便可,而二者之間只有如下四種狀況:sort

1. arr1[i] 與 arr1[i-1]都不交換,這個的前提是 arr1[i]  > arr1[i-1],有 dp[i][len(arr2)] = dp[i-1][len(arr2)] ;di

2. 只有arr1[i] 須要交換,對於任意的arr2[j] > arr1[i-1],都有 dp[i][j] = dp[i-1][len(arr2)] + 1;

3. 只有arr1[i-1] 須要交換,對於任意的 arr2[j] < arr1[i],都有 dp[i][len(arr2)]  = dp[i-1][j] + 1;

4.二者都要交換,若是i-1與j-1交換,那麼i就和j交換,有dp[i][j] = dp[i-1][j-1] + 1

最後的結果只須要求出四種狀況的最小值便可。

代碼以下:

class Solution {
public:
    int makeArrayIncreasing(vector<int>& arr1, vector<int>& arr2) {
        set<int> st(arr2.begin(), arr2.end());
        //arr2.clear();
        arr2.assign(st.begin(), st.end());
        //arr2.sort();
        sort(arr2.begin(), arr2.end());
        vector <vector<int>> dp ;for (int i =0;i< arr1.size();i++){
            vector<int> v2 (arr2.size()+1,2001);
            dp.push_back(v2);
        }
        for (int i = 0 ;i < arr2.size();i++){
            dp[0][i] = 1;
        }
        int res = 2001;
        int LAST_INDEX = arr2.size();
        dp[0][arr2.size()] = 0;
        //int ] = 0;
        for (int i =1 ;i < arr1.size();i++){
            for (int j = 0;j < arr2.size();j++){
                //only [i] exchange
                if (arr2[j] > arr1[i-1]){
                    dp[i][j] = min(dp[i][j],dp[i-1][LAST_INDEX] + 1);
                }
                //both [i] and [i-1] exchange
                if(j > 0){
                    dp[i][j] = min(dp[i][j],dp[i-1][j-1] + 1);
                }
                //only [i-1] change
                if (arr1[i] > arr2[j]){
                    dp[i][LAST_INDEX] = min(dp[i][LAST_INDEX],dp[i-1][j]);
                }
            }
            // no exchange
            if (arr1[i] > arr1[i-1]){
                dp[i][LAST_INDEX] = min(dp[i][LAST_INDEX],dp[i-1][LAST_INDEX]);
            }
        }
        for (int i = 0; i <= arr2.size();i++){
            res = min(res,dp[arr1.size()-1][i]);
        }
        return res == 2001 ? -1 : res;
    }
};
相關文章
相關標籤/搜索