【每日一题】33. Search in Rotated Sorted Array
题目描述
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.
Your algorithm’s runtime complexity must be in the order of O(log n).
Example 1:
Input: nums = [4,5,6,7,0,1,2], target = 0
Output: 4
Example 2:
Input: nums = [4,5,6,7,0,1,2], target = 3
Output: -1
假设按照升序排序的数组在预先未知的某个点上进行了旋转。
( 例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] )。
搜索一个给定的目标值,如果数组中存在这个目标值,则返回它的索引,否则返回 -1 。
你可以假设数组中不存在重复的元素。
你的算法时间复杂度必须是 O(log n) 级别。
题解
暴力循环
首先想到的解法是暴力循环O(N),不管数组是否有序,直接一次遍历,判断数组中是否有target存在。
虽然,题目中限制了时间复杂度要求,但是O(N)也能通过测试!
class Solution {
public:
int search(vector<int>& nums, int target) {
int idx = -1;
for (int i=0; i< nums.size(); i++){
if (nums[i] == target){
idx = i;
break;
}
}
return idx;
}
};
二分查找
下面看题目要求的结果O(logn)。O(logn)+有序数组->二分查找。题目给定也是一个有序数组经过一次旋转,所以,为了使用二分查找,我们需要在给定的数组中找到有序的片段,然后再利用二分查找法。
步骤:
- 考虑Corner case:空数组,长度为1的数组;
- 其他情况,设定左右边界;
- 如果mid == target,直接退出,返回mid
- 如果nums[left] <= nums[mid],说明left,mid子数组为有序数组,然后我们再来确定,target是否在这个子数组中:
- nums[left] <= target && target < nums[mid]: 在,变换左边界
- 否则,变换右边界
- 如果nums[left] > nums[mid],说明,mid,right 为有序子数组,然后我们确定,target是否在这个子数组中:
- nums[mid] < targe && target <= nums[right]:在,变换左边界
- 不在,变换右边界
要注意边界调节,left,right不同的初始值,while里的判断条件也不相同,明确是否取等号,此时的left,right如何变换
class Solution {
public:
int search(vector<int>& nums, int target) {
int size = (int)nums.size();
if (size == 0) return -1;
if (size == 1) return nums[0] == target ? 0 : -1;
int idx = -1, left = 0, right = size - 1;
while (left <= right){
int mid = left + (right - left)/2;
if (nums[mid] == target){
idx = mid;
break;
}
if(nums[left] <= nums[mid]){
if (nums[left] <= target && target< nums[mid])
right = mid - 1;
else
left = mid + 1;
}
else{
if (nums[mid] < target && target <= nums[right])
left = mid + 1;
else
right = mid - 1;
}
}
return idx;
}
};
- 3039: 玉蟾宫
- 大公司都有哪些开源项目之腾讯
- Vue拖拽组件开发实例
- 一小时培训之神经网络入门
- 【LeetCode 290】 关关的刷题日记28 Word Pattern
- Redis知识点速查
- 上传伪技术~很多人都以为判断了后缀,判断了ContentType,判断了头文件就真的安全了。是吗?
- SpringBoot的微信点餐系统后台开发要点
- 【LeetCode 463】 关关的刷题日记29 Island Perimeter
- 搭建移动端的跨平台开发环境
- 30分钟全面解析-SQL事务+隔离级别+阻塞+死锁
- 【最新TensorFlow1.4.0教程03】利用Eager Execution构建和训练卷积神经网络(CNN)
- 360护心镜脚本分析及N种绕过方式
- 清北集训Day6T1(生成函数)
- 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 数组属性和方法
- Linux文件服务器实战详解(系统用户)
- 关于bash函数你可能不知道的一些事情(译)
- Linux Centos7系统端口占用问题的解决方法
- Linux中利用sudo进行赋权的方法详解
- Centos7下用户登录失败N次后锁定用户禁止登陆的方法
- Linux服务器被黑以后的详细处理步骤
- linux下用户程序同内核通信详解(netlink机制)
- yum安装本地rpm软件方案详解
- CentOS 部署 flask项目的方法
- 在linux服务器下使用版本控制软件SVN的方法
- centos中yum命令删除还原的补救方法介绍
- Linux 创建子进程执行任务的实现方法
- Linux系统下安装jdbc与tomcat的图文教程
- Linux系统下利用C程序输出某进程的内存占用信息
- .NET Standard中配置TargetFrameworks输出多版本类库