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
2024-09-28
目录

生成数组Java

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

# 题目

给定三个整数 n、m 和 k 。考虑使用下图描述的算法找出正整数数组中最大的元素。

1420e.png

请你构建一个具有以下属性的数组 arr :

  • arr 中包含确切的 n 个整数。
  • 1 <= arr[i] <= m 其中 (0 <= i < n) 。
  • 将上面提到的算法应用于 arr 之后,search_cost 的值等于 k 。 返回在满足上述条件的情况下构建数组 arr 的 方法数量 ,由于答案可能会很大,所以 必须 对 10^9 + 7 取余。

示例 1:

输入:n = 2, m = 3, k = 1
输出:6
解释:可能的数组分别为 [1, 1], [2, 1], [2, 2], [3, 1], [3, 2] [3, 3]

示例 2:

输入:n = 5, m = 2, k = 3
输出:0
解释:没有数组可以满足上述条件

示例 3:

输入:n = 9, m = 1, k = 1
输出:1
解释:唯一可能的数组是 [1, 1, 1, 1, 1, 1, 1, 1, 1]

提示:

  • 1 <= n <= 50
  • 1 <= m <= 100
  • 0 <= k <= n

# 思路

记忆化DFS + 快速幂

# 解法

class Solution {
    public int numOfArrays(int n, int m, int k) {
        if (k > m) {
            return 0;
        }
        // 每个峰值的Si => [i+1, m - (k - (i+1))]; 峰值组合情况C(k,m)
        // 大于峰间的Si >= max(a0...ai)
        int t = m - k + 1, v = n - k;
        // 记忆化 res[i][t][v] 表示 第i个峰值是t是后面有v个时候的情况
        long[][][] res = new long[k][t][v + 1];
        return (int) (dfs(0, 0, 0, res, v, t, k) % mod);
    }
    private static final int mod = (int) 1e9 + 7;
    private long dfs(int k_, int v_, int t_, long[][][] res, int v, int t, int k) {
        if (k_ >= k) {
            return 1;
        }
        // 当前峰值范围 可用余数
        int l = Math.max(k_ + 1, t_ + 1), r = t + k_, V = v - v_;
        long n = 0;
        int L = k_ + 1;
        while (l <= r) {
            long m = 0;
            int V_ = v - v_;
            if (res[k_][l - L][V_] != 0) {
                m += res[k_][l - L][V_];
                m %= mod;
            } else {
                while (V_ >= 0) {
                    long pow = pow(l, V_, mod);
                    long dfs = dfs(k_ + 1, v_ + V_, l, res, v, t, k) % mod;
                    long m_ = ((pow * dfs) % mod);
                    res[k_][l- L][V] += m_;
                    res[k_][l- L][V] %= mod;
                    m += m_;
                    m %= mod;
                    V_--;
                    if (k_ == k-1) {
                        break;
                    }
                }
            }
            n += m;
            n %= mod;
            l++;
        }
        return n;
    }
    public long pow(long n, long m, int mod) {
        long res = 1L;
        n %= mod;
        for (; m != 0; m /= 2) {
            if ((m & 1) == 1) {
                res = (res * n) % mod;
            }
            n = (n * n) % mod;
        }
        return res;
    }
}

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
54
55
56
57
58
59
60
61

# 总结

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