Binary Search In Array
Great variants: https://www.geeksforgeeks.org/variants-of-binary-search/
r = len(nums)
orr = len(nums) - 1
:r = len(nums)
左闭右开,在最后的循环中r是不被包括在循环以内的。因此用while l < r
做循环条件,以l = r
结束。 r的移动规则为r = m
, 因为下一次应该查找右边界为m的前一个元素。[l, m - 1]
, 因为r指向最后一个元素的后一个元素, 当r = m, 下次查找范围就为[l, r) => [l, m - 1]
.r = len(nums) - 1
: 左闭右闭区间。循环条件为while l <= r
, 当l < r
时,会忽略最后一个r
元素。r
的移动规则为r = m - 1
,
Variant 1: Contains (True or False)
1 | arr = [2, 3, 3, 5, 5, 5, 6, 6] |
Variant 2 First occurrence index of target
1 | def firstOccur(arr, target): |
Variant 3 Last occurrence index of target
1 | def lastOccur(arr, target): |
Variant 4 Find first occurance of the smallest element greater than target
1 | def smallestGreater(arr, target): |
Variant 5 Find the last occurance of the greatest element that’s smaller than target
1 | def greatestSmaller(arr, target): |
1 | def binary_search(array) -> int: |
- Correctly initialize the boundary variables left and right. Only one rule: set up the boundary to include all possible elements;
- Decide return value. Is it return left or return left - 1? Remember this: after exiting the while loop, left is the minimal k satisfying the condition function;
- Design the condition function.
410. Split Array Largest Sum
Leetcode: https://leetcode.com/problems/split-array-largest-sum/
Given a candidate C(minimal largest sum), compute the number groups k needed.
(Greedy partition): https://www.youtube.com/watch?v=_k-Jb4b7b_0 after 12:00
1 | def splitArray(self, nums: List[int], m: int) -> int: |
683. K Empty Slots
Leetcode: https://leetcode.com/problems/k-empty-slots/description/
Video: https://www.youtube.com/watch?v=K8Nk0AiIX4s
74. Search a 2D Matrix
Binary search directly in 2D array, and use pivot to find the correct position in matrix.
1 | def searchMatrix(self, matrix: List[List[int]], target: int) -> bool: |
240. Search a 2D Matrix II
Leetcode: https://leetcode.com/problems/search-a-2d-matrix-ii/
1 | def searchMatrix(self, matrix: List[List[int]], target: int) -> bool: |
378. Kth Smallest Element in a Sorted Matrix
Leetcode: https://leetcode.com/problems/kth-smallest-element-in-a-sorted-matrix/
We want to count the number of elements in the left half of the number range of which we know the middle element and the two extremes as well.
An alternate could be to apply the Binary Search on the “number range” instead of the “index range”. As we know that the smallest number of our matrix is at the top left corner and the biggest number is at the bottom lower corner. These two number can represent the “range” i.e., the start and the end for the Binary Search. Here is how our algorithm will work:
- Start the Binary Search with start = matrix[0][0] and end = matrix[n-1][n-1].
- Find middle of the start and the end. This middle number is NOT necessarily an element in the matrix.
- Count all the numbers smaller than or equal to middle in the matrix. As the matrix is sorted, we can do this in O(N).
- While counting, we can keep track of the “smallest number greater than the middle” (let’s call it n1) and at the same time the “biggest number less than or equal to the middle” (let’s call it n2). These two numbers will be used to adjust the “number range” for the Binary Search in the next iteration.
- If the count is equal to ‘K’, n1 will be our required number as it is the “biggest number less than or equal to the middle”, and is definitely present in the matrix.
- If the count is less than ‘K’, we can update start = n2 to search in the higher part of the matrix and if the count is greater than ‘K’, we can update end = n1 to search in the lower part of the matrix in the next iteration.
1 | def find_Kth_smallest(matrix, k): |
34. Find First and Last Position of Element in Sorted Array
Leetcode: https://leetcode.com/problems/find-first-and-last-position-of-element-in-sorted-array/
Note:
Binary search should start with 0
and len(nums)
, not len(nums) - 1
1 | def searchRange(self, nums: List[int], target: int) -> List[int]: |
33. Search in Rotated Sorted Array
Leetcode: https://leetcode.com/problems/search-in-rotated-sorted-array/
[Solution]
- Formula: If a sorted array is shifted, if you take the middle, always one side will be sorted. Take the recursion according to that rule.
- 分情况讨论
1 | def search(self, nums: List[int], target: int) -> int: |
Peak Problem
162. Find Peak Element
Leetcode: https://leetcode.com/problems/find-peak-element/
1 | def findPeakElement(self, nums): |
852. Peak Index in a Mountain Array
Leetcode: https://leetcode.com/problems/peak-index-in-a-mountain-array/
Same as above
1 | def peakIndexInMountainArray(self, A): |
153. Find Minimum in Rotated Sorted Array
Leetcode: https://leetcode.com/problems/find-minimum-in-rotated-sorted-array/
Same as above
1 | def findMin(self, nums): |
410. Split Array Largest Sum
Leetcode: https://leetcode.com/problems/split-array-largest-sum/
Note:
- The answer has to be between the range
[max(nums), sum(nums) + 1)
. - 最少需要多少组
k
, 使得maximum sum不超过mid
- Go find
k
Narrow down scope problem
81. Search in Rotated Sorted Array II
Leetcode: https://leetcode.com/problems/search-in-rotated-sorted-array-ii/
Note:
The key is to narrow down the searching range.
1 | def search(self, nums, target): |
875. Koko Eating Bananas
Leetcode: https://leetcode.com/problems/koko-eating-bananas/
1 | def minEatingSpeed(self, piles: List[int], h: int) -> int: |