前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >阿里今年的年终奖。。

阿里今年的年终奖。。

作者头像
宫水三叶的刷题日记
发布2024-05-03 13:51:21
1630
发布2024-05-03 13:51:21
举报

题目描述

平台:LeetCode

题号:1760

给你一个整数数组 nums,其中 nums[i] 表示第 i 个袋子里球的数目。同时给你一个整数 maxOperations

你可以进行如下操作至多 maxOperations 次:

  • 选择任意一个袋子,并将袋子里的球分到 2 个新的袋子中,每个袋子里都有 正整数 个球。
    • 比方说,一个袋子里有 5 个球,你可以把它们分到两个新袋子里,分别有 1 个和 4 个球,或者分别有 2 个和 3 个球。你的开销是单个袋子里球数目的 最大值 ,你想要 最小化 开销。

请你返回进行上述操作后的最小开销。

示例 1:

代码语言:javascript
复制
输入:nums = [9], maxOperations = 2

输出:3

解释:
- 将装有 9 个球的袋子分成装有 6 个和 3 个球的袋子。[9] -> [6,3] 。
- 将装有 6 个球的袋子分成装有 3 个和 3 个球的袋子。[6,3] -> [3,3,3] 。
装有最多球的袋子里装有 3 个球,所以开销为 3 并返回 3 。

示例 2:

代码语言:javascript
复制
输入:nums = [2,4,8,2], maxOperations = 4

输出:2

解释:
- 将装有 8 个球的袋子分成装有 4 个和 4 个球的袋子。[2,4,8,2] -> [2,4,4,4,2] 。
- 将装有 4 个球的袋子分成装有 2 个和 2 个球的袋子。[2,4,4,4,2] -> [2,2,2,4,4,2] 。
- 将装有 4 个球的袋子分成装有 2 个和 2 个球的袋子。[2,2,2,4,4,2] -> [2,2,2,2,2,4,2] 。
- 将装有 4 个球的袋子分成装有 2 个和 2 个球的袋子。[2,2,2,2,2,4,2] -> [2,2,2,2,2,2,2,2] 。
装有最多球的袋子里装有 2 个球,所以开销为 2 并返回 2 。

示例 3:

代码语言:javascript
复制
输入:nums = [7,17], maxOperations = 2

输出:7

提示:

1 <= nums.length <= 10^5
1 <= maxOperations, nums[i] <= 10^9

二分

最小化不超过 max 次划分操作后的单个袋子最大值,我们将其称为「划分值」。

答案具有二段性:若使用

k \leq \max

次划分操作后可达到最小划分值,此时减少划分操作次数,会使得划分值非单调上升。

因此我们可以二分答案,从而将问题进行等价转换:

**假设当前二分到的值为

limit

,我们需要实现一个线性复杂度为 check 函数,判断能否使用不超过

\max

次划分次数,来使得划分值不超过

limit

**:

  • 若能满足,说明
[limit, +\infty]

范围的划分值,均能使用不超过

\max

次的实现,此时让

r = limit
  • 若不能满足,比
limit

更小的划分值,则更无法在

\max

次操作中满足,说明

[1, limit]

范围划分值均不是答案,此时让

l = limit + 1

考虑如何实现 check 函数,从前往后处理每个

nums[i]

,根据

nums[i]

与当前限制

limit

的大小关系进行分情况讨论:

nums[i] \leq limit

:说明当前袋子不会成为瓶颈,无须消耗划分次数

nums[i] > limit

:此时需要对当前袋子进行划分,直到满足单个袋子球的数量不超过

limit

为止,由于每次划分相当于增加一个袋子,而将

nums[i]

划分成若干个不超过

limit

个球的袋子,需要

\left \lceil \frac{nums[i]}{limit} \right \rceil

个袋子,减去原本的一个,共需要增加

\left \lceil \frac{nums[i]}{limit} \right \rceil

个新袋子,即划分

\left \lceil \frac{nums[i]}{limit} \right \rceil

Java 代码:

代码语言:javascript
复制
class Solution {
    public int minimumSize(int[] nums, int max) {
        int l = 1, r = 0x3f3f3f3f;
        while (l < r) {
            int mid = l + r >> 1;
            if (check(nums, mid, max)) r = mid;
            else l = mid + 1;
        }
        return r;
    }
    boolean check(int[] nums, int limit, int max) {
        int cnt = 0;
        for (int x : nums) cnt += Math.ceil(x * 1.0 / limit) - 1;
        return cnt <= max;
    }
}

C++ 代码:

代码语言:javascript
复制
class Solution {
public:
    int minimumSize(vector<int>& nums, int maxv) {
        int l = 1, r = 0x3f3f3f3f;
        while (l < r) {
            int mid = l + r >> 1;
            if (check(nums, mid, maxv)) r = mid;    
            else l = mid + 1;
        }
        return r;
    }
    bool check(vector<int>& nums, int limit, int maxv) {
        int cnt = 0;
        for (int x : nums) cnt += ceil(x * 1.0 / limit) - 1;
        return cnt <= maxv;
    }
};

Python 代码:

代码语言:javascript
复制
class Solution:
    def minimumSize(self, nums: List[int], maxv: int) -> int:
        def check(nums, limit, maxv):
            return sum([(x + limit - 1) // limit - 1 for x in nums]) <= maxv
        l, r = 1, 0x3f3f3f3f
        while l < r:
            mid = l + r >> 1
            if check(nums, mid, maxv):
                r = mid
            else:
                l = mid + 1
        return r

TypeScript 代码:

代码语言:javascript
复制
function minimumSize(nums: number[], max: number): number {
    function check(nums: number[], limit: number, max: number): boolean {
        let cnt = 0
        for (const x of nums) cnt += Math.ceil(x / limit) - 1
        return cnt <= max
    }
    let l = 1, r = 0x3f3f3f3f
    while (l < r) {
        const mid = l + r >> 1
        if (check(nums, mid, max)) r = mid
        else l = mid + 1
    }
    return r
}
  • 时间复杂度:
O(n \log{M})

,其中

M = 1e9

为值域大小

  • 空间复杂度:
O(1)
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2024-04-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 宫水三叶的刷题日记 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 题目描述
  • 二分
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档