查找算法刷题【二分查找算法】

news2024/9/24 9:24:12

一、原理

        如下图所示的就是二分查找算法的原理:

注意:二分查找算法中一个重要的思想:数组和函数是一样的概念,对可以使用二分法查找要求如下所示。

(1)数组f[i]是有序数组         

(2)函数f(x)是单调的函数

(3)f[i]=d,由x找d容易,由d找x较难

(4)f(x)=y,由x找y容易,由y找x较难

二、代码示例

2.1、二分查找算法对有序数据的查找

#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>


void output(int* arr, int n, int ind) {
    int len = 0;
    for (int i = 0; i < n; i++) {
        len += printf("%4d", i);
    }
    printf("\n");
    for (int i = 0; i < len; i++) printf("-");
    printf("\n");
    for (int i = 0; i < n; i++) {
        if (i == ind) printf("\033[1;32m");
        printf("%4d", arr[i]);
        if (i == ind) printf("\033[0m");
    }
    printf("\n");
    return;
}


/* 二分查找算法 */
int binary_search(int* arry, int len, int findData)
{
    int head = 0, tail = len - 1, mid;
    while (head <= tail)
    {
        mid = (head + tail) / 2;
        printf("\r\n[%d, %d], mid = %d, arr[%d] = %d\n",
                head, tail, mid,
                mid, arry[mid]);
        if (arry[mid] == findData) return mid;
        if (arry[mid] > findData) tail = mid - 1;
        else head = mid + 1;
    }
    return -1;
}


void test(int n)
{
    int findData = 0, ret=0;
    int* arr = (int*)malloc(sizeof(int) * n);
    arr[0] = rand() % 100;
    for (int i = 1; i < n; i++)
    {
        arr[i] = arr[i - 1] + rand() % 100;
    }
    output(arr, n, -1);            //打印数组
    while (~scanf_s("%d", &findData))
    {
        ret = binary_search(arr, n, findData);     //二分法查找
        if (-1 == ret) {
            printf("未找到\r\n");
            break;
        }
        output(arr, n, ret);
    }
    free(arr);
}

运行结果;

2.2、二分查找算法对单调函数的查找

        二分查找算法对函数的查找,就是x取较大值和较小值,然后两者逼近函数的输出值,最终将输出值与目标值对比,只到达到最终的精度要求。

#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>


#define EXP 1e-4       //最后二分法对函数查找的最小精度
#define min(a, b) ((a) < (b) ? (a) : (b))   

double fun(double x) {
    if (x >= 0)     x -= min(x, 3000) * 0.03;
    if (x > 3000)   x -= (min(x, 12000) - 3000) * 0.1;
    if (x > 12000)  x -= (min(x, 25000) - 12000) * 0.2;
    if (x > 25000)  x -= (min(x, 35000) - 25000) * 0.25;
    if (x > 35000)  x -= (min(x, 55000) - 35000) * 0.3;
    if (x > 55000)  x -= (min(x, 80000) - 55000) * 0.35;
    if (x > 80000)  x -= (x - 80000) * 0.45;
    return x;
}

/* 二分查找算法 */
double binary_algorithm(double Belast)
{
    double head = 0, tail = 1000000, mid;    //头为税后最小,尾为税后最大
    while (tail - head >= EXP)               //这里是循环的退出条件,而不是在函数内部
    {
        mid = (head + tail) / 2.0;    
        if (fun(mid) > Belast) tail = mid; 
        else head = mid;
    }
    return head;
}


/* 根据税后收入查税前收入是多少 */
void test1()
{
    double Belast=0.0, Befirst = 0.0;
    printf("\r\n请输入税后收入:");
    while (~scanf_s("%lf", &Belast))
    {
        Befirst = binary_algorithm(Belast);
        if (Befirst == -1) printf("未找到");
        else printf("Befist:%lf\r\n", Befirst);
        printf("\r\n请输入税后收入:");
    }
}


int main()
{
    test1();
    return 0;
}

最终输出结果:

三、二分查找算法的泛式情况

      定义head为数组的头下表,tail为数组的尾部的下表,mid为数组中位数的下表。下面是原始二分法算法,针对“0123456789”形式数组:

while(head <= tail)

{

        mid = (head + tail) / 2;

        if(num[mid] == target)  return true;

        if(num[mid] > target)  tail = mid-1;

        else  head = mid+1;

}

(1)情况一:如果二分查找的问题是“11111111000000”,查找数组中最后一个1的位置。在二分法算法中需要做下面的调整

        head = mid;

        mid = (head + tail + 1) / 2;

(2)情况二:如果二分查找的问题是“00000001111111”,查找数组中第一个1的位置。

        trail= mid

