【秋招刷题打卡】Day03-二分系列之-二分答案

Day03-二分系列之-二分答案

给大家推荐一下咱们的 陪伴打卡小屋 知识星球啦,详细介绍 =>笔试刷题陪伴小屋-打卡赢价值丰厚奖励 <=

⏰小屋将在每日上午发放打卡题目,包括:

  • 一道该算法的模版题 (主要以力扣,牛客,acwing等其他OJ网站的题目作为模版)
  • 一道该算法的应用题(主要以往期互联网大厂 笔试真题 的形式出现,评测在咱们的 笔试突围OJ

在这里插入图片描述

小屋day03

咱们的二分系列用的都是 day02 的二分模版~

二分模版介绍:二分模版

有小伙伴可能会问了,既然系统有自带的二分库,为什么我们还要自己手写二分呢?清隆认为主要有以下两点

  • 在二分的其他应用中,手写二分更利于设置 check 条件和实现具体逻辑
  • 加深对二分的理解和提高代码熟练度

今天给大家带来二分答案相关的题

前言

什么是二分答案

说直白点其实就是先 一个答案,然后通过check函数来检查这个答案 是否合法,继而跟新二分的左右端点。

能够二分答案的题需要题目满足具有一定的性质,如单调性、二段性等等。

🎀 模版题

2187. 完成旅途的最少时间

题目描述

给你一个数组 time ,其中 time[i] 表示第 i 辆公交车完成 一趟 旅途 所需要花费的时间。

每辆公交车可以 连续 完成多趟旅途,也就是说,一辆公交车当前旅途完成后,可以 立马开始 下一趟旅途。每辆公交车 独立 运行,也就是说可以同时有多辆公交车在运行且互不影响。

给你一个整数 totalTrips ,表示所有公交车 总共 需要完成的旅途数目。请你返回完成 至少 totalTrips 趟旅途需要花费的 最少 时间。

示例 1:

输入:time = [1,2,3], totalTrips = 5
输出:3
解释:
- 时刻 t = 1 ,每辆公交车完成的旅途数分别为 [1,0,0] 。
  已完成的总旅途数为 1 + 0 + 0 = 1 。
- 时刻 t = 2 ,每辆公交车完成的旅途数分别为 [2,1,0] 。
  已完成的总旅途数为 2 + 1 + 0 = 3 。
- 时刻 t = 3 ,每辆公交车完成的旅途数分别为 [3,1,1] 。
  已完成的总旅途数为 3 + 1 + 1 = 5 。
所以总共完成至少 5 趟旅途的最少时间为 3 。

示例 2:

输入:time = [2], totalTrips = 1
输出:2
解释:
只有一辆公交车,它将在时刻 t = 2 完成第一趟旅途。
所以完成 1 趟旅途的最少时间为 2 。

解题思路

时间越多,可以完成的旅途也就越多,有 单调性,可以二分答案

在二分之前需要设置区间左右端。

  • 左端点:答案的最小可能值

  • 右端点:答案的最大可能值

  • 当然实际运用中,左端点可以设置的更小点也没事,右端点同理

现在我们尝试来进行 答案,假设当前答案为 X:

那么可以完成的旅途数量为: ∑ i = 0 n − 1 ⌊ x t i m e [ i ] ⌋ \sum_{i=0}^{n - 1} \lfloor \frac{x}{time[i]} \rfloor i=0n1time[i]x

如果比 totalTrips 大了,说明 X 还能继续缩小,那么跟新(左移)右端点,否则跟新(右移)左端点。

此时我们发现在 check 函数判断之后 需要跟新的是右端点,所以使用 第一个二分模版

时间复杂度:O(nlog⁡U),其中 n 为time 的长度,U 为 二分设置的区间长度

参考代码

  • Python

    class Solution:
        def minimumTime(self, time: List[int], totalTrips: int) -> int:
            l, r = 0, int(1e18) + 10 #  设置左右端点
            
            def check(x: int) -> bool:
                sum = 0
                for t in time:
                    sum += x // t
                    if sum >= totalTrips:
                        return True
                return False
            
            while l < r:
                mid = (l + r) // 2
                if check(mid):
                    r = mid
                else:
                    l = mid + 1
            
            return l
    
    
  • Java

    import java.util.List;
    
    class Solution {
        public long minimumTime(int[] time, int totalTrips) {
            long l = 0, r = (long)1e18 + 10; // 设置左右端点
            
            while (l < r) {
                long mid = l + (r - l) / 2;
                if (check(time, mid, totalTrips)) {
                    r = mid;
                } else {
                    l = mid + 1;
                }
            }
            return l;
        }
    
        private boolean check(int[] time, long x, int totalTrips) {
            long sum = 0;
            for (int t : time) {
                sum += x / t;
                if (sum >= totalTrips) {
                    return true;
                }
            }
            return false;
        }
    }
    
    
  • Cpp

    class Solution {
    public:
        long long minimumTime(vector<int>& time, int totalTrips) {
            long long l = 0, r = 1e18 + 10; // 设置左右端点
            auto check = [&](long long x) -> bool{
                long long sum = 0;
                for(int t : time)
                {
                    sum += x / t;
                    if(sum >= totalTrips) return true;
                }
                return false;
            };
            while(l < r)
            {
                long long mid = l + r >> 1; 
                if(check(mid)) r = mid;
                else
                    l = mid + 1;
            }
            return l;
        }
    };
    

🍰 笔试真题

  • 该题来自今年 华为春招 的笔试题,出现在笔试第一题。

K小姐的购物系统调度

评测链接🔗

问题描述

K小姐负责维护一个购物系统,该系统面临着来自多个客户端的请求。为了应对系统的性能瓶颈,需要实现一个降级策略,以防止系统超负荷。

系统需要确定一个请求调用量的最大阈值 v a l u e value value。如果所有客户端的请求总量未超过系统的最大承载量 c n t cnt cnt,则所有请求均可正常处理,此时返回 − 1 -1 1。否则,超过 v a l u e value value 的客户端调用量需要被限制在 v a l u e value value,而未超过 v a l u e value value 的客户端可以正常请求。要求计算可以接受的最大 v a l u e value value,以便尽可能地满足更多的请求。

输入格式

第一行包含 n n n 个空格分隔的正整数 R 1 , R 2 , . . . , R n R_1, R_2, ..., R_n R1,R2,...,Rn,表示每个客户端在一定时间内发送的交易请求数量。

第二行包含一个正整数 c n t cnt cnt,表示购物系统的最大调用量。

输出格式

输出一个整数,表示系统能够接受的最大请求调用量的阈值 v a l u e value value

样例输入

1 4 2 5 5 1 6
13

样例输出

2

解释说明

若将 v a l u e value value 设置成 6 6 6 1 + 4 + 2 + 5 + 5 + 1 + 6 > 13 1+4+2+5+5+1+6>13 1+4+2+5+5+1+6>13 不符合。

v a l u e value value 设置为 2 2 2 1 + 2 + 2 + 2 + 2 + 1 + 2 = 12 < 13 1+2+2+2+2+1+2=12<13 1+2+2+2+2+1+2=12<13 符合。

可以证明 v a l u e value value 最大为 2 2 2

评测数据与规模

  • 0 < n ≤ 1 0 5 0 < n \le 10^5 0<n105
  • 0 ≤ R i ≤ 1 0 5 0 \le R_i \le 10^5 0Ri105
  • 0 ≤ c n t ≤ 1 0 9 0 \le cnt \le 10^9 0cnt109

题解

我们先来判断 题目答案是否有 单调性

  1. 当阈值 v a l u e value value 变小时,请求量会被限制会变多,总的请求量就会减小
  2. 当阈值 v a l u e value value 变大时,请求量会被限制会变少,总的请求量就会变大.

所以 v a l u e value value 最大,答案最大,因此答案具有 单调性

因此我们可以尝试 一个答案 x x x

  • 设置 x x x 的左右边界, 左边界可以设置为 0 0 0 ,右边界最大为 m a x ( R i ) max(R_i) max(Ri),其中 0 < i < n 0 < i < n 0<i<n
  • 每次通过 x x x ,对当前的请求量求和,并和 c n t cnt cnt 做比较。
  • 判断当前 x x x 是否满足条件,如果满足,则尝试猜更大的 x x x,即跟新(右移)左端点
  • 因为是右移左端点,所以这里采用二分的 第二个模版

时间复杂度: O ( n log ⁡ ( n ) ) O(n\log(n)) O(nlog(n))

AC代码

  • Java
import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        List<Integer> list = new ArrayList<>();
        
        // 读取所有输入的整数
        while (sc.hasNextInt()) {
            int x = sc.nextInt();
            list.add(x);
        }

        int[] nums = new int[list.size()];
        
        // 将List转为数组
        for (int i = 0; i < list.size(); i++) {
            nums[i] = list.get(i);
        }

        int left = 0;
        int maxv = Arrays.stream(nums).max().getAsInt(); // 找到数组中的最大值
        int right = maxv;

        // 二分查找最大值
        while (left < right) {
            int mid = (left + right + 1) / 2;
            if (check(nums, mid)) {
                left = mid;
            } else {
                right = mid - 1;
            }
        }

        // 输出结果
        if (right == maxv) {
            System.out.println(-1);
        } else {
            System.out.println(left);
        }
    }

    // 检查是否满足条件
    private static boolean check(int[] nums, int value) {
        long sum = 0;
        for (int i = 0; i < nums.length - 1; i++) {
            sum += Math.min(nums[i], value);
        }
        return sum <= nums[nums.length - 1];
    }
}

  • Cpp

    #include <iostream>
    #include <vector>
    #include <algorithm>
    using namespace std;
    
    bool check(vector<int>& nums, int value) {
        long long sum = 0;
        for (int i = 0; i < nums.size() - 1; ++i) {
            sum += min(nums[i], value);
        }
        return sum <= nums.back(); // nums.back() 返回最后一个元素
    }
    
    int main() {
        vector<int> nums;
        int x;
        
        // 读取所有输入的整数
        while (cin >> x) {
            nums.push_back(x);
        }
    
        int left = 0;
        int maxv = *max_element(nums.begin(), nums.end()); // 找到数组中的最大值
        int right = maxv;
    
        // 二分查找最大值
        while (left < right) {
            int mid = (left + right + 1) / 2;
            if (check(nums, mid)) {
                left = mid;
            } else {
                right = mid - 1;
            }
        }
    
        // 输出结果
        if (right == maxv) {
            cout << -1 << endl;
        } else {
            cout << left << endl;
        }
    
        return 0;
    }
    
    
  • Python

    def check(nums, value):
        total = 0
        for num in nums[:-1]:  # 排除最后一个元素
            total += min(num, value)
        return total <= nums[-1]  # 检查条件是否满足
    
    def main():
        import sys
        input = sys.stdin.read
        nums = list(map(int, input().split()))  # 读取所有输入的整数
    
        left = 0
        maxv = max(nums)  # 找到数组中的最大值
        right = maxv
    
        # 二分查找最大值
        while left < right:
            mid = (left + right + 1) // 2
            if check(nums, mid):
                left = mid
            else:
                right = mid - 1
    
        # 输出结果
        if right == maxv:
            print(-1)
        else:
            print(left)
    
    if __name__ == "__main__":
        main()
    
    

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/751634.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

