二分查找算法——点名

一.题目描述

LCR 173. 点名 - 力扣(LeetCode)

二.题目解析

有0~n-1这n个数,但是数组中只有n-1个数,我们要找到消失的那个数。

三.算法原理

1.哈希表

我们先创建一个n个数的哈希表并初始化为0,然后将数组中的数存放到哈希表中,然后遍历哈希表,找到那个value为0的key,返回key即可。

2.直接遍历

学号是从0~n-1,数组的下标也是从0开始,所以学号和数组的下标是相同的。如果我们在遍历的过程中遇到下标和学号不相等,说明这里就缺少了一个数。而数组的下标是严格递增的,所以当前位置的下标就是缺失的数字。

边界情况:如果我们缺少的是最后一个数,在遍历的过程中,不会退出循环,直到循环结束。此时下标i就是结果。为什么呢?一共有0~n-1这n个数,数组有n-2个数,数组的下标与学号是统一的,说明0~n-2个数都在数组中,那么缺少的数就是n-1。而此时退出循环,i刚好就是n-1,所以我们返回下标即可。

3.位运算

我们可以将该题转化成“单身狗”问题。我们可以用一个变量ret = 0,与数组的每一个元素异或,然后再与0~n-1这n个数异或,此时异或后的结果就是缺失的数字。

4.利用数学公式

我们先将0~n-1这n个数的和求出来,然后减去数组的和,剩下的就是丢失的数

5.二分查找算法

我们观察数组元素与其下标之间的关系:

数组下标与其元素要么相等,要么不相等,这个性质就将数组分为了两端,此时数组呈现出二段性,我们就可以使用二分查找算法来解决。

 我们观察上图可以发现,在根据二段性分成的两个区间中,右区间的左端点的下标就是缺失的数,所以我们要寻找右区间的左端点。

 但是我们需要注意边界情况:如果数组的下标和元素都是一一对应的,那么此时left和right会在数组的结束位置,但此时的下标并不是结果,下标+1才是结果。

此时我们需要判断,如果结束位置的下标和元素相等,那么就是遇到了边界情况,返回下标+1. 

对上面算法的时间和空间复杂度进行分析:

时间复杂度:1~4这几种算法本质上都至少要遍历一次数组,所以其时间复杂度为O(N),而二分算法每一次可以排除一半的数据,所以其时间复杂度为O(logN)

空间复杂度:法一哈希表的方式开了一个大小为n的数组用来模拟哈希表,所以它的空间复杂度为O(N),其他算法的空间复杂度都为O(1) 

四.代码实现

python代码只给出最优的二分写法

// C++

class Solution
{
public:
    //法一:哈希表
    int takeAttendance(vector<int>& records)
    {
        int ret = -1;
        vector<int> v(records.size() + 1, 0);
        for (auto e : records)v[e] = 1;

        for (int i = 0; i < v.size(); ++i)
        {
            if (v[i] == 0) ret = i;
        }
        return ret;
    }

    //法二:直接遍历
    int takeAttendance(vector<int>& records)
    {
        int i = 0;
        for (i = 0; i < records.size(); ++i)
        {
            if (i != records[i]) break;
        }
        return i;
    }

    //法三:位运算——单身狗
    int takeAttendance(vector<int>& records)
    {
        int ans = 0;
        for (auto e : records) ans ^= e;
        for (int i = 0; i < records.size() + 1; ++i) ans ^= i;
        return ans;
    }

    //法四:数学求和公式
    int takeAttendance(vector<int>& records)
    {
        int n = records.size() + 1; // 总数
        int ret = (0 + n - 1) * n / 2;
        for (int i = 0; i < records.size(); ++i) ret -= records[i];
        return ret;
    }

    //法五:二分查找算法
    int takeAttendance(vector<int>& records)
    {
        int left = 0;
        int right = records.size() - 1;
        while (left < right)
        {
            int mid = left + (right - left) / 2;
            if (records[mid] == mid) left = mid + 1;
            else right = mid;
        }
        //细节问题:left走到右端点后,有可能数组完全有序:[0,1,2,3],此时我们要返回的是left+1
        //其他情况,下标就是结果
        if (left == records[left]) return left + 1;
        return left;
    }
};
# python

