国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Leetcode刷題筆記——二分法

這篇具有很好參考價值的文章主要介紹了Leetcode刷題筆記——二分法。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

二分法是搜索算法中極其典型的方法,其要求輸入序列有序并可隨機訪問。算法思想為

輸入:有序數(shù)組nums,目的數(shù)值target
要求輸出:如果target存在在數(shù)組中,則輸出其index,否則輸出-1

  1. 將原數(shù)組通過[left,right]兩個索引劃分范圍,初值left=0,right=數(shù)組的最后一個元素
  2. 當(dāng)left <= right時
    1. middle = (left + right)/2
    2. 判斷nums[middle]是不是要查找的target,如果是則返回結(jié)果
    3. 判斷nums[middle]> target,證明要查找的target在左邊,因此right = middle - 1
    4. 判斷nums[middle]< target,證明要查找的target在右邊,因此left = middle + 1
  3. 沒有查找到return -1。

形如下圖:

Leetcode刷題筆記——二分法

傳統(tǒng)的二分法代碼如下:

func binarySearch(nums []int, target int) int {
	left, right := 0, len(nums)-1
	for left <= right {
		middle := (left + right) / 2
		if nums[middle] == target {
			return middle
		} else if nums[middle] > target {
			right = middle - 1
		} else {
			left = middle + 1
		}
	}
	return -1
}

這里要注意兩個問題:

  1. 上述算法中的第2步中=的判斷,即for left <= right還是for left < right。
  2. 上述算法2.2-2.4中的判斷條件以及下一次查找區(qū)間的設(shè)置
  3. 返回值代表什么意思

for left<= right 中 = 的判斷

首先對于第一個問題,=是否應(yīng)該存在,取決于對于二分查找的初始化定義,例如:

  1. 如果二分查找遍歷的區(qū)間采用[left,right](數(shù)學(xué)中的雙閉區(qū)間)的形式,考慮left==right=成立的情況,則表示區(qū)間內(nèi)只有單個操作數(shù),這種情況還是需要處理,否則無法通過其余方式表示這種情況,所以此時=是必須的。
  2. 如果二分查找遍歷的區(qū)間采用[left,right)的形式,考慮left==right=成立的情況,事實證明,這種情況并不應(yīng)該存在,我們無法用[i,i)表示任何一個區(qū)間,所以,這種情況下,=就不是必須的。

判斷條件以及下一次查找區(qū)間的設(shè)置

然后考察對于第二個問題,判斷條件以及下一次查找區(qū)間應(yīng)該如何設(shè)置?

注意:二分查找是一個經(jīng)典的查找算法,其目的是查找到指定的位置或者值,并不僅限于查找到等于target的index這一種情況。

但無論怎樣,二分查找本身有一個固定模式,即二分,就是從middle處將區(qū)間[left,right]分成兩份,然后根據(jù)middle的情況查找(或者更新新的區(qū)間),因此,我們只需要考慮清楚如下三種條件時要怎么處理即可:

  1. 當(dāng)遍歷到nums[middle] == target時應(yīng)該怎樣處理(新的查找區(qū)間是什么),即當(dāng)前值等于目標值
  2. 當(dāng)遍歷到nums[middle] > target時應(yīng)該怎樣處理(新的查找區(qū)間是什么),即當(dāng)前值大于目標值
  3. 當(dāng)遍歷到nums[middle] < target時應(yīng)該怎樣處理(新的查找區(qū)間是什么),即當(dāng)前值小于目標值

討論完上述兩個問題,其實二分法就有了一個固定的框架:

func binarySearch(nums []int, target int) int {
	left, right := 0, len(nums)-1
	for left <= right {
		middle := (left + right) / 2
		if nums[middle] == target {
			// 當(dāng)前值等于目標值時,如何處理(新的查找區(qū)間是什么)
		} else if nums[middle] > target {
			// 當(dāng)前值大于目標值時,如何處理(新的查找區(qū)間是什么)
		} else {
			// 當(dāng)前值小于目標值時,如何處理(新的查找區(qū)間是什么)
		}
	}
    // 考慮返回值的意義
	return 
}

返回值的含義

最后我們討論返回值的含義這一話題。在傳統(tǒng)的二分查找中,只有在兩種情況下會返回:

  1. 查找到目標target,返回查找到的index
  2. 未查找到目標target,返回-1。(即文章最起始處 步驟3的含義)

這里返回值的含義表示target在nums中的index,該值只會出現(xiàn)在nums[middle]==target這一條件下。然而,剛才提到了二分查找不總是處理等式條件,因此我們總要思考兩種返回值的含義:

  1. nums[middle]==target,這時return代表的是什么?
  2. 數(shù)組中不存在target,此時return的是什么,此時left、right代表什么?

這里我們舉一個稍稍復(fù)雜一點的例子對二分查找進行分析。

  • 搜索插入位置
  • 在排序數(shù)組中查找元素的第一個和最后一個位置

搜索插入位置

題目要求如下:

Leetcode刷題筆記——二分法

這個問題要求返回兩種返回值:

  1. 在數(shù)組中找到目標值,并返回其索引
  2. 如果目標值不存在于數(shù)組中,返回它將會被按順序插入的位置

其中對于情況1,傳統(tǒng)的二分查找算法就可以解決,而情況2,則需要借助于本部分要講解的返回值的含義。

對于傳統(tǒng)的二分法:

func binarySearch(nums []int, target int) int {
	left, right := 0, len(nums)-1
	for left <= right {
		middle := (left + right) / 2
		if nums[middle] == target {
			return middle
		} else if nums[middle] > target {
			right = middle - 1
		} else {
			left = middle + 1
		}
	}
	return -1
}

如果target能在nums數(shù)組中查找到,必定最終查找到一個[i,i]類型的區(qū)間,即區(qū)間中只有一個數(shù)字,否則區(qū)間就要再次進行二分。例如:如果要在下列數(shù)組中查找4所在的位置,查找過程如下,第三步時,查找區(qū)間為[2,3],有兩個值,無法確定答案,則需要再次進行一次查找:

target == 4
nums   1  2  3  4
index  0  1  2  3
1      l        r
2         l     r
3            l  r
4               lr 

那么最終我們處理的情況必定是對于區(qū)間[left,right]中,其中l(wèi)eft == right,因此middle == left == right,此時nums[middle]和target的關(guān)系。

  • nums[middle] > target,則需要從middle左側(cè)繼續(xù)尋找,right = middle - 1,注意此時left = middle,left > right
  • nums[middle] < target,則需要從middle右側(cè)繼續(xù)尋找,left = middle + 1,注意此時right = middle,left > right

所以此時,left指向的永遠是大的那個值,right是小的那個值(因為left <= right時,循環(huán)不會終止,循環(huán)終止條件為left > right,根據(jù)數(shù)組的有序性,nums[left] > nums[right])。

最后,我們考察該題,對于數(shù)組nums,如果目標值不在其中,那么其最終查找到的值只有兩種情況:

  1. nums[middle] < target,此時nums[middle]應(yīng)該是第一個小于target的值,如果要查找target所在位置,應(yīng)該返回大于middle的index,即left
  2. nums[middle] > target,此時nums[middle]應(yīng)該是第一個大于target的值,如果要查找target所在位置,應(yīng)該返回等于middle的index,用target替換middle位置的值,即left

因此,該題的結(jié)果,只需要修改傳統(tǒng)二分查找的最后一行:

func binarySearch(nums []int, target int) int {
	left, right := 0, len(nums)-1
	for left <= right {
		middle := (left + right) / 2
		if nums[middle] == target {
			return middle
		} else if nums[middle] > target {
			right = middle - 1
		} else {
			left = middle + 1
		}
	}
	return left 
}

在排序數(shù)組中查找元素的第一個和最后一個位置

題目要求如下:

