遇到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