算法 | 二分法

在數(shù)據(jù)結(jié)構(gòu)書籍中,在介紹二分法時,常常會加上有序這個前提條件,其中有序的定義要麼是從大到小排序,要麼是從小到大排序。

那么,有序真的是所有問題求解時使用二分的必要條件嗎?
答案是:不

只要正確構(gòu)建左右兩側(cè)的淘汰邏輯,你就可以使用二分法,那我們現(xiàn)在通過以下例子來了解二分法。

1、在一個有序數(shù)組中,找某個數(shù)是否存在
2、在一個有序數(shù)組中,找>=某個數(shù)最左側(cè)的位置
3、在一個有序數(shù)組中,找<=某個數(shù)最右側(cè)的位置
4、局部最小值問題

在一個有序數(shù)組中,找某個數(shù)是否存在

public static boolean exist(int[] sortedArr, int num) {
        if (sortedArr == null || sortedArr.length == 0) {
            return false;
        }
        int L = 0;
        int R = sortedArr.length - 1;
        int mid = 0;
        // L..R 至少兩個數(shù)的時候
        while (L < R) { 
            mid = L + ((R - L) >> 1);
            if (sortedArr[mid] == num) {
                return true;
            } else if (sortedArr[mid] > num) {
                R = mid - 1;
            } else {
                L = mid + 1;
            }
        }
        return sortedArr[L] == num;
    }
在一個有序數(shù)組中,找某個數(shù)是否存在.png

在一個有序數(shù)組中,找大于等于某個數(shù)最左側(cè)的位置

public static int nearestIndex(int[] arr, int value) {
        int L = 0;
        int R = arr.length - 1;
        int index = -1; // 記錄最左的對號
        while (L <= R) { // 至少一個數(shù)的時候
            int mid = L + ((R - L) >> 1);
            if (arr[mid] >= value) {
                index = mid;
                R = mid - 1;
            } else {
                L = mid + 1;
            }
        }
        return index;
    }
在一個有序數(shù)組中,找大于等于某個數(shù)最左側(cè)的位置 .png

在一個有序數(shù)組中,找小于等于某個數(shù)最右側(cè)的位置

public static int nearestIndex(int[] arr, int value) {
        int L = 0;
        int R = arr.length - 1;
        int index = -1; // 記錄最右的對號
        while (L <= R) {
            int mid = L + ((R - L) >> 1);
            if (arr[mid] <= value) {
                index = mid;
                L = mid + 1;
            } else {
                R = mid - 1;
            }
        }
        return index;
    }
在一個有序數(shù)組中,找小于等于某個數(shù)最右側(cè)的位置 .png

局部最小值問題

public static int getLessIndex(int[] arr) {
        if (arr == null || arr.length == 0) {
            return -1; // no exist
        }
        if (arr.length == 1 || arr[0] < arr[1]) {
            return 0;
        }
        if (arr[arr.length - 1] < arr[arr.length - 2]) {
            return arr.length - 1;
        }
        int left = 1;
        int right = arr.length - 2;
        int mid = 0;
        while (left < right) {
            mid = (left + right) / 2;
            if (arr[mid] > arr[mid - 1]) {
                right = mid - 1;
            } else if (arr[mid] > arr[mid + 1]) {
                left = mid + 1;
            } else {
                return mid;
            }
        }
        return left;
    }

局部最小可以使用二分法完成,定義局部最小時隱含的規(guī)律即:一個不存在相同元素的數(shù)組一定存在局部最小值,因為只需要找到一個局部最小值,這樣就可以使用二分查找將數(shù)組規(guī)模逐漸減小。
1、首先判斷數(shù)組第一個值是否小于右邊的值,若小于,則局部最小值為第一個數(shù);否則進行下一步;
2、判斷數(shù)組的最后一個值是否小于左邊的值,若小于,則局部最小值為最后一個數(shù);否則進行下一步;
3、通過二分法來驗證除首位和末尾位置的數(shù)組數(shù)據(jù)的局部最小值,若某值左右兩邊的值都大于該值,那么該值就屬于局部最小值;否則繼續(xù)通過二分法進行查找。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 一、基本二分法的描述 二分搜索(英語:binary search),也稱折半搜索、對數(shù)搜索,是一種在有序數(shù)組中查找...
    胡博要畢業(yè)閱讀 11,435評論 1 4
  • 二分法查找,也稱為折半法,是一種在有序數(shù)組中查找特定元素的搜索算法。 二分法查找的思路如下:(1)首先,從數(shù)組的中...
    涅槃快樂是金閱讀 562評論 0 0
  • 二分法,以優(yōu)秀的復雜()度成功的將順序查找拋在后面,成為我們最常用的算法。 在我們平常的認知里,二分法只能用于解決...
    namedsatan閱讀 775評論 0 1
  • 定義 二分查找也稱折半查找(Binary Search),它是一種效率較高的查找方法。在一個有序二維數(shù)組中,查找指...
    蕭格閱讀 306評論 0 0
  • 二分法的使用 旋轉(zhuǎn)數(shù)組: 假設(shè)按照升序排序的數(shù)組在預(yù)先未知的某個點上進行了旋轉(zhuǎn)。( 例如,數(shù)組 [0,1,2,4,...
    白璞1024閱讀 1,665評論 0 50

友情鏈接更多精彩內(nèi)容