3.1、示例一

        将数组中分为比target大的数,和比target小的数。也就成了“0000001111111”的问题,因为插入数据的下表的索引肯定是中位数靠后一个位置。

/* 使用二分法:有序数组查找是否存在,不存在返回插入位置 */
class Solution {
public:
    int searchInsert(vector<int>& nums, int target) {
        int head = 0, trail = nums.size(), mid;
        while (head < trail)
        {
            mid = (head + trail) / 2;
            if (nums[mid] > target) head = mid + 1;
            else trail = mid;    //找第一个符合要求的元素。
        }
        return head;
    }
};

3.2、示例二

        检查数组中元素出现的次数,就是“1111111000000”的问题。

/* 二分查找法:无限字符串 */
class Solution {
public:
    bool check(string& s, int len)
    {
        int cnt[256] = {0}, k = 0;    //这里cnt必须全部初始化为0
        for (int i = 0; s[i]; i++)
        {
            cnt[s[i]] += 1;
            if (cnt[s[i]] == 1) k+=1;
            if (i >= len)             //这里必须是大于等于
            {
                cnt[s[i - len]] -= 1;
                if (cnt[s[i - len]] == 0) k -= 1;
            }
            if (len == k) return true;
        }
        return false;
    }
    int lengthOfLongestSubstring(string s) {
        int head = 0, trail = s.size(), mid;
        while (head < trail)
        {
            mid = (head + trail + 1) / 2;
            if (check(s, mid)) head = mid;
            else trail = mid - 1;
        }
        return head;
    }
};

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

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

相关文章

mapstruct和lombok同时使用时,转换实体类时数据丢失

全局搜一下maps&#xff0c;找到你进行转换的方法 可以看到新建了TswCaseInfoPlus后直接返回了&#xff0c;说明TswCaseInfoPlus没有set方法&#xff0c;或者说编译后lombok没生效 在pom文件中&#xff0c;编译打包插件中将lombok&#xff0c;mapstruct&#xff0c;lombok-map…

武汉流星汇聚:未来已来,亚马逊多元化战略引领电商行业新纪元

在全球电商的浩瀚星空中&#xff0c;亚马逊无疑是最耀眼的明星之一。凭借其强大的品牌影响力、完善的运营体系以及不断创新的技术应用&#xff0c;亚马逊不仅在美国市场稳坐头把交椅&#xff0c;更在全球范围内不断拓展其业务版图。展望未来&#xff0c;亚马逊的未来发展前景依…

新生开学,需要带的东西有哪些!

每年开学季&#xff0c;先给学子们来个灵魂拷问&#xff1a;你们是否已经做好了迎接新挑战的准备&#xff0c;还是在迷茫中踏入新的征程&#xff1f; 不管怎样&#xff0c;我们先来解决下当下寄件问题。上大学要带啥&#xff1f;行李怎么寄便宜&#xff1f; 寄快递注意事项 …

[论文笔记] LLM-ICL论文:AI模型对prompt格式分隔符的敏感性——结构化Prompt格式

又见惊雷&#xff0c;结构化Prompt格式小小变化竟能让LLM性能波动高达76%&#xff0c;ICLR2024

在Windows上用Visual Studio编译Tesseract

Tesseract是著名的OCR&#xff08;文字识别&#xff09;开源项目。我想自己编译它的源代码。然而总体而言&#xff0c;大型开源项目在Windows上编译多少都会有些磕磕绊绊&#xff0c;如果有幸最后成功了&#xff0c;都值得写一篇文章来纪念一下。这便是本文的由来。 编译环境&…

CRMEB 多店版供应商入驻及管理

一、功能介绍 供应商于移动端提出入驻申请&#xff0c;平台可于入驻申请中审核&#xff0c;审核通过后&#xff0c;该供应商可于平台上架商品。 二、供应商申请 供应商入驻申请 一、功能介绍 平台可以设置商品的供应商&#xff0c;用户下单后由供应商直接发货&#xff0c;自…

FT8493PA-RT隔离型SOP8快充充电器电源IC

FT8493XX&#xff0c;FT8493PA-RT是应用于隔离反激电压变换器的- -款高性能PWM控制器.芯片工作在CCM模式,工作频率随着负载降低而减小.拥有更高的效率,更快的瞬态响应以及更低的待机功耗.同时使用内部抖频技术可以更好的处理ENI. FT8493XX内部集成高压启动可以更快的起机以及更…

智能化Web3:如何利用人工智能优化区块链技术

随着数字技术的飞速发展&#xff0c;Web3和人工智能&#xff08;AI&#xff09;逐渐成为技术创新的两个重要领域。Web3代表了去中心化互联网的未来&#xff0c;而AI则是驱动智能化应用的核心技术。当AI与Web3相结合时&#xff0c;将会对区块链技术的优化产生深远的影响。本文将…

