Algorithm: Binary Search

Binary Search是对于sorted或者部分sorted,能找到大小关系可以使搜索朝着“正确”方向前进的,省掉了不正确方向的搜索。所以是每次搜索都是logn的复杂度。如果需要遍历n个元素,则是O(nlogn)的复杂度。


4. Median of Two Sorted Arrays

33. Search in Rotated Sorted Array

34. Search for a Range


4. Median of Two Sorted Arrays

There are two sorted arrays nums1 and nums2 of size m and n respectively.
Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)).
Example 1:
nums1 = [1, 3]
nums2 = [2]
The median is 2.0
Example 2:
nums1 = [1, 2]
nums2 = [3, 4]

The median is (2 + 3)/2 = 2.5


1)规定nums1的长度一定要小于nums2. 因为比较条件是nums1[m] > nums[n - 1]. 防止数据越界

2)右边界用长度是为了偶数的时候取右边。同时,长度相加再加1是为了第k个值取右边部分。

3) 注意采用MIN、MAX VALUE处理边界情况。


class Solution {
    public double findMedianSortedArrays(int[] nums1, int[] nums2) {
        if (nums1.length > nums2.length) {
            return findMedianSortedArrays(nums2, nums1);
        }
        // 指的右边部分第一个
        int k = (nums1.length + nums2.length + 1) / 2;
        boolean isEven = ((nums1.length + nums2.length) & 1) == 0 ? true : false;
        
        int s = 0;
        int e = nums1.length;
        int m = -1;
        int n = -1;
        
        while (s < e) {
            m = (s + (e - s) / 2) ;
            n = k - m;
            
            if (nums1[m] < nums2[n - 1]) {
                s = m + 1;
            } else {
                e = m;
            }
        }
        
        m = s;
        n = k - s;
        
        int c1 = Math.max(m <= 0 ? Integer.MIN_VALUE : nums1[m - 1], 
                          n <= 0 ? Integer.MIN_VALUE : nums2[n - 1]) ;       
        int c2 = Math.min(m >= nums1.length ? Integer.MAX_VALUE : nums1[m], 
                          n >= nums2.length ? Integer.MAX_VALUE : nums2[n]);     
        if (isEven) {
            return (c1 + c2) * 0.5;
        }   
        return c1;
    }
}


33. Search in Rotated Sorted Array


class Solution {
    private int bSearch(int[] nums, int s, int e, int target) {
        while (s < e) {
            int mid = s + (e - s) / 2;
            if (target == nums[mid]) {
                return mid;
            }
            
            if (target < nums[mid]) {
                e = mid;
            } else {
                s = mid + 1;
            }
        }
        
        if (nums[s] != target) {
            return -1;
        }
        return s;
    }
    public int search(int[] nums, int target) {
        if (nums == null || nums.length == 0) {
            return -1;
        }
        int s = 0;
        int e = nums.length - 1;
        while (s + 1 < e) {
            int mid = s + (e - s) / 2;
            if (nums[s] < nums[mid]) {
                if (target <= nums[mid] && target >= nums[s]) {
                    return bSearch(nums, s, mid, target);
                } else {
                    s = mid;
                    continue;
                }
            } else {
                if (target <= nums[e] && target >= nums[mid]) {
                    return bSearch(nums, mid, e, target);
                } else {
                    e = mid;
                    continue;
                }
            }
        }
        
        if (nums[s] == target) {
            return s;
        }
        
        if (nums[e] == target) {
            return e;
        }
        
        return -1;
    }
}



81. Search in Rotated Sorted Array II


public class Solution {
    private boolean binaryS(int[] nums, int target, int s, int e) {
        while (s < e) {
            int mid = s + (e - s) / 2;
            if (target == nums[mid]) {
                return true;
            }
            
            if (target < nums[mid]) {
                e = mid;
            } else {
                s = mid + 1;
            }
        }
        
        if (nums[s] == target) {
            return true;
        }
        
        return false;
    }
    
