33. 搜索旋转排序数组(中等)

embedded/2024/9/24 7:16:15/

33. 搜索旋转排序数组

  • 1. 题目描述
  • 2.详细题解
  • 3.代码实现
    • 3.1 Python
    • 3.2 Java

1. 题目描述

题目中转:33. 搜索旋转排序数组
在这里插入图片描述
在这里插入图片描述

2.详细题解

    给定数组是严格有序的,但在某个位置的下标处进行了旋转,因此改变了数组有序的特性,但数组局部是有序的,虽可以使用算法复杂度为 O ( n ) O(n) O(n)算法进行逐一遍历查找目标值的索引,但未能利用局部有序的特性。属于在有序的数组中查找数据,首先想到二分查找算法,但该题能使用二分查找算法吗?答案是肯定的,因为数组是局部有序的,如何利用数组局部有序特性呢?在中间数据将数组划分为两个区间时,先判断是左区间有序还是右区间有序,再判断目标值是否在有序的区间内?根据结果再更新相应的左或右指针。 从而利用数组局部有序的特性。
  具体算法如下:

  • Step1:初始化:两个指针 left 和 right,分别指向数组的起始和结束位置;
  • Step2:计算中间元素的索引: mid = (left + right) / 2;
  • Step3:如果 nums[mid] == target,则找到目标值,返回 mid,程序结束;
  • Step4:否则判断那个区间有序:
  •   如果nums[mid] >= nums[left]的值,说明左区间有序;
  •   否则右区间有序;
  • Step4:如果左区间有序:
  •   如果目标值在左区间内,则更新 r i g h t = m i d − 1 right=mid-1 right=mid1
  •   否则在右区间内,则更新 l e f t = m i d + 1 left = mid + 1 left=mid+1;
  • Step5:如果右区间有序(同理):
  •   如果目标值在右区间内,则更新 l e f t = m i d + 1 left=mid+1 left=mid+1
  •   否则在右区间内,则更新 r i g h t = m i d − 1 right = mid - 1 right=mid1;
  • Step6:当指针left小于right时,重复步骤Step2_Step6;
  • Step6:否则返回-1。

  注意,在具体代码实现时,一定要注意边界条件,尤其容易忽略。

3.代码实现

3.1 Python

python">class Solution:def search(self, nums: List[int], target: int) -> int:left, right = 0, len(nums) - 1while left <= right:mid = (left +right) // 2if nums[mid] == target:return midif nums[left] <= nums[mid]:  # 若左边区间有序if nums[left] <= target < nums[mid]:right = mid - 1else:left = mid + 1else:  # 否则,右边区间有序if nums[mid] < target <= nums[right]:left = mid + 1else:right = mid - 1return -1

在这里插入图片描述

3.2 Java

java">class Solution {public int search(int[] nums, int target) {int left = 0, right = nums.length - 1;while (left <= right){int mid = (left + right) / 2;if (nums[mid] == target){return mid;}else if (nums[mid] > nums[left]){// 左区间有序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 -1;}
}

在这里插入图片描述
  将错误测试例子 [ 3 , 1 ] [3, 1] [3,1]代入程序分析,发现 m i d mid mid首次的值为 3 3 3,根据程序判断为左区间无序( i f ( n u m s [ m i d ] > n u m s [ l e f t ] ) if (nums[mid] > nums[left]) if(nums[mid]>nums[left]),则右区间有序,故首先判断目标值是否在右区间范围内,右区间为 [ 3 , 1 ] [3,1] [3,1](但实际是无序的),根据程序判断目标值不在右区间内( i f ( n u m s [ m i d ] < t a r g e t & & t a r g e t < = n u m s [ r i g h t ] ) if (nums[mid] < target\ \ \&\&\ \ target <= nums[right]) if(nums[mid]<target  &&  target<=nums[right])),故右指针更新为 r i g h t = m i d − 1 = − 1 right=mid-1=-1 right=mid1=1,循环条件不满足而推出循环,最终返回-1。但实际该测试案例是有正确值的,在程序初次判断左区间是否有序时存在问题,单独的区间 [ 3 ] [3] [3]是有序而非无序的,而右区间 [ 3 , 1 ] [3,1] [3,1]是无序而非有序,因此应该修改此次代码边界条件,首先判断目标值是否在有序的左区间,不在则更新 左指针 l e f t = m i d + 1 = 1 左指针left=mid+1=1 左指针left=mid+1=1,再进行下一轮判断即可返回正确的目标值所在索引为 1 1 1。优化代码如下:

java">class Solution {public int search(int[] nums, int target) {int left = 0, right = nums.length - 1;while (left <= right){int mid = (left + right) / 2;if (nums[mid] == target){return mid;}else if (nums[mid] >= nums[left]){// 左区间有序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 -1;}
}

