中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁(yè) > news >正文

網(wǎng)站建設(shè)竣工驗(yàn)收?qǐng)?bào)告深圳網(wǎng)絡(luò)公司推廣

網(wǎng)站建設(shè)竣工驗(yàn)收?qǐng)?bào)告,深圳網(wǎng)絡(luò)公司推廣,做外貿(mào)在哪個(gè)網(wǎng)站好,集寧做網(wǎng)站二分查找,又名折半查找,其搜索過(guò)程如下: 從數(shù)組中間的元素開(kāi)始,如果元素剛好是要查找的元素,則搜索過(guò)程結(jié)束如果搜索元素大于或小于中間元素,則排除掉不符合條件的那一半元素,在剩下的數(shù)組中進(jìn)行查找由于每次需要排除掉一半不符合要求的元素,這需要數(shù)組是已經(jīng)排好序的或者是有…

二分查找,又名折半查找,其搜索過(guò)程如下:

  • 從數(shù)組中間的元素開(kāi)始,如果元素剛好是要查找的元素,則搜索過(guò)程結(jié)束
  • 如果搜索元素大于或小于中間元素,則排除掉不符合條件的那一半元素,在剩下的數(shù)組中進(jìn)行查找
  • 由于每次需要排除掉一半不符合要求的元素,這需要數(shù)組是已經(jīng)排好序的或者是有規(guī)律可循的

在二分查找中,對(duì)于每一個(gè)反饋,我們能過(guò)濾掉一半的數(shù)據(jù),因此二分查找相對(duì)于普通遍歷是一個(gè)高效的查找算法,其時(shí)間復(fù)雜度為O(logn),雖然二分查找的思想很簡(jiǎn)單,然而二分查找的細(xì)節(jié)可不少,這里根據(jù)力扣的題型給出兩種二分查找的寫(xiě)法

二分查找基礎(chǔ)版

題目鏈接

使用二分查找的方式在一個(gè)升序的數(shù)組中找到指定的值并且返回,其代碼框架如下:

定義left為左指針,right為右指針,搜索的區(qū)域在[left,right]中
搜索目標(biāo)值為targtwhile(left<=right){//得到查找的中點(diǎn)mid=(left+right)/2//對(duì)于升序數(shù)組當(dāng)前值小于目標(biāo)值,目標(biāo)值應(yīng)該在當(dāng)前值的右側(cè)if(mid<target){左指針右移,如今搜索區(qū)域變?yōu)閇mid,right]}else if(mid>target){右指針左移,如今搜索區(qū)域變?yōu)閇left,mid]}else{只剩下等于的情況了,直接返回結(jié)果找到了目標(biāo)值}
}

代碼如下:

class Solution:def search(self, nums: List[int], target: int) -> int:left, right = 0, len(nums) - 1while left <= right:mid = (right - left) // 2 + leftnum = nums[mid]if num < target:left = mid + 1elif num > target:right = mid - 1else:return midreturn -1

注意,重點(diǎn)來(lái)了!!!注意代碼中的幾個(gè)關(guān)鍵點(diǎn):

  • while循環(huán)中的條件是left<=right,這意味著在搜索不到答案退出循環(huán)時(shí)left=right+1,而在二分查找中我們查找的是[left,right]這個(gè)區(qū)間,這說(shuō)明所有的數(shù)都被搜索到了,記住這一點(diǎn),以下我們統(tǒng)稱left<=right的這種寫(xiě)法為寫(xiě)法一
  • mid=(right-left)//2+left這個(gè)寫(xiě)法其實(shí)與mid=(left+right)/2效果是一致的,這么寫(xiě)的目的是為了防止整形溢出的情況,因?yàn)閘eft+right相加如果大于整形最大值的話會(huì)導(dǎo)致結(jié)果異常
  • 在移動(dòng)左右指針時(shí)使用的是right=mid-1和left=mid+1,這是因?yàn)閙id的值已經(jīng)在上一輪循環(huán)中搜索過(guò)了,不需要再進(jìn)行一次搜索

二分查找進(jìn)階版--尋找左右邊界

為了引出二分查找的第二種寫(xiě)法,這里給出一道非力扣題型的二分查找

尋找左側(cè)邊界

例如對(duì)于數(shù)組[1,2,2,2,3],查找目標(biāo)為2,我們需要返回最左邊的2的下標(biāo)1,如果使用寫(xiě)法一我們的代碼看起來(lái)是下面這樣的:

class Solution:def search(self, nums: List[int], target: int) -> int:left, right = 0, len(nums) - 1while left <= right:mid = (right - left) // 2 + leftnum = nums[mid]if num < target:left = mid + 1elif num > target:right = mid - 1else:right = mid - 1if(left >= len(nums) || nums[left] != target): return -1return left

