leetcode T33

package com.david.leetcode;

public class T33 {
	class Solution {
	    /**
	    普通的二分查找
	    */
	    private int binarySearch(int[] nums,int start,int end,int target){
	        if(start<=end){
	          int mid = (start+end)/2;
	        if(nums[mid]==target) return mid;
	        else if(nums[mid]<target){
	            return binarySearch(nums,mid+1,end,target);
	        }else{
	            return binarySearch(nums,start,mid-1,target);
	        }
	        }
	        return -1;
	    }
	    /**
	    查找旋转点(也就是最小值的坐标),找旋转点的原因见下面search()处
	    */
	    private int searchRotation(int[] nums,int start,int end){
	        if(nums[start]<nums[end]) return start;
	        int mid = (start+end)/2;
	        if(nums[mid]<nums[mid+1]){
	            //注意这里时跟start索引比而不是跟mid-1比,只有这样才能:说明从start-mid是一个递增序列,所以最小值只可能右半个区间
	            if(nums[mid]>nums[start]){
	                return searchRotation(nums,mid+1,end);
	            }else{
	                //注意这里mid要取得到,因为当前nums[mid]有可能是最小值
	                return searchRotation(nums,start,mid);
	            }
	          //nums[mid]>nums[mid+1],则意味着mid+1即为旋转点  
	        }else{
	            return mid+1;
	        }
	    }
	    /**
	    根据target与最小值以及nums[n-1]处值的大小关系,去对应区间来检索target
	    */
	    public int search(int[] nums, int target) {
	       int n = nums.length;
	       if(n==0) return -1;
	       if(n==1) return (nums[0]==target)?0:-1;
	       int minIdx = searchRotation(nums,0,n-1);
	       if(nums[minIdx]==target) return minIdx;
	       if(minIdx==0) return binarySearch(nums,0,n-1,target);
	       //如果nums[minIdx]<target<nums[n-1]:则从右半个区间去找
	       else if(target<=nums[n-1]) return binarySearch(nums,minIdx+1,n-1,target);
	       else{
	           //如果target>nums[n-1]则从左半个区间去找
	           return binarySearch(nums,0,minIdx-1,target);
	       }
	    }
	}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值