Loading

每日力扣1

907.子数组的最小值之和

题目:

给定一个整数数组 arr,找到 min(b) 的总和,其中 b 的范围为 arr 的每个(连续)子数组。

思路:

贡献法,就是对于一个元素,找到以它为最小值或者最大值的一个区间,对于这个区间内每个包含该元素的子区间,它都会有一个贡献,例如:一个元素i,左区间是L,右区间是R,是(L,R)的开区间。根据乘法原理,以i为右端点的区间,左端点存在i-L个,以i为左端点的区间,右端点存在R-i个,因此总共有 (i-L)*(R-i)个子区间。以arr[i]为最小值所产生的贡献则是 arr[i] * (i-L) * (R-i)。

可以用单调栈来寻找每个元素的左边第一个大于自己的元素的下标,寻找右边第一个大于等于自己下标。这里右边是大于等于,因为如果是大于的话,对于两个相同,并且挨着的元素,它会造成重复计算。所以左边或右边有一个是大于等于即可。最后遍历一次记录数组求出结果即可。

2104. 子数组范围和

题目:

给你一个整数数组 numsnums 中,子数组的 范围 是子数组中最大元素和最小元素的差值。

返回 nums所有 子数组范围的

子数组是数组中一个连续 非空 的元素序列。

思路:

与 LC907思路相同,都是算一个元素对于最后结果产生的共享,但不同的是此题是算最大元素和最小元素的差值,而对于一个元素,它作为区间最大值时产生的贡献将会是正的,因为是最大元素减最小元素,而作为区间最小值时产生的贡献则是负值。因此一个元素的贡献将是:

(i-L_min)*(R_min-i) * (-arr[i]) +(i-L_max) * (R_max-i) * (arr[i])

posted @ 2023-09-26 15:41  墨鱼yyyl  阅读(15)  评论(0)    收藏  举报  来源