Binary Search

遇到sorted array 就要想到binary search

模板注意:

1.while (start + 1 < end)  重合或者相邻

2.mid = start + (end - start) / 2   防止溢出

3.A[mid] ==, <, >

4.while 循环结束后分别讨论 A[start/end] == target

 

题目:

1.Search Insert Position

注意1.return!!2.忘记排除A[0]>target的情况

    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 Range

自顶向下思考,想找范围就分别找出左边界和右边界,分别用二分法。

 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

注意:1、忘了分奇偶。  2、当偶数时,应该写除以2.0!自己写的除以2,结果是错误的。(?这里不明白为什么必须写2.0)  3、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

posted on 2015-02-12 05:04  kikiUr  阅读(115)  评论(0编辑  收藏  举报