LeetCode_二分搜索_中等_33.搜索旋转排序数组
1.题目
整数数组 nums 按升序排列,数组中的值互不相同 。
在传递给函数之前,nums 在预先未知的某个下标 k(0 <= k < nums.length)上进行了旋转,使数组变为 [nums[k], nums[k+1], …, nums[n-1], nums[0], nums[1], …, nums[k-1]](下标 从 0 开始 计数)。例如,[0, 1, 2, 4, 5, 6, 7] 在下标 3 处经旋转后可能变为 [4, 5, 6, 7, 0, 1, 2] 。给你旋转后的数组 nums 和一个整数 target ,如果 nums 中存在这个目标值 target,则返回它的下标,否则返回 -1 。请设计一个时间复杂度为O(log n) 的解决方案。
示例 1:
输入:nums = [4,5,6,7,0,1,2], target = 0
输出:4
示例 2:
输入:nums = [4,5,6,7,0,1,2], target = 3
输出:-1
示例 3:
输入:nums = [1], target = 0
输出:-1
提示:
1 <= nums.length <= 5000
-104 <= nums[i] <= 104
nums 中的每个值都 独一无二
题目数据保证 nums 在预先未知的某个下标上进行了旋转
-104<= target<= 104
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/search-in-rotated-sorted-array
2.思路
(1)二分搜索
设计一个时间复杂度为 O(log n) 的搜索方案,最容易想到的应该就是二分搜索,不过本题中的数组是经过一个升序数组”旋转“之后得到的,只是局部有序。所以在使用二分搜索时,关键在于分情况判断 target 所在的区间。
在第一趟的查找过程中,要确定查找区间的开头位置、中间位置以及结尾位置,这里分别定义变量 left、mid 和 right,并赋予相应的值。这三个变量将整个 nums 数组分为两个部分,即 nums[left…mid] 和 nums[mid…right]。
在 left <= right 成立的条件下,分情况进行讨论:
- 若 nums[mid] == target,直接返回 mid 即可;
- 若 nums[left] <= nums[mid]:
如果 nums[left] <= target && target < nums[mid]
:这说明 target 一定在 nums[left…mid] 之间,按照而二分查找的算法思想,此时的查找区间应变为 nums[left…mid],并且 right = mid - 1,进行下一轮查找;如果 nums[left] > target || target >= nums[mid
,这说明 target 在 nums[mid…right] 之间,left = mid + 1,进行下一轮查找;
- 若 nums[left] > nums[mid]:
如果 nums[mid] < target && target <= nums[right]
,这说明 target 在 nums[mid…right] 之间,同理变换区间进行查找。如果 nums[mid] >= target || target > nums[right]
,这说明 target 在 nums[left…mid] 之间,同理变换区间进行查找。
相关题目:
LeetCode_二分搜索_中等_81.搜索旋转排序数组 II
LeetCode_二分搜索_中等_153.寻找旋转排序数组中的最小值
LeetCode_二分搜索_困难_154.寻找旋转排序数组中的最小值 II
3.代码实现(Java)
//思路1————二分搜索
class Solution {
public int search(int[] nums, int target) {
int left = 0;
int right = nums.length - 1;
while (left <= right) {
int mid = left + (right - left) / 2;
if (nums[mid] == target) {
return mid;
}
// nums[left...mid...high]
if (nums[left] <= nums[mid]) {
// nums[left...mid] 有序
if (nums[left] <= target && target < nums[mid]) {
// target 在 nums[left...mid] 中
right = mid - 1;
} else {
// target 在 nums[mid...right] 中
left = mid + 1;
}
} else {
// nums[mid...right] 有序
if (nums[mid] < target && target <= nums[right]) {
// target 在 nums[mid...right] 中
left = mid + 1;
} else {
// target 在 nums[left...mid] 中
right = mid - 1;
}
}
}
return -1;
}
}
相关文章
- Leetcode: The Maze III(Unsolved Lock Problem)
- Leetcode: Find Minimum in Rotated Sorted Array
- 【Leetcode】1299. 将每个元素替换为右侧最大元素(简单)
- JS Leetcode 81. 搜索旋转排序数组 II 题解,补救二分法的可行性
- JS Leetcode 33. 搜索旋转排序数组题解,图解旋转数组中的二分法
- JS Leetcode 74. 搜索二维矩阵题解分析,二分法与坐标轴法
- [LeetCode]Sum of Two Integers
- LeetCode 33. 搜索旋转排序数组
- 189、【动态规划】leetcode ——312. 戳气球(C++版本)
- 150、【动态规划】leetcode ——96. 不同的二叉搜索树(C++版本)
- 【LeetCode】12. Integer to Roman (2 solutions)
- [Leetcode]-Merge Two Sorted Lists
- 【leetcode】538/1038: 把二叉搜索树转化为累加树
- [LeetCode] 1334. Find the City With the Smallest Number of Neighbors at a Threshold Distance 阈值距离内邻居最少的城市
- [LeetCode] Number of Segments in a String 字符串中的分段数量
- [LeetCode] 362. Design Hit Counter 设计点击计数器
- [LeetCode] 270. Closest Binary Search Tree Value 最近的二分搜索树的值
- [LeetCode] 35. Search Insert Position 搜索插入位置
- [LeetCode] 79. Word Search 词语搜索
- [LeetCode] 81. Search in Rotated Sorted Array II 在旋转有序数组中搜索之二
- [LeetCode] 74. Search a 2D Matrix 搜索一个二维矩阵