【算法训练】二分搜索的拓展应用

根据labuladong算法小抄里东哥的总结。有一系列的问题都可以用二分搜索的泛化来解决。

首先需要从题目中抽象出一个自变量x,一个关于x的函数f,以及一个目标值target
同时这三个元素得满足以下条件
(1)f必须是x上的单调函数,单调递增或者单调递减都可以
(2)题目是让你计算满足约束条件的f(x)==target时的x的值。

下面以例题来帮助理解加深这一思路。

一、爱吃香蕉的珂珂 875

在这里插入图片描述

1、分析

可以看到该题是满足我们开头说的条件的。自变量就是吃香蕉的速度k,然后写一个以k为自变量,然后吃完香蕉所需要的时间hour为因变量的函数f。然后就可以用二分搜索的方法取找最小k,也就是我们要找的是左边界。
其中需要注意的一点是,自变量的左右边界也是需要特别注意的。这里她最少每小时吃1根,最多可以一小时就吃完数量最多的那些香蕉。这样left和right就定了。接下来常规寻找左边界套路即可。
具体见代码。

2、代码

python

class Solution:
    def minEatingSpeed(self, piles: List[int], h: int) -> int:
        # 确定自变量的最值,最小值是多少,最大值是多少(这里是一小时吃香蕉的根数,最少吃一根,最多就是这堆香蕉中的数量最大值)
        left,right = 1,max(piles) 
        # 辅助函数,是跟自变量相关的单调函数
        def fn(x,piles):
            hour = 0
            for p in piles:
                hour += p//x
                if p%x!=0:
                    hour += 1
            return hour
        while left<=right:
            mid = left+(right-left)//2
            # 考虑我们到底要找的是左边界还是右边界
            if fn(mid,piles)==h: 
                right = mid-1
            elif fn(mid,piles)<h:
                right = mid-1 #考虑,怎样让fn的值变大一点
            elif fn(mid,piles)>h:
                left = mid+1 #考虑,怎样让fn的值变小一点
        return left

js

/**
 * @param {number[]} piles
 * @param {number} h
 * @return {number}
 */
var fn = function(x,piles){
    let hour = 0;
    for(let p of piles){
        hour += Math.floor(p/x);
        if(p%x!==0){
            hour += 1;
        }
    }
    return hour;
}
var minEatingSpeed = function(piles, h) {
    // 注意到js求数组最大值,以及底板除的方法
    let left=1,right=Math.max(...piles); 
    while(left<=right){
        let mid = left+Math.floor((right-left)/2);
        if(fn(mid,piles)==h){
            right = mid-1;
        }else if(fn(mid,piles)>h){
            left = mid+1;
        }else if(fn(mid,piles)<h){
            right = mid-1;
        }
    }
    return left;

};

二、在D天内送达包裹的能力 1011

在这里插入图片描述

1、分析

首先还是按照要求抽象出三个要素,然后找到自变量的范围。由于包裹是不能拆掉的,所以left值应该是所有weights元素中的最大值。right则是weights数组求和,即一天就运完所有包裹。

2、代码

class Solution:
    def shipWithinDays(self, weights: List[int], days: int) -> int:
        left,right = max(weights),sum(weights) #注意到选择边界也是需要特别注意的,需要与题目要求挂钩。例如包裹是不能分开装的,所以最小运载能力应该等于weights数组最大值,而最大运载能力则是满足一条运完等于所有weight的和
        def fn(x,weights):
            day,temp = 0,0
            for w in weights:
                temp += w 
                if temp>x:
                    day += 1
                    temp = w 
            return day+1 #注意到,如果加上最后一个包裹如果触发了day+1条件,则需要对最后这个包裹进行单独运输;如果加上最后一个包裹也没有触发day+1条件,那么需要对最后这一批包裹进行单独运输。所以最后返回需要+1
        while left<=right:
            mid = left+(right-left)//2
            if fn(mid,weights)==days:
                right = mid-1 #因为我们找最低运载能力,所以是找左边界!
            elif fn(mid,weights)<days:
                right = mid-1
            elif fn(mid,weights)>days:
                left = mid+1
        return left

js

/**
 * @param {number[]} weights
 * @param {number} days
 * @return {number}
 */
var fn = function(x,weights){
    let day=0,temp=0;
    for(let w of weights){
        temp += w;
        if(temp>x){
            day += 1;
            temp = w;
        }
    }
    return day+1;
}
var shipWithinDays = function(weights, days) {
    function sum(arr){
        return arr.reduce((pre,cur)=>{
            return pre+cur
        })
    }
    let left=Math.max(...weights),right=sum(weights);
    while(left<=right){
        let mid = left+Math.floor((right-left)/2);
        let need_ = fn(mid,weights);
        if(need_==days){
            right = mid-1;
        }else if(need_<days){
            right = mid-1;
        }else if(need_>days){
            left = mid+1;
        }
    }
    return left;
};