這段代碼有兩個(gè)注意點(diǎn):

  • 由于要找到最左側(cè)的邊界,在else條件里(num=target), 我們不再直接返回結(jié)果,而是繼續(xù)的收縮右邊界,直到right越界或者找到最左邊界坐標(biāo)
  • 是不是決定很奇怪,為什么最后返回的是left,而且是對(duì)left做越界判定,記不記得我在之前說(shuō)過(guò)left<=right的退出條件是left=right+1,我們復(fù)盤(pán)一下最后一輪循環(huán)的情況,你就知道為什么最后返回的是left而且也是對(duì)left進(jìn)行越界的判斷了
  • 復(fù)盤(pán)最后一輪循環(huán)的過(guò)程,對(duì)于數(shù)組[1,2,2,2,3],target為2,假設(shè)當(dāng)前mid為1,循環(huán)也接近了極限,也就是left=mid=right=1,根據(jù)代碼,在num=target=2的時(shí)候,根據(jù)代碼right=mid-1,那么最后right是否一定不指向正確的結(jié)果1,而left指針還沒(méi)有被移動(dòng),依然指向mid,所以我們最后應(yīng)該返回left
  • 再來(lái)看一種情況對(duì)于數(shù)組[1,2,2,2,3]如果我們查找的是數(shù)字4,由于數(shù)組中的數(shù)字都小于target,我們會(huì)不斷的縮小左邊界,直到退出循環(huán)left=right+1,此時(shí)left一定是越界的,因?yàn)閞ight從頭到尾都沒(méi)動(dòng)過(guò),而left=right+1保證了left越界
  • 再來(lái)看一種情況對(duì)于數(shù)組[1,2,2,2,3]如果查找的是數(shù)字0,由于數(shù)組中的數(shù)字都大于target,我們會(huì)不斷的縮小右邊界,直到退出循環(huán)left=right+1,由于我們最后判斷的是left指針,即使right指針越界了,left=right+1也能保證left剛好在下標(biāo)0的位置,所以是不需要考慮左側(cè)越界的情況的

講到這里是不是覺(jué)得寫(xiě)法一來(lái)解決這樣的問(wèn)題真的很復(fù)雜,所以我們接下來(lái)要說(shuō)寫(xiě)法二

寫(xiě)法二

使用寫(xiě)法二來(lái)解決左側(cè)邊界問(wèn)題,代碼如下:

class Solution:def search(self, nums: List[int], target: int) -> int:left, right = 0, len(nums) - 1while left < right:mid = (right - left) // 2 + leftnum = nums[mid]if num < target:left = mid + 1else:right = midreturn left

注意點(diǎn)如下:

  • while循環(huán)結(jié)束的條件是left<right,這說(shuō)明循環(huán)退出的條件是left==right==mid,最后的返回值我們這里返回的是left,其實(shí)返回right也是可以的,因?yàn)檠h(huán)退出的條件是left==mid==right嘛
  • 可以看到另一個(gè)不同在于在else條件里我們偏移右指針的時(shí)候?qū)懙氖莚ight=mid,我們合并了num>target和num=target的條件,所以為什么是寫(xiě)成right=mid而不是right=mid-1呢?

left=mid+1和right=mid

  • 對(duì)于left=mid+1可以這么理解,mid此時(shí)的值一定不是我們需要的值,所以我們可以直接越過(guò).舉個(gè)例子對(duì)于數(shù)組[1,2,3,4,4,5,5],如果要搜索數(shù)字5,我們第一個(gè)搜索到的數(shù)字mid=(left+right)/2=nums[3]=4,此時(shí)4<target,那么是否一定不是我們需要的結(jié)果,那么我們可以直接越過(guò)
  • 對(duì)于right=mid,mid的值可能是我們需要的值,但是在當(dāng)前循環(huán)中我們無(wú)法判斷出來(lái),所以我們進(jìn)行保留,舉個(gè)列子,對(duì)于數(shù)組[1,5,5,5],如果要搜索數(shù)字5,我們第一個(gè)搜索到的數(shù)字mid=nums[1]=5,此時(shí)的5是下標(biāo)為1的5,并且也是最終我們需要找到的最左側(cè)邊界,此時(shí)right=mid這行代碼就能幫助我們把結(jié)果保留了,而后等待left不斷右移知道left==right就能退出循環(huán)返回最終結(jié)果了

尋找右側(cè)邊界

學(xué)會(huì)了尋找左側(cè)邊界,那么右側(cè)邊界是否也很容易理解了,其實(shí)這里有一個(gè)小坑,還需要填一下,這里先給出尋找右側(cè)邊界的代碼

class Solution:def search(self, nums: List[int], target: int) -> int:left, right = 0, len(nums) - 1while left < right:mid = (right - left + 1) // 2 + leftnum = nums[mid]if num > target:right = mid - 1else:left =  midreturn right
  • 相信你已經(jīng)發(fā)現(xiàn)了,在取mid的時(shí)候我們?cè)诶ㄌ?hào)里加上了一個(gè)1,這是因?yàn)槌绦蛘Z(yǔ)言中除法操作后下標(biāo)向下取整(例如(1+2)/2=1),而在尋找右側(cè)邊界的過(guò)程中,這個(gè)操作會(huì)導(dǎo)致死循環(huán),永遠(yuǎn)退不出循環(huán),舉個(gè)列子:
  • 兩者相除,向下取整,這個(gè)操作是不是說(shuō)明mid在有些情況下會(huì)向左偏向,我們?cè)趯ふ易髠?cè)邊界的時(shí)候,需要它向左偏向因此能退出循環(huán),而在尋找右側(cè)邊界時(shí),需要它向右收縮邊界,此時(shí)是否就和向下取整這個(gè)情況矛盾了,此時(shí)一左一右就會(huì)導(dǎo)致永遠(yuǎn)進(jìn)入死循環(huán)了,因此需要mid=(right-left+1)//2+left這個(gè)操作來(lái)打破這個(gè)死循環(huán)