class Solution:
    def takeAttendance(self, records: List[int]) -> int:
        left,right = 0,len(records)-1
        while left<right:
            mid = left+(right-left)//2
            if mid == records[mid]:
                left = mid+1
            else:
                right = mid
        return left+1 if left == records[left] else left

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

FIDO2密码钥匙与无密码认证:打造安全便捷的数字世界

在数字化时代&#xff0c;密码曾被视为网络安全的基石&#xff0c;但随着网络攻击手段日益复杂&#xff0c;传统的密码认证方法越来越无法抵御这些挑战。对于用户来说&#xff0c;登录密码不仅繁琐易忘&#xff0c;而且一旦泄露&#xff0c;往往会导致数据泄露&#xff0c;造成…

Jmeter进行http接口并发测试

目录&#xff1a; 1、Jmeter设置&#xff08;1&#xff09;设置请求并发数&#xff08;2&#xff09;设置请求地址以及参数&#xff08;3&#xff09;添加结果数 2、启动看结果 1、Jmeter设置 &#xff08;1&#xff09;设置请求并发数 &#xff08;2&#xff09;设置请求地址…

osg中实现模型的大小、颜色、透明度的动态变化

以博饼状模型为对象,实现了模型大小、颜色、透明度的动态变化。 需要注意的是一点: // 创建材质对象osg::ref_ptr<osg::Material> material = new osg::Material;material->setDiffuse(osg::Material::FRONT_AND_BACK, osg::Vec4(0.0, 1.0, 0.0, 0.5));// 获取模型的…

VSCode使用纪要

1、常用快捷键 1&#xff09;注释 ctrl? 单行注释&#xff0c; altshifta 块注释&#xff0c; 个人测试&#xff0c;ctrl? 好像也能块注释 2&#xff09;开多个项目 可以先开一个新窗口&#xff0c;再新窗口打开另一个项目&#xff0c;这时就是同时打开多个项目了。 打开…

Jmeter 简单使用、生成测试报告(一)

一、下载Jmter 去官网下载&#xff0c;我下载的是apache-jmeter-5.6.3.zip&#xff0c;解压后就能用。 二、安装java环境 JMeter是基于Java开发的&#xff0c;运行JMeter需要Java环境。 1.下载JDK、安装Jdk 2.配置java环境变量 3.验证安装是否成功&#xff08;java -versio…

Linux 服务器挖矿木马防护实战:快速切断、清理与加固20250114

Linux 服务器挖矿木马防护实战&#xff1a;快速切断、清理与加固 引言 挖矿木马作为一种常见的恶意软件&#xff0c;对服务器资源和安全构成严重威胁。据安全机构统计&#xff0c;2023 年全球约 45%的 Linux 服务器遭受过挖矿木马攻击&#xff0c;平均每台被感染服务器每月造…

Linux Kernel 之十 详解 PREEMPT_RT、Xenomai 的架构、源码、构建及使用

概述 现在的 RTOS 基本可以分为 Linux 阵营和非 Linux 阵营这两大阵营。非 Linux 阵营的各大 RTOS 都是独立发展,使用上也相对独立;而 Linux 阵营则有多种不同的实现方法来改造 Linux 以实现实时性要求。本文我们重点关注 Linux 阵营的实时内核实现方法! 本文我们重点关注 …

计算机网络(四)——网络层

目录 一、功能 二、IP数据报分片 三、DHCP动态主机配置协议 四、网络地址转换&#xff08;NAT&#xff09;技术 五、无分类编址CIDR 六、ARP地址解析协议 七、ICMP网际控制报文协议 八、IPv4和IPv6的区别 九、IPv4向IPv6的两种过渡技术——双栈协议和隧道技术 十、路由…

apache-skywalking-apm-10.1.0使用

apache-skywalking-apm-10.1.0使用 本文主要介绍如何使用apache-skywalking-apm-10.1.0&#xff0c;同时配合elasticsearch-8.17.0-windows-x86_64来作为存储 es持久化数据使用。 步骤如下&#xff1a; 一、下载elasticsearch-8.17.0-windows-x86_64 1、下载ES(elasticsear…

CVE-2025-22777 (CVSS 9.8):WordPress | GiveWP 插件的严重漏洞