在这里插入图片描述

  执行用时不必过于纠结,对比可以发现,对于pythonjava完全相同的编写,java的时间一般是优于python的;至于编写的代码的执行用时击败多少对手,执行用时和网络环境、当前提交代码人数等均有关系,可以尝试完全相同的代码多次执行用时也不是完全相同,只要确保自己代码的算法时间复杂度满足相应要求即可,也可以通过点击分布图查看其它coder的code。


http://www.ppmy.cn/embedded/56723.html

相关文章

【Python机器学习】算法链与管道——用预处理进行参数选择的注意项

对于许多机器学习算法&#xff0c;提供的特定数据表示非常重要。比如&#xff0c;首先对数据进行缩放&#xff0c;然后手动合并特征&#xff0c;再利用无监督机器学习来学习特征。因此&#xff0c;大多数机器学习应用不仅需要应用多个算法&#xff0c;而且还需要将许多不同的处…

【C++】模板进阶--保姆级解析(什么是非类型模板参数?什么是模板的特化?模板的特化如何应用?)

目录 一、前言 二、什么是C模板&#xff1f; &#x1f4a6;泛型编程的思想 &#x1f4a6;C模板的分类 三、非类型模板参数 ⚡问题引入⚡ ⚡非类型模板参数的使用⚡ &#x1f525;非类型模板参数的定义 &#x1f525;非类型模板参数的两种类型 &#x1f52…

uniapp中实现跳转链接到游览器(安卓-h5)

uniapp中实现跳转链接到游览器&#xff08;安卓-h5&#xff09; 项目中需要做到跳转到外部链接&#xff0c;网上找了很多都不是很符合自己的要求&#xff0c;需要编译成app后是跳转到游览器打开链接&#xff0c;编译成web是在新窗口打开链接。实现的代码如下&#xff1a; 效果&…

【数据分享】国家级旅游休闲街区数据(Excel/Shp格式/免费获取)

之前我们分享过从我国文化和旅游部官网整理的2018-2023年我国50个重点旅游城市星级饭店季度经营状况数据&#xff08;可查看之前的文章获悉详情&#xff09;&#xff01;文化和旅游部官网上也分享有很多与旅游相关的常用数据&#xff0c;我们基于官网发布的名单文件整理得到全国…

使用LoFTR模型进行图像配准、重叠区提取

LoFTR模型源自2021年CVPR提出的一篇论文LoFTR: Detector-Free Local Feature Matching with Transformers&#xff0c;其基于pytorch实现图像配准&#xff0c;与基于superpointsuperglue的方法不同&#xff0c; 是一个端到端的图像配准方法。与LoFTR官方库相关的有loftr2onnx库…

gdb-dashboard:用Python重塑GDB调试体验

gdb-dashboard&#xff1b;一目了然的GDB调试&#xff0c;尽在掌控之中- 精选真开源&#xff0c;释放新价值。 概览 gdb-dashboard是一个用Python编写的模块化视觉界面&#xff0c;为GNU Debugger&#xff08;GDB&#xff09;提供了一个现代化的工作空间。它通过集成多个面板和…

人工智能写作对话系统源码 自然语言的处理能力 前后端分离 带完整的安装代码包以及搭建教程

系统概述 随着互联网信息爆炸式增长&#xff0c;用户对于高质量、个性化内容的需求日益增长&#xff0c;而传统的内容生成方式已难以满足这一需求。另一方面&#xff0c;深度学习和自然语言处理技术的突破性进展&#xff0c;为人机交互提供了新的可能。本项目正是在此背景下应…

Linux 防火墙配置指南:firewalld 端口管理应用案例(二十个实列)

&#x1f3e1;作者主页&#xff1a;点击&#xff01; &#x1f427;Linux基础知识(初学)&#xff1a;点击&#xff01; &#x1f427;&#x1f427;Linux高级管理专栏&#xff1a;点击&#xff01; &#x1f510;Linux中firewalld防火墙&#xff1a;点击&#xff01; ⏰️…