算法之旋转数组的查找问题整理(附二分查找模板)

二分搜索算法解题步骤,吐血整理 基本介绍 二分搜索(折半搜索)是一种在有序数组中查找某一特定元素的搜索算法。从定义可知,运用二分搜索的前提是数组必须是排好序的。另外,输入并不一定是数组,也有可能是给定一个区间的起始和终止的位置。 他的时间复杂度是 O(lgn),非常高效。 特点 他的缺点要求待查找的数组或者区间是排好序的。 对数组进行动态的删除和插入操作并完成查找,平均复杂度会变为 O(n)。 因此,当输入的数组或者区间是排好序的,同时又不会经常变动,而要求从里面找出一个满足条件的元素的时候,二分搜索就是最好的选择。 解题思路 二分搜索一 阅读详情

介绍

  • 旋转数组的定义:
    排好序的数组 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] 。
  • 相关问题
  1. 153. 寻找旋转排序数组中的最小值
    寻找旋转数组中的最小值,数组中每个元素的唯一的。
  2. 154. 寻找旋转排序数组中的最小值 II
    寻找旋转数组中的最小值,数组中包含重复元素。
  3. 33. 搜索旋转排序数组
    在寻找数组中查询是否存在某个值,不包含重复元素。
  4. 81. 搜索旋转排序数组 II
    在寻找数组中查询是否存在某个值,包含重复元素。

以上题目均来自 LeetCode

二分查找模板

  • 模板一
public binarySearch(int[] nums, int target) {
    int n = nums.length;
    if (n == 0) return -1;
    int left = 0, right = n - 1, mid;
    while (left <= right) {
        mid = left + (right - left) / 2;
        if (nums[mid] == target) {
            return mid;
        } else if (nums[mid] < target) {
            left = mid + 1;
        } else {
            right = mid - 1;
        }
    }
}
  • 模板二
public binarySearch(int[] nums, int target) {
    int n = nums.length;
    int left = 0, right = n, mid;
    while (left < right) {
        mid = left + (right - left) / 2;
        if (nums[mid] < target) {
            left = mid + 1;
        } else {
            right = mid;
        }
    }
}
  • 变形
public binarySearch(int[] nums, int target) {
    int n = nums.length;
    int left = 0, right = n, mid;
    while (left < right) {
        mid = left + (right - left + 1) / 2;
        if (nums[mid] > target) {
            right = mid - 1;
        } else {
            left = mid;
        }
    }
}

解法

对于排序数组的查找,很容易想到二分法。

对于旋转数组,依然可以使用二分法进行查找。

问题1

不包含重复值的最小值的查询
使用模板二

class Solution {
    public int findMin(int[] nums) {
        int n = nums.length;
        int i = 0, j = n, mid;
        while (i < j) {
            mid = i + (j - i) / 2;
            if (nums[mid] > nums[n - 1]) {
                i = mid + 1;
            } else {
                j = mid;
            }
        }
        return nums[i];
    }
}
问题2

包含重复值的最小值的查询
在模板二基础上,针对题目变化

class Solution {
    public int findMin(int[] nums) {
        int n = nums.length;
        int left = 0, right = n - 1, mid;
        while (left < right) {
            mid = left + (right - left) / 2;
            if (nums[mid] > nums[right]) {
                left = mid + 1;
            } else if (nums[mid] < nums[right]) {
                right = mid;
            } else {
                right--;
            }
        }
        return nums[left];
    }
}
问题3

不包含重复值的某个元素的查找
使用模板一

class Solution {
    public int search(int[] nums, int target) {
        int n = nums.length;
        int left = 0, right = n - 1, mid;
        while (left <= right) {
            mid = left + (right - left) / 2;
            if (nums[mid] == target) {
                return mid;
            } else if (nums[mid] > target) {
                if (nums[mid] > nums[n - 1] && target <= nums[n - 1]) {
                    left = mid + 1;
                } else {
                    right = mid - 1;
                }
            } else {
                if (nums[mid] <= nums[n - 1] && target > nums[n - 1]) {
                    right = mid - 1;
                } else {
                    left = mid + 1;
                }
            }
        }
        return -1;
    }
}
问题4

包含重复元素的值查找
使用模板一

