LeetCode 33. 搜索旋转排序数组
时间:2020-04-28
本文章向大家介绍LeetCode 33. 搜索旋转排序数组,主要包括LeetCode 33. 搜索旋转排序数组使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
我的LeetCode:https://leetcode-cn.com/u/ituring/
我的LeetCode刷题源码[GitHub]:https://github.com/izhoujie/Algorithmcii
LeetCode 33. 搜索旋转排序数组
题目
假设按照升序排序的数组在预先未知的某个点上进行了旋转。
( 例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] )。
搜索一个给定的目标值,如果数组中存在这个目标值,则返回它的索引,否则返回 -1 。
你可以假设数组中不存在重复的元素。
你的算法时间复杂度必须是 \(\Omicron\left(logn\right)\) 级别。
示例 1:
输入: nums = [4,5,6,7,0,1,2], target = 0
输出: 4
示例 2:
输入: nums = [4,5,6,7,0,1,2], target = 3
输出: -1
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/search-in-rotated-sorted-array
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题思路
题目已经要求算法的时间复杂度是\(\Omicron\left(logn\right)\),所以肯定还是用二分查找来解决的;
思路1-二分查找
二分查找的前提是数组有序,当前数组是局部有序,所以需要先确定有序的区间再使用二分查找;
大致做法不变,但是在判断大小的时候需要确定有序区间;
步骤:
- 左右指针left,right,中间位置mid;
- 确定有序区间,当前分为[left,mid]和[mid,right]两个区间,其中之一必是有序递增区间,判断方法就是看target是否在区间中间;
- 在有序区间中使用常规的二分查找算法逻辑;
算法复杂度:
- 时间复杂度: $ {\color{Magenta}{\Omicron\left(logn\right)}} $
- 空间复杂度: $ {\color{Magenta}{\Omicron\left(1\right)}} $
算法源码示例
package leetcode;
/**
* @author ZhouJie
* @date 2020年1月17日 下午10:22:10
* @Description: 33. 搜索旋转排序数组
*
*/
public class LeetCode_0033 {
public static void main(String[] args) {
int test1[] = { 4, 5, 6, 7, 0, 1, 2 };
int test2[] = { 1, 3 };
int test3[] = { 4, 5, 6, 7, 0, 1, 2 };
System.out.println(new Solution_0033().search_1(test1, 0));
System.out.println(new Solution_0033().search_1(test2, 3));
System.out.println(new Solution_0033().search_1(test3, 8));
}
}
class Solution_0033 {
/**
* @author: ZhouJie
* @date: 2020年2月4日 下午9:39:47
* @param: @param nums
* @param: @param target
* @param: @return
* @return: int
* @Description: 1-未优化的
*
*/
public int search_1(int[] nums, int target) {
if (nums == null) {
return -1;
}
int i = 0, j = nums.length - 1, k;
while (i <= j) {
k = (i + j) / 2;
if (i == j && nums[k] != target) {
return -1;
}
if (nums[k] == target) {
return k;
} else if (nums[i] > nums[k] && nums[k] < nums[j]) {
if (target > nums[k] && target <= nums[j]) {
i = k + 1;
} else {
j = k - 1;
}
} else if (nums[i] < nums[k] && nums[k] > nums[j]) {
if (target >= nums[i] && target < nums[k]) {
j = k - 1;
} else {
i = k + 1;
}
} else if (nums[i] <= nums[k] && nums[k] < nums[j]) {
if (target < nums[k]) {
j = k - 1;
} else {
i = k + 1;
}
} else if (target > nums[j]) {
j = k - 1;
} else {
i = k + 1;
}
}
return -1;
}
/**
* @author ZhouJie
* @date 2020年1月19日 上午12:13:34
* @Description: TODO(方法简述)
* @return int
* @UpdateUser-UpdateDate:[ZhouJie]-[2020年1月19日 上午12:13:34]
* @UpdateRemark:2-思路:关键是找到有序区间,每次的判断仅在有序区间内进行,比较条理清晰;
*
*/
public int search_2(int[] nums, int target) {
if (nums == null) {
return -1;
}
int left = 0, right = nums.length - 1;
int mid;
while (left <= right) {
mid = left + (right - left) / 2;
if (nums[mid] == target) {
return mid;
// 若nums[mid] < nums[right],说明右半边有序递增,这里不能先验左半边,因为mid可能与left相等
} else if (nums[mid] < nums[right]) {
// 若目标值在右侧有序区间内
if (target > nums[mid] && target <= nums[right]) {
left = mid + 1;
// 目标在左侧区间
} else {
right = mid - 1;
}
// 若右半边无序,则说明左半边有序,在左半边进行判断
} else {
// 若目标值在左半边有序区间内
if (target >= nums[left] && target < nums[mid]) {
right = mid - 1;
} else {
left = mid + 1;
}
}
}
return -1;
}
}
原文地址:https://www.cnblogs.com/izhoujie/p/12793524.html
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 云原生时代高性能Java框架—Quarkus(一)
- 云原生时代高性能Java框架—Quarkus(二)
- 使用TypeScript积累自己的类库
- 在Egret项目中使用protobuf
- JavaScript原型与继承
- 当TKE遇上Coding, 业务如何实现快速迭
- cocos creator 1.x透明渐变效果实现
- Cocos Creator 2.x透明渐变效果实现
- Themeleaf通过ajax局部更新
- ubuntu下利用expect实现screen多窗口开机运行
- hetzner服务器购买和安装debian系统
- 安全通告 | Apache SkyWalking SQL注入漏洞安全风险公告(CVE-2020-13921)
- Cmd Markdown 迁移备份的流程
- PyTorch3:计算图torch.autograph
- spark shell 配置 Kryo 序列化