React 服务器渲染 Suspense 组件

React 服务器渲染支持 Suspense 组件&#xff0c;Suspense 在子组件未加载成功时会显示 fallback 组件。服务器渲染的时候&#xff0c;React 如何处理 Suspense 组件的呢&#xff1f;由于 Suspense 不同状态下&#xff0c;显示的内容不同&#xff0c;客户端展示时需要区分状态&…

GuLi商城-商品服务-API-三级分类-删除-页面效果

一步步学习Vue太慢了&#xff0c;准备跳过前端的学习&#xff0c;直接使用前端完整的项目 下载依赖npm install&#xff0c;会报错&#xff0c;排查了好久 我安装的是Node14&#xff0c;所以必须要安装4.14 Vscode终端输入&#xff1a;npm install node-sass4.14 输入&#x…

js异常处理方案

文章目录 异常处理方案同步代码的异常处理Promise 的异常处理async await 的异常处理 感谢阅读&#xff0c;觉得有帮助可以点点关注点点赞&#xff0c;谢谢&#xff01; 异常处理方案 在JS开发中&#xff0c;处理异常包括两步&#xff1a;先抛出异常&#xff0c;然后捕获异常。…

一站式uniapp优质源码项目模版交易平台的崛起与影响

一、引言 随着信息技术的飞速发展&#xff0c;软件源码已成为推动行业进步的重要力量。源码的获取、交易和流通&#xff0c;对于开发者、企业以及项目团队而言&#xff0c;具有极其重要的意义。为满足市场对高质量源码资源的迫切需求&#xff0c;一站式uniapp优质源码项目模版…

