遇到sorted array 就要想到binary searchjava
模板注意:数组
1.while (start + 1 < end) 重合或者相邻spa
2.mid = start + (end - start) / 2 防止溢出指针
3.A[mid] ==, <, >code
4.while 循环结束后分别讨论 A[start/end] == targetblog
题目:递归
1.Search Insert Positionrem
注意1.return!!2.忘记排除A[0]>target的状况get
public int searchInsert(int[] A, int target) { int start = 0; int end = A.length - 1; if (A[0] > target) {//这里没有考虑这种状况! return 0; } while (start + 1 < end) { int mid = start + (end - start)/2; if (A[mid] == target) { return mid; } else if (A[mid] < target) { start = mid; } else { end = mid; } } if (A[end] == target) { return end; } if (A[end] < target) { return end + 1; } if (A[start] == target) { return start; } return start + 1;//这里!忘了写return }
2.Search for a Rangeit
自顶向下思考,想找范围就分别找出左边界和右边界,分别用二分法。
public int[] searchRange(int[] A, int target) { int start = 0; int end = A.length - 1; int mid; int[] bound = new int[2]; //left bound while (start + 1 < end) { mid = start + (end - start) / 2; if (A[mid] == target) { end = mid; } else if (A[mid] < target) { start = mid; } else { end = mid; } } if (A[start] == target) { bound[0] = start; } else if (A[end] == target) { bound[0] = end; } else { bound[0] = bound[1] = -1; return bound; } //right bound start = 0; end = A.length - 1;
while (start + 1 < end) { mid = start + (end - start) / 2; if (A[mid] == target) { start = mid; } else if (A[mid] < target) { start = mid; } else { end = mid; } } if (A[end] == target) { bound[1] = end; } else if (A[start] == target) { bound[1] = start; } else { bound[0] = bound[1] = -1; return bound; } return bound; }
3.Search in Rotated Sorted Array I & II
I:
public int search(int[] A, int target) { int start = 0; int end = A.length - 1; int mid; while (start + 1 < end) { mid = start + (end - start)/2; if (A[mid] == target) { return mid; } if (A[start] < A[mid]) { if (A[start] <= target && target <= A[mid]) { end = mid; } else { start = mid; } } else { if (A[mid] <= target && target <= A[end]) { start = mid; } else { end = mid; } } } if (A[start] == target) { return start; } if (A[end] == target) { return end; } return -1; }
II:讲出最坏状况,例如全是2只有一个1.
public boolean search(int[] A, int target) { for (int i = 0;i <= A.length - 1; i++) { if (A[i] == target) { return true; } } return false; }
4.Search in a 2D Matrix
public boolean searchMatrix(int[][] matrix, int target) { int start, end, mid; int row = matrix.length; int col = matrix[0].length; //check rows start = 0; end = row - 1; while (start + 1 < end) { mid = start + (end - start) / 2; if (matrix[mid][0] == target) { return true; } else if (matrix[mid][0] < target) { start = mid; } else { end = mid; } } if (matrix[end][0] <= target) { row = end; } else if (matrix[start][0] <= target) { row = start; } else { return false; } start = 0; end = col - 1; //check columns while (start + 1 < end) { mid = start + (end - start) / 2; if (matrix[row][mid] == target) { return true; } else if (matrix[row][mid] < target) { start = mid; } else { end = mid; } } if (matrix[row][start] == target) { return true; } if (matrix[row][end] == target) { return true; } return false; }
5.Search in a 2D Matrix II
做业:
Find the First Bad Version
Find a Peek
Sorted Array
题目:
6.Remove Duplicates from Sorted Array I
用两个指针i和count,i从前日后扫,count记录有效数组长度。注意1.循环内比较若两个不相同,要将A[i]赋值给有效长度的A[count](本身写的时候没有写这一句,认为返回查高难度正确,可是A数组将不会改变(?待肯定))。2.循环写成了i = 0开始到 i<= A.length,A[i] != A[i + 1], 这样会报错: java.lang.ArrayIndexOutOfBoundsException:1
public int removeDuplicates(int[] A) { if (A == null || A.length == 0) { return 0; } int count = 1; for (int i = 1; i< A.length; i++) {//注意循环从i=1开始,而且比较A[i]和A[i - 1] if (A[i] != A[i - 1]) { A[count] = A[i]; //注意将A[i]赋值给A[count] count++; } } return count; }
7.Remove Duplicates from Sorted Array II
题目加上条件说能够最多容许重复元素出现两次,那么多加一个count记录重复元素出现次数,先赋值为1,从前日后扫,若相邻相同,则count++,在判断若count >2 则continue,若不相同,则将count从新赋值为1.
public int removeDuplicates(int[] A) { if (A == null || A.length == 0) { return 0; } int count = 1; int index = 1; for (int i = 1; i < A.length; i++) { if (A[i] == A[i - 1]) { count++; if (count > 2) { continue; } } else { count = 1; } A[index] = A[i]; index++; } return index; }
8.Merge Sorted Array
I:将A、B merge到C,从前日后比较大小,小的入C。
II:A有足够空间,将Bmerge到A。A有足够空间,全部大的数有空间,应该从大的数merge,也就是从后往前merge。
public void merge(int A[], int m, int B[], int n) { if (A == null || B == null) return; int len = m + n - 1; while (m > 0 && n > 0) { if (A[m - 1] > B[n - 1]) { A[len] = A[m - 1]; len--; m--; } else { A[len] = B[n - 1]; len--; n--; } } while (n > 0) { A[len] = B[n - 1]; len--; n--; } }
9.Median of Two Sorted Arrays
注意:一、忘了分奇偶。 二、当偶数时,应该写除以2.0!本身写的除以2,结果是错误的。(?这里不明白为何必须写2.0) 三、findKth中特殊状况没有考虑,k==1(?是否是不写这个递归就不成立?就是递归必须有最底层递归是能有结果的?) 递归一进来先考虑极端状况,不考虑极端状况容易递归死循环,stackOverFlow
public double findMedianSortedArrays(int A[], int B[]) { int len = A.length + B.length; if (len % 2 == 0) { return (findKth(A, 0, B, 0, len/2) + findKth(A, 0, B, 0, len/2 + 1))/2.0; } else { return findKth(A, 0, B, 0, len/2 + 1); } } public int findKth(int A[], int A_start, int B[], int B_start, int k) { if (A_start >= A.length) { return B[B_start + k - 1]; } if (B_start >= B.length) { return A[A_start + k - 1]; } if (k == 1) { return Math.min(A[A_start], B[B_start]); } int A_key = (A_start + k/2 - 1) < A.length ? A[A_start + k/2 - 1] : Integer.MAX_VALUE; int B_key = (B_start + k/2 - 1) < B.length ? B[B_start + k/2 - 1] : Integer.MAX_VALUE; if (A_key < B_key) { return findKth(A, A_start + k/2, B, B_start, k - k/2); } else { return findKth(A, A_start, B, B_start + k/2, k - k/2); } }
10.Recover Rotated Sorted Array
三部翻转法。必须掌握。
public class Solution { /** * @param nums: The rotated sorted array * @return: The recovered sorted array */ private void reverse(ArrayList<Integer> nums, int start, int end) { for (int i = start, j = end; i < j; i++, j--) { int temp = nums.get(i); nums.set(i, nums.get(j)); nums.set(j, temp); } } public void recoverRotatedSortedArray(ArrayList<Integer> nums) { for (int index = 0; index < nums.size() - 1; index++) { if (nums.get(index) > nums.get(index + 1)) { reverse(nums, 0, index); reverse(nums, index + 1, nums.size() - 1); reverse(nums, 0, nums.size() - 1); return; } } } }
Conclusion:
Binary Search:exclude half part every time
Sorted Arrays:if sorted,try binary search
if not sorted, try sort it first