Leetcode 2552. Count Increasing Quadruplets
Woodyiiiiiii opened this issue · comments
这道题是典型的三元/四元组题型,一般这种题型的解法,要满足合理的时间复杂度,我总结 :
- 从中间索引出发
- 对边缘索引预处理DP
这题的条件有:
0 <= i < j < k < l < n
和nums[i] < nums[k] < nums[j] < nums[l]
1 <= nums[i] <= nums.length
- 隐藏条件:
4 <= nums.length <= 4000
,暗示要用O(n^2)
或者O(n^2lgn)
照例从j和k出发,两次循环后定位j和k,那么如何找到i和l呢?这就要预处理DP了。我们用prefix表示i/nums[i]的数目,用suffix表示l/nums[l]的数目,利用有限元素(1<=nums[i]<=n) 的条件。详情看代码如何DP:
class Solution {
public long countQuadruplets(int[] nums) {
int n = nums.length;
// 表示i/nums[i]的数目
long[] prefix = new long[n + 1];
// 表示l/nums[l]的数目
// 预处理l
long[][] suffix = new long[n][n + 1];
for (int l = n - 1; l >= 0; --l) {
for (int r = 1; r < nums[l]; ++r) {
suffix[l][r]++;
}
if (l > 0) {
System.arraycopy(suffix[l], 0, suffix[l - 1], 0, n + 1);
}
}
long ans = 0;
for (int i = 0; i < n; ++i) {
// j
if (i > 0 && i < n - 1) {
int j = i;
for (int k = j + 1; k < n - 1; ++k) {
if (nums[k] < nums[j]) {
ans += prefix[nums[k]] * suffix[k + 1][nums[j]];
}
}
}
// 处理i
for (int v = nums[i] + 1; v <= n; ++v) {
prefix[v]++;
}
}
return ans;
}
}
类似三元/四元组题目: