[二分查找] 旋转数组

news2024/11/28 22:42:18

1. (严格递增序列)旋转数组的元素查找

 简单来说分为三种情况进行分析

1. 整个旋转数组单调递增

根据x和A[mid]的大小关系,更迭范围。

        // 1. 整个旋转数组单调递增
        if (A[left]<A[right]){
            if (A[mid] == x)return mid;
            else if (x < A[mid])right = mid-1;
            else if (x > A[mid])left = mid+1;
        }

2. 旋转数组分为两个递增序列,mid位于第一个递增序列当中

mid将旋转数组分为两块区间,但第一块区间的值的条件并不是简单的x<A[mid],因为小于A[mid]的元素还有可能为最下面的区间,如图。

        // 2. 旋转数组分为两个递增序列,mid位于第一个递增序列当中
        if (A[mid]>A[left]){
            if (x == A[mid])return mid;
            else if (x<A[mid] && x >= A[left]){
                right = mid-1;
            }else{
                left = mid+1;
            }
        }

 3. mid位于第二个递增序列当中

        // 3. 旋转数组分为两个递增序列,mid位于第二个递增序列当中
        if (A[mid]<A[left]){
            if (x == A[mid])return mid;
            else if (x>A[mid] && x<=A[right]){
                left = mid+1;
            }else {
                right = mid-1; 
            }
        }

最后的总代码:

#include <cstdio>

const int N= 1e5+10;
int A[N];
int n,x;
int binary_search(int A[],int left,int right,int x){
    int mid;
    while (left < right){
        mid = left + (right-left)/2;
        
        // 1. 整个旋转数组单调递增
        if (A[left]<A[right]){
            if (A[mid] == x)return mid;
            else if (x < A[mid])right = mid-1;
            else if (x > A[mid])left = mid+1;
        }
        // 2. 旋转数组分为两个递增序列,mid位于第一个递增序列当中
        if (A[mid]>A[left]){
            if (x == A[mid])return mid;
            else if (x<A[mid] && x >= A[left]){
                right = mid-1;
            }else{
                left = mid+1;
            }
        }
        // 3. 旋转数组分为两个递增序列,mid位于第二个递增序列当中
        if (A[mid]<A[left]){
            if (x == A[mid])return mid;
            else if (x>A[mid] && x<=A[right]){
                left = mid+1;
            }else {
                right = mid-1; 
            }
        }
    }
    if (A[left]==x)return left;
    return -1;
}
int main(){

    scanf("%d%d",&n,&x);
    for (int i=0;i<n;i++)scanf("%d",&A[i]);

    printf("%d",binary_search(A,0,n-1,x));
    return 0;

}

2.(非递减序列)旋转数组的元素查找

思路一致,由于会出现重复的元素,因此,对寻找第一个x的寻找条件进行修改即可。

不过由于非递减的条件不好写,因此我们可以用else来表示

#include <cstdio>

const int N= 1e5+10;
int A[N];
int n,x;
int binary_search(int A[],int left,int right,int x){
    int mid;
    while (left < right){
        mid = left + (right-left)/2;

        // 2. 旋转数组分为两个非递减序列,mid位于第一个非递减序列当中
        if (A[mid]>A[left]){
            if (x == A[mid])right = mid;
            else if (x<A[mid] && x >= A[left]){
                right = mid-1;
            }else{
                left = mid+1;
            }
        }else if (A[mid]<A[left]){
            // 3. 旋转数组分为两个递增序列,mid位于第二个递增序列当中
            if (x == A[mid])right=mid;
            else if (x>A[mid] && x<=A[right]){
                left = mid+1;
            }else {
                right = mid-1;
            }
        }else {
            //1. 整个旋转数组非递减
            if (A[mid] == x)right = mid;
            else if (x < A[mid])right = mid-1;
            else if (x > A[mid])left = mid+1;
        }
    }
    if (A[left]==x)return left;
    return -1;
}
int main(){

    scanf("%d%d",&n,&x);
    for (int i=0;i<n;i++)scanf("%d",&A[i]);

    printf("%d",binary_search(A,0,n-1,x));
    return 0;

}

3. 旋转数组的最小值,通过数组左端元素判断最小值出现的位置

两个代码相同。需要注意 A[left] == A[mid] 的情况,最小值在右侧区间中

#include <cstdio>

const int N= 1e5+10;
int A[N];
int n;
int binary_search(int A[],int left,int right){
    int mid;
    while (left < right){
        mid = left + (right-left)/2;
        // 1. 整个旋转数组单调递增
        if (A[left]<A[right]){
            return A[left];
        }
        // 2. 旋转数组分为两个单调递增序列,mid位于第一个单调递增序列当中
        if (A[mid]>A[left]){
            left = mid+1;
        }else if (A[mid]<A[left]){
            // 3. 旋转数组分为两个递增序列,mid位于第二个递增序列当中
            right = mid;
        }else if(A[mid]==A[left]){
            // A[left] == A[mid] 的情况,最小值在右侧区间中
            left = mid+1;
        }
        //printf("%d,%d\n",left,right);
    }
    return A[left];
}
int main(){

    scanf("%d",&n);
    for (int i=0;i<n;i++)scanf("%d",&A[i]);

    printf("%d",binary_search(A,0,n-1));
    return 0;

}

4. 旋转数组的中位数

#include <cstdio>

const int N= 1e5+10;
int A[N];
int n;
int binary_search(int A[],int left,int right){
    int mid;
    while (left < right){
        mid = left + (right-left)/2;
        // 1. 整个旋转数组单调递增
        if (A[left]<A[right]){
            return left;
        }
        // 2. 旋转数组分为两个单调递增序列,mid位于第一个单调递增序列当中
        if (A[mid]>A[left]){
            left = mid+1;
        }else if (A[mid]<A[left]){
            // 3. 旋转数组分为两个递增序列,mid位于第二个递增序列当中
            right = mid;
        }else if(A[mid]==A[left]){
            // A[left] == A[mid] 的情况,最小值在右侧区间中
            left = mid+1;
        }
        //printf("%d,%d\n",left,right);
    }
    return left;
}
int main(){

    scanf("%d",&n);
    for (int i=0;i<n;i++)scanf("%d",&A[i]);

    int minpos = binary_search(A,0,n-1);
    //printf("%d",minpos);
    if (n%2==0){
        printf("%.1f",(A[(minpos+n/2)%n]+A[(minpos+n/2)%n-1])/2.0);
    }else {
        printf("%.1f",A[(minpos+n/2)%n]/1.0);
    }
    return 0;

}

 重点在于后面中位数的求解

    if (n%2==0){
        printf("%.1f",(A[(minpos+n/2)%n]+A[(minpos+n/2)%n-1])/2.0);
    }else {
        printf("%.1f",A[(minpos+n/2)%n]/1.0);
    }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/968005.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C语言枚举类型enum详解、枚举变量。枚举函数

文章目录 枚举定义枚举应用枚举函数枚举函数2 枚举定义 关键字&#xff1a;enum 用途&#xff1a;定义一个取值受限制的整型变量&#xff0c;用于限制变量取值范围&#xff1b;宏定义的集合 定义枚举变量&#xff1a; enum{FALSE 0, TRUE 1} EnumName; 因为枚举变量类型较长…

矢量图片转换 Vector Magic for mac

Vector Magic会帮你进行自动识别和分析&#xff0c;转换过程中用户可选择相应的转换级别&#xff0c;从而达到自已所需的效果。 只需上传即可在线自动将 JPG、PNG、BMP 和 GIF 位图图像转换为真正的 SVG、Eps 和 PDF 矢量图像。真正的全彩描摹&#xff0c;无需安装软件&#xf…

java 对IP地址进行排序,或类ip地址的字符串进行排序

java 对IP地址进行排序&#xff0c;或类ip地址的字符串进行排序 排序前先认识一下这个拆分字符串非常好用的类 1.StringTokenizer类 1.1 构造方法 StringTokenizer(String str) &#xff1a;构造一个用来解析 str 的 StringTokenizer 对象。java 默认的分隔符是空格(“”)、…

PHP NBA球迷俱乐部系统Dreamweaver开发mysql数据库web结构php编程计算机网页

一、源码特点 PHP NBA球迷俱乐部系统是一套完善的web设计系统&#xff0c;对理解php编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。 基于PHP的NBA球迷俱乐部 二、功能介绍 1、前台主要功能&#xff1a; 系统首页 网站介…

项目(补充2):智慧教室

一。emWin环境的搭建 1.codeBlock下载 开源免费。 2.使用stm的Cubemx提供的作图软件 &#xff08;1&#xff09;在C盘下找到第三方的固件库&#xff0c;旁边有个ST文件夹 注意&#xff1a;我在下载cubemx为默认的路径 &#xff08;2&#xff09;STemWin中的Soft提供了绘图…

【STM32】学习笔记(EXTI)

EXTI外部中断 中断&#xff1a;在主程序运行过程中&#xff0c;出现了特定的中断触发条件&#xff08;中断源&#xff09;&#xff0c;使得CPU暂停当前正在运行的程序&#xff0c;转而去处理中断程序&#xff0c;处理完成后又返回原来被暂停的位置继续运行 中断优先级&#x…

字符串颜色

字体颜色 30&#xff1a;黑 31&#xff1a;红 32&#xff1a;绿 33&#xff1a;黄 34&#xff1a;蓝色 35&#xff1a;紫色 36&#xff1a;深绿 37&#xff1a;白色 字体背景颜色 40&#xff1a;黑 41&#xff1a;深红 42&#xff1a;绿 43&#xff1a;黄色 44&#xff1a;蓝…

使用 Tkinter 在 Python 中构建井字游戏!

