首页 > 其他分享 >33. 搜索螺旋数组

33. 搜索螺旋数组

时间:2024-09-19 17:01:28浏览次数:1  
标签:有序 nums 33 螺旋 mid 数组 目标值 left

题目描述:

整数数组 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. 数组的某一部分是升序排列的,但另一部分因为旋转的原因可能并不是升序排列。
  2. 通过找到旋转点,我们能够把数组划分成两个部分,一部分是递增的,另一部分在旋转后也保持递增但次序不同。

在这种情况下,传统的二分查找算法无法直接使用,因为整个数组并不是完全有序的。不过,可以通过观察发现,每次将数组一分为二时,总有一部分是有序的,这是我们可以利用的特性。

思路分析

  1. 确定二分查找的基础:二分查找的核心是在每一步将搜索空间减半。我们每次通过将数组分成两部分,分别检查目标值是否在其中一部分的有序区间内,从而决定搜索的方向。

  2. 如何判断哪部分是有序的:

    • 每次通过比较 nums[left] 和 nums[mid] 来判断左半部分是否有序。
    • 如果 nums[left] <= nums[mid],则说明左半部分是有序的。因为旋转不会影响这一部分,nums[left] 到 nums[mid] 保持递增。
    • 否则,右半部分一定是有序的,即 nums[mid] <= nums[right]。
  3. 在有序区间内查找目标值:

    • 如果左半部分是有序的,并且目标值 target 落在这个有序区间中,那么我们缩小搜索范围到左半部分,即更新 right = mid - 1。
    • 如果目标值不在左半部分有序区间内,则我们将搜索范围缩小到右半部分,即更新 left = mid + 1。
  4. 反之亦然:如果发现右半部分是有序的,执行同样的判断。如果目标值在右半部分有序区间内,就在右侧继续查找;否则,继续在左侧查找。

  5. 终止条件:每次通过调整 left 和 right 指针,最终要么找到目标值,要么当 left > right 时,确定目标值不存在。

思路示例

以数组 [4, 5, 6, 7, 0, 1, 2] 和 target = 1 为例,具体操作如下:

  • 初始状态:

    • left = 0,right = 6,mid = 3,nums[mid] = 7。
    • 比较 nums[left] = 4 和 nums[mid] = 7,确定左半部分 [4, 5, 6, 7] 是有序的。
    • 目标 1 不在这个有序区间内,搜索右半部分 [0, 1, 2]。
  • 第二次查找:

    • 更新 left = 4,right = 6,mid = 5,nums[mid] = 1。
    • 找到目标值 1,返回 mid = 5。

这个过程利用了旋转数组的有序性特征,确保了每次都能在正确的区间内查找目标值。

点击查看代码
func search(nums []int, target int) int {
    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 target >= nums[left] && target < nums[mid] {
                right = mid - 1
            } else {
                left = mid + 1
            }
        } else {
            // 右半部分有序
            if target > nums[mid] && target <= nums[right] {
                left = mid + 1
            } else {
                right = mid - 1
            }
        }
    }

    // 目标值不存在
    return -1
}

标签:有序,nums,33,螺旋,mid,数组,目标值,left
From: https://www.cnblogs.com/CharlseGo/p/18420970

相关文章

  • 【洛谷 P5730】【深基5.例10】显示屏 题解(数组+循环)
    【深基5.例10】显示屏题目描述液晶屏上,每个阿拉伯数字都是可以显示成的点阵的(其中X表示亮点,.表示暗点)。现在给出数字位数(不超过)和一串数字,要求输出这些数字在显示屏上的效果。数字的显示方式如同样例输出,注意每个数字之间都有一列间隔。输入格式第一行输入一个正整数,表示数......
  • 【LeetCode Hot 100】4. 寻找两个正序数组的中位数
    题目描述要求出两个数组的中位数,第一想法当然是将这两个数组进行归并排序,然后直接得到排序后长数组的中位数。由于本题的两个数组都是排序后的数组,因此省去了排序的步骤。这种方法的时间复杂度为\(O(m+n)\),空间复杂度由于要存储排序后的长数组,所以也是\(O(m+n)\)。有没有相对更......
  • 34. 在排序数组中查找元素的第一个和最后一个位置
    思路先判断target是否存在列表中,不存在直接输出存在,则找出第一个等于target值的列表位置,即目标值在列表中的开始位置接着在当前位置继续往下查找,找到最后一个目标值等于列表值的位置(也可用二分查找找到等于target值的位置+往前、往后找到开始、结束位置,但会超限,可参考(......
  • 【日记】书荒了(337 字)
    正文几乎玩了一周之后上班的第一天。确实有些惫懒。基本都在解决一些之前代班同事留下来的遗留工作。整理了一下,发现工作清单上好多任务都没什么意义。今天打印准考证,发现考试地点在市里……本来还想着,考完去找灵玩儿,这下不行了。而且一天考两科。这我是真没想到。所以......
  • springboot零食购物系统-计算机毕业设计源码43357
    基于Web零食购物系统的设计与实现摘要本项目旨在设计和实现一个基于Web的零食购物系统,旨在满足用户对零食购物的便捷性和个性化需求。通过整合现代Web开发技术,包括前端界面设计和后端逻辑开发,系统将实现用户注册登录、商品浏览、购物车管理、订单结算等功能,旨在为用户提供......
  • 【C总集篇】第八章 数组和指针
    文章目录第八章数组和指针数组数组回顾初始化数组初始化数组介绍初始化失败案例部分初始化自动匹配数组给数组赋值数组边界指定数组大小多维数组二维数组的定义二维数组的初始化指针与数组函数数组与指针函数数组与指针初了解使用指针形参指针操作八种基本指针......
  • 对象字符串转换为数组对象
    数据源格式:'{\n"填写说明":"每个学期的开学之前,需要调整这里面的配置,这样课表和一卡通对接的才能是正确的数据",\n"学年编号":"2024-2025",\n"学期编号":"1"\n}'"{"填写说明":"每个学期的开学之前,需要调整这里面的配置,这样课表和一卡......
  • 2321. 拼接数组的最大分数
    题目链接2321.拼接数组的最大分数思路最大子数组和-变体题解链接转换成最大子数组和(Python/Java/C++/Go)关键点无时间复杂度\(O(n)\)空间复杂度\(O(1)\)代码实现:classSolution:defmaximumsSplicedArray(self,nums1:List[int],nums2:Lis......
  • 918. 环形子数组的最大和
    题目链接918.环形子数组的最大和思路最大子数组和-简单变体题解链接没有思路?一张图秒懂!(Python/Java/C++/Go/JS)关键点无时间复杂度\(O(n)\)空间复杂度\(O(1)\)代码实现:classSolution:defmaxSubarraySumCircular(self,nums:List[int])->......
  • 152. 乘积最大子数组
    题目链接152.乘积最大子数组思路最大子数组和-简单变体题解链接动态规划关键点无时间复杂度\(O(n)\)空间复杂度\(O(1)\)代码实现:classSolution:defmaxProduct(self,nums:List[int])->int:answer=premax=premin=nums[0]......