comments | difficulty | edit_url | tags | |
---|---|---|---|---|
true |
困难 |
|
对于一个整数数组 nums
,逆序对是一对满足 0 <= i < j < nums.length
且 nums[i] > nums[j]
的整数对 [i, j]
。
给你两个整数 n
和 k
,找出所有包含从 1
到 n
的数字,且恰好拥有 k
个 逆序对 的不同的数组的个数。由于答案可能很大,只需要返回对 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 个逆序对。
提示:
1 <= n <= 1000
0 <= k <= 1000
我们定义
接下来我们考虑如何得到
假设前
- 如果
$i$ 插入到第$1$ 个位置,那么逆序对增加了$i-1$ 个,所以$f[i][j]+=f[i-1][j-(i-1)]$ 。 - 如果
$i$ 插入到第$2$ 个位置,那么逆序对增加了$i-2$ 个,所以$f[i][j]+=f[i-1][j-(i-2)]$ 。 - ...
- 如果
$i$ 插入到第$i-1$ 个位置,那么逆序对增加了$1$ 个,所以$f[i][j]+=f[i-1][j-1]$ 。 - 如果
$i$ 插入到第$i$ 个位置,那么逆序对不变,所以$f[i][j]+=f[i-1][j]$ 。
所以
我们注意到
时间复杂度
class Solution:
def kInversePairs(self, n: int, k: int) -> int:
mod = 10**9 + 7
f = [1] + [0] * k
s = [0] * (k + 2)
for i in range(1, n + 1):
for j in range(1, k + 1):
f[j] = (s[j + 1] - s[max(0, j - (i - 1))]) % mod
for j in range(1, k + 2):
s[j] = (s[j - 1] + f[j - 1]) % mod
return f[k]
class Solution {
public int kInversePairs(int n, int k) {
final int mod = (int) 1e9 + 7;
int[] f = new int[k + 1];
int[] s = new int[k + 2];
f[0] = 1;
Arrays.fill(s, 1);
s[0] = 0;
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= k; ++j) {
f[j] = (s[j + 1] - s[Math.max(0, j - (i - 1))] + mod) % mod;
}
for (int j = 1; j <= k + 1; ++j) {
s[j] = (s[j - 1] + f[j - 1]) % mod;
}
}
return f[k];
}
}
class Solution {
public:
int kInversePairs(int n, int k) {
int f[k + 1];
int s[k + 2];
memset(f, 0, sizeof(f));
f[0] = 1;
fill(s, s + k + 2, 1);
s[0] = 0;
const int mod = 1e9 + 7;
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= k; ++j) {
f[j] = (s[j + 1] - s[max(0, j - (i - 1))] + mod) % mod;
}
for (int j = 1; j <= k + 1; ++j) {
s[j] = (s[j - 1] + f[j - 1]) % mod;
}
}
return f[k];
}
};
func kInversePairs(n int, k int) int {
f := make([]int, k+1)
s := make([]int, k+2)
f[0] = 1
for i, x := range f {
s[i+1] = s[i] + x
}
const mod = 1e9 + 7
for i := 1; i <= n; i++ {
for j := 1; j <= k; j++ {
f[j] = (s[j+1] - s[max(0, j-(i-1))] + mod) % mod
}
for j := 1; j <= k+1; j++ {
s[j] = (s[j-1] + f[j-1]) % mod
}
}
return f[k]
}
function kInversePairs(n: number, k: number): number {
const f: number[] = new Array(k + 1).fill(0);
f[0] = 1;
const s: number[] = new Array(k + 2).fill(1);
s[0] = 0;
const mod: number = 1e9 + 7;
for (let i = 1; i <= n; ++i) {
for (let j = 1; j <= k; ++j) {
f[j] = (s[j + 1] - s[Math.max(0, j - (i - 1))] + mod) % mod;
}
for (let j = 1; j <= k + 1; ++j) {
s[j] = (s[j - 1] + f[j - 1]) % mod;
}
}
return f[k];
}