二分查找——Search in Rotated Sorted Array

本文介绍了一种在旋转数组中查找特定元素的算法实现。旋转数组原本是按非递减顺序排列,可能存在重复元素。该算法通过自定义的搜索方法实现,能够有效地定位目标值并返回布尔结果。

题目:

在旋转数组中寻找数组,旋转数组在旋转前为不降序排序数组,可能有重复数字。若没找到,返回-1。


public boolean search(int[] data,int target)
	{
		if(data == null||data.length == 0)
			return false;
		int left=0;
		int right=data.length-1;
		while(left < right-1)
		{
			int mid=left+(right-left)/2;
			if(data[mid] == target)
				return true;
			if(data[mid] > data[left])//data[mid]在左半段
			{
				if(data[mid] > target&&data[left] <= target)
					right=mid; 
				else
					left=mid;
			}else if(data[mid] < data[left])//在右半段
			{
				if(data[mid] < target&&target <= data[right])
					left=mid;
				else
					right=mid;
			}else  //data[mid] == data[left],无法判断data[mid]在哪半个区间中
				left++;//递增left缩小搜索范围。
		}
		if(data[left] == target)
			return true;
		if(data[right] == target)
			return true;
		return false;
	}


<think>我们正在讨论二分查找的习题。根据引用内容,用户希望获取一些二分查找相关的练习题。引用中提到了几个经典例题和练习题,包括: 1. 引用[1]中的经典例题1:搜索插入位置(最经典的二分查找),代码中给出了一个解法。 2. 引用[1]中的经典例题2(未具体给出,但提到了)。 3. 引用[2]中给出了一个二分查找的算法框架和简单的描述。 4. 引用[3]中提到了几个练习题:搜索旋转排序数组、搜索旋转排序数组II、寻找旋转排序数组中的最小值(两个变体)。 因此,我们可以整理出一些二分查找的习题,并按照难度和类型进行分类。 注意:用户要求的是习题,所以我们需要提供题目描述(或者题目名称)以便用户练习。由于引用中并没有完整的题目描述,我们可以根据常见的二分查找题目类型来给出建议。 根据引用内容,我们可以总结如下: 1. 基础二分查找:在有序数组中查找目标值,如果存在返回索引,否则返回应插入的位置(即引用1中的例题)。 2. 有重复值的情况:查找第一个出现的位置或最后一个出现的位置。 3. 旋转排序数组的二分查找(非完全有序)。 因此,我们可以列出以下习题: 一、基础二分查找 1. 搜索插入位置(LeetCode 35) 2. 在排序数组中查找元素的第一个和最后一个位置(LeetCode 34)—— 有重复值的情况 二、旋转排序数组问题(非完全有序) 1. 搜索旋转排序数组(LeetCode 33) 2. 搜索旋转排序数组 II(LeetCode 81) 3. 寻找旋转排序数组中的最小值(LeetCode 153) 4. 寻找旋转排序数组中的最小值 II(LeetCode 154) 三、其他变体 1. 有效的完全平方数(LeetCode 367) 2. x 的平方根(LeetCode 69) 3. 寻找峰值(LeetCode 162) 4. 在排序数组中查找元素的第一个位置和最后一个位置(重复值处理,LeetCode 34) 由于引用[3]中提到了非完全有序的二分查找,我们可以将这些旋转数组的题目作为重点。 另外,用户可能希望得到一些练习的资源,我们可以提供一些在线评测平台的题目链接(如果允许的话),但通常我们只给出题目名称和来源。 因此,我们可以这样回答: </think>以下是二分查找相关的经典习题分类及推荐,结合了基础题型和进阶变体: ### 一、基础二分查找 1. **标准二分查找** ```python def binary_search(nums, target): left, right = 0, len(nums) - 1 while left <= right: mid = (left + right) // 2 if nums[mid] == target: return mid elif nums[mid] < target: left = mid + 1 else: right = mid - 1 return -1 # 未找到 ``` **习题**: - 在有序数组中查找目标值(LeetCode 704) - 搜索插入位置(LeetCode 35)[^1] --- ### 二、重复元素边界问题 2. **查找第一个/最后一个匹配项** ```python # 查找第一个等于target的位置 def search_first(nums, target): left, right = 0, len(nums) - 1 while left <= right: mid = (left + right) // 2 if nums[mid] < target: left = mid + 1 else: right = mid - 1 return left if nums[left] == target else -1 ``` **习题**: - 在排序数组中查找元素的第一个和最后一个位置(LeetCode 34) - 统计有序矩阵中的负数(需结合边界判定) --- ### 三、旋转数组问题[^3] 3. **非完全有序数组** ```python def search_rotated(nums, target): left, right = 0, len(nums) - 1 while left <= right: mid = (left + right) // 2 if nums[mid] == target: return mid # 左半段有序 if nums[left] <= nums[mid]: if nums[left] <= target < nums[mid]: right = mid - 1 else: left = mid + 1 # 右半段有序 else: if nums[mid] < target <= nums[right]: left = mid + 1 else: right = mid - 1 return -1 ``` **习题**: - 搜索旋转排序数组(LeetCode 33) - 寻找旋转排序数组中的最小值(LeetCode 153) - 搜索旋转排序数组 II(含重复值,LeetCode 81) --- ### 四、抽象模型应用 4. **二分答案型问题** ```python # 在连续空间中二分(如求平方根) def mySqrt(x): left, right = 0, x while left <= right: mid = (left + right) // 2 if mid * mid <= x < (mid+1)*(mid+1): return mid elif mid * mid > x: right = mid - 1 else: left = mid + 1 ``` **习题**: - $x$ 的平方根(LeetCode 69) - 寻找峰值(LeetCode 162) - 在D天内送达包裹的能力(LeetCode 1011) --- ### 五、二维二分查找 5. **矩阵与二分结合** **习题**: - 搜索二维矩阵(每行有序,LeetCode 74) - 有序矩阵中第K小的元素(LeetCode 378)
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值