[Leetcode] 629. K Inverse Pairs Array 解题报告
2018-01-16 22:28
393 查看
题目:
Given two integers
find how many different arrays consist of numbers from
that there are exactly
We define an inverse pair as following: For
in the array, if
it's an inverse pair; Otherwise, it's not.
Since the answer may be very large, the answer should be modulo 109 + 7.
Example 1:
Example 2:
Note:
The integer
in the range [0, 1000].
思路:
比较容易辨别出来是一道DP的题目,但是确实算是比较难的了,下面是参考网上的代码之后我的理解。定义dp
[k]表示从1到n构成的数中含有k个逆序对的个数,则我们可以推导出dp
[k]和dp[n - 1][i]之间的递推关系:
如果我们把n放在最后一位,则所有的k个逆序对均来自于前n - 1个数所构成的逆序对,和n无关;
如果我们把n放在倒数第二位,则有1个逆序对和n有关,有k - 1个逆序对来自前n - 1个数所构成的逆序对;
……
如果我们把n放在第一位,则有n-1个逆序对和n有关,k - (n - 1)个逆序对来自前n - 1个数所构成的逆序对。
所以:dp
[k] = dp[n-1][k]+dp[n-1][k-1]+dp[n-1][k-2]+…+dp[n-1][k+1-n+1]+dp[n-1][k-n+1]。但问题是 k - (n - 1)有可能为负数,也就是说根据n和k的不同,上面的式子有可能从某个项之后就不合法了,我们这里先写出来占位,从而得到下面两个式子:
dp
[k] = dp[n-1][k]+dp[n-1][k-1]+dp[n-1][k-2]+…+dp[n-1][k+1-n+1]+dp[n-1][k-n+1]
dp
[k+1] = dp[n-1][k+1]+dp[n-1][k]+dp[n-1][k-1]+dp[n-1][k-2]+…+dp[n-1][k+1-n+1]
把上面两个式子相减可以推导出:dp
[k+1] = dp
[k]+dp[n-1][k+1]-dp[n-1][k+1-n]。这样就可以写出代码了。
当然由于dp
[k]只和dp
[x],dp[n-1][x]有关,所以该代码还可以进一步将空间复杂度从O(nk)降低到O(k)。时间复杂度是O(nk)。
代码:
class Solution {
public:
int kInversePairs(int n, int k) {
long long mod = 1000000007;
if (k < 0 || k > n * (n - 1) / 2) { // k is out of the valid range
return 0;
}
if (k == 0 || k == n * (n - 1) / 2) { // k is in the corner case
return 1;
}
vector<vector<long long>> dp(n + 1, vector<long long>(k + 1, 0));
dp[2][0] = 1, dp[2][1] = 1; // initialization for starting point
for (int i = 3; i <= n; ++i) {
dp[i][0] = 1;
for (int j = 1; j <= min(k, i * (i - 1) / 2); ++j) {
dp[i][j] = dp[i][j - 1] + dp[i - 1][j];
if (j >= i) {
dp[i][j] -= dp[i - 1][j - i];
}
dp[i][j] = (dp[i][j] + mod) % mod;
}
}
return static_cast<int>(dp
[k]);
}
};
Given two integers
nand
k,
find how many different arrays consist of numbers from
1to
nsuch
that there are exactly
kinverse pairs.
We define an inverse pair as following: For
ithand
jthelement
in the array, if
i<
jand
a[i]>
a[j]then
it's an inverse pair; Otherwise, it's not.
Since the answer may be very large, the answer should be modulo 109 + 7.
Example 1:
Input: n = 3, k = 0 Output: 1 Explanation: Only the array [1,2,3] which consists of numbers from 1 to 3 has exactly 0 inverse pair.
Example 2:
Input: n = 3, k = 1 Output: 2 Explanation: The array [1,3,2] and [2,1,3] have exactly 1 inverse pair.
Note:
The integer
nis in the range [1, 1000] and
kis
in the range [0, 1000].
思路:
比较容易辨别出来是一道DP的题目,但是确实算是比较难的了,下面是参考网上的代码之后我的理解。定义dp
[k]表示从1到n构成的数中含有k个逆序对的个数,则我们可以推导出dp
[k]和dp[n - 1][i]之间的递推关系:
如果我们把n放在最后一位,则所有的k个逆序对均来自于前n - 1个数所构成的逆序对,和n无关;
如果我们把n放在倒数第二位,则有1个逆序对和n有关,有k - 1个逆序对来自前n - 1个数所构成的逆序对;
……
如果我们把n放在第一位,则有n-1个逆序对和n有关,k - (n - 1)个逆序对来自前n - 1个数所构成的逆序对。
所以:dp
[k] = dp[n-1][k]+dp[n-1][k-1]+dp[n-1][k-2]+…+dp[n-1][k+1-n+1]+dp[n-1][k-n+1]。但问题是 k - (n - 1)有可能为负数,也就是说根据n和k的不同,上面的式子有可能从某个项之后就不合法了,我们这里先写出来占位,从而得到下面两个式子:
dp
[k] = dp[n-1][k]+dp[n-1][k-1]+dp[n-1][k-2]+…+dp[n-1][k+1-n+1]+dp[n-1][k-n+1]
dp
[k+1] = dp[n-1][k+1]+dp[n-1][k]+dp[n-1][k-1]+dp[n-1][k-2]+…+dp[n-1][k+1-n+1]
把上面两个式子相减可以推导出:dp
[k+1] = dp
[k]+dp[n-1][k+1]-dp[n-1][k+1-n]。这样就可以写出代码了。
当然由于dp
[k]只和dp
[x],dp[n-1][x]有关,所以该代码还可以进一步将空间复杂度从O(nk)降低到O(k)。时间复杂度是O(nk)。
代码:
class Solution {
public:
int kInversePairs(int n, int k) {
long long mod = 1000000007;
if (k < 0 || k > n * (n - 1) / 2) { // k is out of the valid range
return 0;
}
if (k == 0 || k == n * (n - 1) / 2) { // k is in the corner case
return 1;
}
vector<vector<long long>> dp(n + 1, vector<long long>(k + 1, 0));
dp[2][0] = 1, dp[2][1] = 1; // initialization for starting point
for (int i = 3; i <= n; ++i) {
dp[i][0] = 1;
for (int j = 1; j <= min(k, i * (i - 1) / 2); ++j) {
dp[i][j] = dp[i][j - 1] + dp[i - 1][j];
if (j >= i) {
dp[i][j] -= dp[i - 1][j - i];
}
dp[i][j] = (dp[i][j] + mod) % mod;
}
}
return static_cast<int>(dp
[k]);
}
};
相关文章推荐
- leetcode 629. K Inverse Pairs Array
- leetcode解题报告(13):K-diff Pairs in an Array
- 【LeetCode】532. K-diff Pairs in an Array 解题报告
- [leetcode]629. K Inverse Pairs Array
- [Leetcode] 532. K-diff Pairs in an Array 解题报告
- 【LeetCode】Find All Numbers Disappeared in an Array 解题报告
- leetcode解题报告(4):Search in Rotated Sorted ArrayII
- [Leetcode] 659. Split Array into Consecutive Subsequences 解题报告
- 【LeetCode】Convert Sorted Array to Binary Search Tree 解题报告
- [leetcode] 421. Maximum XOR of Two Numbers in an Array 解题报告
- 【LeetCode】215. Kth Largest Element in an Array 解题报告
- K Inverse Pairs Array - LeetCode
- [leetcode] 373. Find K Pairs with Smallest Sums 解题报告
- 【LeetCode】462. Minimum Moves to Equal Array Elements II 解题报告(Python)
- [Leetcode] 26. Remove Duplicates from Sorted Array 解题报告
- [Leetcode] 336. Palindrome Pairs 解题报告
- [LeetCode] Search in Rotated Sorted Array II 解题报告
- 【LeetCode】Swap Nodes in Pairs 解题报告
- [leetcode] 330. Patching Array 解题报告
- 【LeetCode】Two Sum II - Input array is sorted 解题报告