二分查找系列

本文总结了一些二分查找的变形,其中大部分来自 leetcode 

1. (leetcode 33) Search in Rotated Sorted Array

   (i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2).

public int search(int[] nums, int key) {
        int lo = 0,hi = nums.length - 1;
        while(lo <= hi){
            int mid = lo + (hi - lo)/2;
            if(nums[mid] == key) return mid;
            if(nums[mid] < nums[hi]){//右半部分有序
                if(nums[mid] < key && key <= nums[hi]){
                    lo = mid + 1; //key 落在有序部分
                }else{ //否则 key 落在无序部分
                    hi = mid -1;
                }
            }else{ //左半部分有序
                if(nums[lo] <= key && key < nums[mid]){
                    hi = mid -1; //key 落在有序部分
                }else{ //否则 key 落在无序部分
                    lo = mid + 1;
                }
            }
        }
        return -1;
    }
View Code

2. (leetcode 81) Search in Rotated Sorted Array II

    (i.e. 1 2 4 4 4 4 4 might become 4 4 4 1 2 4 4 ).

//关于最后 nums[mid] == nums [hi] 的情况
            //1 2 1 1 1
            //l   m   h -> hi--;
            //1 2 1 1 1
            //l m   h  
    public boolean search(int[] nums, int target) {
        if(null == nums || nums.length < 0) return false;
        int lo = 0,hi = nums.length - 1;
        while(lo <= hi){
            int mid = lo + (hi - lo)/2;
            // get it
            if(nums[mid] == target)  return true;
            //找到有序的部分进行查找
            if(nums[mid] < nums[hi]){// 后半部分有序
                if(nums[mid] < target && target <= nums[hi]){
                    lo = mid + 1;   
                }else{
                    hi = mid - 1;  
                } 
            }else if(nums[mid] > nums[hi]){// 前半部分有序
                if(nums[lo] <= target && target < nums[mid]){
                    hi = mid - 1;
                } else{
                    lo = mid + 1;
                }
            }else{ //nums[mid] == nums[hi] 
                hi -- ;
            }
        }
        return false;
    }
View Code

3.  Find Minimum in Rotated Sorted Array

  旋转的数组中,找到最小的数

  若 nums[mid] > nums[hi] min 落在 [mid+1, hi]

  若 nums[mid] < nums[hi] min 落在 [0, mid] 上

 public int findMin(int[] nums) {
        int lo = 0,hi = nums.length - 1;
        while( lo < hi){
            int mid = lo + (hi - lo)/2 ;
            //mid > hi,min in [mid+1,hi]
            if(nums[mid] > nums[hi]){
                lo = mid + 1;
            }
            //mid < hi, min in [0,mid] 
            if(nums[mid] < nums[hi]){
                hi = mid;
            }
        }
        return nums[lo];
    }
View Code

4. Find Minimum in Rotated Sorted Array II

  跟上次的题目一样,只不过带重复的,与题目 1 -> 2 的思路完全一样

  若 nums[mid] > nums[hi] min 落在 [mid+1, hi]

  若 nums[mid] < nums[hi] min 落在 [0, mid] 上

  若 nums[mid] == nums[hi]  则 hi--之后做进一步判断

  public int findMin(int[] nums) {
        int lo = 0, hi = nums.length -1;
        while(lo < hi){
            int mid = lo + (hi - lo)/2;
            if(nums[mid] > nums[hi]){
                lo = mid + 1;
            }else if(nums[mid] < nums[hi]){
                hi = mid;
            }else{
                hi--;
            }
        }
        return nums[lo];
    }
View Code

 5. Find Peak Element (leetcode)

public int Peak(int nums[])
    {
        int lo = 0, hi = nums.length - 1;
        while(lo < hi)
        {
            int m1 = lo + (hi - lo) / 2;
            int m2 = m1 + 1;
            if(nums[m1] < nums[m2]){
                lo = m2;
            }else{
                hi = m1;
            }
        }
        return nums[lo];
    }
View Code

 

posted @ 2016-08-02 10:15  ooon  阅读(561)  评论(0编辑  收藏  举报