You are given an integer array nums
and an integer threshold
.
Find any subarray of nums
of length k
such that every element in the subarray is greater than threshold / k
.
Return the size of any such subarray. If there is no such subarray, return -1
.
A subarray is a contiguous non-empty sequence of elements within an array.
Example 1:
Input: nums = [1,3,4,3,1], threshold = 6 Output: 3 Explanation: The subarray [3,4,3] has a size of 3, and every element is greater than 6 / 3 = 2. Note that this is the only valid subarray.
Example 2:
Input: nums = [6,5,6,5,8], threshold = 7 Output: 1 Explanation: The subarray [8] has a size of 1, and 8 > 7 / 1 = 7. So 1 is returned. Note that the subarray [6,5] has a size of 2, and every element is greater than 7 / 2 = 3.5. Similarly, the subarrays [6,5,6], [6,5,6,5], [6,5,6,5,8] also satisfy the given conditions. Therefore, 2, 3, 4, or 5 may also be returned.
Constraints:
1 <= nums.length <= 105
1 <= nums[i], threshold <= 109
This problem asks to find the size of any subarray within nums
of length k
where every element is greater than threshold / k
. Two approaches are presented, both leveraging the concept of finding the longest subarray fulfilling the condition.
Solution 1: Union Find
This approach cleverly uses a Union-Find data structure to efficiently merge adjacent subarrays.
Initialization:
p
: A parent array for the Union-Find, initially setting each element to itself (representing individual subarrays).size
: An array storing the size of each subarray (initially 1).arr
: A sorted array of pairs (num, index)
, sorted in descending order of num
. This allows us to process the largest elements first.Iteration and Merging:
arr
(largest elements first).(v, i)
:
i-1
and i+1
) are already visited (vis
). If so, it merges their subarrays using the merge
function.merge
function performs the Union-Find operation, updating the parent and size arrays.v > threshold / size[find(i)]
(the current element is greater than the threshold divided by its subarray size), then it means a valid subarray is found, and its size is returned.Union Find Functions:
find(x)
: Finds the root parent of element x
(representing its subarray).merge(a, b)
: Merges the subarrays containing elements a
and b
.Time Complexity Analysis (Solution 1):
arr
takes O(N log N) time.find
and merge
operations in Union Find take (amortized) O(α(N)) time, where α(N) is the inverse Ackermann function, which is practically constant for all realistic input sizes.Space Complexity Analysis (Solution 1):
p
, size
, arr
, and vis
.Solution 2: Monotonic Stack
This approach utilizes two monotonic stacks to efficiently find the left and right boundaries of the subarray for each element.
Left Boundary:
stk
is used.v
is processed, the stack is popped until the top element is smaller than v
.left[i]
array stores the index of the leftmost element that is smaller than nums[i]
.Right Boundary:
right[i]
array, using a monotonic decreasing stack iterating from right to left.Verification:
v > threshold / k
for each element, where k = right[i] - left[i] - 1
. If this is true, it means a valid subarray of length k
is found.Time Complexity Analysis (Solution 2):
Space Complexity Analysis (Solution 2):
left
, right
, and the stacks.Conclusion:
Both solutions correctly solve the problem. Solution 2 (Monotonic Stack) is generally preferred because of its superior O(N) time complexity compared to Solution 1's O(N log N) time complexity. However, Solution 1's Union Find approach is a creative and elegant method that could be advantageous in slightly different variations of the problem. The choice depends on the specific constraints and performance requirements.