leetcode刷題記錄 演算法(二)二分法

2021-10-25 07:47:32 字數 3563 閱讀 3887

二分法就不多講了,很基礎的演算法,適用於排好序的數,可以提公升很高的效率。

704.二分查詢

執行用時:276 ms, 在所有 python3 提交中擊敗了98.03%的使用者

class

solution

:def

search

(self, nums: list[

int]

, target:

int)

->

int:

low =

0 high =

len(nums)-1

while

(low<=high)

: temp =

(low+high)//2

if nums[temp]

==target:

return temp

elif nums[temp]

>target:

high = temp-

1elif nums[temp]

low = temp+

1return

-1

class

solution

:def

searchinsert

(self, nums: list[

int]

, target:

int)

->

int:

low, high =0,

len(nums)-1

while

(low<=high)

: temp =

(low+high)//2

if nums[temp]

==target:

return temp

elif nums[temp]

>target:

high = temp-

1elif nums[temp]

low = temp+

1return low

162.查詢峰值。

這道題比較難(中等難度的對於我這種小白來說就是難的了),一開始還是沒做出來,看了官方給的解題思路。

力扣的描述是:

峰值元素是指其值大於左右相鄰值的元素。

給定乙個輸入陣列 nums,其中 nums[i] ≠ nums[i+1],找到峰值元素並返回其索引。

陣列可能包含多個峰值,在這種情況下,返回任何乙個峰值所在位置即可。

你可以假設 nums[-1] = nums[n] = -∞。

而且要求了o(logn)的時間複雜度。

看題目:

1.只要找到乙個峰值就可以

2.相鄰元素不相等

3.nums[-1] = nums[n] = -∞

這樣三個條件。

一開始我寫**的時候,總是以nums[i-1]nums[i+1]作為峰值的判別條件,從而導致列表的兩端很難處理,總是溢位,需要進行很多條件判斷,越寫越長,**逐漸複雜了起來,想來應該不會出這麼沒有營養的題目,就沒忍住看了答案(哭)。

官方解答中,最重要的一點就是可以通過只比較nums[i] 和 nums[i+1]的大小,就能達到判斷的目的。

取i為當前要處理的列表的中點,考慮如下幾種情況:

nums[i] > nums[i+1]

此時,將游標從中點[i]向右側移動,值是下降的;

又因為nums[-1]可以看作負無窮,所以將游標從[-1]向右移動,值必然是上公升的;

所以在列表的左半部分,[0, i+1]中(兩側都包含,因為i可能是峰值)值先上公升在下降,必然存在乙個峰值。

nums[i] < nums[i+1]

此時,將游標從中點[i]向右側移動,值是上公升的;

又因為nums[n]可以看作負無窮,所以將游標從[n]向左移動,值必然是上公升的;

所以在列表的右半部分,(i, n-1]中(左側i不包含,因為i必然不可能是峰值)值先上公升在下降,必然存在乙個峰值。

很容易想到,這裡應該使用遞迴,但是我還沒學到遞迴,就暫時用迭**了一下。

可見做演算法題主要還是思路。

class

solution

:def

findpeakelement

(self, nums: list[

int])-

>

int:

left,right =0,

len(nums)-1

while

(left<=right)

:if left == right:

return left

temp =

(left+right)//2

if nums[temp]

>nums[temp+1]

: right = temp

elif nums[temp]

: left = temp+

1##+1拋棄無用值,而且如果left和right都不+-1的話,最終left無法等於right,會無限迴圈。

然後是74題,搜尋二維矩陣。

這道題也是比較簡單的,讀題可以了解到,如果將矩陣鋪平,其實就是乙個已經排好序的列表,我們完全可以套用之前的**,只不過將temp進行一下換算就可以滿足要求。

class

solution

:def

searchmatrix

(self, matrix: list[list[

int]

], target:

int)

->

bool

:## 這裡排除了乙個特殊情況,因為如果是空矩陣,下面的**會報錯if(

len(matrix)==0

):return

false

## 獲取矩陣的維度,如果用numpy的話應該是matrix.shape

m, n =

len(matrix)

,len

(matrix[0]

) length = m*n ##計算總長度

left, right =

0, length-

1while

(left <= right)

: temp =

(left+right)//2

## 與前面的**相比只有這裡不一樣,將長度換算為行列數

x = temp // n

y = temp % n

if matrix[x]

[y]== target:

return

true

elif matrix[x]

[y]> target:

right = temp-

1elif matrix[x]

[y]< target:

left = temp+

1return

false

好啦,二分法就先做這幾道題。

LeetCode初級演算法刷題記錄

1 刪除排序陣列中的重複項。給定乙個排序陣列,你需要在 原地 刪除重複出現的元素,使得每個元素只出現一次,返回移除後陣列的新長度。不要使用額外的陣列空間,你必須在 原地 修改輸入陣列 並在使用 o 1 額外空間的條件下完成。class solution int i 0 for int j 1 j n...

leetcode刷題記錄

我覺得每天來兩道,練習練習,再看看人家是怎麼優化的。1.給定乙個整數陣列 nums 和乙個目標值 target,請你在該陣列中找出和為目標值的那 兩個 整數,並返回他們的陣列下標。c 暴力求解,204ms,9.1m class solution for index,num in enumerate ...

LeetCode刷題記錄

動態規劃和貪心演算法的異同點 class solution throw newruntimeexception 時間複雜度 o n 2 對於每個元素,我們試圖通過遍歷陣列的其餘部分來尋找它所對應的目標元素,這將耗費 o n o n 的時間。因此時間複雜度為 o n 2 需要一種方法,尋找符合要求的元...