class Solution {
    public boolean search(int[] nums, int target) {
        int n = nums.length;
        int left = 0, right = n - 1, mid;
        while (left <= right) {
            mid = left + (right - left) / 2;
            if (nums[mid] == target) {
                return true;
            }
            // 因为下面用到了n-1,所以不能用right;如果此处用right,下面判断就要用nums[0]
            if (nums[left] == nums[mid]) {
                left++;
                continue;
            }
            if (nums[mid] > target) {
                if (nums[mid] > nums[n - 1] && target <= nums[n - 1]) {
                    left = mid + 1;
                } else {
                    right = mid - 1;
                }
            } else {
                if (nums[mid] <= nums[n - 1] && target > nums[n - 1]) {
                    right = mid - 1;
                } else {
                    left = mid + 1;
                }
            }
        }
        return false;
    }
}

虽然使用了二分查找,但是由于存在重复元素,当数组中所有元素相等且不等于target时,需要遍历数组中所有元素。因此时间复杂度为O(n)。

Python3实现旋转数组的3种算法 例如,给定一个数组 [4,5,6,7,0,1,2],它可能经过旋转变为 [0,1,2,4,5,6,7]。本文介绍了三种实现旋转数组的算法:线性时间复杂度算法、二分查找算法和分治算法。二分查找算法是一种常见的搜索算法,适用于有序数组。与线性时间复杂度算法相比,二分查找算法的实现更为简单,但需要预先确定旋转点的位置。线性时间复杂度算法:该算法的时间复杂度为O(log n),其中n为数组的长度。在每种情况下,我们分别处理左半部分、中间部分和右半部分的子数组,然后将结果进行合并,找到目标元素的位置并返回。 阅读详情

相关推荐

二.二分查找(mid)

搜索旋转排序数组 class Solution: def search(self, nums: List[int], target: int) -> int: def findElement(nums, target): left = 0; right = len(nums) - 1 while left <= right: mid = (left + right) // 2

812

198-旋转数组中的查找

题目如下: 假设按照升序排序的数组在预先未知的某个点上进行了旋转。 ( 例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] )。 搜索一个给定的目标值,如果数组中存在这个目标值,则返回它的索引,否则返回 -1 。 你可以假设数组中不存在重复的元素。 你的算法时间复杂度必须是 O(log n) 级别。 示例 1: 输入: nums = [4,5,6,7,0,1,2], target = 0 输出: 4 示例 2: 输入: nums = [4,5,6,7,0,1,2], tar

LINZEYU666的博客 174

用Python实现一个简单的远程桌面服务端和客户端

