Description
You are given an integer array nums
and an integer k
. Your task is to partition nums
into one or more non-empty contiguous segments such that in each segment, the difference between its maximum and minimum elements is at most k
.
Return the total number of ways to partition nums
under this condition.
Since the answer may be too large, return it modulo 109 + 7
.
Β
Example 1:
Input: nums = [9,4,1,3,7], k = 4
Output: 6
Explanation:
There are 6 valid partitions where the difference between the maximum and minimum elements in each segment is at most k = 4
:
[[9], [4], [1], [3], [7]]
[[9], [4], [1], [3, 7]]
[[9], [4], [1, 3], [7]]
[[9], [4, 1], [3], [7]]
[[9], [4, 1], [3, 7]]
[[9], [4, 1, 3], [7]]
Example 2:
Input: nums = [3,3,4], k = 0
Output: 2
Explanation:
There are 2 valid partitions that satisfy the given conditions:
[[3], [3], [4]]
[[3, 3], [4]]
Β
Constraints:
2 <= nums.length <= 5 * 104
1 <= nums[i] <= 109
0 <= k <= 109
Solution
Python3
class Solution:
def countPartitions(self, nums: List[int], k: int) -> int:
N = len(nums)
MOD = 10 ** 9 + 7
maxQ, minQ = deque(), deque()
dp = [0] * (N + 1)
dp[0] = 1
acc = 1
i = 0
for j, x in enumerate(nums):
while maxQ and x > nums[maxQ[-1]]:
maxQ.pop()
while minQ and x < nums[minQ[-1]]:
minQ.pop()
maxQ.append(j)
minQ.append(j)
while nums[maxQ[0]] - nums[minQ[0]] > k:
acc = (acc - dp[i]) % MOD
i += 1
if maxQ[0] < i:
maxQ.popleft()
if minQ[0] < i:
minQ.popleft()
dp[j + 1] = acc
acc = (acc + dp[j + 1]) % MOD
return dp[N]