[M数学] lc1802. 有界数组中指定下标处的最大值(贪心+二分+数学推公式)

1. 题目来源

链接:1802. 有界数组中指定下标处的最大值

2. 题目解析

直觉的贪心思路,证明看官方题解吧。至于数学思路也推荐看官方题解,一开始确实想着推公式的,最后没走下去。

贪心思路:

  • index 值最大,剩余两边依次递减即可
  • index 值越大,形成后的数组总和越大,越接近 maxSum

所以,可以在不超过 maxSum 二分最大的 arr[index] 是多少即可,也就是二分答案了。

index 作为最大值的下标,如何计算左侧、右侧的元素和,策略如下:

  • 左侧待填充的长度为 index,右侧待填充的长度为 n-index-1
  • 当二分答案值能将这个长度填满时,则意味着这个长度的尾部,不需要用 1 来做最后填充,反之则需要用 1 来做最后填充。
    • 不用 1 填充时,说明 length+1<big 即为等差数列,首项需要单独计算
    • 用 1 填充时,等差数列,首项为 1 / 0

计算过程会超过 int,需要开 long


  • 时间复杂度 O ( l o g n ) O(log_n) O(logn)
  • 空间复杂度 O ( 1 ) O(1) O(1)

class Solution {
public:
    int maxValue(int n, int index, int maxSum) {
        int l = 1, r = maxSum;      // 二分最大值
        while (l < r) {
            int mid = l + r + 1 >> 1;
            if (check(mid, n, index, maxSum)) l = mid;  
            else r = mid - 1; 
        }

        return r;
    }

    // 最大值是 mid,左侧长度为 index(不包括 mid) 右侧长度为 n - index - 1(不包括mid)
    bool check(int mid, int n, int index, int maxSum) {
        int ll = index, lr = n - index - 1;
        return mid + cal(mid, ll) + cal(mid, lr) <= maxSum;
    }

    // 如果 长度+1 < 最大值的话,说明最大值依次递减到数组端点处,还有余值,不用一味填充1
    // 如果 长度+1 >= 最大值的话,说明最大值依次递减到数组断点处,没有余值了,后面的一部分需要填充1了
    // 需要注意不要报 long 了 
    long cal(int big, int length) {
        if (length + 1 < big) {
            int a0 = big - length, an = big - 1;
            return (long)(an + a0) * length / 2;
        } else {
            int ones = length - (big - 1);
            return (long)big * (big - 1) / 2 + ones;
        }
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ypuyu

如果帮助到你,可以请作者喝水~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值