總結(jié)

這里很重要哦,如果理解了這里,就離徹底理解二分寫(xiě)法不遠(yuǎn)了

  • 寫(xiě)法一適合用于在[left,right]這個(gè)范圍內(nèi)找到值,例如最基礎(chǔ)的二分寫(xiě)法,這種寫(xiě)法需要判斷最后返回的是left還是right,要分析最后一次循環(huán)后造成的結(jié)果
  • 寫(xiě)法二適合用于在[left,right]這個(gè)區(qū)間內(nèi)排除值,然后在left=right=mid的時(shí)候找到最后的答案,因此寫(xiě)法二的if條件里寫(xiě)的是target值一定不存在的情況
  • 在寫(xiě)法二中如果else條件里是left=mid這個(gè)條件(趨向是收縮左邊界和向下取整相反),需要修改mid為(right-left+1)//2+left來(lái)避免死循環(huán)情況的出現(xiàn)

二分搜索代碼很簡(jiǎn)單,但細(xì)節(jié)是魔鬼,如果覺(jué)得自己理解了可以使用寫(xiě)法二做做這一題,題目鏈接

http://www.risenshineclean.com/news/3681.html

相關(guān)文章:

  • 影視 網(wǎng)站建設(shè) 新媒體百度云盤(pán)網(wǎng)頁(yè)版
  • 做文獻(xiàn)綜述用什么網(wǎng)站長(zhǎng)沙seo行者seo09
  • 外貿(mào)中間體做哪個(gè)網(wǎng)站好制作網(wǎng)頁(yè)的軟件有哪些
  • 網(wǎng)站模板怎么進(jìn)鶴壁seo推廣
  • wordpress企業(yè)門(mén)戶網(wǎng)站碼迷seo
  • 網(wǎng)站建設(shè)項(xiàng)目申請(qǐng)seo外鏈優(yōu)化培訓(xùn)
  • WordPress小說(shuō)網(wǎng)源碼惠州企業(yè)網(wǎng)站seo
  • 網(wǎng)站建設(shè)選青島的公司好不好大數(shù)據(jù)查詢官網(wǎng)
  • it項(xiàng)目管理軟件排名沈陽(yáng)seo網(wǎng)站推廣
  • Java做網(wǎng)站的學(xué)習(xí)路線網(wǎng)站seo站群軟件
  • 什么網(wǎng)站做兼職最好離我最近的電腦培訓(xùn)中心
  • 連鎖網(wǎng)站開(kāi)發(fā)中國(guó)做網(wǎng)站的公司排名
  • 網(wǎng)站建設(shè) zzit6適合35歲女人的培訓(xùn)班
  • 襄陽(yáng)做淘寶網(wǎng)站推廣數(shù)字營(yíng)銷(xiāo)案例
  • 做外貿(mào)商城網(wǎng)站成功品牌策劃案例
  • 手機(jī)網(wǎng)站范例網(wǎng)站設(shè)計(jì)制作的服務(wù)怎么樣
  • 蘿崗企業(yè)網(wǎng)站建設(shè)百度seo是啥
  • 免插件WordPress對(duì)接公眾號(hào)贛州seo外包
  • 網(wǎng)站建設(shè)驗(yàn)收?qǐng)?bào)告范本市場(chǎng)調(diào)研方案怎么寫(xiě)
  • 動(dòng)態(tài)網(wǎng)站開(kāi)發(fā)大賽成都網(wǎng)站建設(shè)方案推廣
  • 建立企業(yè)網(wǎng)站流程市場(chǎng)營(yíng)銷(xiāo)課程
  • 和各大網(wǎng)站做視頻的工作谷歌優(yōu)化方法
  • 一個(gè)視頻多平臺(tái)發(fā)布撫州seo外包
  • 做國(guó)外網(wǎng)站賺錢(qián)網(wǎng)站改版seo建議
  • 燕郊做網(wǎng)站的公司網(wǎng)絡(luò)營(yíng)銷(xiāo)成功的品牌
  • 浦東新區(qū)做網(wǎng)站廣告推廣宣傳
  • 鶴壁做網(wǎng)站怎么開(kāi)通網(wǎng)站平臺(tái)
  • 域名新聞網(wǎng)站種子資源
  • 鄭州做網(wǎng)站推國(guó)內(nèi)推廣平臺(tái)
  • 做seo網(wǎng)站地圖重要嗎寧波最好的推廣平臺(tái)