一、说明 做你还记得小时候玩井字游戏吗&#xff1f;这是一个简单的游戏&#xff0c;只需一支笔或铅笔就可以在一张纸上玩。但是你知道你也可以使用Python的Tkinter库创建一个井字游戏吗&#xff1f;在本文中&#xff0c;我们将介绍使用 Tkinter 创建井字游戏的过程。在本文结束…

vue的 ECMAScript 6的学习

一 ECMAScript 6 1.1 ECMAScript 6 ECMAScript 和 JavaScript 的关系是&#xff0c;前者是后者的规格&#xff0c;后者是前者的一种实现&#xff08;另外的 ECMAScript 方言还有 Jscript 和 ActionScript&#xff09;。 因此&#xff0c;ES6 既是一个历史名词&#xff0c;也…

word添加字体库

1001 Fonts ❤ Free Fonts Baby!51044 free fonts in 28637 families Free licenses for commercial use Direct font downloads Mac Windows Linuxhttps://www.1001fonts.com/ 下载字体后复制粘贴到下面的位置&#xff1a;

IDEA自定义模板

IDEA自定义模板 &#xff08;1&#xff09;定义sop模板 ①在Live Templates中增加模板 ②先定义一个模板的组 ③在模板组里新建模板 ④定义模板 Abbreviation:模板的缩略名称Description:模板的描述Template text:模板的代码片段应用范围。比如点击Define。选择如下&…

输出图元(四)8-1 图元、屏幕坐标、指定二维世界坐标系统

用于图形应用的通用软件包称为计算机图形应用编程接口(CCAPI)它提供可以在C等程序设计语言中用来创建图形的函数库。如第3 章所指出的&#xff0c;函数库可以分成几种类型。创建图形时最先要做的一件事就是要描述显示场景的组成部分。图形的组成部分可以是树木和地形家具和墙壁…

无涯教程-JavaScript - CUBEKPIMEMBER函数

描述 该函数返回关键绩效指标(KPI)属性,并在单元格中显示KPI名称。 语法 CUBEKPIMEMBER (connection, kpi_name, kpi_property, [caption])争论 Argument描述Required/OptionalconnectionName of the connection to the cube - A text stringRequiredkpi_nameName of the K…

13. 性能测试

目录 1. 什么是性能测试 1.1 常见的性能问题 1.2 性能测试的概念 1.3 性能测试和功能测试的区别 1.4 性能的好坏如何定义 1.5 影响性能的因素 2. 为什么进行性能测试 3. 性能测试常见专业术语以及衡量指标 4. 性能测试分类 4.1 基准测试 4.2 负载测试 4.3 压力测…

FC-CLIP-卷积永存:开放词汇分割与单一冻结卷积CLIP

论文链接&#xff1a;https://arxiv.org/abs/2308.02487 Github&#xff1a;GitHub - bytedance/fc-clip: This repo contains the code for our paper Convolutions Die Hard: Open-Vocabulary Segmentation with Single Frozen Convolutional CLIP 机构&#xff1a;约翰霍普…

PLL原语例化使用时常见问题

目录 一、前言 二、常见问题 问题一、综合阶段报错[Synth 8-439] 问题二、综合阶段报错[Synth 8-448] 问题三、在实现阶段DRC报错DRC PDRC-38 问题四、在实现阶段DRC报错DRC PDRC-43 一、前言 在设计中经常会使用PLL的原语进行例化使用&#xff0c;PLL如果直接例化使用将…

十二、MySQL(DQL)分组/排序/分页查询如何实现?

总括 select 字段列表 from 表名 [where 条件] (group by)/(order by)/(limit) 分组字段名 分组查询 1、分组查询 &#xff08;1&#xff09;基础语法&#xff1a; select 字段列表 from 表名 [where 条件] group by 分组字段名 [having 分组之后的过滤条件] &#xff08;…

【C++初阶】queue的常见操作和模拟实现以及deque的介绍

&#x1f466;个人主页&#xff1a;Weraphael ✍&#x1f3fb;作者简介&#xff1a;目前学习C和算法 ✈️专栏&#xff1a;C航路 &#x1f40b; 希望大家多多支持&#xff0c;咱一起进步&#xff01;&#x1f601; 如果文章对你有帮助的话 欢迎 评论&#x1f4ac; 点赞&#x1…

相交链表:k神题解的一点小感慨

题目&#xff1a; 给你两个单链表的头节点 headA 和 headB &#xff0c;请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点&#xff0c;返回 null 。 图示两个链表在节点 c1 开始相交&#xff1a; 题目数据 保证 整个链式结构中不存在环。 朴素解法 用…

linux中busybox与文件系统的关系

busybox与文件系统 在 Linux 中&#xff0c;BusyBox 是一个精简的、多功能的工具集合&#xff0c;它包含了一系列常用的命令和实用程序&#xff0c;如 ls、cp、mkdir 等。BusyBox 的目标是提供一个功能完整而又占用空间较小的工具集合&#xff0c;适用于嵌入式系统或资源受限的…