二分算法(优化)

二分算法

一、前言

今天又是一个优化算法------二分算法

二、二分

2.1 概述

在一个有序数组中查找一个数。

每次考察数组当前部分的中间元素,如果中间元素刚好是要找的,就结束搜索过程;如果中间元素小于所查找的值,那么左侧的只会更小,不会有所查找的元素,只需到右侧查找;如果中间元素大于所查找的值,同理,只需到左侧查找。

2.2 代码

cpp 复制代码
int binarySearch(int a[],int size,int target)
{
    int l=0,r=size-1;
    int ans=-1;
    while(l<=r)
    {
        int mid=l+(r-l)/2;
        if(a[mid]>=target)
        {
            ans=mid;
            r=mid-1;
        }
        else
        {
            l=mid+1;
        }
    }
    return ans;
}

注意

  • 不能背板子,二分很++灵活++!!!
  • 边界条件(while循环条件)是和循环内容配套的,很容易写着写着陷入死循环

时间复杂度O(logn)

2.3 常见题型

  • 查找某个数的位置

    洛谷:P2249 【深基13.例1】查找

  • 枚举答案,但降低时间复杂度,判断一个解是否可行(猜答案)

  • 最小化最大值/最大化最小值以及其他求最值问题

    洛谷

    • P2678 NOIP 2015 提高组 跳石头(最大化最小值)
    • P1873 COCI 2011/2012 #5 EKO / 砍树(最大化最小值)
    • P1824 USACO05FEB 进击的奶牛 Aggressive Cows G(最大化最小值)

    leetcode:875.爱吃香蕉的珂珂(最小化最大值)

    解题过程

    • 无论是最小化最大值还是最大化最小值,先明白题目让求的是什么
    • 确定答案区间,二分答案(确定二分的区间),假设mid就是答案
    • 接着根据题设条件(题目中的其他参数)继续和mid比较,更新mid,最终得解

2.4 补充

在C++头文件algorithm中,有两个函数底层就是二分,在解题中使用起来很方便

cpp 复制代码
#include<algorithm>
// qian'd
lower_bound(arr.begin(), arr.end(), val);	
// 在[begin, end)中找到第一个位置并返回其地址,使得val插入在这个位置前面
upper_bound(arr.begin(), arr,end(), val);
// 在[begin, end)中找到最后一个位置并返回其地址,使得val插入在这个位置前面

三、小结

关于二分,一定要注意循环条件,不然容易陷入死循环

本篇结合灵神题单,洛谷官方书籍等以及我自己的见解而来~

相关推荐
lueluelue478 小时前
LeetCode:链表
算法·leetcode·链表
隐积9 小时前
3.1.7.Qt容器大家族(3):QVariant——万能盒子
开发语言·qt
橘子汽水16811 小时前
Leetcode 23,543合并K个升序链表,二叉树的直径
算法·leetcode·链表
huameinan狮子11 小时前
Adaboost算法原理与计算实例
算法
Tri_Function11 小时前
动态规划DP1(c++)
c++
别怪我很水11 小时前
API中提供了VelocityTracker类用于计算触摸事件MotionEvent的速度,而其内部默认使用的方法就是最小二乘法,本 ...
算法·gitee·最小二乘法
名字还没想好☜12 小时前
Next.js ‘use client‘ 到底加在哪:Server/Client Components 边界与常见报错
开发语言·前端·javascript·react·next.js
初级代码游戏13 小时前
iOS开发 Swift 速记1:变量和基本数据类型
开发语言·ios·swift
酷在前行13 小时前
【R生态】PERMANOVA 进阶实战:距离选择、PERMDISP、两两比较与受限置换(保姆级教程)
开发语言·r语言