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
2022-09-17
目录

K个逆序对数组Java

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

# 题目

给出两个整数 n 和 k,找出所有包含从 1 到 n 的数字,且恰好拥有 k 个逆序对的不同的数组的个数。

逆序对的定义如下:对于数组的第i个和第 j个元素,如果满i < j且 a[i] > a[j],则其为一个逆序对;否则不是。

由于答案可能很大,只需要返回 答案 mod 109 + 7 的值。

示例 1:

输入: n = 3, k = 0
输出: 1
解释: 
只有数组 [1,2,3] 包含了从1到3的整数并且正好拥有 0 个逆序对。

示例 2:

输入: n = 3, k = 1
输出: 2
解释: 
数组 [1,3,2] 和 [2,1,3] 都有 1 个逆序对。

说明:

  • n 的范围是 [1, 1000] 并且 k 的范围是 [0, 1000]。

# 思路

int[][] dp = new int[n+1][k+1];
dp[i][j] 表示1到i恰好拥有j个逆序对的方案数, 转移的时候根据最后一个数的不同位置划分为i个子集进行转移

# 解法


class Solution {

    private final int MOD = (int) 1e9 + 7;

    public int kInversePairs(int n, int k) {
        // dp[i][j] 表示1到i恰好拥有j个逆序对的方案数, 转移的时候根据最后一个数的不同位置划分为i个子集进行转移
        // 但是要注意直接暴力枚举位置的话复杂度o(n^3)会超时,所以得优化一下
        long[][] dp = new long[n + 1][k + 1];
        dp[0][0] = 1;

        for (int i = 1; i <= n; i++) {
            long sum = 0;
            for (int j = 0; j <= k; j++) {
                sum += dp[i - 1][j];
                if (j + 1 > i) sum -= dp[i - 1][j - i];
                dp[i][j] = (dp[i][j] + sum) % MOD;
            }
        }
        return (int) (dp[n][k] % MOD);
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

# 总结

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