leetcode 二分查詢

2021-10-10 05:21:41 字數 4967 閱讀 7960

題目要求複雜度有log,可以想到二分,因為時間複雜度:o(logn)

1.二分查詢的關鍵是——題目條件:陣列有序

(實際應用:若資料量太大,使用陣列順序儲存,可能占用記憶體太大)

陣列有序,二分查詢

陣列區域性有序,二分查詢

陣列無序,先排序,再二分查詢

2.平方根

3.二叉搜尋樹,中序遍歷有序,想到二分查詢

4.q:mid := left + (right - left) >> 1

1).int是32位帶符號數,left、right若是兩個很大的正數,加完後可能會超出int範圍,導致溢位,故

mid :=

(left + right)/2=

(2*left+right-left)/2

=(2*left)/2

+(right-left)/2

=left +

(right-left)/2

=left +

(right-left)

>>

1

2)計算機移位運算會更高效

計算機位運算比算術運算更快,因為alu運算單元底層其實也是用閘電路實現的,涉及到的是數電方面。

golong中位運算的優先順序》邏輯運算

5.二分查詢時,l、r的變化由情況而定

for l < r / for l <= r

r = mid / r–

l = mid + 1 / l++

func

binarysearchleft

(second [

]int

,target int

)int

else

if second[mid]

< target

else

}if second[left]

== target

return-1

}

右邊界查詢:一定要中間位置mid計算,需+1。

因為在最後left和right相鄰時,如果mid不+1,則left, mid指向同乙個位置,right指向它們的下乙個位置,在nums[left]已經等於目標值的情況下,left=mid不更新,則這三個位置的值都不會更新,從而進入了死迴圈!

func

binarysearchright

(second [

]int

,target int

)int

else

if second[mid]

< target

else

}if second[right]

== target

return-1

}

注 :查詢左右邊界的**可合併為一段**:

leftindex :=

find

(nums,target,0,

true

)//flag=true是找最左開始下標

if leftindex ==

len(nums)

||nums[leftindex]

!= target

res[0]

= leftindex

res[1]

=find

(nums,target,leftindex,

false

)//flag=false是找最右開始下標

return res

}func

find

(nums [

]int

,target int

,low int

,flag bool

)int

else

if nums[mid]

== target && flag ==

false

else

if nums[mid]

< target

else

}if flag

else

}

7.旋轉排序陣列

兩大特點:

1.末尾元素一定小於等於首位元素(假設陣列長度大於1)

2.由兩個單調陣列組成,前面單調的陣列》=後面的單調陣列

1)找出最小值位置

func

minarray

(numbers [

]int

)int

else

if numbers[mid]

< numbers[right]

else

}return numbers[left]

}

2)陣列無重複元素,找出給定目標值的下標

func

search

(nums [

]int

, target int

)int

//下面這行有個等號,與其他不同。eg:[3,1],target=1

if nums[left]

<= nums[mid]

else

}else

else}}

return-1

}

3)陣列有重複元素,找出給定目標值是否存在

func

search

(nums [

]int

, target int

)bool

if nums[left]

== nums[mid]

else

if nums[left]

< nums[mid]

else

}else

else}}

return

false

}

4)陣列有重複元素,找出給定目標值的下標。

若有多個相同元素,返回索引值最小的乙個。

func

search

(nums [

]int

, target int

)int

if nums[mid]

== target

else

if nums[left]

== nums[mid]

else

if nums[left]

< nums[mid]

else

}else

else}}

return-1

}

162.尋找峰值

給你乙個輸入陣列 nums,找到峰值元素並返回其索引。陣列可能包含多個峰值,在這種情況下,返回 任何乙個峰值 所在位置即可。

輸入:nums = [1,2,1,3,5,6,4]

輸出:1 或 5

可以想成,陣列區域性有序
35.搜尋插入位置

給定乙個排序陣列和乙個目標值,在陣列中找到目標值,則返回其索引。如果目標值不存在於陣列中,返回它將會被按順序插入的位置。

你可以假設陣列中無重複元素。

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

輸出: 2

有序陣列中找第乙個大於等於target元素的位置

func

searchinsert

(nums [

]int

, target int

)int

else

if nums[mid]

< target

else

}return left

}

nc .有重複數字的公升序陣列的插入位置。

尋找陣列中第乙個大於等於target的位置,如果陣列中不存在這樣的數(指不存在大於等於查詢值的數),則輸出陣列長度加一。

輸入:5,4,[1,2,4,4,5]

輸出:3

說明:輸出位置從1開始計算

func

searchinsert

( target int

, a [

]int

)int

else

if a[mid]

>= target

else

if a[mid]

< target

}return left +

1}

有序矩陣中第 k 小的元素

給你乙個 n x n 矩陣 matrix ,其中每行和每列元素均按公升序排序,找到矩陣中第 k 小的元素。

請注意,它是 排序後 的第 k 小元素,而不是第 k 個 不同 的元素。

func

kthsmallest

(matrix [

]int

, k int

)int

else

}return left

}func

findsmallthanmid

(matrix [

]int

,target int

)int

else

}return cnt

}

尋找重複數

給定乙個包含 n + 1 個整數的陣列 nums ,其數字都在 1 到 n 之間(包括 1 和 n),可知至少存在乙個重複的整數。

假設 nums 只有 乙個重複的整數 ,找出 這個重複的數 。

輸入:nums = [1,3,4,2,2]

輸出:2

func

findduplicate

(nums [

]int

)int

}if cnt > mid

else

}return left

}

LeetCode 查詢 二分查詢

給定乙個 n 個元素有序的 公升序 整型陣列 nums 和乙個目標值 target 寫乙個函式搜尋 nums 中的 target,如果目標值存在返回下標,否則返回 1。示例 輸入 nums 1,0,3,5,9,12 target 9 輸出 4 解釋 9 出現在 nums 中並且下標為 4 輸入 nu...

leetcode 二分查詢

leetcode 29 給定兩個整數,被除數dividend和除數divisor。將兩數相除,要求不使用乘法 除法和 mod 運算子。返回被除數dividend除以除數divisor得到的商。演算法設計 用2進製的左移操作,每次對被除數左移1位,比較除數與被除數左移的後的大小關係,並在結果中加上左移...

leetcode 二分查詢

二分查詢基本實現 public intbinarysearch int nums,int key return 1 變種二分查詢,找出陣列中key重複元素最左位置 注意邊界 public intbinarysearch int nums,int key if nums l key return l ...