Leetcode33题的理解---动笔就变得简单

本文探讨了一种特殊的有序数组搜索问题,即数组经过旋转后的目标值查找。通过分析旋转点位置,利用二分查找思想高效实现搜索,并提供了两种实现方法:递归和迭代。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目:

 

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.

题目分析:(关键判断出旋转点,在左边还是右边)

 

 

L(坐标)

M

h

 

 

 

该开始的时候是这样的,我们也不知道旋转点在哪里

接下来我们利用二分的思想,if(nums[m]<nums[l])则一定可以说旋转点(未知点x)一定在L-M)之间,那么情况如下:

L

x

 

M

h

>nums[m]

 

<nums[m]

 

>nums[m]&&<nums[l]

我们无非考虑的是l,h如何移动的问题

右边情况简单我们可以这样判断:

If(nums[m]<target&&nums[h]>target){

L=m+1;

}else{
h=m-1;

}

因为我们根据这两个只判断的所以首先判断这两个值是否满足条件,这种情况考虑完了,接下来考虑if(nums[m]>nums[l])这种情况,说明旋转点一定在m点的右侧,情况如下:

L

M

 

x

H

<nums[m]

 

>nums[m]

 

<nums[m]&&<nums[l]

这种情况下m点的右侧比较简单因此:

If(nums[m]>target&&nums[l]<target){

H=m-1;

}else{

L=m+1;

}

在此之前还是需要对m 点和l点的值是否等于target值进行判断,综上所述情况分析完毕

 

当我看到这个题的时候,我的第一反应是用递归,写出来用的时间不长,但显然还应该有更好的办法,我当时就是没有画图,只是在自己脑中分析情况,就像捡了芝麻丢了西瓜,总是掉掉一些情况,浪费了很长的时间,因此还是动动笔头比较好,几分钟就搞定,第二种方法就是分析的结果,具体而言,我也不知道哪个方法好,但是我记录的目的,是想自己以后不要懒着动笔,只是一时的清楚是不好的.更加的浪费时间.

 

递归的方法:

 

class Solution {
    public int find(int[] nums,int target,int l,int h){
		int ret=-1;
		int m=l+(h-l)/2;
		if(nums[m]==target){
			return m;
		}
		if(l==h){
			return ret;
		}
		if(nums[l]>nums[h]){
			int t1=find(nums,target,l,m);
			int t2=find(nums,target,m+1,h);
			if(t1>t2){
				return t1;
			}else{
				return t2;
			}
		}else{
			if(nums[l]>target){
				return -1;
			}
			if(nums[h]<target){
				return -1;
			}
			while(h>=l){
				m=l+(h-l)/2;
				if(nums[m]>target){
					h=m-1;
				}else{
					if(nums[m]==target){
						return m;
					}
					l=m+1;
				}
			}
		}
		return ret;
	}
    public int search(int[] nums, int target) {
        
        int ret=-1;
        if(nums.length==0){
			return ret;
		}
		ret=this.find(nums, target, 0, nums.length-1);
		return ret;
    }
}

另一种

 

 

int ret=-1;
		if(nums.length==0){
			return ret;
		}
		int l=0;
		int h=nums.length-1;
		int m;
		while(h>=l){
			m=l+(h-l)/2;
			if(nums[m]>nums[l]){
				if(nums[m]==target){
					return m;
				}
				if(nums[l]==target){
					return l;
				}
				if(nums[l]<target&&nums[m]>target){
					h=m-1;
				}else{
					l=m+1;
				}
							
			}else{
				if(nums[m]==target){
					return m;
				}
				if(nums[h]==target){
					return h;
				}
				if(nums[h]>target&&nums[m]<target){
					l=m+1;
				}else{
					h=m-1;
				}
				
				
			}
		}

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值