Binary Search Tree
BinarySearch 所施加的对象是sorted吗? it depends 但是是连续的
一定是Array吗?也可以是binary search tree
数据类型是什么?
本质:reduce half of current size, 所以时间是log(n)
BinarySearch是连续的黑或连续的白找分界线
Q1 L278 First Bad Version
1 1 1 1 0 0 0 0
public int firstBadVersion(int n){
if(n <= 0) return n;
if(n == 1) return isBadVersion(n)? 1 : 0;
int left = 0, right = n;
while(left + 1 < right){
int mid = left+(right-left)/2;
if(isBadVersion(mid)){
right = mid;
}else{
left = mid;
}
}
return isBadVersion(left)?left:right;
}
Q2 L374 Guess Number
note: -1 is target < mid
public int guessNumber(int n){
if(n == 0) return n;
int left = 1, right = n;
while(left+1 < right){
int mid = left + (right - left)/2;
if(guess(mid) < 0){
right = mid;
}else{
left = mid;
}
}
return guess(left) == 0? left : right;
}
Q3 Classical Binary Search Template
left + right /2: integer overflow. left是integer所取的最大值减去1000, right是最大值减去10 --> 990/2 + left. integer可以装得下
corner case 顺序不能换
TC: log(n),因为每次取mid把n变成1/2 n,
SC: log(n)个mid,o(1)的话因为编译器的garbage collection机制
S1:找target: left <= right -> left = mid + 1, right = mid - 1;
S3:找分界线
public int binarySearch(int[] arr, int target){
//corner case
if(arr == null ||arr.length == 0) return -1;
int left = 0;
int right = arr.length-1;
while(left < right + 1){
int mid = left + (right-left)/2;
if(arr[mid] == target){
return mid;
}
if(arr[mid] < target){
left = mid;
}else{
right = mid;
}
}
if(arr[left] == target) return left;
if(arr[right] == target) return right;
return -1;
}
onsite面经:
ads amazon:
do sth risk; 坚持自己
OOD: video player; playlist design
most challenge project
OOD: design a delivery system with core objects like warehouse, customer address
negative feedback from customer
背包问题,return maximum weight
BQ:miss deadline
Leetcode 39: combination sum --> DFS
BQ轮:backend position, why amazon, sth to reach
Q4 Start & Last position of Target
4.2 first position of Target
find the 分界线, 并不是找到target就return
public int firstPosition(int[] arr, int target){
if(arr == null || arr.length == 0) return -1;
int left = 0, right = arr.length-1;
while(left + 1 < right){
int mid = left + (right - left)/2;
if(arr[mid] < target){
left = mid;
}else{
right = mid;
}
}
if(arr[left] == target) return left;
if(arr[right] == target) return right;
return -1;
}
4.3
check arr[right] first
arr[mid] <= target, left = mid
public int lastPosition(int[] arr, int target){
if(arr == null || arr.length == 0) return -1;
int left = 0, right = arr.length-1;
while(left + 1 < right){
int mid = left + (right - left)/2;
if(arr[mid] <= target){
left = mid;
}else{
right = mid;
}
}
if(arr[right] == target) return right;
if(arr[left] == target) return left;
return -1;
}
4.0 Start & Last
option1:两次binary search
option2:find the first position, then make the right at left position, ++, until the right position != target. [left, right)
which one is better?
option 1: TC = logn + logn = O(logn)
option 2: TC = logn + k
so, if k < logn, option is better; it depends the number of the repetition
public static void main(String[] args) { int[] array = new int[] {1, 2, 3, 3, 3, 3,4,5}; int target = 3; JavaApplication43 app = new JavaApplication43(); int firstIndex = app.findStartAndLast(array, target); int lastIndex = app.findLast(array, firstIndex, target); System.out.println(firstIndex); System.out.println(lastIndex); } public int findStartAndLast(int[] arr, int target) { if (arr == null || arr.length == 0) { return -1; } int left = 0, right = arr.length - 1; while (left + 1 < right) { int mid = left + (right - left) / 2; if (arr[mid] < target) { left = mid; } else { right = mid; } } if (arr[left] == target) { return left; } if (arr[right] == target) { return right; } return -1; } public int findLast(int arr[], int firstIndex,int target){ for(int i = firstIndex; i < arr.length; i++){ if(arr[i] != target){ return i-1; } } return arr.length-1; }
Q5 Closest Position of Target
clarify the one or two answer
demo first
find the dividing line
use S3:
option 1, right - target 和 target - left相比
option 2, use absolute(defensive / preventive drive / program)
public int binarySearch(int[] arr, int target){
//corner case
if(arr == null ||arr.length == 0) return -1;
int left = 0;
int right = arr.length-1;
while(left < right + 1){
int mid = left + (right-left)/2;
if(arr[mid] == target){
return mid;
}
if(arr[mid] < target){
left = mid;
}else{
right = mid;
}
}
return(Math.abs(arr[left] - target) < Math.abs(arr[right] - target)) ? left : right;
}
Q5.1 k Closest position of Target
t = 9, 1 2 3 10 80 90 100
再做一次谁近取谁
k需要和arr.length比较
public List<Integer> binarySearch(int[] arr, int target, int k){
//corner case
if(arr == null ||arr.length == 0) return -1;
if(k > arr.length) return -1;
List<Integer> ans = new ArrayList<>();
if(k == arr.length){
ans = Arrays.asList(arr);
}
int left = 0;
int right = arr.length-1;
while(k-- > 0){
while(left < right + 1){
int mid = left + (right-left)/2;
if(arr[mid] == target){
return mid;
}
if(arr[mid] < target){
left = mid;
}else{
right = mid;
}
}
ans.add(Math.abs(arr[left] - target) < Math.abs(arr[right] - target)) ? left : right)
);
}
return ans;
}
Q6 Largest smaller Position of Target
约等于first position
post-processing 需要注意target是否在最左边
Q7 Smallest larger Position of Target
约等于last position
Q7.1 L35 Search Insert Range
given a target, find a position for the target to insert
Ref L34 Search for a Range
1 2 3 3 3 4 5 6
开闭区间 need to be clarified
(1.9, 3.1) --> 2 3 3 3 --> int[2]{1,4}; 1, 4 are the index
[1.9, 3.1] --> need to equal 1.9 and 3.1
Q8 L162 Find Peak/Valley Element
1 3 5 7 9 8 6 4 2 3 4 5
1 1 1 1 1 0 0 0 1 1 1 1
Peak is the Turning point, Valley is the dividing line
compare arr[mid] with arr[mid-1] OR arr[mid+1]
need to clarify
which number is the peak, what about the maximum num
how many peaks
Q9 L702 UnknownSize Position of Target --> streaming flow
input太大,内存放不下, 放在硬盘里
左边当右边,右边界每次乘二的方式向右扩大,使左右可以包含target
probing --> hash collision
use S1 since we are looking for a target
public int UnknownSize(MyArray myArray, int target){ //TODO: long
if(arr == null || arr.length == 0) return -1;
int left = 0;
int right = 1;
while( myArray.get(right) != null && myArray.get[right] < target){
left = right;
right *= 2;
}
while(left <= right){
int mid = left + (right - left)/2;
if(myArray.get(mid) != null && arr[arr[mid] == target) return mid;
else if(myArray.get(mid) != null && arr[mid] < target) left = mid + 1;
else right = mid - 1;
}
return -1;
}
9.2 Drop egg
只有一个鸡蛋 --> 一层一层地试
鸡蛋不限,尽量少
9.3 Bond
Q10 Matrix Position of Target
10.1 L74
[ [1, 3, 5, 7], [10, 11, 16, 20], 6 [1][2] [23, 30, 34, 50] ]
可以展开成为一个array
S1: primitive 2 times binary search( logm + logn)
S2: int[][] matrix vs List<List<Integer>>
rows = matrix.length;
cols = matrix[0].length;
matrix[0][0] = 0;
matrix[rows-1][cols-1] --> rows * cols -1
array[mid] --> matrix[mid / cols][mid % cols]
public int[] matrixSearch(int[][] matrix, int target){
//corner case
if(matrix == null || matrix[0].length == 0 || matrix[0] == null|| matirx[0].length == 0)
return new int[]{-1, -1};
int rows = matrix.length;
int cols = matrix[0].length;
int start = 0, end = row * col -1;
while(start <= end){
int mid = start + (end - start) / 2;
int i = mid / cols;
int j = mid % cols;
if(matrix[i][j] == target){
return new int[]{i, j};
}else if(matrix[i][j] > target){
end = mid - 1;
}else{
start = mid + 1;
}
}
return new int[]{-1, -1};
}
TC: log(m*n) = logm + logn
面经:
tight time
design cache, TC: O(1)
clarify what is cache
implement a hashmap
most challenge project
find method
10.2 L240 Search a 2D Matrix || Quadrate Search
不可以展开变成一个array
Q14 天平秤重 (三分法):
把一堆球分成ABC三份,A和B一样重,那么target 在C里
或者哪边重,target在哪边
Q15 10堆球
(idealsum - sum)/ 0.1
Last updated
Was this helpful?