BinarySearch

前提

必須是有序數(shù)組夺溢。

思路

image.png

無(wú)重復(fù)數(shù)組二分查找

package com.pl.arithmetic.search;

import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 *
 * @Description: TODO
 * </p>
 * @ClassName BinarySearch
 * @Author pl
 * @Date 2020/12/20
 * @Version V1.0.0
 */
public class BinarySearch {

    public static void main(String[] args) {
       int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 , 11, 12, 13,14,15,16,17,18,19,20 };
        int resIndex = binarySearch(arr, 0, arr.length - 1, 11);
        System.out.println("resIndex=" + resIndex);
    }


    public static int binarySearch(int[] arr,int leftIndex,int rightIndex,int targetValue){
        //todo 先判斷是否需要查找
        if (leftIndex>rightIndex){
            return -1;
        }
        //todo 中指比較,遞歸查找
        int midIndex =  (leftIndex+rightIndex)/2;
        int midValue = arr[midIndex];
        if (midValue == targetValue){
            return midIndex;
        }
        //和midValue比較杂拨,如果小于midValue,左遞歸枕磁,反之右遞歸
        if (midValue>targetValue){
            return binarySearch(arr,0, midIndex-1,targetValue);
        }else {
            return binarySearch(arr,midIndex+1,rightIndex,targetValue);
        }
    }
}

有重復(fù)數(shù)組二分查找

思路

1.退出條件
leftIndx>rightIndex
2.中值比較
如果相等许起,先不退出,因?yàn)榍疤崾怯行驍?shù)組蚂会,找其左右是否也有相同值,直到左右都不等于targetValue
3.二分遞歸

package com.pl.arithmetic.search;

import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 *
 * @Description: TODO
 * </p>
 * @ClassName BinarySearch
 * @Author pl
 * @Date 2020/12/20
 * @Version V1.0.0
 */
public class BinarySearch {

    public static void main(String[] args) {
        int arr[] = { 1, 8, 10, 89,1000,1000,1000, 1234 };
       // int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 , 11, 12, 13,14,15,16,17,18,19,20 };
        //
    /*  int resIndex = binarySearch(arr, 0, arr.length - 1, 11);
        System.out.println("resIndex=" + resIndex);*/

        List<Integer> resIndexList = binarySearchPlus(arr, 0, arr.length - 1, 1000);
        System.out.println("resIndexList=" + resIndexList);
    }


    public static int binarySearch(int[] arr,int leftIndex,int rightIndex,int targetValue){
        //todo 先判斷是否需要查找
        if (leftIndex>rightIndex){
            return -1;
        }
        //todo 中指比較,遞歸查找
        int midIndex =  (leftIndex+rightIndex)/2;
        int midValue = arr[midIndex];
        if (midValue == targetValue){
            return midIndex;
        }
        //和midValue比較耗式,如果小于midValue胁住,左遞歸,反之右遞歸
        if (midValue>targetValue){
            return binarySearch(arr,0, midIndex-1,targetValue);
        }else {
            return binarySearch(arr,midIndex+1,rightIndex,targetValue);
        }
    }

    //完成一個(gè)課后思考題:
    /*
     * 課后思考題: {1,8, 10, 89, 1000, 1000刊咳,1234} 當(dāng)一個(gè)有序數(shù)組中彪见,
     * 有多個(gè)相同的數(shù)值時(shí),如何將所有的數(shù)值都查找到娱挨,比如這里的 1000
     *
     * 思路分析
     * 1. 在找到mid 索引值余指,不要馬上返回
     * 2. 向mid 索引值的左邊掃描,將所有滿(mǎn)足 1000跷坝, 的元素的下標(biāo)酵镜,加入到集合ArrayList
     * 3. 向mid 索引值的右邊掃描,將所有滿(mǎn)足 1000探孝, 的元素的下標(biāo)笋婿,加入到集合ArrayList
     * 4. 將Arraylist返回
     */
    public static List<Integer> binarySearchPlus(int[] arr, int leftIndex, int rightIndex, int targetValue){
        //todo 先判斷是否需要查找
        //只有遍歷了整個(gè)數(shù)組都沒(méi)找到所要的targetValue才會(huì)到滿(mǎn)足這個(gè)條件
        if (leftIndex>rightIndex){
            return new ArrayList<Integer>();
        }
        //todo 遞歸查找誉裆,中指比較,找到后不立即退出顿颅,因?yàn)槎植檎仪疤崾怯行驍?shù)組,需要查找其值左右是否為要找的項(xiàng)足丢,左右兩邊查找粱腻,直到其左右兩邊都不等于targetValue庇配,返回targetIndexList
        int midIndex =  (leftIndex+rightIndex)/2;
        int midValue = arr[midIndex];
        if (midValue == targetValue){
            List<Integer> targetIndexList = new ArrayList<>();
            targetIndexList.add(midIndex);
            //從midIndex左面線(xiàn)性查找
            int midLeftIndex = midIndex -1;
            while (true){
                if (midLeftIndex<leftIndex || arr[midLeftIndex]!=targetValue){
                    break;
                }
                targetIndexList.add(midLeftIndex);
                midLeftIndex--;
            }
            //從midIndex右面查找
            int midRightIndex = midIndex+1;
            while (true){
                if (midRightIndex>rightIndex || arr[midRightIndex] != targetValue){
                    break;
                }
                targetIndexList.add(midRightIndex);
                midRightIndex++;
            }
            return targetIndexList;
        }
        //和midValue比較,如果小于midValue绍些,左遞歸捞慌,反之右遞歸
        if (midValue>targetValue){
            return binarySearchPlus(arr,0, midIndex-1,targetValue);
        }else {
            return binarySearchPlus(arr,midIndex+1,rightIndex,targetValue);
        }
    }
}

