leetcode 34. 在排序數(shù)組中查找元素的第一個(gè)和最后一個(gè)位置:二分查找

對(duì)于二分查找筋现,我們經(jīng)常頭疼于它的邊界值問(wèn)題,是要【左閉右開(kāi)】(即[left, right) )進(jìn)行搜索箱歧?還是【左閉右閉】(即[left,right] )進(jìn)行搜索矾飞?對(duì)于【左閉右開(kāi)】的寫(xiě)法,在左右收斂時(shí)我們時(shí)常要考慮向左半段搜索時(shí)mid是否要-1后再賦給right呀邢,或向右半段搜索時(shí)mid是否要+1后再賦值給left的問(wèn)題洒沦,想著想著開(kāi)始懷疑人生。价淌。申眼。

相對(duì)于【左閉右開(kāi)】瞒津,【左閉右閉】的寫(xiě)法就比較統(tǒng)一,不過(guò)往左還是右括尸,mid都需要做一次+1或-1的操作巷蚪,比較方便記憶,當(dāng)然如果你寫(xiě)熟了并且理解了兩種寫(xiě)法濒翻,right的開(kāi)閉完全取決你的心情屁柏。。這里提供一個(gè)標(biāo)準(zhǔn)的【左閉右閉】的二分查找模板肴焊,認(rèn)準(zhǔn)了這個(gè)模板前联,后面我們均按這個(gè)模板來(lái)作答。

    /**
     * 標(biāo)準(zhǔn)二分的模板
     *
     * @param nums
     * @param target
     * @return
     */
    private int search_template(int[] nums, int target) {
        // 左閉右閉
        int left = 0, right = nums.length - 1;
        // 終止條件為left=right+1
        while (left <= right) {
            // 如果寫(xiě)成(left+right)>>1娶眷,可能溢出
            int mid = left + ((right - left) >> 1);
            if (nums[mid] == target) {
                return mid;
            } else if (nums[mid] < target) {
                left = mid + 1;
            } else if (nums[mid] > target) {
                right = mid - 1;
            }
        }
        return -1;
    }

如果模板上面的模板看明白了似嗤,那么這道題就不難解答,我們分別定義一個(gè)尋找左邊界的方法leftBound和一個(gè)尋找右邊界的方法rightBound:

相對(duì)于二分查找模板届宠,這里多了三步(比如說(shuō)尋找左邊界的方法):

1烁落、在發(fā)現(xiàn)找到一個(gè)target對(duì)象時(shí),不返回豌注,而是繼續(xù)讓right=mid-1伤塌,也就是向左邊收斂,找左邊界轧铁;

2每聪、后面有兩個(gè)返回-1的條件,我們一起來(lái)看一下:

  • left ≥ nums.length :這一步考慮的是如果出現(xiàn)當(dāng)前數(shù)組中所有的元素都小于target元素齿风,那么在跳出循環(huán)前會(huì)最后一次進(jìn)入nums[mid] < target的分支药薯,而最后一次left=mid+1后,left會(huì)越界救斑,因此我們要考慮left越界的情況童本;
  • nums[left] ≠ target:這一步考慮的是,如果數(shù)組中不存在target的情況脸候,那么此時(shí)left指向的元素便不是我們要的左邊界穷娱;

3、最后返回left运沦,即為要尋找的左邊界泵额。

右邊界同理,不再贅述携添。

public class Solution {

    public int[] searchRange(int[] nums, int target) {
        return new int[]{leftBound(nums, target), rightBound(nums, target)};
    }

    private int leftBound(int[] nums, int target) {
        int left = 0, right = nums.length - 1;
        while (left <= right) {
            int mid = left + ((right - left) >> 1);
            if (nums[mid] < target) {
                left = mid + 1;
            } else if (nums[mid] > target) {
                right = mid - 1;
            } else if (nums[mid] == target) {
                // 繼續(xù)向左邊收斂
                right = mid - 1;
            }
        }
        // 檢查是否越界嫁盲,或者不存在
        if (left >= nums.length || nums[left] != target) {
            return -1;
        }
        return left;
    }

    private int rightBound(int[] nums, int target) {
        int left = 0, right = nums.length - 1;
        while (left <= right) {
            int mid = left + ((right - left) >> 1);
            if (nums[mid] < target) {
                left = mid + 1;
            } else if (nums[mid] > target) {
                right = mid - 1;
            } else if (nums[mid] == target) {
                // 繼續(xù)向右邊收斂
                left = mid + 1;
            }
        }
        // 檢查是否越界,或者不存在
        if (right < 0 || nums[right] != target) {
            return -1;
        }
        return right;
    }

}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末薪寓,一起剝皮案震驚了整個(gè)濱河市亡资,隨后出現(xiàn)的幾起案子澜共,更是在濱河造成了極大的恐慌,老刑警劉巖锥腻,帶你破解...
    沈念sama閱讀 217,277評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件嗦董,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡瘦黑,警方通過(guò)查閱死者的電腦和手機(jī)京革,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)幸斥,“玉大人匹摇,你說(shuō)我怎么就攤上這事〖自幔” “怎么了廊勃?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,624評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)经窖。 經(jīng)常有香客問(wèn)我坡垫,道長(zhǎng),這世上最難降的妖魔是什么画侣? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,356評(píng)論 1 293
  • 正文 為了忘掉前任冰悠,我火速辦了婚禮,結(jié)果婚禮上配乱,老公的妹妹穿的比我還像新娘溉卓。我一直安慰自己,他們只是感情好搬泥,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,402評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布桑寨。 她就那樣靜靜地躺著,像睡著了一般佑钾。 火紅的嫁衣襯著肌膚如雪西疤。 梳的紋絲不亂的頭發(fā)上烦粒,一...
    開(kāi)封第一講書(shū)人閱讀 51,292評(píng)論 1 301
  • 那天休溶,我揣著相機(jī)與錄音,去河邊找鬼扰她。 笑死兽掰,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的徒役。 我是一名探鬼主播孽尽,決...
    沈念sama閱讀 40,135評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼忧勿!你這毒婦竟也來(lái)了杉女?” 一聲冷哼從身側(cè)響起瞻讽,我...
    開(kāi)封第一講書(shū)人閱讀 38,992評(píng)論 0 275
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎熏挎,沒(méi)想到半個(gè)月后速勇,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,429評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡坎拐,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,636評(píng)論 3 334
  • 正文 我和宋清朗相戀三年烦磁,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片哼勇。...
    茶點(diǎn)故事閱讀 39,785評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡都伪,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出积担,到底是詐尸還是另有隱情陨晶,我是刑警寧澤,帶...
    沈念sama閱讀 35,492評(píng)論 5 345
  • 正文 年R本政府宣布帝璧,位于F島的核電站珍逸,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏聋溜。R本人自食惡果不足惜谆膳,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,092評(píng)論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望撮躁。 院中可真熱鬧漱病,春花似錦、人聲如沸把曼。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,723評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)嗤军。三九已至注盈,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間叙赚,已是汗流浹背老客。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,858評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留震叮,地道東北人胧砰。 一個(gè)月前我還...
    沈念sama閱讀 47,891評(píng)論 2 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像苇瓣,于是被迫代替她去往敵國(guó)和親尉间。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,713評(píng)論 2 354