演算法細節系列(5) 二分查詢應用

2021-07-30 03:43:51 字數 2648 閱讀 8320

題目**於leetcode: id

title

acceptance

difficulty

35search insert position

39.3%

easy

367valid perfect square

37.8%

easy

153find minimum in rotated sorted array

39.2%

medium

154find minimum in rotated sorted array ii

36.6%

hard

詳見連線:

public

intsearchinsert(int nums, int target) else

}//邊界條件

if (nums[rt] < target) return rt + 1;

return rt;

}

考點為lfrt的變動,以上是閉區間的解決方案。主要注意邊界條件的使用,需要對陣列最後乙個元素進行邊界判斷。

public

class

solution

private

intbinarysearch(int num, int target)else

}if (target % rt == 0 && target / rt == rt) return rt;

return -1;

}}

官網還有其它兩種解法,此處主要用二分查詢。簡單敘述下它的思想,假設nums = 9,那麼我們可以構造乙個」陣列」,或者稱為解空間更合適。12

3456

7891

491625

3649

6481

那麼我們只需要在給定的解空間內找尋到對應的nums,很明顯我們能在1~9的解空間內,找到對應的9,需要注意一點!為了防止大數相乘溢位,這裡判斷語句為target / mid > mid,把這部分解給排除後,迴圈外還需要增加乙個額外的判斷,如 42 / 6 > 6,但是它並不是perfect square.

public

intfindmin(int nums) else

}//邊界條件

if (nums[rt] > nums[rt-1]) return nums[rt-1];

return nums[rt];

}

這是一種解法,需要注意nums[mid] > nums[mid-1],所以lf的初始值必須在1,否則會越界。單純的這個條件是無法找到最小的,原因如下,當陣列沒有發生旋轉時,它的切分不斷向rt靠近,顯然離想要搜尋的越來越遠,所以還需要加上nums[mid] > nums[rt]如果存在旋轉,且搜尋的最小值在右側,必然割掉左半部分。邊界條件的考慮在於,如果沒有旋轉的陣列,while迴圈一直走rt = mid,那麼必然rt會慢慢接近lf = 1,針對這個問題我們要額外的邊界條件去判斷。

其實有一種方式可以幫助我們理解,我們要找的是最小,但二分的目的在於丟棄一部分而去搜尋另一部分,所以終極目標在於找到左半部分和右半部分的唯一區別的條件,如果能把它們唯一區分,那就自然能解。

這裡有一種更優美的方式,我們只需要加乙個條件即可。nums[mid] > nums[rt],這就能區分左和右了。所以有

public

class

solution

else

}return nums[rt];

}}

好處很明顯,nums[mid] < nums[rt]時,rt會不斷向lf靠近,而因為沒有了mid-1所以lf可以取0,那麼自然而然的邊界就不需要再考慮了。而左半部分也能被清楚的區分,一舉兩得。

public

class

solution else

if(nums[mid] < nums[rt])else

}return nums[rt];

}}

好吧,我是看了解決方案才理解的,沒有想到當相等情況下,直接對rt--就好了,它主要針對如下情況:

[3,3,3,3,3,3,3,3,3,3,3,1,3,3]

ifelse前面已經說了很多了,我不多說,主要遇到nums[mid] == nums[rt]時,rt--的確很巧妙!!!如果把這個等號放在if中,那麼會出現[1,2,3,3,3,3,3,3,3]檢測出錯的情況,原因在於lf會不斷向rt靠近,但顯然在它的搜尋路徑中是找不到最小值的,為了規避這種情況,我們讓相等時rt--,那麼不管上面哪兩種情況,它都能解決了,呵呵,想不到。

二分查詢細節問題

1.1 兩種實現 情況一 right nums.length int binary search int nums,int target else if nums mid target else if nums mid target 因為迴圈的結束條件是 left right,它們指向的元素未被判斷...

二分查詢細節永不忘

二分查詢中大於小於,甚至判斷條件中的 很容易弄混。下面一起來捋清楚,保證了解原理,不會再錯。重點的概念在於選區的區間 我建議選取的區間為左閉右閉,即 l,r 當然其他方式也可以,我們不做講述。因此需要注意以下三點即可 1.r arr.length 1而不是length 這樣使得r為末數的下標,有意義...

查詢演算法 二分查詢

利用二分查詢演算法查詢某乙個元素,前提條件是該被查詢的元素是乙個已經有序的陣列。二分查詢的思想是將陣列元素的最高位 high 和最低位 low 進行標記,取陣列元素的中間 mid 和和要查詢的值 key 進行比較,如果目標值比中間值要大,則將最低位設定為mid 1,繼續進行查詢。如果目標值小於中間值...