錯(cuò)誤code

package com.pl.arithmetic.search;

import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 *
 * @Description: TODO
 * </p>
 * @ClassName BinarySearch
 * @Author pl
 * @Date 2020/12/20
 * @Version V1.0.0
 */
public class BinarySearch {

    public static void main(String[] args) {
        int arr[] = { 1, 8, 10, 89,1000,1000, 1234 };
       // int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 , 11, 12, 13,14,15,16,17,18,19,20 };
        //
    /*  int resIndex = binarySearch(arr, 0, arr.length - 1, 11);
        System.out.println("resIndex=" + resIndex);*/

        List<Integer> resIndexList = binarySearchPlus(arr, 0, arr.length - 1, 1000);
        System.out.println("resIndexList=" + resIndexList);
    }


    public static int binarySearch(int[] arr,int leftIndex,int rightIndex,int targetValue){
        //todo 先判斷是否需要查找
        if (leftIndex>rightIndex){
            return -1;
        }
        //todo 中指比較,遞歸查找
        int midIndex =  (leftIndex+rightIndex)/2;
        int midValue = arr[midIndex];
        if (midValue == targetValue){
            return midIndex;
        }
        //和midValue比較,如果小于midValue柬批,左遞歸啸澡,反之右遞歸
        if (midValue>targetValue){
            return binarySearch(arr,0, midIndex-1,targetValue);
        }else {
            return binarySearch(arr,midIndex+1,rightIndex,targetValue);
        }
    }

    //完成一個(gè)課后思考題:
    /*
     * 課后思考題: {1,8, 10, 89, 1000, 1000,1234} 當(dāng)一個(gè)有序數(shù)組中氮帐,
     * 有多個(gè)相同的數(shù)值時(shí)嗅虏,如何將所有的數(shù)值都查找到,比如這里的 1000
     *
     * 思路分析
     * 1. 在找到mid 索引值上沐,不要馬上返回
     * 2. 向mid 索引值的左邊掃描皮服,將所有滿(mǎn)足 1000, 的元素的下標(biāo)参咙,加入到集合ArrayList
     * 3. 向mid 索引值的右邊掃描龄广,將所有滿(mǎn)足 1000, 的元素的下標(biāo)蕴侧,加入到集合ArrayList
     * 4. 將Arraylist返回
     */
    public static List<Integer> binarySearchPlus(int[] arr, int leftIndex, int rightIndex, int targetValue){
        //todo 先判斷是否需要查找
        //只有遍歷了整個(gè)數(shù)組都沒(méi)找到所要的targetValue才會(huì)到滿(mǎn)足這個(gè)條件
        if (leftIndex>rightIndex){
            return new ArrayList<Integer>();
        }
        //todo 遞歸查找择同,中指比較,找到后不立即退出,因?yàn)槎植檎仪疤崾怯行驍?shù)組净宵,需要查找其值左右是否為要找的項(xiàng)奠衔,左右兩邊查找,直到其左右兩邊都不等于targetValue塘娶,返回targetIndexList
        int midIndex =  (leftIndex+rightIndex)/2;
        int midValue = arr[midIndex];
        if (midValue == targetValue){
            List<Integer> targetIndexList = new ArrayList<>();
            targetIndexList.add(midIndex);
            //從midIndex左面線(xiàn)性查找
            int midLeftIndex = --midIndex;
            while (true){
                if (midLeftIndex<leftIndex || arr[midLeftIndex]!=targetValue){
                    break;
                }
                targetIndexList.add(midLeftIndex);
                midLeftIndex--;
            }
            //從midIndex右面查找
            int midRightIndex = ++midIndex;
            while (true){
                if (midRightIndex>rightIndex || arr[midRightIndex] != targetValue){
                    break;
                }
                targetIndexList.add(midRightIndex);
                midRightIndex++;
            }
            return targetIndexList;
        }
        //和midValue比較归斤,如果小于midValue,左遞歸刁岸,反之右遞歸
        if (midValue>targetValue){
            return binarySearchPlus(arr,0, midIndex-1,targetValue);
        }else {
            return binarySearchPlus(arr,midIndex+1,rightIndex,targetValue);
        }
    }
}

