4 LintCode 二分法題目(二)

2021-10-11 18:36:55 字數 3743 閱讀 8589

描述

給乙個公升序陣列,找到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 ...