Elastic Stack--介绍及架构部署:ElasticSearch、Kibana、Filebeat的RPM包部署安装及基础使用

前言&#xff1a;本博客仅作记录学习使用&#xff0c;部分图片出自网络&#xff0c;如有侵犯您的权益&#xff0c;请联系删除 学习B站博主教程笔记&#xff1a; 最新版适合自学的ElasticStack全套视频&#xff08;Elk零基础入门到精通教程&#xff09;Linux运维必备—Elastic…

HTML学习笔记——用HTML记录学习过程5-全局属性

全局属性可以用来配置元素的共有行为 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>5-全局属性</title> </head> <body><div>id属性用于指定html元素的唯一id</div>…

Linux常用应急排查命令(持续更新)20240827更

1、history &#xff08;1&#xff09;使用history查看历史命令&#xff0c;分析攻击者使用过何命令 history&#xff08;2&#xff09;但攻击者也能回使用history -c 清除掉历史命令 history -c&#xff08;3&#xff09;使用cat查看cat /root/.bash_history 文件也可以查看…

设计模式-结构型模式-适配器模式

1.适配器模式定义 将类的接口转化为客户期望的另一个接口&#xff0c;适配器可以让不兼容的两个类一起协同工作&#xff1b; 1.1 适配器模式的优缺点 优点 将目标类和适配者类解耦&#xff0c;通过引入一个适配器类来重用现有的适配者类&#xff0c;无需修改原有结构&#x…

有效提高媒体曝光率,智能推荐为什么是“最大的计算系统之一”?

导语&#xff1a;我认为很少有人意识到&#xff0c;推荐系统是世界上构想过的最大的计算系统之一。——Jensen Huang &#xfeff; 在信息过载的时代背景下&#xff0c;智能推荐系统已广泛应用于电子商务、社交媒体、新闻资讯、视频音乐、旅游出行等领域&#xff0c;为用户提…

央行沟通与市场影响以日本央行与黄金市场为例

日本央行加息与市场反应 在近期&#xff0c;日本央行采取了出人意料的行动&#xff0c;将短期利率从0-0.1%上调至0.25%&#xff0c;这是自3月结束长达8年负利率政策以来的第二次加息。这一举动迅速引发了全球市场的关注&#xff0c;尤其是那些依赖低利率环境进行套利交易的市场…

每天学习一个基础算法之选择排序

目录 前言&#xff1a; 一、选择排序的基本思路和实现方法 1、基本思路 2、实现方法 二、选择排序的执行过程示意图 三、选择排序的实现代码 选择排序代码主体&#xff08;以接口函数的形式&#xff09; 测试部分&#xff08;主函数调用&#xff09; 四、对选择排序复杂度的分析…

系统架构师软考重难点划分及学习要点

目录 引言 综合知识 案例分析 案例分析题型及选择策略 历年案例分析题型及分值分布 学习与应试策略 论文 考试规则 写作要求与技巧 忌讳与注意事项 常见题目与考查方向 引言 系统架构师软考是许多IT从业人员进阶的必经之路。面对这门考试&#xff0c;如何有效划分重难…

社区维修平台

TOC springboot0751社区维修平台 第一章 绪 论 1.1背景及意义 系统管理也都将通过计算机进行整体智能化操作&#xff0c;对于社区维修平台所牵扯的管理及数据保存都是非常多的&#xff0c;例如住户管理、社区公告管理、维修工管理、维修订单管理、接单信息管理、订单信息管…

Windows系统安装MySQL

下载MySQL 打开网址MySQL :: Download MySQL Community Server点击图下所示位置Download 进入图下所示界面&#xff0c;点击图下所示位置不登录下载 已下载完成 安装MySQL 将下载好的压缩包解压到一个专门的位置&#xff0c;该软件为绿色版软件&#xff0c;解压即可使用 配置…

SSM课程资源库APP—计算机毕业设计源码23834

目 录 摘要 1 绪论 1.1开发的意义 1.2研究现状 1.3ssm框架介绍 1.3论文结构与章节安排 2 课程资源库APP系统分析 2.1 可行性分析 2.2 系统流程分析 2.2.1 数据流程 3.3.2 业务流程 2.3 系统功能分析 2.3.1 功能性分析 2.3.2 非功能性分析 2.4 系统用例分析 2.5…

如何把多行SQL或多行内容转为一行内容

安装notepad 链接&#xff1a;https://pan.quark.cn/s/b01284447533 提取码&#xff1a;5BEc 行合并 1.选中内容 2. 编辑 --- 行操作 --- 合并行 3.效果