不積跬步,無以致千里;不積小流,無以成江海。python
內容主要是我的學習使用,題目分類以及部分參考資料來自於CyC的博客,很是感謝大佬,題目來源於LeetCode,很是感謝本站支持。git
二分查找又稱折半查找,顧名思義就是每查找比較一次,就會去掉一半的不匹配項,重複執行此步驟直到找到目標元素或者不能夠在分割github
實現 int sqrt(int x) 函數。
計算並返回 x 的平方根,其中 x 是非負整數。
因爲返回類型是整數,結果只保留整數的部分,小數部分將被捨去。算法
示例 1:數組
輸入: 4 輸出: 2
示例 2:app
輸入: 8 輸出: 2 說明: 8 的平方根是 2.82842..., 因爲返回類型是整數,小數部分將被捨去。
解題思路:函數
計算平方根能夠採用多種方法,具體可參考LeetCode官方,單元測試
代碼實現學習
class Solution: def mySqrt(self, x: int) -> int: if (x <= 1): # 處理0,1特殊狀況 return x; left = 1 right = x // 2 # 肯定區間 while left <= right: mid = left + (right-left) // 2 num = mid * mid if num > x: right = mid - 1 elif num < x: left = mid + 1 elif num == x: return mid return right
給你一個排序後的字符列表letters
,列表中只包含小寫英文字母。另給出一個目標字母 target
,請你尋找在這一有序列表裏比目標字母大的最小字母。測試
在比較時,字母是依序循環出現的。舉個例子:
target = 'z'
而且字符列表爲letters = ['a', 'b']
,則答案返回'a'
示例:
輸入: letters = ["c", "f", "j"] target = "a" 輸出: "c" 輸入: letters = ["c", "f", "j"] target = "c" 輸出: "f"
解題思路:
target
代碼實現
class Solution: def nextGreatestLetter(self, letters: List[str], target: str) -> str: left = 0 right = len(letters) - 1 while left <= right: mid = left + (right - left) // 2 if letters[mid] > target: right = mid - 1 elif letters[mid] < target: left = mid + 1 else: left = mid + 1 return letters[left] if left < len(letters) else letters[0]
給定一個只包含整數的有序數組,每一個元素都會出現兩次,惟有一個數只會出現一次,找出這個數。
示例 1:
輸入: [1,1,2,3,3,4,4,8,8] 輸出: 2
示例 2:
輸入: [3,3,7,7,10,11,11] 輸出: 10
注意: 您的方案應該在 O(log n)時間複雜度和 O(1)空間複雜度中運行。
解題思路:
[1,1,2,2,3,3,4,5,5]
,該數組分割後前[1,1,2,2]
,後爲[3,4,5,5]
,因爲都是偶數個,因此一定有一組是不含單一元素的,咱們只須要比較中間元素和前一元素是否相等,不想等的則是正確一組,反之是須要下次查找[3,3,7,7,10,11,11]
,該數組分割後前[3,3,7]
,後爲[10,11,11]
,因爲都是奇數個,因此不能肯定那一組究竟是包含單一元素,咱們仍然經過比較中間元素和前一元素是否相等,則相等則表示那一組是正確的,反之不正確。代碼實現
class Solution: def singleNonDuplicate(self, nums: List[int]) -> int: left = 0 right = len(nums) - 1 while left <= right: mid = left + (right - left) // 2 tag = len(nums[:mid]) % 2 == 0 # 判斷分割的左側是否是偶數對 if tag: if nums[mid] == nums[mid - 1]: right = mid - 1 else: left = mid + 1 else: if nums[mid] == nums[mid - 1]: left = mid + 1 else: right = mid - 1 return nums[right]
假設你有 n 個版本 [1, 2, ..., n],你想找出致使以後全部版本出錯的第一個錯誤的版本。
你能夠經過調用 bool isBadVersion(version) 接口來判斷版本號 version 是否在單元測試中出錯。實現一個函數來查找第一個錯誤的版本。你應該儘可能減小對調用 API 的次數。
示例:
給定 n = 5,而且 version = 4 是第一個錯誤的版本。 調用 isBadVersion(3) -> false 調用 isBadVersion(5) -> true 調用 isBadVersion(4) -> true 因此,4 是第一個錯誤的版本。
解題思路:
mid
版本是正確的,則表示錯誤版本處於[mid+1,right]
,不斷縮減右區間mid
版本是錯誤的,則表示錯誤版本處於[left,mid]
,不斷縮減左區間代碼實現
class Solution: def firstBadVersion(self, n): """ :type n: int :rtype: int """ left = 1 right = n while left < right: mid = left + (right - left) // 2 if isBadVersion(mid): right = mid else: left = mid + 1 return left
假設按照升序排序的數組在預先未知的某個點上進行了旋轉。
( 例如,數組 [0,1,2,4,5,6,7] 可能變爲 [4,5,6,7,0,1,2] )。
請找出其中最小的元素。你能夠假設數組中不存在重複元素
示例 1:
輸入: [3,4,5,1,2] 輸出: 1
示例 2:
輸入: [4,5,6,7,0,1,2] 輸出: 0
解題思路:
[4, 5, 6, 7, 0, 1, 2], mid = 3, nums[mid] = 7, nums[-1] = 2
, 故 nums[mid] > nums[-1]
,說明數組旋轉後較小的一部分升序序列在mid右邊,更新區間:left = mid + 1
;[6, 7, 1, 2, 3, 4, 5], mid = 3, nums[mid] = 2, nums[-1] = 5
,故 nums[mid] < nums[-1]
,說明數組旋轉後較小的一部分升序序列在mid左邊,更新區間:right = mid - 1
。代碼實現
class Solution: def findMin(self, nums: List[int]) -> int: left = 0 right = len(nums) - 1 while left <= right: mid = left + (right - left) // 2 if nums[mid] > nums[-1]: left = mid + 1 else: right = mid - 1 return nums[left]
給定一個按照升序排列的整數數組 nums,和一個目標值 target。找出給定目標值在數組中的開始位置和結束位置。
你的算法時間複雜度必須是 O(log n) 級別。
若是數組中不存在目標值,返回 [-1, -1]。
示例 1:
輸入: nums = [5,7,7,8,8,10], target = 8 輸出: [3,4]
示例 2:
輸入: nums = [5,7,7,8,8,10], target = 6 輸出: [-1,-1]
解題思路:
代碼實現
class Solution: def searchRange(self, nums: List[int], target: int) -> List[int]: left = 0 right = len(nums) - 1 ret = [] while left <= right: mid = left + (right - left) // 2 if nums[mid] > target: right = mid - 1 elif nums[mid] < target: left = mid + 1 else: right = mid - 1 if left == len(nums): ret.append(-1) else: ret.append(left if nums[left] == target else -1) left = 0 right = len(nums) - 1 while left <= right: mid = left + (right - left) // 2 if nums[mid] > target: right = mid - 1 elif nums[mid] < target: left = mid + 1 else: left = mid + 1 if left == 0: ret.append(-1) else: ret.append(left-1 if nums[left-1] == target else -1) return ret