深度学习实验第T1周:实现mnist手写数字识别

>- **&#x1f368; 本文为[&#x1f517;365天深度学习训练营](https://mp.weixin.qq.com/s/0dvHCaOoFnW8SCp3JpzKxg) 中的学习记录博客** >- **&#x1f356; 原作者&#xff1a;[K同学啊](https://mtyjkh.blog.csdn.net/)** 目录 目录 一、前言 二、我的环境 三、…

【数据集划分——针对于原先图片已经整理好类别】训练集|验证集|测试集

目标&#xff1a;用split-folders进行数据集划分 学习资源&#xff1a;https://www.youtube.com/watch?vC6wbr1jJvVs 努力的小巴掌 记录计算机视觉学习道路上的所思所得。 现在已经有了数据集&#xff0c;并且&#xff0c;注意&#xff0c;是已经划分好类别的&#xff01; …

esp12实现的网络时钟校准

网络时间的获取是通过向第三方服务器发送GET请求获取并解析出来的。 在本篇博客中&#xff0c;网络时间的获取是一种自动的行为&#xff0c;当系统成功连接WiFi获取到网络天气后&#xff0c;系统将自动获取并解析得到时间和日期&#xff0c;为了减少误差每两分钟左右进行一次校…

【Docker】创建 swarm 集群