    public boolean search(int[] nums, int target) {
        
        if (nums == null || nums.length == 0) {
            return false;
        }
        
        
        int low = 0;
        int high = nums.length - 1;
        int mid = 0;
        
        while (low + 1 < high) {
            
            mid = low + (high - low) / 2; //prevent overflow
            int midVal = nums[mid];
            
            if (nums[low] == midVal) {
                 ++low;
                 continue;
            }
            
            if (midVal == nums[high]) {
                --high;
                continue;
            }
            
            if (nums[mid] == target) {//directly return if we are lucky
                return true;
            }
            
            if (nums[low] < nums[mid]) {// left part is sorted
                if (target >= nums[low] && target <= nums[mid]) { //only when it is sorted, this can be used as criteria
                    return binaryS(nums, target, low, mid);
                } else { //
                    low = mid;
                }
            } else { // right part is sorted
                if (target >= nums[mid] && target <= nums[high]) {
                    return binaryS(nums, target, mid, high);
                } else {
                    high = mid;
                }
            }
        }
        
        if (target == nums[low]) {
            return true;
        }
        
        if (target == nums[high]) {
            return true;
        }
        
        return false;
    }
}

34. Search for a Range


class Solution {
    public int[] searchRange(int[] nums, int target) {
        int x = -1;
        int y = -1;
        if (nums == null || nums.length == 0) {
            return new int[]{x, y};
        }

        int s = 0;
        int e = nums.length - 1;
        while (s < e) {
            int mid = s + (e - s) / 2;
            if (target > nums[mid]) {
                s = mid + 1;
            } else {
                e = mid;
            }
        }
        
        if (nums[s] != target) {
            return new int[]{x, y};
        }
        x = s;
    
        s = 0;
        e = nums.length - 1;
        while (s < e) {
            int mid = (s + (e - s) / 2) + 1;
            if (target < nums[mid]) {
                e = mid - 1;
            } else {
                s = mid;
            }
        }
        
        y = s;
        return new int[]{x, y};
    }
}
35. Search Insert Position


class Solution {
    public int searchInsert(int[] nums, int target) {
        if (nums == null || nums.length == 0) {
            return 0;
        }
        
        int i = 0;
        int j = nums.length - 1;
        
        while (i < j) {
            int mid = i + (j - i) / 2;
            if (nums[mid] == target) {
                return mid;
            }
            
            if (target < nums[mid]) {
                j = mid;
            } else {
                i = mid + 1;
            }
        }
        
        if (target <= nums[i]) {// 这里的等号是,只有一个数且这个数与target相等是不会进入循环的。
            return i;
        }
        
        return i + 1;
    }
}

50. Pow(x, n)


class Solution {
    private double pow(double x, int n) {
        if (n == 0) {
            return 1;
        }
        
        if (n == 1) {
            return x;
        }
        
        boolean ood = false;
        if ((n & 1) == 1) {
            ood = true;
        }
        
        n = (n >>> 1);
        if (ood) {
            return pow(x * x, n) * x;
        }
        return pow(x * x, n);
    }
    
    public double myPow(double x, int n) {
        if (n < 0) {
            x = 1/x;
            if (n == Integer.MIN_VALUE) {
                n = Integer.MAX_VALUE;
                x = x * x;
            } else {
                n = -n;
            }
        }
        return pow(x, n);
    }
}


69. Sqrt(x)


class Solution {
    public int mySqrt(int x) {
        if (x == 0 || x == 1) {
            return x;
        }
        long start = 1;
        long end = x;
        long mid = 0; 
        while (start + 1 < end) {
            mid = start + (end - start) / 2;
            if (mid * mid < x) {
                start = mid;
            } else if (mid * mid > x){
                end = mid;
            } else {
                return (int)mid;
            }
        }
        if (end * end < x) {
            return (int)end;
        }
        return (int)start;
    }
}


74. Search a 2D Matrix


public class Solution {
    public boolean searchMatrix(int[][] matrix, int target) {
        if (matrix == null || matrix.length == 0 || matrix[0] == null || matrix[0].length == 0) {
            return false;
        }
        
        int row = matrix.length;//3
        int col = matrix[0].length;//4
        
        if (target < matrix[0][0] || target > matrix[row - 1][col - 1]) {
            return false;
        }
        
        int s = 0;
        int e = col * row - 1;
        
        while (s < e) {
            int mid = s + (e - s) / 2;
            int val = matrix[mid / col][mid % col];
            if (target > val) {
                s = mid + 1;
            } else if (target < val) {
                e = mid;
            } else {
                return true;
            }
        }
        
        if (matrix[s / col][s % col] == target) {
            return true;
        }
        
        return false;
    }
}



你可能感兴趣的:(Algorithm)