[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 }

 

相关题目

907. Sum of Subarray Minimums

2104. Sum of Subarray Ranges

2281. Sum of Total Strength of Wizards

LeetCode 题目总结

posted @ 2022-07-12 05:23  CNoodle  阅读(295)  评论(0编辑  收藏  举报