Welcome to Subscribe On Youtube
Formatted question description: https://leetcode.ca/all/1950.html
1950. Maximum of Minimum Values in All Subarrays
Level
Medium
Description
You are given an integer array nums
of size n
. You are asked to solve n
queries for each integer i
in the range 0 <= i < n
.
To solve the i-th
query:
- Find the minimum value in each possible subarray of size
i + 1
of the arraynums
. - Find the maximum of those minimum values. This maximum is the answer to the query.
Return a 0-indexed integer array ans
of size n
such that ans[i]
is the answer to the i-th
query.
A subarray is a contiguous sequence of elements in an array.
Example 1:
Input: nums = [0,1,2,4]
Output: [4,2,1,0]
Explanation: i=0:
- The subarrays of size 1 are [0], [1], [2], [4]. The minimum values are 0, 1, 2, 4.
- The maximum of the minimum values is 4.
i=1:
- The subarrays of size 2 are [0,1], [1,2], [2,4]. The minimum values are 0, 1, 2.
- The maximum of the minimum values is 2.
i=2:
- The subarrays of size 3 are [0,1,2], [1,2,4]. The minimum values are 0, 1.
- The maximum of the minimum values is 1.
i=3:
- There is one subarray of size 4, which is [0,1,2,4]. The minimum value is 0.
- There is only one value, so the maximum is 0.
Example 2:
Input: nums = [10,20,50,10]
Output: [50,20,10,10]
Explanation: i=0:
- The subarrays of size 1 are [10], [20], [50], [10]. The minimum values are 10, 20, 50, 10.
- The maximum of the minimum values is 50.
i=1:
- The subarrays of size 2 are [10,20], [20,50], [50,10]. The minimum values are 10, 20, 10.
- The maximum of the minimum values is 20.
i=2:
- The subarrays of size 3 are [10,20,50], [20,50,10]. The minimum values are 10, 10.
- The maximum of the minimum values is 10.
i=3:
- There is one subarray of size 4, which is [10,20,50,10]. The minimum value is 10.
- There is only one value, so the maximum is 10.
Constraints:
n == nums.length
1 <= n <= 10^5
0 <= nums[i] <= 10^9
Solution
Use monotonic stack, where the elements of the corresponding indices are ascending from bottom to top of the stack. Use two arrays left
and right
to store each element’s closest left index and right index such that the elements at the indices are less than the current element. Loop over nums
from left to right, and fill in the arrays left
and right
.
Then loop over 0 <= i < n
. For each i
, let num = nums[i]
, and the range length with num
as the smallest element is range = right[i] - left[i] - 1
. Let ans[range - 1]
be the maximum of such values of num
. Then for i
from n - 2
to 0, ans[i]
is the maximum of ans[i]
and ans[i + 1]
. Finally, return ans
.
-
class Solution { public int[] findMaximums(int[] nums) { int length = nums.length; int[] left = new int[length]; int[] right = new int[length]; Arrays.fill(right, length); int minimum = Integer.MAX_VALUE; Deque<Integer> stack = new LinkedList<Integer>(); for (int i = 0; i < length; i++) { minimum = Math.min(minimum, nums[i]); while (!stack.isEmpty() && nums[stack.peek()] >= nums[i]) right[stack.pop()] = i; left[i] = stack.isEmpty() ? -1 : stack.peek(); stack.push(i); } int[] maximums = new int[length]; Arrays.fill(maximums, minimum); for (int i = 0; i < length; i++) { int num = nums[i]; int range = right[i] - left[i] - 1; maximums[range - 1] = Math.max(maximums[range - 1], num); } for (int i = length - 2; i >= 0; i--) maximums[i] = Math.max(maximums[i], maximums[i + 1]); return maximums; } } ############ class Solution { public int[] findMaximums(int[] nums) { int n = nums.length; int[] left = new int[n]; int[] right = new int[n]; Arrays.fill(left, -1); Arrays.fill(right, n); Deque<Integer> stk = new ArrayDeque<>(); for (int i = 0; i < n; ++i) { while (!stk.isEmpty() && nums[stk.peek()] >= nums[i]) { stk.pop(); } if (!stk.isEmpty()) { left[i] = stk.peek(); } stk.push(i); } stk.clear(); for (int i = n - 1; i >= 0; --i) { while (!stk.isEmpty() && nums[stk.peek()] >= nums[i]) { stk.pop(); } if (!stk.isEmpty()) { right[i] = stk.peek(); } stk.push(i); } int[] ans = new int[n]; for (int i = 0; i < n; ++i) { int m = right[i] - left[i] - 1; ans[m - 1] = Math.max(ans[m - 1], nums[i]); } for (int i = n - 2; i >= 0; --i) { ans[i] = Math.max(ans[i], ans[i + 1]); } return ans; } }
-
class Solution { public: vector<int> findMaximums(vector<int>& nums) { int n = nums.size(); vector<int> left(n, -1); vector<int> right(n, n); stack<int> stk; for (int i = 0; i < n; ++i) { while (!stk.empty() && nums[stk.top()] >= nums[i]) { stk.pop(); } if (!stk.empty()) { left[i] = stk.top(); } stk.push(i); } stk = stack<int>(); for (int i = n - 1; i >= 0; --i) { while (!stk.empty() && nums[stk.top()] >= nums[i]) { stk.pop(); } if (!stk.empty()) { right[i] = stk.top(); } stk.push(i); } vector<int> ans(n); for (int i = 0; i < n; ++i) { int m = right[i] - left[i] - 1; ans[m - 1] = max(ans[m - 1], nums[i]); } for (int i = n - 2; i >= 0; --i) { ans[i] = max(ans[i], ans[i + 1]); } return ans; } };
-
class Solution: def findMaximums(self, nums: List[int]) -> List[int]: n = len(nums) left = [-1] * n right = [n] * n stk = [] for i, x in enumerate(nums): while stk and nums[stk[-1]] >= x: stk.pop() if stk: left[i] = stk[-1] stk.append(i) stk = [] for i in range(n - 1, -1, -1): while stk and nums[stk[-1]] >= nums[i]: stk.pop() if stk: right[i] = stk[-1] stk.append(i) ans = [0] * n for i in range(n): m = right[i] - left[i] - 1 ans[m - 1] = max(ans[m - 1], nums[i]) for i in range(n - 2, -1, -1): ans[i] = max(ans[i], ans[i + 1]) return ans
-
func findMaximums(nums []int) []int { n := len(nums) left := make([]int, n) right := make([]int, n) for i := range left { left[i], right[i] = -1, n } stk := []int{} for i, x := range nums { for len(stk) > 0 && nums[stk[len(stk)-1]] >= x { stk = stk[:len(stk)-1] } if len(stk) > 0 { left[i] = stk[len(stk)-1] } stk = append(stk, i) } stk = []int{} for i := n - 1; i >= 0; i-- { x := nums[i] for len(stk) > 0 && nums[stk[len(stk)-1]] >= x { stk = stk[:len(stk)-1] } if len(stk) > 0 { right[i] = stk[len(stk)-1] } stk = append(stk, i) } ans := make([]int, n) for i := range ans { m := right[i] - left[i] - 1 ans[m-1] = max(ans[m-1], nums[i]) } for i := n - 2; i >= 0; i-- { ans[i] = max(ans[i], ans[i+1]) } return ans } func max(a, b int) int { if a > b { return a } return b }