二分算法


  1. 基本介紹

二分思想一般用於查找,見其名知其意,這是一個半半開的算法。第一次接觸二分思想的時候是高中的數學學習中,給定一個方程 f(x) = 0的根所在的區間,可以用根存在定理不斷二分區間,當區間長度小於給定的精度時,即可近似求出方程的解,當然也可以用來求平方根和立方根等。同樣,這種查找思想也可以運用於計算機內結構化數據的查找。(tips: 二分查找思想簡單,細節魔鬼)。(詳講博客推薦)

二分查找有很多應用,由於其時間復雜度很低,它可以暴力破解很大的數據。

  1. 核心思想

使用二分查找的前提:待查找序列必須有序(升序或降序,本文主要以升序為例)

確定查找區間(left, right),取區間中間值mid = (left + right)/2,比較中間值與左右兩邊的值,確定待查元素key所在區間,舍棄無效區間(mid = left 或mid = right)。

  1. 算法效率分析

時間復雜度:對於數據規模n,每次二分會使查找區間長度減半。最好情況只需要一次查找即可,最壞情況要找()次。綜上述,二分算法其漸進時間復雜度為O()。所以,很多地方考查找時卡時間復雜的時候就要考慮使用二分啦。

       空間復雜度:沒有使用額外空間,比較友好。

  1. 代碼實現
  • 朴素實現
int BinaryChop(int *arr, int len, int key) {
    int left = 0, right = len, mid;
    while (left < right) {
        mid = (left + right) / 2;
        if (arr[mid] == key)
            return mid; // 找到返回元素位置
        else if (arr[mid] > key)
            right = mid - 1;
        else
            left = mid + 1;
    }
    return -1;// 沒找到返回-1
}
  • 通用實現
int search(int k) {
    int l = -1,r = n;//注意的是數組是從0開始的
    while(l + 1 < r) {
        int mid = l + r >> 1;
        if(a[mid] <= k)
            l = mid;
        else 
            r = mid;
    }
    return r;//返回的是大於k的第一個位置
}

 

  • C++中STL內的函數

lower_bound(begin, end, num):從數組的begin位置到end-1位置二分查找第一個大於等於num的數字,找到返回該數字的地址,不存在則返回end。通過返回的地址減去起始地址begin,得到找到數字在數組中的下標。

 

upper_bound(begin, end, num):從數組的begin位置到end-1位置二分查找第一個大於num的數字,找到返回該數字的地址,不存在則返回end。通過返回的地址減去起始地址begin,得到找到數字在數組中的下標。

 

  1. 習題鏈接

  https://www.luogu.com.cn/problem/P2249 P2249 【深基13.例1】查找

  https://www.luogu.com.cn/problem/P1102 P1102 A-B 數對

  https://www.luogu.com.cn/problem/P1024 P1024 [NOIP2001提高組]一元三次方程求解

  https://www.luogu.com.cn/problem/P1678 P1678 煩惱的高考志願

  https://www.luogu.com.cn/problem/P2440 P2440 木材加工

  http://120.78.128.11/Problem.jsp?pid=2145 二分法模板

  http://120.78.128.11/Problem.jsp?pid=1762 杯子

  http://120.78.128.11/Problem.jsp?pid=2366 二分強化——全面查詢

  http://120.78.128.11/Problem.jsp?pid=2446 Champion_Q的魔法蛋糕

  https://www.luogu.com.cn/problem/P2678 P2678 [NOIP2015 提高組] 跳石頭

  https://www.luogu.com.cn/problem/P3853 P3853 [TJOI2007]路標設置

 

  我的題解:

  洛谷-P2249 【深基13.例1】查找 - Kirk~~ - 博客園 (cnblogs.com)

  洛谷-P1102 A-B 數對 - Kirk~~ - 博客園 (cnblogs.com)

  洛谷-P1024 [NOIP2001 提高組] 一元三次方程求解 - Kirk~~ - 博客園 (cnblogs.com)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM