複雜度
可能對應的演算法
備註o(1)
位運算常數級複雜度,一般面試中不會有
o(logn)
二分法,倍增法,快速冪演算法,輾轉相除法
o(n)
列舉法,雙指標演算法,單調棧演算法,kmp演算法,rabin karp,manacher』s algorithm
又稱作線性時間複雜度
o(nlogn)
快速排序,歸併排序,堆排序
o(n^2)
列舉法,動態規劃,dijkstra
o(n^3)
列舉法,動態規劃,floyd
o(2^n)
與組合有關的搜尋問題
o(n!)
與排列有關的搜尋問題
while的目的是縮小一半的區間
二分法基礎概念–leetcode704
class
solution
int left =
0, right = nums.length -1;
// 要點1: left + 1 < right
while
(left +
1< right)
else
if(nums[mid]
< target)
else
if(nums[mid]
> target)
}//要點5:出迴圈的時候,判斷誰是題目所要的答案
if(nums[left]
== target)
if(nums[right]
== target)
return-1
;}}
q: 要點1處為什麼要用 left + 1 < right?而不是 left < right 或者 left <= right?
a: 為了避免死迴圈。二分法的模板中,整個程式架構分為兩個部分:
通過 while 迴圈,將區間範圍從 n 縮小到 2 (只有 left 和 right 兩個點)。
在 left 和 right 中判斷是否有解。
left < right 或者 left <= right 在尋找目標最後一次出現的位置的時候,會出現死迴圈。
q: 要點2處為什麼要用 left + (right - left) / 2?而不是 (left + right) / 2?
a: 為了避免可能出現加法溢位,也就是說加法的結果大於整型能夠表示的範圍,因為這裡的/號的結果多向左取數。但是left 和 right都為正數,因此 right - left 不會出現加法溢位問題。
q: 要點3處為什麼明明可以 left = mid + 1 偏偏要寫成 left = mid?
a: 大部分時候,mid 是可以 +1 和 -1 的。在一些特殊情況下,比如尋找目標的最後一次出現的位置時,當 target 與 nums[mid] 相等的時候,是不能夠使用 mid + 1 或者 mid - 1 的。因為會導致漏掉解。那麼為了節省腦力,統一寫成 left = mid 或 right = mid 並不會造成任何解的丟失,並且也不會損失效率——log(n) 和 log(n+1) 沒有區別。
q: 要點4處為什麼不直接return mid?
a: 分成三種情況。
當查詢目標值在排序陣列中的末尾位置時候(尋找右側邊界的二分搜尋),此處需要設定為left = mid;
;
當只是單純的查詢乙個在排序陣列中的目標值時,則可以設定為return mid。
q: 要點5處為什麼要設定判斷?
a:該模板中,當left和right相鄰時候,就不會走while迴圈,此時target就是left和right兩個值的其中乙個,故此處做判斷。
先用arraylist倍增找到≥target的乙個區間範圍,再去用二分法找到題目所要求的target。
分成四種情況討論mid所在的位置,即波谷,波峰,上公升趨勢的某點,下降趨勢的某點
參考:演算法班筆記 第二章 二分與 logn 演算法
//迭**法 <=
//right < target < left
intbinary_search
(int
nums,
int target)
else
if(nums[mid]
> target)
else
if(nums[mid]
== target)
}// 直接返回
return-1
;}intleft_bound
(int
nums,
int target)
else
if(nums[mid]
> target)
else
if(nums[mid]
== target)
}// 最後要檢查 left 越界的情況
if(left >= nums.length || nums[left]
!= target)
return-1
;return left;
}int
right_bound
(int
nums,
int target)
else
if(nums[mid]
> target)
else
if(nums[mid]
== target)
}// 最後要檢查 right 越界的情況
if(right <
0|| nums[right]
!= target)
return-1
;return right;
}
STL中的二分查詢(binary search)
stl中對於有序序列 vector,list等 提供了相當相當強大的二分搜尋binary search演算法。對於可以隨機訪問容器 如vector等 binary search負載度為對數級別 logn 對於非隨機訪問容器 如list 則演算法複雜度為線性。現在簡要介紹一下幾種常用的binary s...
Java 二分搜尋 二分查詢
對陣列元素進行逐個查詢顯然是費時費力的工作,我們可以使用一些方法快速地搜尋出陣列中元素的指定位置.接下來我們介紹一種方法 二分搜尋法 二分搜尋法充分利用了元素間的次序關係.基本思想 將n元素分成個數大致相同的涼拌,取arr n 2 與欲查詢的x做比較,如果 下面將採用兩種方式 遞迴 非遞迴 來展示二...
二分(二分答案 二分搜尋)與單調性
經典二分搜尋是二分空間範圍。二分答案又叫二分猜值,是二分解的值空間。其實可以統一,普通的二分搜尋也是二分答案值域 下標空間,也是猜值。二分必須滿足單調性,最直觀的,二分搜尋只能在有序陣列上進行。單調性體現在,下標和元素值是單調的,也就是 if j i 有 a j a i 一般二分答案解決的問題是最優...