当前位置: 首页 > article >正文

LeetCode【0033】搜索旋转排序数组

本文目录

  • 1 中文题目
  • 2 求解方法:二分查找
    • 2.1 方法思路
    • 2.2 Python代码
    • 2.3 复杂度分析
    • 2.4 不可以的投机取巧法
  • 3 题目总结

1 中文题目

整数数组 nums 按升序排列,数组中的值 互不相同

在传递给函数之前, n u m s nums nums 在预先未知的某个下标 k ( 0 ≤ k < n u m s . l e n g t h ) k(0 \leq k < nums.length) k0k<nums.length上进行了 旋转,使数组变为 [ n u m s [ k ] , n u m s [ k + 1 ] , . . . , n u m s [ n − 1 ] , n u m s [ 0 ] , n u m s [ 1 ] , . . . , n u m s [ k − 1 ] ] [nums[k], nums[k+1], ..., nums[n-1], nums[0], nums[1], ..., nums[k-1]] [nums[k],nums[k+1],...,nums[n1],nums[0],nums[1],...,nums[k1]](下标 从 0 开始 计数)。例如, [ 0 , 1 , 2 , 4 , 5 , 6 , 7 ] [0,1,2,4,5,6,7] [0,1,2,4,5,6,7] 在下标 3 3 3 处经旋转后可能变为 [ 4 , 5 , 6 , 7 , 0 , 1 , 2 ] [4,5,6,7,0,1,2] [4,5,6,7,0,1,2]

给定 旋转后 的数组 n u m s nums nums 和一个整数 t a r g e t target target ,如果 n u m s nums nums 中存在这个目标值 t a r g e t target target ,则返回它的下标,否则返回 − 1 -1 1

注意: 必须设计一个时间复杂度为 O ( l o g n ) O(log n) O(logn) 的算法解决此问题。

示例:

输入:nums = [4,5,6,7,0,1,2], target = 0
输出:4
输入:nums = [4,5,6,7,0,1,2], target = 3
输出:-1
输入:nums = [1], target = 0
输出:-1

提示:

  • 1 ≤ n u m s . l e n g t h ≤ 5000 1 \leq nums.length \leq 5000 1nums.length5000
  • − 1 0 4 ≤ n u m s [ i ] ≤ 1 0 4 -10^4 \leq nums[i] \leq 10^4 104nums[i]104
  • n u m s nums nums 中的每个值都 独一无二
  • 题目数据保证 n u m s nums nums 在预先未知的某个下标上进行了旋转
  • − 1 0 4 ≤ t a r g e t ≤ 1 0 4 -10^4 \leq target \leq 10^4 104target104

2 求解方法:二分查找

2.1 方法思路

方法核心

  • 使用改进的二分查找
  • 根据有序部分的位置判断搜索区间
  • 利用旋转数组的特性进行查找

实现步骤

(1)初始化:

  • 设置双指针left和right
  • 处理空数组特殊情况

(2)二分查找:

  • 计算中间位置
  • 判断mid位置的值

(3)区间判断:

  • 判断哪半部分是有序的
  • 确定目标值可能在的区间

方法示例

输入:nums = [4,5,6,7,0,1,2], target = 0

过程演示:
1. 初始状态:
   left = 0, right = 6
   mid = 3, nums[mid] = 7

2. 第一次迭代:
   nums[left] <= nums[mid]:左半部分有序
   target不在[4,7]内
   left = mid + 1 = 4

3. 第二次迭代:
   left = 4, right = 6
   mid = 5, nums[mid] = 1
   nums[left] > nums[mid]:右半部分有序
   target在[0,1]内
   right = mid - 1 = 4

4. 第三次迭代:
   left = 4, right = 4
   mid = 4, nums[mid] = 0
   找到目标值

返回:4

2.2 Python代码

class Solution:
    def search(self, nums: List[int], target: int) -> int:
        if not nums:
            return -1
            
        left, right = 0, len(nums) - 1
        
        while left <= right:
            mid = left + (right - left) // 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

2.3 复杂度分析

  • 时间复杂度:O(log n)
    • 每次迭代将搜索范围减半
    • 典型的二分查找复杂度
  • 空间复杂度:O(1)
    • 只使用常数额外空间

2.4 不可以的投机取巧法

class Solution:
    def search(self, nums: List[int], target: int) -> int:
        if target in nums:
            return nums.index(target)
        else:
            return -1
  • 时间复杂度:O(n)
    • in 操作需要O(n)时间
    • index()方法需要O(n)时间

没有利用题目中的数组是有序的特点,也没有利用数组只经过一次旋转的特点


3 题目总结

题目难度:中等
数据结构:数组
应用算法:二分查找


http://www.kler.cn/a/392645.html

相关文章:

  • logback之pattern详解以及源码分析
  • Ubuntu升级ssh版本到9.8
  • 使用 Docker 搭建 Hadoop 集群
  • Redis--如何保障缓存数据库一致性?(面试高频问题)
  • 【从零开始入门unity游戏开发之——unity篇01】unity6基础入门开篇——游戏引擎是什么、主流的游戏引擎、为什么选择Unity
  • 2- Linux系统的命令帮助
  • C/C++基础知识复习(20)
  • LeetCode通过栈解题逆波兰表达式 有效的括号 栈的压入、弹出序列 最小栈
  • 重构代码之用委托替代继承
  • 在linux中使用nload实时查看网卡流量
  • Unity 2022 Nav Mesh 自动寻路入门
  • JavaScript高级程序设计基础(四)
  • 关系型数据库和非关系型数据库详解
  • AXI DMA IP BUG踩坑记录
  • gin入门
  • 网上商城系统设计与Spring Boot框架
  • NoSQL数据库与关系型数据库的主要区别
  • SpringMVC案例学习(一)--计算器设计登录页面设计
  • 【代码随想录day29】【C++复健】134. 加油站;135. 分发糖果;860.柠檬水找零;406. 根据身高重建队列
  • [动态规划]最长公共子序列
  • vue 计算属性get set
  • 白酒除高级醇提升口感工艺
  • Javascript高级—如何实现一个类型判断函数?
  • 基于复现油炸鸡的智能手表的过程(1)
  • windows工具 -- 使用rustdesk和云服务器自建远程桌面服务, 手机, PC, Mac, Linux远程桌面 (简洁明了)
  • 前端-同源与跨域