-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathk_inverse_paris_array.cpp
More file actions
118 lines (106 loc) · 2.5 KB
/
k_inverse_paris_array.cpp
File metadata and controls
118 lines (106 loc) · 2.5 KB
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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
// 629. K Inverse Pairs Array
// Refer: https://leetcode.com/problems/k-inverse-pairs-array
// Author: xianfeng.zhu@gmail.com
#include <cstdio>
#include <vector>
#include <map>
// Brutal force, time limit exceeded
class Solution1 {
public:
int kInversePairs(int n, int k) {
if (n < 1) {
return 0;
}
// Caculate inverse pairs of factorial(n)
// n = 1, factorial(1) = 1
// idx, val
// 0, 0
// n = 2, factorial(2) = 2
// idx, val
// 0, 0
// 1, 1
// n = 3, factorial(3) = factorial(2) * 3 = 6
// idx, val
// 0, 0
// 1, 1
// 2, 1
// 3, 2
// 4, 2
// 5, 3
std::vector<int> nums = {0};
for (int x = 2; x <= n; x++) {
const size_t size = nums.size();
nums.reserve(x * size);
for (int i = 1; i < x; i++) {
for (int j = 0; j < size; j++) {
nums.push_back(nums[j] + i);
}
}
}
// Caculate k pairs
std::map<int, int> pairs;
for (const auto val: nums) {
pairs[val] += 1;
}
return pairs[k];
}
};
// Dynamic programming
class Solution2 {
public:
int kInversePairs(int n, int k) {
if (n < 1 || k < 0) {
return 0;
}
// Implementation logic:
// 1. pair size, s(n)
// s(n) = s(n-1) + n - 1
// 2. number for pairs, f(n)(k)
// f(n)(k) = f(n)(k-1) + f(n-n)(k)
// if (k > n) {
// f(n)(k) -= f(n-1)(k-n);
// }
// Caculate pairs size
std::vector<int> sizes(n + 1);
sizes[0] = 1;
for (int i = 1; i <= n; i++) {
sizes[i] = sizes[i - 1] + i - 1;
}
// Verify k
if (k >= sizes[n]) {
// Invalid k
return 0;
} else if (k >= sizes[n] / 2) {
// Correct k to first half
k = sizes[n] - k - 1;
}
// Allocate arrays to store numbers
std::vector<std::vector<int>> nums(n + 1, std::vector<int>(k + 1));
// Caculate numbers
for (int i = 1; i <= n; i++) {
for (int j = 0; j <= k; j++) {
if (j == 0) {
nums[i][j] = 1;
} else if (j < sizes[i]) {
nums[i][j] = nums[i][j - 1] + nums[i - 1][j];
if (j >= i) {
nums[i][j] -= nums[i - 1][j - i];
}
}
}
}
return nums[n][k];
}
};
using Solution = Solution2;
int main(int argc, char* argv[]) {
int n = 3;
int k = 1;
if (argc > 2) {
n = atoi(argv[1]);
k = atoi(argv[2]);
}
const int val = Solution().kInversePairs(n, k);
printf("n = %d, k = %d -> k pairs = %d\n", n, k, val);
return 0;
}