LeetCode 81中等二分查找
搜索旋转排序数组 II 图解题解
这道题到底在问什么
给你 旋转后 的数组 nums 和一个整数 target ,请你编写一个函数来判断给定的目标值是否存在于数组中。如果 nums 中存在这个目标值 target ,则返回 true ,否则返回 false 。 你必须尽可能减少整个操作步骤。
- nums,target
- [2,5,6,0,0,1,2], 0
- 输出
- true
先想最直接的笨办法
数组/字符串状态条跟着代码走:推进语句是:while l <= r:。处理过的部分不再重新枚举。(动画第 10 步)
最优解:一步一步想明白
- 3下面 9 步动画会按主解代码推进,而不是泛泛讲题型。
- 4先读清 搜索旋转排序数组 II 的输入输出数组/字符串状态条跟着代码走:先把示例输入映射到代码参数:def search(self, nums, target):。
- 5l = 0;r = len(nums) - 1数组/字符串状态条跟着代码走:开局只立住必要变量:l = 0;r = len(nums) - 1。
- 6while l <= r:数组/字符串状态条跟着代码走:主流程从这里开始:while l <= r:。
- 7if nums[mid] == target:数组/字符串状态条跟着代码走:题目条件落到这一行:if nums[mid] == target:。
- 8更新核心状态数组/字符串状态条跟着代码走:对应代码:更新答案变量。这一行决定当前轮对答案有什么贡献。
- 9l++, r--数组/字符串状态条跟着代码走:边界跟着代码看:if nums[mid] == target:。
- 10while l <= r:数组/字符串状态条跟着代码走:推进语句是:while l <= r:。处理过的部分不再重新枚举。
- 11return False数组/字符串状态条跟着代码走:到这里,l 已经能表达题目要求。
- 12return:return False数组/字符串状态条跟着代码走:最后检查返回形态:返回值、原地修改或设计类状态,要和 LeetCode 判题方式一致。
- 15记住这题的代码骨架:题意约束先落到状态变量,再用循环或递归维护它。
⚠️ 容易写错的地方
✗ 错:遇到 nums[l]==nums[mid]==nums[r] 仍硬判
✓ 对:l++, r--
无法判断哪边有序
✗ 错:把无重复模板照搬
✓ 对:加入重复处理
重复值会破坏二分判定
完整代码(Python)
Python
class Solution:
def search(self, nums, target):
l = 0
r = len(nums) - 1
while l <= r:
mid = (l + r) // 2
if nums[mid] == target:
return True
if nums[l] == nums[mid] == nums[r]:
l += 1
r -= 1
elif nums[l] <= nums[mid]:
if nums[l] <= target < nums[mid]:
r = mid - 1
else:
l = mid + 1
else:
if nums[mid] < target <= nums[r]:
l = mid + 1
else:
r = mid - 1
return False复杂度
时间复杂度
O(n) 最坏,平均 O(log n)
重复时可能线性退化
空间复杂度
O(1)
只用指针
看不够?换成动画再走一遍
上面的推演每一步都对应一帧动画。点开交互动画版,能一步步看着 搜索旋转排序数组 II 的数据怎么变、指针怎么走,还能切 Python / Java / C++ 跟着练。
面试官可能追问
这道题为什么用「二分查找」,换最直接的暴力解会差在哪?+
二分查找抓住了本题的结构特征,把暴力解里重复的工作省掉;暴力解通常要多嵌套一层枚举,数据一大就超时。具体对比见上文「暴力解及其卡点」与「最优解逐步推演」两节。
时间复杂度为什么是 undefined?怎么推出来的?+
按上文复杂度小节的推导,时间复杂度为 undefined。
本平台为独立第三方培训机构,与华为技术有限公司无任何关联;课程的服务内容与权益以购买协议为准,学习效果因个人情况而异。「华为 OD」「华为可信」等仅为对岗位与考试方向的客观描述,相关商标归各自权利人所有。