81. Search in Rotated Sorted Array II

一、题目

  1、审题

  

  2、分析

    给出一个整数数组,数组本来为有序的且可能存在重复整数。

    现在将数组后面未知个连续的元素移动到数组前面,形成新的数组。此时,判断 target 是否存在于该新数组中。

 

二、解答

  1、思路:

    方法一、

      ①、由于数组分成了两部分有序的数字组合,先利用二分查找找到中间数字集合的下标;

      ②、在数组的前部分有序元素和后部分有序元素中分别进行二分查找 target,若找到,返回 true, 否则返回 false。

public boolean search(int[] nums, int target) {
        int low = 0;
        int high = nums.length - 1;
        if(high < 0)
            return false;
        
        while(low < high) {
            int mid = (low + high) / 2;
            
            if(nums[low] > nums[mid])
                high = mid;
            else if(nums[low] < nums[mid])
                low = mid;
            else {    // nums[low] == nums[mid]
                if(nums[low] < nums[high]){
                    low = high;
                    break;
                }
                else if(nums[low] == nums[high] )
                    low++;
                else  {// nums[low] > nums[high]
                    if(low == mid)    
                        break;
                    low = mid;
                }
            }
        }
        
        int mid = low;
        int index;
        if(target > nums[0]) {
            index = binarySearch(nums, 0, mid, target);
        }
        else if(target < nums[0]) {
            index = binarySearch(nums, mid+1, nums.length-1, target);
        }
        else {
            return true;
        }
        
        return index != -1;
    }

    private int binarySearch(int[] nums, int start, int end, int target) {
        
        while(start <= end) {
            int mid = (start + end) / 2;
            
            if(nums[mid] < target)
                start = mid+1;
            else if(nums[mid] > target)
                end = mid - 1;
            else
                return mid;
        }
        
        return -1;
    }

    

    方法二、

      将数组当成一个整体直接进行二分查找,只是修改查找条件。

public boolean search(int[] nums, int target) {
        int start = 0;
        int end = nums.length - 1;
        int mid = -1;
        
        while(start <= end) {
            mid = (start + end) / 2;
            if(nums[mid] == target)
                return true;
             //If we know for sure right side is sorted or left side is unsorted
            if(nums[mid] < nums[end] || nums[mid] < nums[start]) {
                if(target > nums[mid] && target <= nums[end])
                    start = mid + 1;
                else
                    end = mid - 1;
            }
             //If we know for sure left side is sorted or right side is unsorted
            else if(nums[mid] > nums[start] || nums[mid] > nums[end]) {
                if(target < nums[mid] && target >= nums[start]) {
                    end = mid - 1;
                }
                else {
                    start = mid + 1;
                }
            }
            //If we get here, that means nums[start] == nums[mid] == nums[end], then shifting out
            //any of the two sides won't change the result but can help remove duplicate from
            //consideration, here we just use end-- but left++ works too
            else {
                end--;
            }
            
        }
        return false;
    }

 

posted @ 2018-09-23 22:46  skillking2  阅读(109)  评论(0编辑  收藏  举报