目录 1. 更改防火墙设置 2. 安装 Docker 组件 3. 启动 Docker 服务&#xff0c;并检查服务状态。 4. 修改配置文件&#xff0c;监听同一端口号。 5. 下载 Swarm 组件 6. 创建集群&#xff0c;加入节点 7. 启动集群 8. 查询集群节点信息 9. 查询集群具体信息 10. 查询…

用Python设置Excel工作表网格线的隐藏与显示

Excel表格界面的直观性很大程度上得益于表格中的网格线设计&#xff0c;这些线条帮助用户精确对齐数据&#xff0c;清晰划分单元格。网格线是Excel界面中默认显示的辅助线&#xff0c;用于辅助定位&#xff0c;与单元格边框不同&#xff0c;不影响打印输出。然而&#xff0c;在…

【Linux:文件描述符】

文件描述符&#xff1a; 文件描述符的分配原则&#xff1a;最小未分配原则 每一个进程中有一个task_struct结构体&#xff08;PCB)&#xff0c;而task_struct中含有struct file_sturct*file的指针&#xff0c;该指针指向了一个struct files_struct的结构体该结构体中含有一个f…

Python27 神经网络中的重要概念和可视化实现

1. 神经网络背后的直观知识 神经网络的工作方式非常相似&#xff1a;它接受多个输入&#xff0c;经过多个隐藏层中的多个神经元进行处理&#xff0c;并通过输出层返回结果&#xff0c;这个过程在技术上称为“前向传播”。 接下来&#xff0c;将神经网络的输出与实际输出进行比…

Java | Leetcode Java题解之第202题快乐数

题目&#xff1a; 题解&#xff1a; class Solution {private static Set<Integer> cycleMembers new HashSet<>(Arrays.asList(4, 16, 37, 58, 89, 145, 42, 20));public int getNext(int n) {int totalSum 0;while (n > 0) {int d n % 10;n n / 10;totalS…

Windows下activemq开启jmx

1.activemq版本信息 activemq&#xff1a;apache-activemq-5.18.4 2.Windows下activemq开启jmx 1.进入activemq conf目录&#xff0c;备份activemq.xml文件 2.编辑activemq.xml文件&#xff0c;在broker节点增加useJmx"true" <broker xmlns"http://active…

Vuetify3:​快捷回到顶部

在Vuetify 3中&#xff0c;要实现回到顶部&#xff0c;我们需要创建悬浮按钮&#xff0c;如下&#xff1a; <template><v-list><div class"position-fixed right-0 bottom-0" style"top:50%;"><v-list-item ><v-btn icon"…

黑马点评项目总结1-使用Session发送验证码和登录login和 使用Redis存储验证码和Redis的token登录

黑马先是总结了从session实现登录&#xff0c;然后是因为如果使用了集群方式的服务器的话&#xff0c;存在集群共享session互相拷贝效率低下的问题&#xff0c;接着引出了速度更快的内存型的kv数据库Redis&#xff0c; 使用Session发送验证码和登录login 举个例子&#xff1a…

『Django』模型入门教程-操作MySQL

theme: smartblue 点赞 关注 收藏 学会了 本文简介 一个后台如果没有数据库可以说废了一半。日常开发中大多数时候都在与数据库打交道。Django 为我们提供了一种更简单的操作数据库的方式。 在 Django 中&#xff0c;模型(Model)是用来定义数据库结构的类。每个模型类通常对…

kali下安装使用蚁剑(AntSword)

目录 0x00 介绍0x01 安装0x02 使用1. 设置代理2. 请求头配置3. 编码器 0x00 介绍 蚁剑&#xff08;AntSword&#xff09;是一个webshell管理工具。 官方文档&#xff1a;https://www.yuque.com/antswordproject/antsword 0x01 安装 在kali中安装蚁剑&#xff0c;分为两部分&am…

matlab绘制二维曲线,如何设置线型、颜色、标记点类型、如何设置坐标轴、matlab 图表标注、在图中标记想要的点

matlab绘制二维曲线&#xff0c;如何设置线型、颜色、标记点类型、如何设置坐标轴、matlab 图表如何标注、如何在图中标记想要的点 matlab绘制二维曲线&#xff0c;如何在图中标记想要的点。。。如何设置线型、颜色、标记点类型。。。如何设置坐标轴。。。matlab 图表标注操作…

视频网站系统

摘 要 随着互联网的快速发展和人们对视频内容的需求增加&#xff0c;视频网站成为了人们获取信息和娱乐的重要平台。本论文基于SpringBoot框架&#xff0c;设计与实现了一个视频网站系统。首先&#xff0c;通过对国内外视频网站发展现状的调研&#xff0c;分析了视频网站的背景…