Binary Search

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

相關文章
相關標籤/搜索