【Java練習(xí)題】搜索插入位置

給定一個(gè)排序數(shù)組和一個(gè)目標(biāo)值,在數(shù)組中找到目標(biāo)值党涕,并返回其索引。如果目標(biāo)值不存在于數(shù)組中巡社,返回它將會(huì)被按順序插入的位置膛堤。你可以假設(shè)數(shù)組中無(wú)重復(fù)元素。
示例 1:

輸入: [1,3,5,6], 5
輸出: 2
示例 2:

輸入: [1,3,5,6], 2
輸出: 1
示例 3:

輸入: [1,3,5,6], 7
輸出: 4
示例 4:

輸入: [1,3,5,6], 0
輸出: 0

解題思路
題目告訴你“排序數(shù)組”晌该,其實(shí)就是在暗示你用二分查找法, 二分查找法的思想并不難肥荔,但寫(xiě)好一個(gè)二分法并不簡(jiǎn)單。

public class Solution3 {

    public int searchInsert(int[] nums, int target) {
        int len = nums.length;
        if (nums[len - 1] < target) {
            return len;
        }

        int left = 0;
        int right = len - 1;

        while (left <= right) {
            int mid = (left + right) / 2;
            // 等于的情況最簡(jiǎn)單朝群,我們應(yīng)該放在第 1 個(gè)分支進(jìn)行判斷
            if (nums[mid] == target) {
                return mid;
            } else if (nums[mid] < target) {
                // 題目要我們返回大于或者等于目標(biāo)值的第 1 個(gè)數(shù)的索引
                // 此時(shí) mid 一定不是所求的左邊界燕耿,
                // 此時(shí)左邊界更新為 mid + 1
                left = mid + 1;
            } else {
                // 既然不會(huì)等于,此時(shí) nums[mid] > target
                // mid 也一定不是所求的右邊界
                // 此時(shí)右邊界更新為 mid - 1
                right = mid - 1;
            }
        }
        // 注意:一定得返回左邊界 left姜胖,
        // 如果返回右邊界 right 提交代碼不會(huì)通過(guò)
        // 【注意】下面我嘗試說(shuō)明一下理由誉帅,如果你不太理解下面我說(shuō)的,那是我表達(dá)的問(wèn)題
        // 但我建議你不要糾結(jié)這個(gè)問(wèn)題,因?yàn)槲覍⒁榻B的二分查找法模板蚜锨,可以避免對(duì)返回 left 和 right 的討論

        // 理由是對(duì)于 [1,3,5,6]档插,target = 2,返回大于等于 target 的第 1 個(gè)數(shù)的索引亚再,此時(shí)應(yīng)該返回 1
        // 在上面的 while (left <= right) 退出循環(huán)以后郭膛,right < left,right = 0 氛悬,left = 1
        // 根據(jù)題意應(yīng)該返回 left则剃,
        // 如果題目要求你返回小于等于 target 的所有數(shù)里最大的那個(gè)索引值,應(yīng)該返回 right

        return left;
    }
}

Java
int mid = (left + right) / 2
這行代碼是有問(wèn)題的如捅,在 left 和 right 都比較大的時(shí)候棍现,left + right 很有可能超過(guò) int 類型能表示的最大值,即整型溢出伪朽,為了避免這個(gè)問(wèn)題轴咱,應(yīng)該寫(xiě)成:

Java
int mid = left + (right - left) / 2 ;
事實(shí)上,int mid = left + (right - left) / 2 在 right 很大烈涮、 left 是負(fù)數(shù)且很小的時(shí)候, right - left 也有可能超過(guò) int 類型能表示的最大值窖剑,只不過(guò)一般情況下 left 和 right 表示的是數(shù)組索引值坚洽,left 是非負(fù)數(shù),因此 right - left 溢出的可能性很小西土。

public class Solution {

    public int searchInsert(int[] nums, int target) {
        int len = nums.length;

        if (len == 0) {
            return 0;
        }

        int left = 0;
        int right = len;

        while (left < right) {
            int mid = left + (right - left) / 2;
            if (nums[mid] < target) {
                left = mid + 1;
            } else {
                right = mid;
            }
        }
        return left;
    }
}

更好的寫(xiě)法是:

Java
int mid = (left + right) >>> 1 ;

int mid=(left+right)>>>1int mid=(left+right)/2有什么區(qū)別

>>>是右移運(yùn)算讶舰,在計(jì)算機(jī)中是一種運(yùn)算操作,但是他的運(yùn)算結(jié)果正好能對(duì)應(yīng)一個(gè)整數(shù)的二分之一值需了,這就正好能代替數(shù)學(xué)上的除2運(yùn)算跳昼,但是比除2運(yùn)算要快。

(1)如果 left 和 right 表示的是數(shù)組的索引肋乍,就要考慮“索引是否有效” 鹅颊,即“索引是否越界” 是重要的定界依據(jù);

左右邊界一定要包括目標(biāo)元素墓造,當(dāng) target 比數(shù)組中的最后一個(gè)數(shù)字還要大(不能等于)的時(shí)候堪伍,插入元素的位置就是數(shù)組的最后一個(gè)位置 + 1,即 (len - 1 + 1 =) len觅闽,如果忽略掉這一點(diǎn)帝雇,把右邊界定為 len - 1 ,代碼就不能通過(guò)在線測(cè)評(píng)蛉拙。