輸出[5,4,5]

analyze

73,82行出錯(cuò)
int midLeftIndex = --midIndex;
int midRightIndex = ++midIndex;
這樣賦值脏里,midIndex內(nèi)存地質(zhì)發(fā)生變化

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市虹曙,隨后出現(xiàn)的幾起案子迫横,更是在濱河造成了極大的恐慌,老刑警劉巖酝碳,帶你破解...
    沈念sama閱讀 219,366評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件矾踱,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡疏哗,警方通過(guò)查閱死者的電腦和手機(jī)呛讲,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,521評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人贝搁,你說(shuō)我怎么就攤上這事吗氏。” “怎么了雷逆?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,689評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵弦讽,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我膀哲,道長(zhǎng)往产,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,925評(píng)論 1 295
  • 正文 為了忘掉前任某宪,我火速辦了婚禮捂齐,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘缩抡。我一直安慰自己奠宜,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,942評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布瞻想。 她就那樣靜靜地躺著压真,像睡著了一般。 火紅的嫁衣襯著肌膚如雪蘑险。 梳的紋絲不亂的頭發(fā)上滴肿,一...
    開(kāi)封第一講書(shū)人閱讀 51,727評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音佃迄,去河邊找鬼泼差。 笑死,一個(gè)胖子當(dāng)著我的面吹牛呵俏,可吹牛的內(nèi)容都是我干的堆缘。 我是一名探鬼主播,決...
    沈念sama閱讀 40,447評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼普碎,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼吼肥!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起麻车,我...
    開(kāi)封第一講書(shū)人閱讀 39,349評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤缀皱,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后动猬,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體啤斗,經(jīng)...
    沈念sama閱讀 45,820評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,990評(píng)論 3 337
  • 正文 我和宋清朗相戀三年赁咙,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了钮莲。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片免钻。...
    茶點(diǎn)故事閱讀 40,127評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖臂痕,靈堂內(nèi)的尸體忽然破棺而出伯襟,到底是詐尸還是另有隱情猿涨,我是刑警寧澤握童,帶...
    沈念sama閱讀 35,812評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站叛赚,受9級(jí)特大地震影響澡绩,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜俺附,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,471評(píng)論 3 331
  • 文/蒙蒙 一肥卡、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧事镣,春花似錦步鉴、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,017評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至随闪,卻和暖如春阳似,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背铐伴。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,142評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工撮奏, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人当宴。 一個(gè)月前我還...
    沈念sama閱讀 48,388評(píng)論 3 373
  • 正文 我出身青樓畜吊,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親户矢。 傳聞我的和親對(duì)象是個(gè)殘疾皇子定拟,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,066評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • 先從最簡(jiǎn)單的binarySearch開(kāi)始青自。 下面我們寫(xiě)的是lower_bound和upper_bound,這兩個(gè)函...
    啦啦哇哈哈閱讀 499評(píng)論 0 0
  • 本文內(nèi)容為練習(xí)LeetCode題目時(shí)的解題思路和不同算法的記錄驱证,實(shí)現(xiàn)語(yǔ)言為C++延窜,代碼保存在Github,均已在L...
    SK木眠閱讀 1,005評(píng)論 0 0
  • 全文包含 12000+ 字荠藤、30 張高清圖片,預(yù)計(jì)閱讀時(shí)間為 40 分鐘获高,強(qiáng)烈建議先收藏再仔細(xì)閱讀哈肖。 作者 | 李...
    五分鐘學(xué)算法閱讀 1,361評(píng)論 0 16
  • 算法思想 一、二分查找 1. 算法思想 算法詳解 算法細(xì)節(jié) 一定要看二分查找細(xì)節(jié).md 實(shí)現(xiàn)時(shí)需要注意以下細(xì)節(jié): ...
    因丶為閱讀 364評(píng)論 0 0
  • 久違的晴天念秧,家長(zhǎng)會(huì)淤井。 家長(zhǎng)大會(huì)開(kāi)好到教室時(shí),離放學(xué)已經(jīng)沒(méi)多少時(shí)間了摊趾。班主任說(shuō)已經(jīng)安排了三個(gè)家長(zhǎng)分享經(jīng)驗(yàn)币狠。 放學(xué)鈴聲...
    飄雪兒5閱讀 7,523評(píng)論 16 22