leetcode——第232场周赛—4

原题链接

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

一个子数组 (i, j) 的 分数 定义为 min(nums[i], nums[i+1], …, nums[j]) * (j - i + 1) 。一个 好 子数组的两个端点下标需要满足 i <= k <= j 。

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

由题意可知,左边界<=k<=右边界,则我们可以从下标k开始,逐渐向左右边界扩展,找到最大值。

m i n ( n u m s [ i ] , n u m s [ i + 1 ] , . . . , n u m s [ j ] ) = m i n ( n u m s [ i − 1 ] , n u m s [ i ] , n u m s [ i + 1 ] , . . . , n u m s [ j ] ) min(nums[i], nums[i+1], ..., nums[j])=min(nums[i-1],nums[i], nums[i+1], ..., nums[j]) min(nums[i],nums[i+1],...,nums[j])=min(nums[i1],nums[i],nums[i+1],...,nums[j]),则 m i n ( n u m s [ i ] , n u m s [ i + 1 ] , . . . , n u m s [ j ] ) ∗ ( j − i + 1 ) < m i n ( n u m s [ i − 1 ] , n u m s [ i ] , n u m s [ i + 1 ] , . . . , n u m s [ j ] ) ∗ [ j − ( i − 1 ) + 1 ] min(nums[i], nums[i+1], ..., nums[j]) * (j - i + 1)<min(nums[i-1],nums[i], nums[i+1], ..., nums[j]) * [j - (i -1)+ 1] min(nums[i],nums[i+1],...,nums[j])(ji+1)<min(nums[i1],nums[i],nums[i+1],...,nums[j])[j(i1)+1],即当 n u m s [ i − 1 ] > = m i n ( n u m s [ i ] , n u m s [ i + 1 ] , . . . , n u m s [ j ] ) nums[i-1]>=min(nums[i], nums[i+1], ..., nums[j]) nums[i1]>=min(nums[i],nums[i+1],...,nums[j])时,左指针向左移动一定能取到更大值,右指针同理

代码如下:

class Solution {
    public int maximumScore(int[] nums, int k) {
    	/*bg:左指针  ed:右指针  area:最大可能分数  min:对应公式中的min(nums[i], nums[i+1], ..., nums[j])*/
        int bg=k,ed=k,area=nums[k],min=nums[k];
        /*当左指针未触及到左边界或右指针未触及到右边界时*/
        while (bg > 0 || ed < nums.length-1){
        	/*当左指针未触及到左边界且nums[bg-1]>=min,左指针向左移动一位*/
            while (bg>0&&nums[bg-1]>=min){
                bg--;
            }
            /*当右指针未触及到左边界且nums[ed+1]>=min,右指针向右移动一位*/
            while (ed<nums.length-1&&nums[ed+1]>=min){
                ed++;
            }
            /*计算并更新分数*/
            area=Math.max(area,min*(ed-bg+1));
            /*当左指针触及到边界,且右指针未触及到边界,右指针向右移动*/
            if((bg<=0&&ed<nums.length-1)){
                min=nums[++ed];
            /*当右指针触及到边界,且左指针未触及到边界,左指针向左移动*/
            }else if(bg>0&&ed>=nums.length-1){
                min=nums[--bg];
            /*当左右指针均未触及到边界,选择较大的一方移动*/
            }else if(bg>0&&ed<nums.length-1){
                if(nums[bg-1]>=nums[ed+1]){
                    min=nums[--bg];
                }else{
                    min=nums[++ed];
                }
            }
        }
        return area;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值