Offer 驾到,掘友接招!我正在参与2022春招系列活动-刷题打卡任务,点击查看活动详情。
给你一个整数数组 nums 。nums 中,子数组的 范围 是子数组中最大元素和最小元素的差值。返回 nums 中 所有 子数组范围的 和 。子数组是数组中一个连续 非空 的元素序列。
此题我们可以采用暴力枚举,就是把所有子数组的可能全部列举出来,并求出每个子数组中最大值与最小值的差,最后相加得到结果。
举个例子:
[4, -2, -3, 4, 1]
对于这个数组,它有如下几种子数组:
- 1个元素的子数组:[4]、[-2]、[-3]、[4]、[1]
- 2个元素的子数组:[4,-2]、[-2,-3]、[-3,4]、[4,1]
- 3个元素的子数组:[4,-2,-3]、[-2,-3,4]、[-3,4,1]
- 4个元素的子数组:[4,-2,-3,4]、[-2,-3,4,1]
- 5个元素的子数组:[4,-2,-3,4,1]
那么如何枚举也是一个问题,我们可以从数组的第一个元素开始,不断地往后扩展子数组的长度,以此进行遍历,如下图所示:
我们可以定义两个指针left和right,其中left为子数组的左边界,right为子数组的右边界,通过left和right指针能够确定一个子数组,同时记录这个子数组中的最大值和最小值,得到差并计算结果。
代码如下:
public static long subArrayRanges(int[] nums) {
long result = 0;
// 定义左边界
for (int left = 0; left < nums.length; ++left) {
int min = Integer.MAX_VALUE;
int max = Integer.MIN_VALUE;
// 定义右边界
for (int right = left; right < nums.length; ++right) {
// 记录最大值与最小值
// 如果新添进子数组的元素不大于最大值,不小于最小值,则仍然会使用前面记录的最大值与最小值
min = Math.min(min, nums[right]);
max = Math.max(max, nums[right]);
// 计算结果
result += max - min;
}
}
return result;
}