LeetCode 题解工作台

单调数组对的数目 I

给你一个长度为 n 的 正 整数数组 nums 。 如果两个 非负 整数数组 (arr1, arr2) 满足以下条件,我们称它们是 单调 数组对: 两个数组的长度都是 n 。 arr1 是单调 非递减 的,换句话说 arr1[0] 。 arr2 是单调 非递增 的,换句话说 arr2[0] >= a…

category

5

题型

code_blocks

5

代码语言

hub

3

相关题

当前训练重点

困难 · 状态·转移·动态规划

bolt

答案摘要

我们定义 表示下标 的单调数组对的数目,且 $arr1[i] = j$。初始时 $[i][j] = 0$,答案为 $\sum_{j=0}^{\textit{nums}[n-1]} f[n-1][j]$。 当 $i = 0$ 时,有 $[0][j] = 1$,其中 $0 \leq j \leq \textit{nums}[0]$。

Interview AiBox logo

Interview AiBox 实时 AI 助手,陪你讲清 状态·转移·动态规划 题型思路

试试 AiBox 面试助手arrow_forward
description

题目描述

给你一个长度为 n 的  整数数组 nums 。

如果两个 非负 整数数组 (arr1, arr2) 满足以下条件,我们称它们是 单调 数组对:

  • 两个数组的长度都是 n 。
  • arr1 是单调 非递减 的,换句话说 arr1[0] <= arr1[1] <= ... <= arr1[n - 1] 。
  • arr2 是单调 非递增 的,换句话说 arr2[0] >= arr2[1] >= ... >= arr2[n - 1] 。
  • 对于所有的 0 <= i <= n - 1 都有 arr1[i] + arr2[i] == nums[i] 。

请你返回所有 单调 数组对的数目。

由于答案可能很大,请你将它对 109 + 7 取余 后返回。

 

示例 1:

输入:nums = [2,3,2]

输出:4

解释:

单调数组对包括:

  1. ([0, 1, 1], [2, 2, 1])
  2. ([0, 1, 2], [2, 2, 0])
  3. ([0, 2, 2], [2, 1, 0])
  4. ([1, 2, 2], [1, 1, 0])

示例 2:

输入:nums = [5,5,5,5]

输出:126

 

提示:

  • 1 <= n == nums.length <= 2000
  • 1 <= nums[i] <= 50
lightbulb

解题思路

方法一:动态规划 + 前缀和优化

我们定义 f[i][j]f[i][j] 表示下标 [0,..i][0,..i] 的单调数组对的数目,且 arr1[i]=jarr1[i] = j。初始时 [i][j]=0[i][j] = 0,答案为 j=0nums[n1]f[n1][j]\sum_{j=0}^{\textit{nums}[n-1]} f[n-1][j]

i=0i = 0 时,有 [0][j]=1[0][j] = 1,其中 0jnums[0]0 \leq j \leq \textit{nums}[0]

i>0i > 0 时,我们可以根据 f[i1][j]f[i-1][j'] 计算 f[i][j]f[i][j]。由于 arr1\textit{arr1} 是单调非递减的,因此 jjj' \leq j。又由于 arr2\textit{arr2} 是单调非递增的,因此 nums[i]jnums[i1]j\textit{nums}[i] - j \leq \textit{nums}[i - 1] - j'。即 jmin(j,j+nums[i1]nums[i])j' \leq \min(j, j + \textit{nums}[i - 1] - \textit{nums}[i])

答案为 j=0nums[n1]f[n1][j]\sum_{j=0}^{\textit{nums}[n-1]} f[n-1][j]

时间复杂度 O(n×m)O(n \times m),空间复杂度 O(n×m)O(n \times m)。其中 nn 表示数组 nums\textit{nums} 的长度,而 mm 表示数组 nums\textit{nums} 中的最大值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Solution:
    def countOfPairs(self, nums: List[int]) -> int:
        mod = 10**9 + 7
        n, m = len(nums), max(nums)
        f = [[0] * (m + 1) for _ in range(n)]
        for j in range(nums[0] + 1):
            f[0][j] = 1
        for i in range(1, n):
            s = list(accumulate(f[i - 1]))
            for j in range(nums[i] + 1):
                k = min(j, j + nums[i - 1] - nums[i])
                if k >= 0:
                    f[i][j] = s[k] % mod
        return sum(f[-1][: nums[-1] + 1]) % mod
speed

复杂度分析

指标
时间complexity depends on n and the maximum nums[i] value due to DP iterations and prefix sums, roughly O(n * maxValue). Space complexity is O(n * maxValue) for the DP table.
空间Depends on the final approach
psychology

面试官常问的追问

外企场景
  • question_mark

    Check if candidate correctly defines dp[i][s] and understands state transitions.

  • question_mark

    Observe whether prefix sums are used to optimize the cumulative counts in DP.

  • question_mark

    Watch for correct handling of repeated elements and monotonic constraints.

warning

常见陷阱

外企场景
  • error

    Forgetting to enforce monotonicity when updating DP states.

  • error

    Inefficiently iterating without prefix sums, leading to timeouts.

  • error

    Incorrectly summing final DP values, missing some valid pairs.

swap_horiz

进阶变体

外企场景
  • arrow_right_alt

    Counting strictly increasing monotonic pairs instead of non-decreasing.

  • arrow_right_alt

    Finding monotonic triples or larger tuples with similar DP approach.

  • arrow_right_alt

    Applying the DP state transition pattern to other bounded integer arrays with combinatorial constraints.

help

常见问题

外企场景

单调数组对的数目 I题解:状态·转移·动态规划 | LeetCode #3250 困难