三、分割数组的最大值

在这里插入图片描述

1、分析

其实这道题和上一道运输题是一样的。我觉得需要绕一下的就是二分搜索的边界
因为至少是一个元素为一个子数组,所以left值应该是nums中元素的最大值。而right则是将整个数组当作一个子数组,然后求和。

具体见代码

2、代码

class Solution:
    def splitArray(self, nums: List[int], m: int) -> int:
        left,right = max(nums),sum(nums) #注意到子数组的和的最大值,那么这个值的最小情况:每个元素单独成一个子数组时,取所有元素中的最大值;最大的情况:原数组本身作为一个子数组,所以为所有元素之和。
        def fn(x,nums):  #找到子数组最大值和子数组数量之间的关系
            res,cur = 0,0
            for n in nums:
                cur += n 
                if cur>x: #每当元素之和加起来大于x了,就证明得另分为一个子数组了,所以res+1
                    res += 1
                    cur = n 
            return res+1 #这题和船运1011题很像,也就是剩下的元素会单独构成一个子数组的
        while left<=right:
            mid = left+(right-left)//2
            need_ = fn(mid,nums)
            if need_==m:
                right = mid-1 #明确到我们要找的是左边界
            elif need_<m:
                right = mid-1
            elif need_>m:
                left = mid+1
        return left

js

/**
 * @param {number[]} nums
 * @param {number} m
 * @return {number}
 */