Leetcode刷題筆記——二分法

注意這里查找的是元素第一次和最后一次出現(xiàn)的位置,這里我們以查找第一次出現(xiàn)的位置舉例,后者同理。

考察我們在判斷條件以及下一次查找區(qū)間的設(shè)置中強調(diào)的,考察二分查找的三種情況:

情況 分析 操作
nums[middle] == target時,即當(dāng)前值等于目標值 第一次出現(xiàn)的位置可能在當(dāng)前值前面 right = middle - 1
nums[middle] > target時,即當(dāng)前值大于目標值 第一次出現(xiàn)的位置在當(dāng)前值前面 right = middle - 1
nums[middle] < target時,即當(dāng)前值小于目標值 第一次出現(xiàn)的位置在當(dāng)前值后面 left = middle + 1

與之前不同的是當(dāng)nums[middle] == target時,不再有返回值了,那么考慮最后返回值的含義,最終left > right時情況有如下3種:

情況 分析 操作
nums[middle] == target 此時,middle前的值必定<middle,而不是等于(只要等于,考慮上表的情況1,會使right = middle - 1) return left
nums[middle] > target 此情況不存在,因為如果有這種情況會繼續(xù)使right=middle-1 不進行操作
nums[middle] < target 此時middle必定是target前的第一個元素 return left

經(jīng)過上面的分析后,可以清晰的寫出代碼:

    l, r := 0, len(nums)-1
	for l <= r {
		m := (l + r) / 2
		if nums[m] >= target {
			r = m - 1
		} else {
			l = m + 1
		}
	}
    result := l

而查找元素出現(xiàn)的最后一個位置,只需要反過來,最后return right即可。代碼如下:

    l, r: = 0, len(nums)-1
	for l <= r {
		m := (l + r) / 2
		if nums[m] <= target {
			l = m + 1
		} else {
			r = m - 1
		}
	}
    result := r

總結(jié)

本文詳細分析了二分查找的所有細節(jié),對于二分查找處理的問題,我們常常需要更加關(guān)注本文討論的后兩個問題:

  1. 判斷條件以及下一次查找區(qū)間的設(shè)置
  2. 返回值的含義

最后填充模版即可。文章來源地址http://www.zghlxwxcb.cn/news/detail-689907.html

func binarySearch(nums []int, target int) int {
	left, right := 0, len(nums)-1
	for left <= right {
		middle := (left + right) / 2
		if nums[middle] == target {
			// 當(dāng)前值等于目標值時,如何處理(新的查找區(qū)間是什么)
		} else if nums[middle] > target {
			// 當(dāng)前值大于目標值時,如何處理(新的查找區(qū)間是什么)
		} else {
			// 當(dāng)前值小于目標值時,如何處理(新的查找區(qū)間是什么)
		}
	}
    // 考慮返回值的意義
	return 
}

