【Leetcode】1793. 好子数组的最大分数

文章目录

题目

题目链接🔗

给你一个整数数组 n u m s nums nums (下标从 0 0 0 开始)和一个整数 k k k 。

一个子数组 ( i , j ) (i, j) (i,j) 的 分数 定义为 m i n ( n u m s i , n u m s i + 1 , . . . , n u m s j ) ∗ ( j − i + 1 ) min(numsi, numsi+1, ..., numsj) * (j - i + 1) min(numsi,numsi+1,...,numsj)∗(j−i+1)。一个 子数组的两个端点下标需要满足 i ≤ k ≤ j i \leq k \leq j i≤k≤j 。

请你返回 子数组的最大可能 分数 。

示例 1
输入 :nums = 1,4,3,7,4,5, k = 3
输出 :15
解释 :最优子数组的左右端点下标是 (1, 5) ,分数为 m i n ( 4 , 3 , 7 , 4 , 5 ) ∗ ( 5 − 1 + 1 ) = 3 ∗ 5 = 15 min(4,3,7,4,5) * (5-1+1) = 3 * 5 = 15 min(4,3,7,4,5)∗(5−1+1)=3∗5=15 。
示例 2:
输入 :nums = 5,5,4,5,4,1,1,1, k = 0
输出 :20
解释 :最优子数组的左右端点下标是 (0, 4) ,分数为 m i n ( 5 , 5 , 4 , 5 , 4 ) ∗ ( 4 − 0 + 1 ) = 4 ∗ 5 = 20 min(5,5,4,5,4) * (4-0+1) = 4 * 5 = 20 min(5,5,4,5,4)∗(4−0+1)=4∗5=20 。
提示

  • 1 ≤ n u m s . l e n g t h ≤ 1 0 5 1 \leq nums.length \leq 10^5 1≤nums.length≤105
  • 1 ≤ n u m s i ≤ 2 ∗ 1 0 4 1 \leq numsi \leq 2 * 10^4 1≤numsi≤2∗104
  • 0 ≤ k < n u m s . l e n g t h 0 \leq k < nums.length 0≤k<nums.length

思路

为了解决这个问题,我们可以使用单调栈进行预处理。我们可以维护两个数组 l e f t left left 和 r i g h t right right,其中 l e f t i lefti lefti 和 r i g h t i righti righti 分别表示 n u m s i numsi numsi 的左边和右边比 n u m s i numsi numsi 小,且离 n u m s i numsi numsi 最近的位置。因此,以 n u m s i numsi numsi 为最小值的最长子数组就应该是 ( l e f t i , r i g h t i ) (lefti, righti) (lefti,righti)。当 k k k 在 ( l e f t i , r i g h t i ) (lefti, righti) (lefti,righti) 范围内时,我们维护 n u m s i × ( r i g h t i − l e f t i − 1 ) numsi × (righti−lefti−1) numsi×(righti−lefti−1) 的最大值即可。

代码

c++ 复制代码
class Solution {
public:
    int maximumScore(vector<int>& nums, int k) {
        int n = nums.size();
        vector<int> left(n, -1), right(n, n);
        stack<int> stk;
        for(int i = 0; i < n; i++) {
            while(!stk.empty() && nums[stk.top()] >= nums[i]) {
                right[stk.top()] = i;
                stk.pop();
            }
            if(!stk.empty()) left[i] = stk.top();
            stk.push(i);
        }
        int ans = 0;
        for(int i = 0; i < n; i++) {
            int l = left[i], r = right[i];
            if(l < k && k < r) {
                ans = max(ans, nums[i]*(r - l - 1));
            }
        }
        return ans;
    }
};

复杂度分析

时间复杂度

  • 预处理阶段的时间复杂度为 O(n),其中 n 是数组的长度。
  • 寻找最大分数时,遍历了数组,时间复杂度为 O(n)。

综上所述,总的时间复杂度为 O(n)。

空间复杂度

  • 使用了额外的数组 left 和 right,它们的空间复杂度均为 O(n)。
  • 使用了一个栈,最坏情况下需要存储整个数组,因此空间复杂度为 O(n)。

综上所述,总的空间复杂度为 O(n)。

结果

总结

通过单调栈预处理出 l e f t left left 和 r i g h t right right 数组,可以在 O ( n ) O(n) O(n) 的时间复杂度内解决这个问题。这种方法利用了单调栈的性质,使得寻找以 n u m s i numsi numsi 为最小值的子数组的左右边界成为可能。

相关推荐
lqqjuly2 分钟前
知识蒸馏:理论、算法与可运行实现
人工智能·深度学习·算法
水上冰石11 分钟前
comfui的sd1.5模型,有多少采样算法,详解每一个采样算法
人工智能·算法
黎阳之光28 分钟前
视频孪生+空天地水工融合,黎阳之光构建智慧水利监测新范式
大数据·人工智能·物联网·算法·安全
凯瑟琳.奥古斯特34 分钟前
子查询原理与实战案例解析
开发语言·数据库·职场和发展·数据库开发
cheems952740 分钟前
[算法手记] 贪心 爬楼梯问题
算法·贪心算法
KaMeidebaby1 小时前
卡梅德生物技术快报|酵母双杂交 cDNA 文库构建与蛋白互作筛选流程
服务器·前端·数据库·人工智能·算法
圣保罗的大教堂1 小时前
leetcode 3300. 替换为数位和以后的最小元素 简单
leetcode
sheeta19981 小时前
LeetCode 每日一题笔记 日期:2026.05.27 题目:3121. 统计特殊字母的数量 II
笔记·算法·leetcode
ST——Jess1 小时前
年度行业趋势研究报告:泛心理数字化赛道“流日推演”的算法困境与高保真交互范式重构
人工智能·算法·架构
Tisfy1 小时前
LeetCode 3300.替换为数位和以后的最小元素:一次遍历
数学·算法·leetcode·模拟