comments | difficulty | edit_url | rating | source | tags | |||||
---|---|---|---|---|---|---|---|---|---|---|
true |
困难 |
2432 |
第 330 场周赛 Q4 |
|
给你一个长度为 n
下标从 0 开始的整数数组 nums
,它包含 1
到 n
的所有数字,请你返回上升四元组的数目。
如果一个四元组 (i, j, k, l)
满足以下条件,我们称它是上升的:
0 <= i < j < k < l < n
且nums[i] < nums[k] < nums[j] < nums[l]
。
示例 1:
输入:nums = [1,3,2,4,5] 输出:2 解释: - 当 i = 0 ,j = 1 ,k = 2 且 l = 3 时,有 nums[i] < nums[k] < nums[j] < nums[l] 。 - 当 i = 0 ,j = 1 ,k = 2 且 l = 4 时,有 nums[i] < nums[k] < nums[j] < nums[l] 。 没有其他的四元组,所以我们返回 2 。
示例 2:
输入:nums = [1,2,3,4] 输出:0 解释:只存在一个四元组 i = 0 ,j = 1 ,k = 2 ,l = 3 ,但是 nums[j] < nums[k] ,所以我们返回 0 。
提示:
4 <= nums.length <= 4000
1 <= nums[i] <= nums.length
nums
中所有数字 互不相同 ,nums
是一个排列。
我们可以枚举四元组中的
- 统计有多少个
$l$ 满足$l \gt k$ 且$nums[l] \gt nums[j]$ ; - 统计有多少个
$i$ 满足$i \lt j$ 且$nums[i] \lt nums[k]$ 。
我们可以使用两个二维数组
那么答案就是所有的
时间复杂度为
class Solution:
def countQuadruplets(self, nums: List[int]) -> int:
n = len(nums)
f = [[0] * n for _ in range(n)]
g = [[0] * n for _ in range(n)]
for j in range(1, n - 2):
cnt = sum(nums[l] > nums[j] for l in range(j + 1, n))
for k in range(j + 1, n - 1):
if nums[j] > nums[k]:
f[j][k] = cnt
else:
cnt -= 1
for k in range(2, n - 1):
cnt = sum(nums[i] < nums[k] for i in range(k))
for j in range(k - 1, 0, -1):
if nums[j] > nums[k]:
g[j][k] = cnt
else:
cnt -= 1
return sum(
f[j][k] * g[j][k] for j in range(1, n - 2) for k in range(j + 1, n - 1)
)
class Solution {
public long countQuadruplets(int[] nums) {
int n = nums.length;
int[][] f = new int[n][n];
int[][] g = new int[n][n];
for (int j = 1; j < n - 2; ++j) {
int cnt = 0;
for (int l = j + 1; l < n; ++l) {
if (nums[l] > nums[j]) {
++cnt;
}
}
for (int k = j + 1; k < n - 1; ++k) {
if (nums[j] > nums[k]) {
f[j][k] = cnt;
} else {
--cnt;
}
}
}
long ans = 0;
for (int k = 2; k < n - 1; ++k) {
int cnt = 0;
for (int i = 0; i < k; ++i) {
if (nums[i] < nums[k]) {
++cnt;
}
}
for (int j = k - 1; j > 0; --j) {
if (nums[j] > nums[k]) {
g[j][k] = cnt;
ans += (long) f[j][k] * g[j][k];
} else {
--cnt;
}
}
}
return ans;
}
}
const int N = 4001;
int f[N][N];
int g[N][N];
class Solution {
public:
long long countQuadruplets(vector<int>& nums) {
int n = nums.size();
memset(f, 0, sizeof f);
memset(g, 0, sizeof g);
for (int j = 1; j < n - 2; ++j) {
int cnt = 0;
for (int l = j + 1; l < n; ++l) {
if (nums[l] > nums[j]) {
++cnt;
}
}
for (int k = j + 1; k < n - 1; ++k) {
if (nums[j] > nums[k]) {
f[j][k] = cnt;
} else {
--cnt;
}
}
}
long long ans = 0;
for (int k = 2; k < n - 1; ++k) {
int cnt = 0;
for (int i = 0; i < k; ++i) {
if (nums[i] < nums[k]) {
++cnt;
}
}
for (int j = k - 1; j > 0; --j) {
if (nums[j] > nums[k]) {
g[j][k] = cnt;
ans += 1ll * f[j][k] * g[j][k];
} else {
--cnt;
}
}
}
return ans;
}
};
func countQuadruplets(nums []int) int64 {
n := len(nums)
f := make([][]int, n)
g := make([][]int, n)
for i := range f {
f[i] = make([]int, n)
g[i] = make([]int, n)
}
for j := 1; j < n-2; j++ {
cnt := 0
for l := j + 1; l < n; l++ {
if nums[l] > nums[j] {
cnt++
}
}
for k := j + 1; k < n-1; k++ {
if nums[j] > nums[k] {
f[j][k] = cnt
} else {
cnt--
}
}
}
ans := 0
for k := 2; k < n-1; k++ {
cnt := 0
for i := 0; i < k; i++ {
if nums[i] < nums[k] {
cnt++
}
}
for j := k - 1; j > 0; j-- {
if nums[j] > nums[k] {
g[j][k] = cnt
ans += f[j][k] * g[j][k]
} else {
cnt--
}
}
}
return int64(ans)
}