返回介绍

solution / 2500-2599 / 2552.Count Increasing Quadruplets / README

发布于 2024-06-17 01:03:04 字数 5559 浏览 0 评论 0 收藏 0

2552. 统计上升四元组

English Version

题目描述

给你一个长度为 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 是一个排列。

解法

方法一:枚举 + 预处理

我们可以枚举四元组中的 $j$ 和 $k$,那么问题转化为,对于当前的 $j$ 和 $k$:

  • 统计有多少个 $l$ 满足 $l \gt k$ 且 $nums[l] \gt nums[j]$;
  • 统计有多少个 $i$ 满足 $i \lt j$ 且 $nums[i] \lt nums[k]$。

我们可以使用两个二维数组 $f$ 和 $g$ 分别记录这两个信息。其中 $f[j][k]$ 表示有多少个 $l$ 满足 $l \gt k$ 且 $nums[l] \gt nums[j]$,而 $g[j][k]$ 表示有多少个 $i$ 满足 $i \lt j$ 且 $nums[i] \lt nums[k]$。

那么答案就是所有的 $f[j][k] \times g[j][k]$ 的和。

时间复杂度为 $O(n^2)$,空间复杂度为 $O(n^2)$。其中 $n$ 是数组的长度。

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)
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文