本文介绍了一个基于Python的轻量级远程桌面解决方案,针对商业软件在嵌入式系统上的兼容性问题、性能问题和成本问题。系统采用客户端-服务端架构,包含两个通信通道:5000端口传输压缩视频流,5001端口传输控制事件。通过多线程设计、图像压缩(JPEG+zlib)和网络优化(禁用Nagle算法)等技术手段提高性能。服务端实现了高效的屏幕捕获(使用mss库)、图像处理流水线和事件处理逻辑。客户端采用PyQt5构建UI界面,包含视频接收线程以减少主线程负担。该方案具有跨平台、开源免费、轻量级(核心代码不到500行

Hi20240217的博客 1660

【经典算法】旋转数组查找

给出一个数组{1,3,4,6,7,9,11}\{1,3,4,6,7,9,11\},它的旋转数组可以是{4,6,7,9,11,1,3}\{4,6,7,9,11,1,3\},已知原始数组是递增的,旋转数组由原始数组变形而来,查找该旋转数组中某个元素是否存在。

菜鸟的自学之路 4641

CCC数字钥匙3.0标准解读(16)

介绍通信过程最重要部分:身份认证和加密.介绍需要身份认证的过程和需要加密的数据及过程.

weixin_41738640的博客 1533

告别复杂配置:dbswitch vs 传统工具(Kettle/DataX)在Greenplum数据同步中的性能对比

本文深入对比了新兴工具dbswitch与传统ETL工具Kettle、DataX在Greenplum数据同步中的表现。重点分析了dbswitch如何通过免中间文件、利用二进制COPY协议等设计,在异构数据库同步场景下实现更优的性能和更简化的配置,为技术选型提供清晰参考。

transformer2023的博客 1046

旋转数组的二分查找

旋转数组的二分查找 可参考Leetcode 33、81题 1. 何为旋转数组 讲一个有序数组从任意位置隔断分为两部分,两部分调换位置,调换位置之后的数组即为旋转数组 2. 如何对旋转数组进行二分查找(假定数组中不含重复元素) 重点:对于旋转数组来说,无论从哪一个点将数组分开,左右两边中必有一边是有序的 二分查找步骤:时间复杂度O(logN) 定义三个指针:left、middle、right 比较left是否小于middle,是则左半部分有序,否则右半部分有序 判断要查找的元素是否在有序部分,是则继续

wsldyyq的博客 1886

告别纸上谈兵:在Xilinx Artix-7 FPGA上实测RGMII接口,从ILA抓包到PC Ping通全流程记录

本文详细记录了在Xilinx Artix-7 FPGA平台上实现RGMII接口的全过程,包括硬件配置、Vivado工程设置、双沿数据转换代码实现以及ILA波形分析。通过实测数据包捕获和PC端Ping测试,验证了千兆以太网通信的稳定性和可靠性,为工业通信网关等应用提供了实用参考。

weixin_33701251的博客 287

33 搜索旋转排序数组

题目 整数数组 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 和一个整数

Mirevas的博客 127

OpenMV模块视觉测距(避障)+颜色识别+TFT-LCD显示(实现原理与代码分析)

上图所示代码实际运行的帧率比较低,主要原因有以下两个:1.硬件问题,博主使用的版本比较低,可以尝试使用高版本OpenMV2.图像滤波问题。之前加入图像滤波是想提高色块识别的准确性,但是相应的运算速度也会下降。

ediykk的博客 1万+

手把手教你学simulink实例--基于Simulink的储能系统性能评估与仿真

储能系统是现代能源体系中的关键组成部分,广泛应用于可再生能源并网、电网调峰调频、电力质量改善以及电动汽车充电等领域。为了提高储能系统的运行效率和可靠性,对其性能进行准确评估至关重要。基于MATLAB/Simulink平台,可以构建储能系统的动态模型,并通过仿真分析其在不同工况下的性能表现。本项目旨在研究储能系统的建模方法、控制策略及其性能评估指标,并通过Simulink仿真验证系统的动态特性和稳态性能。

MHD0815的博客 195

算法:二分查找

二分查找算法讲解以及一些相关题目的总结

yanxiao07的博客 1980

QGis软件 —— 2、QGis加载在线地图两种方式(谷歌地图、天地图)

QGis软件 —— 2、QGis加载在线地图两种方式(谷歌地图)

1万+

[Java恶补day24] 整理模板·考点三【二分查找】

本文总结了二分查找算法的核心要点和两种典型应用: 二分查找模板:重点介绍了四种区间表示法(闭区间、开区间、左开右闭、左闭右开),强调区间端点更新的处理规则。提供了防止mid溢出的计算方法:mid = low + (high - low)/2。 Java数组操作:包括数组初始化、遍历、排序等常用方法。 两道典型题目: 34题:在有序数组中查找目标值的起始和结束位置,通过两次二分查找分别确定下界和上界,时间复杂度O(log n)。 2529题:统计有序数组中正负数的最大数量,可作为34题的配套练习

FUNNY123 1542

Qt入门教程【基础控件篇】QLineEdit输入框

QLineEdit输入框

小鱼酱的博客 3262

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

【优选算法篇】:揭开二分查找算法的神秘面纱--数据海洋中的精准定位器

基本思想二分查找算法的基本思想是:首先确定目标值可能存在的区间,然后逐步缩小区间直到确定目标值的位置或者确定目标值不存在。这个过程中,每次都会将查找范围缩小一半,因此大大提高了查找效率。前提条件有些地方可能对于二分查找算法的前提条件要求必须是有序的待查找数组,如果数组无序则不能使用二分查找。但实际上并不是“必须有序”才能使用,只要待查找数组满足二段性,可以将数组分成两个区间,这两个区间中的子数组又是有序的,同样可以使用二分查找,在后面的一些例题中就有这样的使用。算法步骤这里不具体讲解,直接在后面通过模板来讲

2301_82347435的博客 1413

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

二分查找——部分题目汇总——长长文详细分享

5道二分查找题目整理和分享

bestme 1996

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

常用算法整理:二分查找

基础二分查找二分查找是大家最常用的也是最简单的一种算法。二分查找在面试中是非常常见的一题,而且很多时候二分查找是时间效率最高的一种搜索方式。最简单的二分查找就是查找有序不重复数组中给定值的位置,基本模板如下:var search = function(nums, target) { var s = 0, e = nums.length - 1, m; while(s+1<e) {

言川的博客 1077

二分查找六题通关:从标准模板到旋转数组(Python + C++)

本文整理了6道经典二分查找题目,涵盖标准模板、边界查找、旋转数组等核心考点。每道题包含题目描述、解题思路、图解示意、Python/C++代码实现和复杂度分析。通过704题掌握标准二分模板,35题学习插入位置处理,34题练习左右边界查找,33和153题解决旋转数组问题,69题拓展平方根计算。掌握这6题可系统提升二分查找能力,应对大多数变体问题。

qq_43441284的博客 974

算法刷题重温(七): 二分查找

1. 写在前面 今天复习二分查找,二分查找看似简单,其实变形和细节很多, 所以一定要把握住一个核心叫做:循环不变量,关于这个东西的解释,可以参考这篇文章。这里不解释这个了, 之前我也看过东哥写的算法小抄上的框架模板, 东哥也解释的很清楚,最后还统一了一种写法, 这个看个人习惯和理解吧, 通过之前的刷题,我还是习惯先记忆两种解题思路,每一种思路又有两种代码框架的写法,所以再记住这两种写法,相当于4个代码框架, 就基本能应付这一块的题目了, 我觉得既然是总结,这次应该先从宏观的思路入手,再去分析框架代码的写法,

Miracle8070 994

二分查找、数组交集与环形链表:算法面试三大高频题型解析

二分查找作为O(logN)时间复杂度的经典算法,通过分治策略快速定位目标值,是处理有序数据集的核心技术。双指针技巧在数组交集等问题中展现高效的去重与遍历能力,而快慢指针法则为环形链表检测提供了空间最优解。这些基础算法不仅是大厂面试的高频考点,更可组合应用于实际工程场景,如美团2023校招笔试中的场次安排问题就融合了二分与双指针思想。掌握这些算法的工业级实现与边界处理,能有效提升代码健壮性,其中防溢出计算、哈希去重优化等技巧尤为关键。

weixin_34248487的博客 358

LeetCode算法题整理(200题左右)

Leetcode

qq_38253797的博客 1万+

Leetcode算法题解整理之二分专题部分

算法题解之二分专题 二分查找算法模板 二分模板一共有两个,分别适用于不同情况。 算法思路:假设目标在闭区间[l,r],每次将区间长度缩小一半,当l = r时,我们就找到了目标值。 版本1: 当我们将区间[l,r]划分成[l,mid]和[mid + l, r]时,其更新操作是r= mid或者l = mid + 1;计算mid时不需要加1 C++代码模板: int bsearch_1(int l, int r) { while (l < r) { int mid = l + r >>

weixin_43488529的博客 268

二分查找算法在编程竞赛中的实战应用与优化

二分查找是一种基于分治思想的高效搜索算法,其核心原理是通过不断缩小搜索范围来快速定位目标元素。该算法的时间复杂度为O(log n),在处理大规模数据时优势明显。在工程实践中,二分查找不仅用于有序数组查询,还广泛应用于网络延迟优化、资源分配等场景。编程竞赛中常见的变种包括旋转数组搜索、峰值查找、带权二分等,这些都需要对标准算法进行创造性改造。通过维护循环不变式、处理边界条件和优化判定函数,可以解决算法实现中的死循环和精度问题。掌握lower_bound、upper_bound等标准实现,以及二维矩阵搜索等高级

weixin_33859844的博客 314

leetcode二分查找问题整理

自从做完leetcode上的三道关于二分查找的题后,我觉得它是比链表找环还恶心的题,首先能写出bugfree代码的人就不多,而且可以有各种变形,适合面试的时候不断挑战面试者,一个程序猿写代码解决问题的能力都能在这个过程中考察出来。 在有序数组中寻找等于target的数的下标,没有的情况返回应该插入的下标位置 :http://oj.leetcode.com...

weixin_33739523的博客 90
上一篇: 正则表达式 -- 一文成为正则老司机
下一篇: 算法之单调栈的使用总结(含接雨水、柱状图等经典问题)
Elmerr
博客等级 码龄12年 178粉丝 33原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值