LeetCode 33. Search in Rotated Sorted Array

一 题目

Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand.

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

You are given a target value to search. If found in the array return its index, otherwise return -1.

You may assume no duplicate exists in the array.

Your algorithm's runtime complexity must be in the order of O(log n).

Example 1:

Input: nums = [4,5,6,7,0,1,2], target = 0
Output: 4

Example 2:

Input: nums = [4,5,6,7,0,1,2], target = 3
Output: -1

Accepted 476,367  Submissions  1,436,616

二 分析

medium级别难度。给定一个 “升序” 的 无重复 数组,从中寻找target值。

这个数组不是真正意义的升序,是被rotated  (旋转)过的升序。

因为要求时间复杂度在O(log n). 所以容易想到二分查找。

这里不能直接使用二分查找。需要寻找规律.对于普通升序数组[0,1,2,3,4,5,6,7],其旋转后可能情况有:

[1,2,3,4,5,6,7,0]

[2,3,4,5,6,7,0,1]

[3,4,5,6,7,0,1,2]

[4,5,6,7,0,1,2,3]

[5,6,7,0,1,2,3,4]

[6,7,0,1,2,3,4,5]

[7,0,1,2,3,4,5,6]

如红色标出所示,如果nums[mid]<nums[right],即中间的数小于最右边的数,那么mid(包括mid)右边的数是有序的,如果中间的数大于最右边的数,那么mid(包括mid)左边的数是有序的。那我们每次都可以折半查找。

这个很重要,也是解题的关键。我也是看了https://www.cnblogs.com/grandyang/p/4325648.html 才明白。

有序的特点已经找到了,我们只需要判断目标值是否在绝对升序的范围内,就可以确定二分的边界了。

注意一点:mid 取值 直接=(left+right)/2 .这样有的边界case两个数值的{1,3} 求1过不了。

代码如下:

public static void main(String[] args) {
		 int[] nums2 = {3,1};
		  int res2 = search(nums2,3);
		  System.out.println(res2);
		
		  int[] nums1 = {1,3};
		  int res1 = search(nums1,1);
		  System.out.println(res1);
		   res1 = search(nums1,3);
		  System.out.println(res1);
		  
		  
   int[] nums = {4,5,6,7,0,1,2};
    int res = search(nums,0);
   System.out.println(res);

    res = search(nums,3);
  System.out.println(res);
   
	}
	
	//二分
	 public static int search(int[] nums, int target) {
	     //coner case
		 if(nums ==null){
	    	 return -1;
	     }
		 int left =0;
		 int right = nums.length-1;
		 
		 while(left<=right){
			 int mid = left+((right - left) >> 1);
			 if(nums[mid] == target){
				 return mid;
			 }
			 //右边有序
			 if(nums[ mid] < nums[right ]){
				 //target落在右侧区间
				 if(nums[mid]<target&&target<= nums[right] ) {
					 left = mid+1;					 
				 }else{
					//target落在左侧区间
					 right = mid -1;
				 }
			 }else{
				 //左边有序
				 // target落在左侧区间
				 if(nums[left] <=target && target< nums[mid]  ){
					 right = mid -1;
				 }else{
					 //target落在右侧区间
					 left = mid +1;
				 }			
			 }			 
		 }
		 
		 return -1;		 
	 }

Runtime: 0 ms, faster than 100.00% of Java online submissions for Search in Rotated Sorted Array.

Memory Usage: 37.1 MB, less than 81.76% of Java online submissions forSearch in Rotated Sorted Array.

 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值