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 mostk.
Return the total number of ways to partition nums under this condition.
Since the answer may be too large, return it modulo109 + 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
Solutions
Solution 1: Dynamic Programming + Two Pointers + Ordered Set
We define \(f[i]\) as the number of ways to partition the first \(i\) elements. If an array satisfies that the difference between its maximum and minimum values does not exceed \(k\), then any of its subarrays also satisfies this condition. Therefore, we can use two pointers to maintain a sliding window representing the current subarray.
When we reach the \(r\)-th element, we need to find the left pointer \(l\) such that the subarray from \(l\) to \(r\) satisfies that the difference between the maximum and minimum values does not exceed \(k\). We can use an ordered set to maintain the elements in the current window, so that we can quickly get the maximum and minimum values.
Each time we add a new element, we insert it into the ordered set and check the difference between the maximum and minimum values in the current window. If it exceeds \(k\), we move the left pointer \(l\) until the condition is satisfied. The number of partition ways ending at the \(r\)-th element is \(f[l - 1] + f[l] + \ldots + f[r - 1]\). We can use a prefix sum array to quickly calculate this value.
The answer is \(f[n]\), where \(n\) is the length of the array.
The time complexity is \(O(n \times \log n)\) and the space complexity is \(O(n)\), where \(n\) is the length of the array \(\textit{nums}\).