JavaInterview JavaInterview
首页
指南
分类
标签
归档
  • CSDN (opens new window)
  • 文档集合 (opens new window)
  • 系统架构 (opens new window)
  • 微信号 (opens new window)
  • 公众号 (opens new window)

『Java面试+Java学习』
首页
指南
分类
标签
归档
  • CSDN (opens new window)
  • 文档集合 (opens new window)
  • 系统架构 (opens new window)
  • 微信号 (opens new window)
  • 公众号 (opens new window)
  • 指南
  • 简历

  • Java

  • 面试

  • 算法

  • algorithm
  • leetcode
JavaInterview.cn
2023-02-21
目录

使数组严格递增Java

文章发布较早,内容可能过时,阅读注意甄别。

# 题目

给你两个整数数组 arr1 和 arr2,返回使 arr1 严格递增所需要的最小「操作」数(可能为 0)。

每一步「操作」中,你可以分别从 arr1 和 arr2 中各选出一个索引,分别为 i 和 j,0 <= i < arr1.length 和 0 <= j < arr2.length,然后进行赋值运算 arr1[i] = arr2[j]。

如果无法让 arr1 严格递增,请返回 -1。

示例 1:

输入:arr1 = [1,5,3,6,7], arr2 = [1,3,2,4]
输出:1
解释:用 2 来替换 5,之后 arr1 = [1, 2, 3, 6, 7]。

示例 2:

输入:arr1 = [1,5,3,6,7], arr2 = [4,3,1]
输出:2
解释:用 3 来替换 5,然后用 4 来替换 3,得到 arr1 = [1, 3, 4, 6, 7]。

示例 3:

输入:arr1 = [1,5,3,6,7], arr2 = [1,6,3,3]
输出:-1
解释:无法使 arr1 严格递增。

提示:

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

# 思路

其实也是DP,用hashmap维护当前能实现的所有情况,即以i结尾需要在前面变换j次。

如arr1 = [1,5,3,6,7], arr2 = [1,3,2,4]。 要使第一个数严格有序,则只有一种情况:以1结尾,需要变换0次

要是前两个数严格有序,在上一步的基础上,有两种情况:以5结尾,需变换0次;以2结尾,需把当前的5变成2,需变换1次

要使前3个数严格有序,则只有一种情况,上一步的以5结尾,已经无法再找到一个数使他严格有序了,因此抛弃5结尾的情况,以2结尾的情况,当前的3就是符合严格有序的,因此为以3结尾,变换1次

要使前4个数严格有序,在上一步的基础上,则有两种情况,当前的6是符合的,则可以以6结尾,变换1次,也可以将6变成4,以4结尾,变换2次。

依此类推

# 解法


class Solution {
    public int makeArrayIncreasing(int[] arr1, int[] arr2) {

        Arrays.sort(arr2);
        int m = arr1.length;
        int n = arr2.length;
        HashMap<Integer, Integer> map = new HashMap(); // (i,j) 表示当前长度变成i需要j步
        HashMap<Integer, Integer> next = new HashMap();
        map.put(arr1[0], 0);
        if(arr2[0] < arr1[0]) {
            map.put(arr2[0], 1);
        }
        for(int i = 1; i < m; i++) {
            for(Map.Entry<Integer, Integer> entry : map.entrySet()) {
                if(entry.getKey() < arr1[i]) {
                    if(!next.containsKey(arr1[i]) || next.get(arr1[i]) > entry.getValue()) {
                        next.put(arr1[i], entry.getValue());
                    }
                } 
                int val = find(arr2, entry.getKey());
                if(val != -1 &&(!next.containsKey(val) || next.get(val) > entry.getValue() + 1)){
                    next.put(val, entry.getValue() + 1);
                }
            }
            map = next;
            next = new HashMap();
            if(map.isEmpty()) {
                return -1;
            }
        }
        int res = Integer.MAX_VALUE;
        for(Map.Entry<Integer, Integer> entry : map.entrySet()) {
            res = Math.min(res, entry.getValue());
        }
        return res;
    }
    private int find(int[] arr, int target) {
        if(arr[arr.length-1] <= target) {
            return -1;
        }
        int l = 0, r = arr.length -1;
        while(l < r) {
            int mid = l + (r-l) / 2;
            if(arr[mid] > target) {
                r = mid;
            } else if(arr[mid] <= target) {
                l = mid + 1;
            }
        }
        return arr[l];
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53

# 总结

  • 分析出几种情况,然后分别对各个情况实现
微信 支付宝
最近更新
01
1686. 石子游戏VI Java
08-18
02
1688. 比赛中的配对次数 Java
08-18
03
1687. 从仓库到码头运输箱子 Java
08-18
更多文章>
Theme by Vdoing | Copyright © 2019-2025 JavaInterview.cn
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式