目录
二分搜索
模版
744. Find Smallest Letter Greater Than Target
367. Valid Perfect Square
74. Search a 2D Matrix
240. Search a 2D Matrix II
33. Search in Rotated Sorted Array
69. Sqrt(x)
29. Divide Two Integers
441. Arranging Coins
153. Find Minimum in Rotated Sorted Array
二分法描述了在有序集合中搜索特定值的过程,其时间复杂度是O(logn)。
1
def binarySearch(nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: int
"""
if len(nums) == 0:
return -1
left, right = 0, len(nums) - 1
while left <= right:
mid = (left + right) // 2
if nums[mid] == target:
return mid
elif nums[mid] < target:
left = mid + 1
else:
right = mid - 1
# End Condition: left > right
return -1
2
def binarySearch(nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: int
"""
if len(nums) == 0:
return -1
left, right = 0, len(nums)
while left < right:
mid = (left + right) // 2
if nums[mid] == target:
return mid
elif nums[mid] < target:
left = mid + 1
else:
right = mid
# Post-processing:
# End Condition: left == right
if left != len(nums) and nums[left] == target:
return left
return -1
Given a list of sorted characters
letters
containing only lowercase letters, and given a target lettertarget
, find the smallest element in the list that is larger than the given target.Letters also wrap around. For example, if the target is
target = 'z'
andletters = ['a', 'b']
, the answer is'a'
.Examples:
Input: letters = ["c", "f", "j"] target = "a" Output: "c" Input: letters = ["c", "f", "j"] target = "c" Output: "f" Input: letters = ["c", "f", "j"] target = "d" Output: "f" Input: letters = ["c", "f", "j"] target = "g" Output: "j" Input: letters = ["c", "f", "j"] target = "j" Output: "c" Input: letters = ["c", "f", "j"] target = "k" Output: "c"
class Solution:
def nextGreatestLetter(self, letters, target):
"""
:type letters: List[str]
:type target: str
:rtype: str
"""
#find the insert position
lo, hi = 0,len(letters)-1
while(lo<=hi):
mid = int((lo+hi)/2)
if letters[mid] > target:hi=mid-1
else:lo = mid+1
return letters[lo%len(letters)]
Given a positive integer num, write a function which returns True if num is a perfect square else False.
Note: Do not use any built-in library function such as
sqrt
.Example 1:
Input: 16 Output: true
Example 2:
Input: 14 Output: false
class Solution:
def isPerfectSquare(self, num):
"""
:type num: int
:rtype: bool
"""
lo = 0;hi = num
while(lo <= hi):
mid = int((lo+hi)/2)
if mid**2 == num:return True
elif mid**2 > num:hi = mid -1
else:lo = mid+1
return False
Write an efficient algorithm that searches for a value in an m x n matrix. This matrix has the following properties:
- Integers in each row are sorted from left to right.
- The first integer of each row is greater than the last integer of the previous row.
Example 1:
Input: matrix = [ [1, 3, 5, 7], [10, 11, 16, 20], [23, 30, 34, 50] ] target = 3 Output: true
Example 2:
Input: matrix = [ [1, 3, 5, 7], [10, 11, 16, 20], [23, 30, 34, 50] ] target = 13 Output: false
双重binary search
class Solution(object):
def searchMatrix(self, matrix, target):
"""
:type matrix: List[List[int]]
:type target: int
:rtype: bool
"""
if not matrix or not matrix[0]:return False
row_lo = 0;row_hi = len(matrix)-1
col_lo = 0;col_hi = len(matrix[0])-1
while(row_lo<=row_hi):
mid = (row_lo + row_hi) // 2
if matrix[mid][0] == target:return True
elif matrix[mid][0] > target:row_hi = mid-1
else:row_lo = mid+1
#lower or larger
if row_lo-1 < 0:return False
while(col_lo <= col_hi):
mid = (col_lo + col_hi) // 2
if matrix[row_lo-1][mid] == target:return True
elif matrix[row_lo-1][mid]>target:col_hi = mid-1
else:col_lo = mid+1
return False
Write an efficient algorithm that searches for a value in an m x n matrix. This matrix has the following properties:
- Integers in each row are sorted in ascending from left to right.
- Integers in each column are sorted in ascending from top to bottom.
Example:
Consider the following matrix:
[ [1, 4, 7, 11, 15], [2, 5, 8, 12, 19], [3, 6, 9, 16, 22], [10, 13, 14, 17, 24], [18, 21, 23, 26, 30] ]
Given target =
5
, returntrue
.Given target =
20
, returnfalse
.
遍历每行再binary search,slow
class Solution(object):
def searchMatrix(self, matrix, target):
"""
:type matrix: List[List[int]]
:type target: int
:rtype: bool
"""
if not matrix or not matrix[0]:return False
for row in range(len(matrix)):
col_lo = 0;col_hi = len(matrix[0])-1
while(col_lo <= col_hi):
mid = (col_lo + col_hi) // 2
if matrix[row][mid] == target:return True
elif matrix[row][mid]>target:col_hi -= 1
else:col_lo += 1
return False
Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand.
(i.e.,
[0,1,2,4,5,6,7]
might become[4,5,6,7,0,1,2]
).You are given a target value to search. If found in the array return its index, otherwise return
-1
.You may assume no duplicate exists in the array.
Your algorithm's runtime complexity must be in the order of O(log n).
Example 1:
Input: nums = [4,5,6,7,0,1,2]
, target = 0 Output: 4Example 2:
Input: nums = [4,5,6,7,0,1,2]
, target = 3 Output: -1
class Solution:
def search(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: int
"""
if target not in nums:return -1
minpos = nums.index(min(nums))
part1 = nums[:minpos]
part2 = nums[minpos:]
if target in part1:
lo = 0;hi = minpos-1
while(lo<=hi):
mid = (lo+hi) // 2
if nums[mid] == target:return mid
elif nums[mid] > target:hi = mid-1
else:lo = mid+1
else:
lo = 0;hi=len(part2)-1
while(lo <= hi):
mid = (lo+hi) // 2
if part2[mid] == target:return mid+minpos
elif part2[mid] > target:hi = mid-1
else:lo = mid+1
Implement
int sqrt(int x)
.Compute and return the square root of x, where x is guaranteed to be a non-negative integer.
Since the return type is an integer, the decimal digits are truncated and only the integer part of the result is returned.
Example 1:
Input: 4 Output: 2
Example 2:
Input: 8 Output: 2 Explanation: The square root of 8 is 2.82842..., and since the decimal part is truncated, 2 is returned.
class Solution:
def mySqrt(self, x):
"""
:type x: int
:rtype: int
"""
if x==1 or x == 0:return x
lo = 1;hi = x
while(lo<=hi):
mid = (lo+hi) // 2
if mid**2 <= x and (mid+1)**2 > x:return mid
elif mid**2 > x:hi = mid -1
else:lo = mid+1
Given two integers
dividend
anddivisor
, divide two integers without using multiplication, division and mod operator.Return the quotient after dividing
dividend
bydivisor
.The integer division should truncate toward zero.
Example 1:
Input: dividend = 10, divisor = 3 Output: 3
Example 2:
Input: dividend = 7, divisor = -3 Output: -2
Note:
- Both dividend and divisor will be 32-bit signed integers.
- The divisor will never be 0.
- Assume we are dealing with an environment which could only store integers within the 32-bit signed integer range: [−231, 231 − 1]. For the purpose of this problem, assume that your function returns 231 − 1 when the division result overflows.
class Solution:
def divide(self, dividend, divisor):
"""
:type dividend: int
:type divisor: int
:rtype: int
"""
if dividend == 0:return 0
tag = -1 if dividend*divisor < 0 else 1
dividend, divisor = abs(dividend),abs(divisor)
MAX = (1<<31)-1
MIN = -1*(1<<31)
lo = 1;hi = dividend
while(lo <= hi):
mid = (lo+hi) // 2
if mid*divisor <=dividend and (mid+1) * divisor>dividend:
if (tag == -1 and mid*tag>=MIN) or (tag==1 and mid*tag<=MAX):return mid*tag
else: return MAX
elif mid*divisor > dividend:hi = mid-1
else:lo = mid+1
return 0
You have a total of n coins that you want to form in a staircase shape, where every k-th row must have exactly k coins.
Given n, find the total number of full staircase rows that can be formed.
n is a non-negative integer and fits within the range of a 32-bit signed integer.
Example 1:
n = 5 The coins can form the following rows: ¤ ¤ ¤ ¤ ¤ Because the 3rd row is incomplete, we return 2.
Example 2:
n = 8 The coins can form the following rows: ¤ ¤ ¤ ¤ ¤ ¤ ¤ ¤ Because the 4th row is incomplete, we return 3.
class Solution(object):
def arrangeCoins(self, n):
"""
:type n: int
:rtype: int
"""
if n == 0 or n == 1:return n
lo = 1;hi = n
while(lo <= hi):
mid = (lo + hi) // 2
totalcoins = mid*(mid+1)/2
leave = n - totalcoins
if totalcoins <= n and leave < (mid+1):return mid
elif totalcoins > n:hi = mid -1
else:lo = mid + 1
Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand.
(i.e.,
[0,1,2,4,5,6,7]
might become[4,5,6,7,0,1,2]
).Find the minimum element.
You may assume no duplicate exists in the array.
Example 1:
Input: [3,4,5,1,2] Output: 1Example 2:
Input: [4,5,6,7,0,1,2] Output: 0
# The isBadVersion API is already defined for you.
# @param version, an integer
# @return a bool
# def isBadVersion(version):
class Solution:
def firstBadVersion(self, n):
"""
:type n: int
:rtype: int
"""
if n==0:return 0
lo = 1;hi = n
while(lo <= hi):
mid = (lo + hi) // 2
if isBadVersion(mid) == True:hi = mid -1
else:lo = mid + 1
return hi+1