LeetCode 907.子数组的最小值的和

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

由于答案可能很大,因此 返回答案模 10^9 + 7 。

示例

示例 1:
输入:arr = [3,1,2,4]
输出:17
解释:
子数组为 [3],[1],[2],[4],[3,1],[1,2],[2,4],[3,1,2],[1,2,4] [3,1,2,4]。
最小值为  3,1,2,4,1,1,2,1,1,1,和为 17。

示例 2:
输入:arr = [11,81,94,43,3]
输出:444

解题思路

  • 明确要求的是每个子数组都必须是连续的,然后找出子数组中的最小值。
  • 那么从第一个元素开始,那么以该元素开头的连续的子数组就是 [arr[i]]、[arr[i], arr[i+1]]、[arr[i], arr[i+1], a[i+2]]、… 、[arr[i], arr[i+1], a[i+2], … ,a[i + arr.length-1 - i ]]
  • 设置两个指针,p 是用来遍历整个数组, q是用来标记当前连续子数组的末尾元素位置。连续子数组就是从 p -> q 的所有元素。
  • 标记当前元素为最小值 minValue ,然后q指针每往后移一位,则需要判断当前连续子数组的最小值,即 minValue = Math.min(minValue, arr[q]) 。然后将该值 加入res。
  • 关键:每个元素作为连续子数组的首元素,然后从该元素往后遍历,每个元素作为连续子数组的尾元素。同时更新最小值。

代码

/**
 * @param {number[]} arr
 * @return {number}
 */
var sumSubarrayMins = function(arr) {
  let res = 0; // 结果
  let p = 0; // 首元素指针
  while (p < arr.length){
    let q = p; // 尾元素指针
    let minV = arr[p] // 保存连续子元素最小值
    while(q < arr.length){
      minV = Math.min(minV, arr[q]) // 更新最小值
      res += minV; // 将最小值加一起
      q++; 
    }
    p++;
  }
  return res % 1000000007; // 结果对 10^9 + 7取余
};

你可能感兴趣的:(LeetCode,leetcode,算法,数据结构)