漏洞描述 GiveWP 插件中发现了一个严重漏洞&#xff0c;该插件是 WordPress 最广泛使用的在线捐赠和筹款工具之一。该漏洞的编号为 CVE-2025-22777&#xff0c;CVSS 评分为 9.8&#xff0c;表明其严重性。 GiveWP 插件拥有超过 100,000 个活跃安装&#xff0c;为全球无数捐赠平…

【声音场景分类--论文阅读】

1.基于小波时频图特征在声音场景分类 基于小波时频图特征在声音场景分类任务中的表现 2.增强增强高效音频分类网络 https://arxiv.org/pdf/2204.11479v5 https://github.com/Alibaba-MIIL/AudioClassfication 音频分类网络如图4所示。在此阶段&#xff0c;主要重点是建立一…

java导出pdf文件

java导出pdf&#xff0c;前端下载 1、制作pdf模板2、获取pdf导出中文需要的文件3、实现4、前端发起请求并生成下载链接 使用注意点 因为原来制作的pdf表单内容过于复杂&#xff0c;下面代码只包含前两行的操作。 本次操作需要前端向后端发起请求&#xff0c;后端返回数据给前端…

1月13日学习

[HITCON 2017]SSRFme 直接给了源代码&#xff0c;题目名称还是ssrf&#xff0c;那么该题大概率就是SSRF的漏洞&#xff0c;进行代码审计。 <?php// 检查是否存在 HTTP_X_FORWARDED_FOR 头&#xff0c;如果存在&#xff0c;则将其拆分为数组&#xff0c;并将第一个 IP 地址…

在一个sql select中作多个sum并分组

有表如下&#xff1b; 单独的对某一个列作sum并分组&#xff0c;结果如下&#xff1b; 对于表的第7、8行&#xff0c;num1都有值&#xff0c;num2都是null&#xff0c;对num2列作sum、按id分组&#xff0c;结果在id为4的行会显示一个null&#xff1b; 同时对2个列作sum&#x…

[Deep Learning] Anaconda+CUDA+CuDNN+Pytorch(GPU)环境配置-2025

文章目录 [Deep Learning] AnacondaCUDACuDNNPytorch(GPU)环境配置-20250. 引子1. 安装Anaconda1.1 安装包下载&#xff1a;1.2 启用安装包安装1.3 配置(系统)环境变量1.4 验证Anaconda是否安装完毕1.5 Anaconda换源 2. 安装CUDACuDNN2.1 判断本机的CUDA版本2.2 下载适合自己CU…

不需要配置文件实现Javaweb项目的启动

1.首先看一下web.xml主要配置内容 <?xml version"1.0" encoding"UTF-8"?> <web-app xmlns"http://xmlns.jcp.org/xml/ns/javaee"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://xm…

【网络篇】IP知识

IPv4首部与IPv6首部 IPv4相对于IPv6的好处&#xff1a; 1.IPv6可自动配置&#xff0c;即使没有DHCP服务器也可以实现自动分配IP地址&#xff0c;实现即插即用。 2.IPv6包首部长度采用固定40字节&#xff0c;删除了选项字段&#xff0c;以及首部校验和&#xff0c;简化了首部…

MyBatis核心流程

目录 数据处理的发展 MyBatis概述 ​编辑 MyBatis核心流程 观察测试类 重要对象和流程 SqlSessionFactory [初始化] 创建SqlSession会话对象 创建XxxMapper[代理]对象 执行SQL操作 [复杂一丢丢] ​编辑 数据处理的发展 1.原生JDBC 2. DBUtils工具类 [jdbctemp..] 3. …

低代码独特架构带来的编译难点及多线程解决方案

前言 在当今软件开发领域&#xff0c;低代码平台以其快速构建应用的能力&#xff0c;吸引了众多开发者与企业的目光。然而&#xff0c;低代码平台独特的架构在带来便捷的同时&#xff0c;也给编译过程带来了一系列棘手的难点。 一&#xff0c;低代码编译的难点 &#xff08;1…

Spring Security单点登录

本文介绍了Spring Security单点登录的概念和基本原理。单点登录是指用户只需登录一次&#xff0c;即可在多个相互信任的系统中实现无缝访问和授权。通过Spring Security框架的支持&#xff0c;可以实现有效的用户管理和权限控制。最后&#xff0c;本文提供了实际应用案例&#…