(2)中位數(shù)先寫(xiě)int mid = (left + right) >>> 1 ; 根據(jù)循環(huán)里分支的編寫(xiě)情況尸闸,再做調(diào)整理解這一點(diǎn),首先要知道:當(dāng)數(shù)組的元素個(gè)數(shù)是偶數(shù)的時(shí)候,中位數(shù)有左中位數(shù)和右中位數(shù)之分吮廉。

當(dāng)數(shù)組的元素個(gè)數(shù)是偶數(shù)的時(shí)候:
使用 int mid = left + (right - left) / 2 ;得到左中位數(shù)的索引睹栖;

使用int mid = left + (right - left + 1) / 2 ; 得到右中位數(shù)的索引。

當(dāng)數(shù)組的元素個(gè)數(shù)是奇數(shù)的時(shí)候茧痕,以上二者都能選到最中間的那個(gè)中位數(shù)野来。
其次,

int mid = left + (right - left) / 2 ; 等價(jià)于int mid = (left + right) >>> 1踪旷;

int mid = left + (right - left + 1) / 2 ; 等價(jià)于int mid = (left + right + 1) >>> 1;
記憶方法:

(right - left) 不加 1 選左中位數(shù)曼氛,加 1 選右中位數(shù)。

public class Solution {

    public int searchInsert(int[] nums, int target) {
        int len = nums.length;

        if (len == 0) {
            return 0;
        }

        int left = 0;
        int right = len;

        while (left < right) {
            int mid = left + ((right - left) >>> 1);
            if (nums[mid] < target) {
                left = mid + 1;
            } else {
                right = mid;
            }
        }
        return left;
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末令野,一起剝皮案震驚了整個(gè)濱河市舀患,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌气破,老刑警劉巖聊浅,帶你破解...
    沈念sama閱讀 221,635評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異现使,居然都是意外死亡低匙,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,543評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén)碳锈,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)顽冶,“玉大人,你說(shuō)我怎么就攤上這事售碳∏恐兀” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,083評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵贸人,是天一觀的道長(zhǎng)间景。 經(jīng)常有香客問(wèn)我,道長(zhǎng)艺智,這世上最難降的妖魔是什么倘要? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,640評(píng)論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮力惯,結(jié)果婚禮上碗誉,老公的妹妹穿的比我還像新娘。我一直安慰自己父晶,他們只是感情好哮缺,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,640評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著甲喝,像睡著了一般尝苇。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 52,262評(píng)論 1 308
  • 那天糠溜,我揣著相機(jī)與錄音淳玩,去河邊找鬼。 笑死非竿,一個(gè)胖子當(dāng)著我的面吹牛震庭,可吹牛的內(nèi)容都是我干的践宴。 我是一名探鬼主播,決...
    沈念sama閱讀 40,833評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼婿着!你這毒婦竟也來(lái)了沿侈?” 一聲冷哼從身側(cè)響起衣形,我...
    開(kāi)封第一講書(shū)人閱讀 39,736評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤翎苫,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后零聚,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體袍暴,經(jīng)...
    沈念sama閱讀 46,280評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,369評(píng)論 3 340
  • 正文 我和宋清朗相戀三年隶症,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了政模。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,503評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡沿腰,死狀恐怖览徒,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情颂龙,我是刑警寧澤,帶...
    沈念sama閱讀 36,185評(píng)論 5 350
  • 正文 年R本政府宣布纽什,位于F島的核電站措嵌,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏芦缰。R本人自食惡果不足惜企巢,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,870評(píng)論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望让蕾。 院中可真熱鬧浪规,春花似錦、人聲如沸探孝。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,340評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)顿颅。三九已至缸濒,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背庇配。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,460評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工斩跌, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人捞慌。 一個(gè)月前我還...
    沈念sama閱讀 48,909評(píng)論 3 376
  • 正文 我出身青樓耀鸦,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親啸澡。 傳聞我的和親對(duì)象是個(gè)殘疾皇子袖订,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,512評(píng)論 2 359

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

  • 給定一個(gè)排序數(shù)組和一個(gè)目標(biāo)值,在數(shù)組中找到目標(biāo)值锻霎,并返回其索引著角。如果目標(biāo)值不存在于數(shù)組中,返回它將會(huì)被按順序插入的...
    FiveZM閱讀 459評(píng)論 0 0
  • 更多精彩內(nèi)容旋恼,請(qǐng)關(guān)注【力扣簡(jiǎn)單題】吏口。 題目 難度:類型:數(shù)組 給定一個(gè)排序數(shù)組和一個(gè)目標(biāo)值,在數(shù)組中找到目標(biāo)值冰更,并...
    玖月晴閱讀 1,262評(píng)論 0 0
  • 35 Search Insert Position 搜索插入位置 Description:Given a sort...
    air_melt閱讀 159評(píng)論 0 1
  • 題目需求 給定一個(gè)排序數(shù)組和一個(gè)目標(biāo)值产徊,在數(shù)組中找到目標(biāo)值,并返回其索引蜀细。如果目標(biāo)值不存在于數(shù)組中舟铜,返回它將會(huì)被按...
    Jimhou閱讀 207評(píng)論 0 0
  • 35. 搜索插入位置 問(wèn)題 給定一個(gè)排序數(shù)組和一個(gè)目標(biāo)值,在數(shù)組中找到目標(biāo)值奠衔,并返回其索引谆刨。如果目標(biāo)值不存在于數(shù)組...
    王可尊閱讀 313評(píng)論 0 0