題目要求複雜度有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 ...