2439. 最小化数组中的最大值

        哈喽,兄弟们,今天遇到非常有意思的一道题目,设计非常巧妙,非常有技巧性,来跟大家分享一下:

一:题目描述:

        

 

二:题目分析:

        题目描述的非常清晰易懂,大概就是给你一个数组,你可以操作无限次数,每次找到一个下标为i的数字,这个数字必须不是第一个数字,然后执行该数字减一,同时该下标的前一位置的数字加一,操作无限次数,然后找出最大的数字 ,并且在全部数字中不存在比该数字更小的最大值。拿到该题目最暴力的解法就是:单独写出一个方法,每次循环找出最大值的下标,然后在数组中进行操作,在最大数字的基础上执行减1操作,然后在前一个位置的数字进行加一操作,一次循环遍历,代码如下:

但是由于数据量的原因,超时。

        这道题目就好比层次不齐的山峰,要想其可能的将山峰变得平整,就是把高的部分填入低的部分。这道题目一样,仔细分析,题目说白了就是找到一个基准,假设为x,遍历时,假如该数字大于x,则需要把多余的部分进行存储起来,因为这部分是要较小的数字进行分摊的,同样假如一个数字小于等于x,那么代表这个数字没有超过基准,可以分担超过基准数字的部分。 问题来了,怎么不断的寻找合适的基准的,答案就是二分,通过不断的调整中间值,来缩小范围。

class Solution {

    public int minimizeArrayValue(int[] nums) {

        int left = nums[0],right = 1000000000;

        while(left < right) {

            long buff = 0;

            boolean flag = true;

            int x = (right - left) / 2 + left;

            for(int i = 0;i < nums.length;i++) {

                if(nums[i] > x) {

                    buff -= (nums[i] - x);

                }else {

                    buff += (x - nums[i]);

                }

                if(buff < 0) {

                    flag = false;

                    break;

                }

            }

            if(flag) {

                right = x;

            }else {

                left = x + 1;

            }

        }

        return left;

    }

}

 假如看不懂的兄弟们,可以参考一下该视频:【LeetCode】2439. Minimize Maximum of Array_哔哩哔哩_bilibili

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值