LeetCode //C - 1187. Make Array Strictly Increasing

1187. Make Array Strictly Increasing

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 arr1i = arr2j.

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 <= arr1i, arr2i <= 10^9

From: LeetCode

Link: 1187. Make Array Strictly Increasing


Solution:

Ideas:

dpj means after processing current prefix, using j replacements, the minimum possible last value. Smaller last value is better.

Code:
c 复制代码
#include <stdlib.h>
#include <limits.h>

#define INF 0x3f3f3f3f
#define LLINF 4000000000000000000LL

int cmpInt(const void* a, const void* b) {
    int x = *(int*)a, y = *(int*)b;
    return (x > y) - (x < y);
}

int upperBound(int* arr, int size, long long target) {
    int l = 0, r = size;
    while (l < r) {
        int m = l + (r - l) / 2;
        if ((long long)arr[m] <= target) l = m + 1;
        else r = m;
    }
    return l;
}

int makeArrayIncreasing(int* arr1, int arr1Size, int* arr2, int arr2Size) {
    qsort(arr2, arr2Size, sizeof(int), cmpInt);

    int m = 0;
    for (int i = 0; i < arr2Size; i++) {
        if (i == 0 || arr2[i] != arr2[i - 1]) {
            arr2[m++] = arr2[i];
        }
    }

    long long* dp = (long long*)malloc((arr1Size + 1) * sizeof(long long));
    long long* ndp = (long long*)malloc((arr1Size + 1) * sizeof(long long));

    for (int i = 0; i <= arr1Size; i++) dp[i] = LLINF;
    dp[0] = -1;

    for (int i = 0; i < arr1Size; i++) {
        for (int j = 0; j <= arr1Size; j++) ndp[j] = LLINF;

        for (int j = 0; j <= i; j++) {
            if (dp[j] == LLINF) continue;

            if ((long long)arr1[i] > dp[j]) {
                if (arr1[i] < ndp[j]) ndp[j] = arr1[i];
            }

            int idx = upperBound(arr2, m, dp[j]);
            if (idx < m) {
                if ((long long)arr2[idx] < ndp[j + 1]) {
                    ndp[j + 1] = arr2[idx];
                }
            }
        }

        long long* temp = dp;
        dp = ndp;
        ndp = temp;
    }

    for (int i = 0; i <= arr1Size; i++) {
        if (dp[i] != LLINF) {
            free(dp);
            free(ndp);
            return i;
        }
    }

    free(dp);
    free(ndp);
    return -1;
}
相关推荐
SuperByteMaster17 分钟前
wfi进入之前没有清除basepri, 导致中断优先级不够,wfi 退不出来
c语言
徐小黑ACG24 分钟前
Golang 基础05 结构体struct
开发语言·算法·golang
Navigator_Z1 小时前
LeetCode //C - 1286. Iterator for Combination
c语言·算法·leetcode
北极有牛1 小时前
cpp学习笔记--常量指针
java·开发语言·算法
GPU实战笔记1 小时前
云端 GPU 训练的账户余额提醒:它能说明什么,不能说明什么?
深度学习·算法·成本管理·gpu云计算·云端训练
浮链序2 小时前
怎么证明"你这个模型是偷我的"——把蒸馏变成取证工具
算法·安全·llm
小O的算法实验室2 小时前
IEEE TMC,面向异构物联网的多目标量子行为拓扑优化算法
算法
圣保罗的大教堂2 小时前
leetcode 301. 删除无效的括号 困难
leetcode
liliangcsdn3 小时前
派息率指标的应用探索和分析
大数据·算法
垆边人似月.3 小时前
华为机试题 :两数之和
c++·算法·华为