[LeetCode] 2104. Sum of Subarray Ranges
You are given an integer array nums
. The range of a subarray of nums
is the difference between the largest and smallest element in the subarray.
Return the sum of all subarray ranges of nums
.
A subarray is a contiguous non-empty sequence of elements within an array.
Example 1:
Input: nums = [1,2,3] Output: 4 Explanation: The 6 subarrays of nums are the following: [1], range = largest - smallest = 1 - 1 = 0 [2], range = 2 - 2 = 0 [3], range = 3 - 3 = 0 [1,2], range = 2 - 1 = 1 [2,3], range = 3 - 2 = 1 [1,2,3], range = 3 - 1 = 2 So the sum of all ranges is 0 + 0 + 0 + 1 + 1 + 2 = 4.
Example 2:
Input: nums = [1,3,3] Output: 4 Explanation: The 6 subarrays of nums are the following: [1], range = largest - smallest = 1 - 1 = 0 [3], range = 3 - 3 = 0 [3], range = 3 - 3 = 0 [1,3], range = 3 - 1 = 2 [3,3], range = 3 - 3 = 0 [1,3,3], range = 3 - 1 = 2 So the sum of all ranges is 0 + 0 + 0 + 2 + 0 + 2 = 4.
Example 3:
Input: nums = [4,-2,-3,4,1] Output: 59 Explanation: The sum of all subarray ranges of nums is 59.
Constraints:
1 <= nums.length <= 1000
-109 <= nums[i] <= 109
Follow-up: Could you find a solution with O(n)
time complexity?
子数组范围和。
给你一个整数数组 nums 。nums 中,子数组的 范围 是子数组中最大元素和最小元素的差值。
返回 nums 中 所有 子数组范围的 和 。
子数组是数组中一个连续 非空 的元素序列。
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/sum-of-subarray-ranges
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
这道题暴力解不难,最优解是单调栈。
做这道题之前,需要先做907题。907题单调栈的解法看懂之后,这道题基本就没有问题了。这道题要我们求的是子数组里的范围和,范围和 = 子数组最大值 - 子数组最小值。那么我们用单调栈把数组扫描两遍,第一遍找到所有的最小值,第二遍找到所有的最大值即可。
时间O(n)
空间O(n)
Java实现
1 class Solution { 2 public long subArrayRanges(int[] nums) { 3 int len = nums.length; 4 int j; 5 int k; 6 long res = 0; 7 8 Deque<Integer> stack = new ArrayDeque<>(); 9 for (int i = 0; i <= len; i++) { 10 int cur = i == len ? Integer.MIN_VALUE : nums[i]; 11 while (!stack.isEmpty() && cur < nums[stack.peek()]) { 12 j = stack.pop(); 13 k = stack.isEmpty() ? -1 : stack.peek(); 14 res -= (long) nums[j] * (i - j) * (j - k); 15 } 16 stack.push(i); 17 } 18 19 stack.clear(); 20 for (int i = 0; i <= len; i++) { 21 int cur = i == len ? Integer.MAX_VALUE : nums[i]; 22 while (!stack.isEmpty() && cur > nums[stack.peek()]) { 23 j = stack.pop(); 24 k = stack.isEmpty() ? -1 : stack.peek(); 25 res += (long) nums[j] * (i - j) * (j - k); 26 } 27 stack.push(i); 28 } 29 return res; 30 } 31 }
相关题目