- Finding the first and last appearance:
- Setting the i <= j:
- Exclude left sliding through (find the first appearance): left = mid - 1 (include "=", return right in the end)
- Exclude right sliding through (find the last appearance): right = mid + 1 (include "=", return left in the end)
- if search value: i<=j should care that the terminal index is not the answer if the target falls out of range of the search space
- Find peak element:
- Finding two mid points: mid, mid + 1, compare:
- if num[mid1] < nums[mid2[: low = mid2
- else high = mid1
- Trail and test (adopting 1)
- for certain criteria: if >=: l slide through mid to mid +1, return r (or <= r slide thorugh to mid -1, return l)
- Search value in a rotated sorted array (distinct):
- if nums[mid] hits the value. return the mid index
- Find the continuous increasing part (whether nums[i] < nums[mid], or >, slide thru to mid+1 if ==.
- Comparing whether targets fall into the continuous part:
- nums[i] < nums[mid]: if nums[i] <= target < nums[mid]: assign j = mid - 1; else assign i = mid + 1 (go to the discontinuous part)
- nums[i] > nums[mid] (right part continuous): if nums[mid] < target <= nums[j]: assign i = mid + 1; else assign j = mid - 1
- nums[i] == nums[mid] : just sliding through to i = mid + 1 since nums[mid] != target
- return -1 (if search failed)
- Search value in a rotated sorted array (duplicates)
- only difference: handling cases of == among nums[i]. nums[j], nums[mid]: if nums[i] == nums[mid] == nums[j]: move both i and j. (i++/j--); else if only nums[i] == nums[mid]: i sliding through to mid + 1: i = mid + 1. In this case, leaving no space for nums[i] == nums[mid]
- Only leave cases where: nums[i] < nums[mid] (test nums[i] <= target < nums[mid]); or nums[i] > nums[mid] (test nums[mid] < target <= nums[j])
Find minimum in a rotated sorted array:
Assumption: exists, no duplicates
- selecting right as the comparison nums[mid[ vs nums[right] because natually the number increases from left to the right -> if nums[mid] > nums[right] -> there MUST BE a pivot on (mid, right] so we can throw our left and directly go left = mid + 1. We cannot draw similar conclusion on the left since if nums[mid] > nums[left] : we cannot infer there is a pivot in [left, mid).
Assumption: exists, DUPLICATES:
- similar to case before: except handling the duplicates: if (nums[mid] == nums[right]) right-= 1;
Find first and last position
M1: search a float point approach: search (target - 0.5) and (target+ 0.5) instead: found the first upper bound for query value
Standard solution:
Search for the first appearance:
Condition: i < j -> (so check [i]([j])) in the end
mid = (i + j) /2; i = mid + 1; j = mid;
Search for the last appearance
Condition i < j without check since already checked
mid = (i + j + 1) /2 since we need to preserve the mid from the left if nums[mid] == target -> i = mid -> we need to bias the mid to the right to prevent being stuck.
Search in a 2D partial ordering:
Use Trail and Error to find the upper bound (number that are <= than [mid]) in order to deal with duplicates. for each search:
Start with "middle" point: the point that has the largest value in one dim and least value in another dim. (This helps opt out less optimal solution after the comparison)
With Heap: Maintaining n candidates: initialized by the first column: Each time a value pops out, add in its "children" the value at the same column index but at the next row (if there is)
Search in a window: (Find k closest)
Find the optimal starting point i that [i] < [i + k]