到了這里,關(guān)于Leetcode刷題筆記——二分法的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • 【力扣】74. 搜索二維矩陣 <二分法>

    給你一個滿足下述兩條屬性的 m x n 整數(shù)矩陣: 每行中的整數(shù)從左到右按非遞減順序排列。 每行的第一個整數(shù)大于前一行的最后一個整數(shù)。 給你一個整數(shù) target ,如果 target 在矩陣中,返回 true ;否則,返回 false 。 示例 1: 1 3 5 7 10 11 16 20 23 30 34 60 輸入:matrix = [[1,3,5,7],[10,

    2024年02月15日
    瀏覽(22)
  • 【算法】—二分法詳解

    【算法】—二分法詳解

    ①定義: 二分查找算法也稱折半搜索算法,對數(shù)搜索算法,是一種在 有序數(shù)組 中查找某一特定元素的搜索算法。搜索過程從數(shù)組的中間元素開始,如果中間元素正好是要查找的元素,則搜索過程結(jié)束;如果某一特定元素大于或者小于中間元素,則在數(shù)組大于或小于中間元素

    2024年02月09日
    瀏覽(25)
  • 06-C++ 基本算法 - 二分法

    06-C++ 基本算法 - 二分法

    在這個筆記中,我們將介紹二分法這種基本的算法思想,以及它在 C++ 中的應(yīng)用。我們將從一個小游戲猜數(shù)字開始,通過這個案例來引出二分法的概念。然后我們將詳細講解什么是二分法以及它的套路和應(yīng)用。最后,我們還會介紹 C++ STL 中的二分查找函數(shù)。讓我們一起來探索

    2024年02月16日
    瀏覽(16)
  • 算法:二分法---尋找H指數(shù)

    算法:二分法---尋找H指數(shù)

    1、題目: 給你一個整數(shù)數(shù)組 citations ,其中 citations[i] 表示研究者的第 i 篇論文被引用的次數(shù)。計算并返回該研究者的 h 指數(shù) 。 根據(jù)維基百科上 h 指數(shù)的定義: h 代表“高引用次數(shù)” ,一名科研人員的 h 指數(shù) 是指他(她)至少發(fā)表了 h 篇論文,并且每篇論文 至少 被引用

    2024年02月08日
    瀏覽(21)
  • 【算法】【算法雜談】旋轉(zhuǎn)數(shù)組的二分法查找

    【算法】【算法雜談】旋轉(zhuǎn)數(shù)組的二分法查找

    當(dāng)前所有算法都使用測試用例運行過,但是不保證100%的測試用例,如果存在問題務(wù)必聯(lián)系批評指正~ 在此感謝左大神讓我對算法有了新的感悟認識! 原問題 給定一個從小到大有序的數(shù)組,該數(shù)組存在重復(fù)的數(shù),并且該數(shù)組可能經(jīng)過旋轉(zhuǎn)處理,如arr = [1,2,3,4,5,6,7]代表數(shù)組未旋

    2024年02月06日
    瀏覽(32)
  • 數(shù)據(jù)結(jié)構(gòu)和算法之二分法查找

    二分法查找,也稱作 二分查找 或 折半查找 ,是一種在有序數(shù)組中快速查找特定元素的算法。它采用分治法思想,通過將問題劃分為規(guī)模更小的子問題,并且通過對子問題的查找來解決原問題。 二分法查找的思路是不斷地將數(shù)組一分為二,然后判斷目標值在哪一部分,進而

    2024年02月09日
    瀏覽(31)
  • 初階算法(3):二分法的講解與實現(xiàn)(C語言),以及二分不止光在有序數(shù)組中的應(yīng)用

    ?第一章?初階算法(1):通過簡單的排序算法來認識時間復(fù)雜度 ?第二章?初階算法(2):進行詳細地介紹插入排序的細節(jié)和時間復(fù)雜度 ?第三章 初階算法(3):二分法的講解與實現(xiàn),以及二分不止光在有序數(shù)組中的應(yīng)用 目錄 系列文章目錄 前言 一、二分法的講解與實現(xiàn)

    2024年02月14日
    瀏覽(25)
  • 二分法簡單題

    2024年01月24日
    瀏覽(27)
  • 二分法相關(guān)使用

    二分法相關(guān)使用

    在線OJ:704. 二分查找 有序數(shù)組下的二分思路如下: 由于這里是有序數(shù)組, 我們可以可以先得到中點位置, 中點可以把數(shù)組分為左右兩邊; 如果中點位置的值等于目標值, 直接返回中點位置; 如果中點位置的值小于目標值, 則去數(shù)組中點左側(cè)按同樣的方式查找; 如果中點位置的值大

    2024年02月07日
    瀏覽(17)
  • 二分法MATLAB代碼

    二分法MATLAB代碼

    本質(zhì)是通過不斷進行區(qū)間壓縮來獲取函數(shù)零點。 二分法的終止條件:區(qū)間長度小于等于精度要求 。 流程: 如下圖所示:

    2024年02月05日
    瀏覽(25)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包