当前位置: 首页 > article >正文

leetcode 2104. 子数组范围和

题目如下
在这里插入图片描述

数据范围
在这里插入图片描述

法一:
	观察到数组最长仅为1000那么我们可以使用复杂度为n方的方法搜索每一个子数组求出它们的的最大和最小值加到答案里面就行。
法二:
	法一的重复计算太多,许多包含同一个最小值或者最大值的子数组被重复计算了。事实上结果是由所有的最大值之和减去所有的最小值之和。在这里我们要先明白所有的最小值集合包含了数组的每一个数(即使是数组最大值x也是[x]这个子数组的最小值)也就是说我们令f(x)为以下标x的数对应的最小值数量,其中(0 <= x < n)然后我们再把所有的 num[x] * f(x)
相加就是所有最小值之和,所有最大值之和同理。然后我们相减即可得到答案。
至于具体的做法这里以找到以下标i为最小值的子数组数量为例:
	我们只需要找到l r其中l是左边第一个小于这个数的下标 r为右边第一个小于这个数的下标,那么我们可以从[l,i] [i,r]	得到数量。(排列组合)

通过代码
法一

class Solution {
public:
    long long subArrayRanges(vector<int>& nums) {
        long long ans = 0;
        int n = nums.size();
        int min1,max1;
        for(int i = 0;i < n;i++){
            min1 = nums[i];
            max1 = min1;
            for(int j = i;j < n;j++){
                max1 = max(max1,nums[j]);
                min1 = min(min1,nums[j]);
                ans += ((long long)max1 - min1);
            }
           
        }
        return ans;
    }
};

在这里插入图片描述
法二

class Solution {
public:
    long long subArrayRanges(vector<int>& nums) {
        long long ans = 0;
        int n = nums.size();
        stack<int> s1, s2;
        vector<int> l1(n), r1(n), l2(n), r2(n);
        long long min1 = 0, max1 = 0;
        for (int i = 0; i < n; i++) {
            while (!s1.empty() && nums[s1.top()] >= nums[i])
                s1.pop();
            l1[i] = (s1.empty()) ? -1 : s1.top();
            s1.push(i);
            while (!s2.empty() && nums[s2.top()] <= nums[i])
                s2.pop();
            r1[i] = (s2.empty()) ? -1 : s2.top();
            s2.push(i);
        }s1 = stack<int>();
        s2 = stack<int>();
        for (int i = n - 1; i >= 0; i--) {
            while (!s1.empty() && nums[s1.top()] > nums[i])
                s1.pop();
            l2[i] = (s1.empty()) ? n : s1.top();
            s1.push(i);
            while (!s2.empty() && nums[s2.top()] < nums[i])
                s2.pop();
            r2[i] = (s2.empty()) ? n : s2.top();
            s2.push(i);
        }
        for(int i = 0;i < n;i++){
            min1 += (long long)(i - l1[i]) * (l2[i] - i) * nums[i];
            max1 += (long long)(i - r1[i]) * (r2[i] - i) * nums[i];
            
        }
        return max1 - min1;
    }
};

在这里插入图片描述


http://www.kler.cn/a/541214.html

相关文章:

  • java和vue开发的图书馆借阅管理系统小程序
  • 每日一题——没有重复项数字的全排列
  • 音频进阶学习十一——离散傅里叶级数DFS
  • 在CT107D单片机综合训练平台上,8个数码管分别单独依次显示0~9的值,然后所有数码管一起同时显示0~F的值,如此往复。
  • JDK 21 模板字符串详解
  • 【Pandas】pandas Series sum
  • C++STL(六)——list模拟
  • IEEE期刊Word导出PDF注意事项
  • 性能优化中的系统架构优化
  • (五)Spring Boot学习——spring security +jwt使用(前后端分离模式)
  • 【文本处理】如何在批量WORD和txt文本提取手机号码,固话号码,提取邮箱,删除中文,删除英文,提取车牌号等等一些文本提取固定格式的操作,基于WPF的解决方案
  • [2025年最新]2024.3版本idea无法安装插件问题解决
  • 思科模拟器配置VRRP-详细
  • 【MySQL — 数据库基础】深入解析MySQL的聚合查询
  • 【进程与线程】如何编写一个守护进程
  • Linux——信号的保存与处理
  • 火爆的DeepSeek大模型怎么和智能家居结合?
  • 在 Windows 系统中如何快速进入安全模式的两种方法
  • Android LifecycleOwner 闪退,java 继承、多态特性!
  • 从零开始:使用Jenkins实现高效自动化部署
  • 【Mybatis】动态 SQL:代码与数据的灵动共舞,奏响数据库查询的华丽乐章
  • 在CT107D单片机综合训练平台上实现外部中断控制LED闪烁
  • BUU34 [BSidesCF 2020]Had a bad day1 【php://filter】
  • 【机器学习】数据预处理之数据归一化
  • Vue 中的自定义指令是什么?如何使用?
  • WPS接入DeepSeek模型