描述
給乙個公升序陣列,找到target最後一次出現的位置,如果沒出現過返回-1。
樣例
輸入:nums =[1
,2,2
,4,5
,5], target =
2輸出:2
輸入:nums =[1
,2,2
,4,5
,5], target =
6輸出:-
1
解題思路
簡單二分,只是當mid=target時,還要繼續找下去。
ac**
public
intlastposition
(int
nums,
int target)
int left =
0, right = nums.length -1;
while
(left +
1< right)
else
if(nums[mid]
< target)
else
}// right值等於target
if(nums[right]
== target)
// left值等於target
if(nums[left]
== target)
return-1
;}
描述
給n
個整數的山脈陣列,即先增後減的序列,找到山頂(最大值)
陣列嚴格遞增,嚴格遞減
樣例
輸入: nums =[1
,2,4
,8,6
,3] 輸出:
8
輸入: nums =[10
,9,8
,7],
輸出:10
解題思路
和前面的尋找峰值題一樣乙個思路。
對於位置p:
由此二分找到答案。
ac**
public
intmountainsequence
(int
nums)
if(nums[nums.length -1]
> nums[nums.length -2]
)int left =
0, right = nums.length -1;
while
(left +
1< right)
// 山頂在右側
if(nums[mid]
> nums[mid -1]
)else
}// 判斷山頂
if(nums[right]
> nums[right +1]
&& nums[right]
> nums[right -1]
)if(nums[left]
> nums[left +1]
&& nums[left]
> nums[left -1]
)return0;
}
描述
給乙個按照公升序排序的非負整數陣列。這個陣列很大以至於你只能通過固定的介面arrayreader.get(k)
來訪問第k個數(或者c++裡是arrayreader->get(k)),並且你也沒有辦法得知這個陣列有多大。
找到給出的整數target第一次出現的位置。你的演算法需要在o(logk)的時間複雜度內完成,k為target第一次出現的位置的下標。
如果找不到target,返回-1。
如果你訪問了乙個不可訪問的下標(比如越界),arrayreader 會返回2,147,483,647
樣例
輸入:[1
,3,6
,9,21
,...
], target =
3輸出:
1
輸入:[1,
3,6,
9,21,
...]
, target =
4輸出:
-1
挑戰
o(logn)的時間複雜度,n是target第一次出現的下標。
解題思路
首先第一想法就是二分,但粗看找不到有邊界,挑戰也是只用logk的時間複雜度。所以思考怎麼找到右邊界。
將初始有邊界定位1,然後不斷*2,直到大於target,這所用的時間複雜度是o(logn),滿足題目要求,找到有邊界後,再簡單二分即可。
ac**
public
intsearchbigsortedarray
(arrayreader reader,
int target)
// 尋找右邊界
int right =1;
while
(reader.
get(right)
< target)
// 左邊界=右邊界/2
int left = right /2;
while
(left +
1< right)
else
if(reader.
get(mid)
< target)
else}if
(reader.
get(left)
== target)
if(reader.
get(right)
== target)
// 沒有答案,返回-1
return-1
;}
描述
假設有乙個排序的按未知的旋轉軸旋轉的陣列(比如,0 1 2 4 5 6 7
可能成為4 5 6 7 0 1 2
)。給定乙個目標值進行搜尋,如果在陣列中找到目標值返回陣列中的索引位置,否則返回-1。你可以假設陣列中不存在重複的元素。
樣例
輸入:[4
,5,1
,2,3
] and target=1,
輸出:2.
輸入:[4,
5,1,
2,3] and target=0,
輸出:-
1.
解題思路
解法一前面做過查詢旋轉排序陣列的最小值:
可以先用前面的方法找到最小值,這樣就把陣列分成了兩段有序排序的陣列,在包含target的區間內在進行一次二分即可。都不包含返回-1。
解法二第乙個方法需要兩次二分,還是有點繁瑣。思考只用一次二分的方法。
對於位置k:
要麼 a[k] < a[right],a[k] < a[left] 右半段是有序的
ac**(解法二)
public
intsearch
(int
a,int target)
int left =
0, right = a.length -1;
while
(left +
1< right)
// left和mid有序上公升,判斷target是否在這半段
if(a[mid]
> a[left]
)else
}else
else}}
if(a[left]
== target)
if(a[right]
== target)
// 沒有找到返回-1
return-1
;}
二分法題目彙總
題目知識點 我的題解 其他題解 69.x 的平方根 二分法找右邊界 力扣題解 官方題解 278.第乙個錯誤的版本 二分法找左邊界 力扣題解 官方題解 triple inversion 二分 排序 csdn題解 官方題解 minimum light radius 二分法找左右邊界 csdn題解 719...
C 二分法查詢,遞迴二分法
用二分法來求需要查詢的值.includeusing namespace std 查詢key元素是否存在 int findkey const int buf 100 const int ilen,const int key else right left mid 1 查詢失敗 return 1 查詢k...
python二分法查詢 Python 二分法查詢
二分法查詢主要的作用就是查詢元素 lst 1,3,5,7,12,36,68,79 資料集 百萬級資料 num int input 請輸入你要查詢的元素資訊 for el in lst if num el print 存在 break else print 不存在 len lst 0 1 2 3 4 ...