var fn = function(x,nums){
    let res=0,cur=0;
    for(let n of nums){
        cur += n;
        if(cur>x){
            res += 1;
            cur = n;
        }
    }
    return res+1
}
var splitArray = function(nums, m) {
    function sum(arr){
        return arr.reduce((pre,cur)=>{
            return pre+cur;
        })
    }
    let left=Math.max(...nums),right=sum(nums);
    while(left<=right){
        let mid = left+Math.floor((right-left)/2);
        let need_ = fn(mid,nums);
        if(need_==m){
            right = mid-1;
        }else if(need_<m){
            right = mid-1;
        }else if(need_>m){
            left = mid+1;
        }
    }
    return left;
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
【项目介绍】 基于Java和CNN网络实现垃圾识别分类安卓APP源码+项目说明文档.zip 1. 功能 基于卷积神经网络的垃圾分类,并将深度学习模型整合到安卓应用,实现了生活垃圾的图像识别与分类。 安卓应用主要包含垃圾搜索、图像识别、题目测试和知识科普等功能模块。垃圾搜索中包含 3986 种物品,图像识别包含 143 种物品,覆盖了居民常见生活垃圾,可以有效辅助人们进行垃圾分类。(自使用SQLite数据库导入项目内txt数据) 算法采用基于MobileNetV2的深度学习分类模型进行迁移学习。MobileNetV2模型于2018年被谷歌发布,是MobileNet的改进版,引入了反向残差结构和线性瓶颈结构提高模型性能。模型优化包括 dropout 正则化、Adam优化器等。图像主要筛选整理于华为垃圾分类挑战赛数据集,并且进行了随机水平翻转、图像旋转等数据增强操作,其中 90%用于训练集,10%用于验证集。 图像识别运行流程为安卓客户端调用图库或图像头权限->选择图片->图片上传到后端->后端使用命令行操作调用算法predict->后端得到预测结果->返回至前端(后续可使用TensorFlow Mobile 把深度学习模型转化为pb格式文件并部署到安卓客户端) 2. 环境配置 TensorFlow2.0 Android studio(安卓开发IDE、Java) springboot框架(maven管理,注意导入的项目文件夹是否正确) 【备注】 1.项目代码均经过功能验证ok,确保稳定可靠运行。欢迎下载食用体验! 2.主要针对各个计算机相关专业,包括计算机科学、信息安全、数据科学与大数据技术、人工智能、通信、物联网等领域的在校学生、专业教师、企业员工。 3.项目具有丰富的拓展空间,不仅可作为入门进阶,也可直接作为毕设、课程设计、大作业、初期项目立项演示等用途。 4.当然也鼓励大家基于此进行二次开发。在使用过程中,如有问题或建议,请及时沟通。 5.期待你能在项目中找到乐趣和灵感,也欢迎你的分享和反馈!
数据挖掘在各行业的应用论文 数据仓库与数据挖掘.caj 空间数据挖掘技术.caj 数据仓库与数据挖掘技术及其在科技情报业的应用前景.caj 相关案件的数据挖掘.caj 数据挖掘技术.caj 一种实时过程控制中的数据挖掘算法研究.caj EIS 环境下的数据挖掘技术的研究.caj 数据挖掘及其工具的选择.caj 数据挖掘技术与中国商业银行业务发展策略.caj 数据挖掘工具DMTools的设计与实现.caj 数据仓库、数据挖掘在银行中的应用.caj 基于信息熵的地学空间数据挖掘模型.caj 数据挖掘及其在商业银行中的应用.caj 数据挖掘与决策支持系统.caj 数据仓库、数据集市和数据挖掘.caj 数据仓库与数据挖掘1.caj IDSS 中数据仓库和数据挖掘的研究与实现.caj 基于粗糙集理论的数据挖掘模型.caj 数据挖掘及其在 SXWG_EIS 中的应用.caj 数据挖掘——技术与应用综述.caj 挖掘转移规则一种新的数据挖掘技术.caj 以地物识别和分类为目标的高光谱数据挖掘.caj 数据挖掘与虚拟数据库.caj 数据挖掘与电力系统.caj 浅说数据挖掘.caj 带Rough算子的决策规则及数据挖掘中的软计算.caj 数据挖掘系统的一种实现策略.caj 信息检索中的数据挖掘技术.caj 红外光谱谱图库中的数据挖掘.caj 中介粗集及其在数据挖掘中的应用.caj 数据挖掘在音高变化规律学习中的应用.caj 数据挖掘技术在财经领域的应用.caj 知识发现和数据挖掘的研究.caj 数据仓库与数据挖掘技术浅谈.caj 用户访问模式数据挖掘的模型与算法研究.caj 数据仓库的建设与数据挖掘技术浅析.caj 分类特征规则的数据挖掘技术.caj 数据挖掘技术的主要方法及其发展方向.caj OLAP和数据挖掘技术在Web日志上的应用.caj 数据挖掘技术12.caj 数据挖掘技术初探.caj 探索式数据挖掘模型的讨论.caj 前向网络bp算法在数据挖掘中的运用.caj 数据挖掘在Internet信息导航系统中的应用研究.caj 数据挖掘技术123.caj 基于粗糙集(Rough set)的数据挖掘及其实现.caj 数据挖掘技术在建模、优化和故障诊断中的应用.caj FCC油品质量指标智能监测系统的数据挖掘与修正技术.caj 一种测试数据挖掘算法的数据源生成方法.caj 基于数据挖掘的类比推理技术在石油产品分析系统中的实现.caj 神经网络在数据挖掘中的应用研究.caj 数据挖掘方法的评述.caj 基于数据挖掘的类比推理技术在石油产品分析系统中的实现1.caj 一个面向电子商务的数据挖掘系统的设计与实现.caj 数据挖掘技术在煤与瓦斯突出预测中的应用研究.caj 基于数据抽取器实现数据挖掘.caj 基于数据挖掘的群决策模型.caj 基于数据挖掘的普通话韵律规则学习.caj 数据挖掘和知识发现的技术方法.caj 可视化数据挖掘技术及其应用.caj 神经网络数据挖掘方法中的数据准备问题.kdh 基于CORBA的数据挖掘工具KDD-DC.caj 基于高校人事信息库的数据挖掘研究.caj 数据挖掘管理系统.caj 电信网告警数据库中的数据挖掘.caj 数据挖掘原理、方法及其应用.caj 一种基于数据仓库的数据挖掘系统的结构框架.caj OLAP与数据挖掘一体化模型的分析与讨论.caj 一种新型数据分析技术——数据挖掘.caj aaa数据挖掘和数据仓库及其在电信业中的应用.caj 数据挖掘技术及其应用.caj 数据挖掘中概念树的标准、生成和实现.kdh XML与面向Web的数据挖掘技术.caj 数据挖掘和数据仓库及其在电信业中的应用.caj 数据挖掘技术及其在地学中的应用.caj 结合数据融合和数据挖掘的医疗监护报警.caj 基于多媒体数据库的数据挖掘系统原型.caj 数据挖掘技术1.caj 股票信息的数据挖掘.caj 多媒体数据挖掘的相关媒体特征库方法.caj 基于数据挖掘的深部采场岩爆知识的自动获取.caj 空间数据挖掘理论与方法的研究.caj 金融数据挖掘中的非线性相关跟踪技术(英文).caj 数据挖掘技术的一个应用模型.caj DNA中的数据挖掘和启动子识别.caj 数据仓库与数据挖掘12.caj 数据挖掘系统设计.caj 数据挖掘方法的研究.caj 用数据挖掘技术优选侧钻井井位.caj 关注政府上网后的数据挖掘.kdh 数据挖掘技术及其在电力系统中的应用.caj 目前数据挖掘算法的评价.caj 基于数据挖掘的地下硐室围岩稳定性判别.caj 基于属性分类的数据挖掘方法.caj 基于数据挖掘模型的高压输电线系统故障诊断.caj 用于建模、优化、故障诊断的数据挖掘技术.caj 格子机数据挖掘方法.caj 数据挖掘及其在电力系统中的应用.kdh 用于

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值