(C语言版)力扣(LeetCode)面试题 17.04. 消失的数字5种解法

news2025/1/21 12:20:19

在这里插入图片描述

消失的数字

  • 题目介绍
  • 第一种解法:按位异或
  • 第二种解法:公式运算
  • 第三种解法:临时数组
  • 第四种解法:相加再相减
  • 第五种解法:快排加二分查找
  • 结语

题目介绍

该题目取自力扣(LeetCode)面试题 17.04. 消失的数字
链接:消失的数字
该题目主要考察时间复杂度的把握,题目如下:
数组nums包含从0到n的所有整数,但其中缺了一个。请编写代码找出那个缺失的整数。你有办法在O(n)时间内完成吗?
注意:本题相对书上原题稍作改动
示例 1:
输入:[3,0,1]
输出:2
示例 2:
输入:[9,6,4,2,3,5,7,0,1]
输出:8
提示1:
你需要多长时间才能算出缺失数字的最小有效位?
提示2:
要找到缺失的数字中的最小有效位,你其实知道有多少个 0 和 1。例如,如果你看到最小有效位有 3 个 0 和 3 个 1,那么缺失的数字的最小值必定是 1。想想看:在任何 0 和 1 的序列中,你会得到 0,然后是 1,然后又是 0,然后又是 1,以此类推。
提示3:
一旦确定最小有效位是 0(或 1),就可以排除所有不以 0 作为最小有效位的数。这个问题和前面的有什么不同?

第一种解法:按位异或

这个解法我们先看一张图:
在这里插入图片描述
这种算法的思路主要是先设临时变量x=0,让它与nums数组中的数遍历按位异或,
此时x保存按位异或的值,再与0-n按位异或,最后得到的值就是缺的那个数字。
代码如下:

int missingNumber(int* nums, int numsSize){
    int misNum = 0;
    for(int i = 0; i < numsSize; i++)
    misNum ^= nums[i];
    for(int j = 0; j < numsSize + 1; j++)
    misNum ^= j;
    return misNum;
}

这里主要是利用了按位异或的特性,任何数与他本身按位异或得到的就是0;
那么在这里x按位异或了本身缺失数字的数组nums,再按位异或0-n的数字,
最后剩下的自然就是缺失的数字了。
时间复杂度:O(n)
空间复杂度:O(1)

第二种解法:公式运算

在这里插入图片描述
我们可以先看一张图,我们知道0-n在数学当中是一个自然数数列,那么他的前n项和公式就可以简化为[n(n-1)d]/2,那么这里的思路就是利用数列的前n项和公式先计算出0-n的总和,再建立一个临时变量k,利用一个for循环将nums中的元素逐个相加,最后两数相减得到的自然就是消失的数了。
代码如下:

int missingNumber(int* nums, int numsSize){
    int misNum = (numsSize+1)*numsSize/2;
    int k=0;
    for(int j = 0; j < numsSize; j++)
    k+=nums[j];
    misNum = misNum-k;
    return misNum;
}

时间复杂度:O(n)
空间复杂度:O(1)

第三种解法:临时数组

在这里插入图片描述
这里的思路就是用空间换时间,首先我们建立一个临时数组temp,使用malloc函数进行动态内存分配,临时数组temp比初始数组要多一个元素位置,然后将每一个位置都赋值为-1(因为nums是0-n,只有负数不会重复,想给负多少都可以),再将nums中的元素利用for循环逐个找到temp中对应下标进行赋值,最后剩下的-1所对应的下标即为消失的数字,最后再用for循环遍历数组,找到值为-1的元素下标,返回下标即为消失的数字(别忘记把temp的空间释放,否则会造成内存泄露的问题)。
代码如下:

int missingNumber(int* nums, int numsSize)
{
    int* temp = (int*)malloc(sizeof(int) * (numsSize + 1));
    if (temp == NULL)
    {
        perror("missingNumber::malloc");
        return 0;
    }
    int i = 0;
    for (i = 0; i < numsSize + 1; i++)
    {
        *(temp+i) = -1;
    }
    for (i = 0; i < numsSize; i++)
    {
        temp[*nums] = *nums;
        nums++;
    }
    for (i = 0; i < numsSize + 1; i++)
    {
        if (*(temp + i) == -1)
        {
            free(temp);
            temp == NULL;
            return i;
        }
    }
    return ;
}

时间复杂度:O(n)
空间复杂度:O(n)

第四种解法:相加再相减

这种方法和公式法类似,这个的好处在于不用怎么动脑子,简单粗暴,先设立临时变量misNum,让misNum和0-n的值逐个相加,再利用一个for循环对nums数组进行遍历相减,最后得到的misNum的值即为消失的数。
代码如下:

int missingNumber(int* nums, int numsSize){
    int misNum = 0;
    for(int j = 0; j < numsSize + 1; j++)
    misNum += j;
    for(int i = 0; i < numsSize; i++)
    misNum -= nums[i];
    return misNum;
}

时间复杂度:O(n)
空间复杂度:O(1)

第五种解法:快排加二分查找

这种方法需要学到后序的数据结构中快速排序的知识,如果尚未学习,可以只参照前面4种解法,后续我还会出单独的板块介绍各类排序。

快速排序使用了“分治法”和“递归”技巧,将一个数组分成两个子数组,其中一个子数组的所有元素都小于另一个子数组的所有元素,并按照同样的方式对这两个子数组进行排序。快速排序中的关键步骤是“Partition(划分)”函数,它选择一个pivot(枢轴),然后通过交换元素的方式,将数组分成两个部分。

在该代码的“Partition”函数中,我们选择第一个元素为枢轴(pivot),然后使用两个指针low和high,从数组的两端开始遍历数组,交换两个指针所指的元素,以保证左侧的元素小于pivot,右侧的元素大于pivot。最后,将枢轴元素放在正确的位置上。

在“QuickSort”函数中,我们使用“Partition”函数将数组划分为两个子数组,然后对这两个子数组递归地进行排序。

在“missingNumber”函数中,我们先对输入数组进行排序,然后使用二分查找的技巧来找到缺失的数字。具体来说,我们定义左侧指针为0,右侧指针为数组的长度,然后计算中间位置mid,如果mid处的元素等于mid,则说明缺失的数字在mid的右侧,我们将左指针移到mid的右侧,否则缺失的数字在mid的左侧,我们将右指针移到mid的左侧。最终,左侧指针指向的位置就是消失的数字。
代码如下:

 int Partition(int *A, int low, int high){
    int pivot=A[low];
    while(low<high){
        while(low<high && A[high]>=pivot) high--;
        A[low]=A[high];
        while(low<high && A[low]<=pivot) low++;
        A[high]=A[low];
    }
    A[low]=pivot;
    return low;
 }

 void QuickSort(int *A, int low, int high){
    if(low<high){
        int PartitionPos = Partition(A,low, high);
        QuickSort(A,low,PartitionPos-1);
        QuickSort(A,PartitionPos+1, high);
    }

 }

int missingNumber(int* nums, int numsSize){
    QuickSort(nums, 0, numsSize-1);
    int left=0, right=numsSize;
    while(left<right){
        int mid=left+(right-left)/2;
        if(nums[mid]==mid){
            left=mid+1;
        }
        else{
            right=mid;
        }
    }
    return left;

}

时间复杂度:O(nlogn)
空间复杂度:O(1)

需要注意的是,这个题目在不考虑时间复杂度的情况下,可以使用别的排序方法,比如,冒泡排序,但是它的时间复杂度为O(n*2),因此不符合本题题意,不过有兴趣的小伙伴可以试一试。

结语

在后续更新中,我会一直写关于OJ题的题解,有兴趣的小伙伴可以关注作者,和作者讨论其他OJ题目,如果觉得内容不错,请给个一键三连吧,蟹蟹你哟!!!

制作不易,如有不正之处敬请指出
感谢大家的来访,UU们的观看是我坚持下去的动力
在时间的催化剂下,让我们彼此都成为更优秀的人吧!!!
在这里插入图片描述

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

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

相关文章

Direct3D 12——灯光——光照模型的概述

将之前所述的所有光照内容都结合起来&#xff0c;即表面反射的光量相当于环境反射光、漫反射光以及 镜面反射光的光量总和。 1.环境光Ca&#xff1a;模拟经表面反射的间接光量。 2.漫反射光Cd&#xff1a;对进入介质内部&#xff0c;又经过表面下吸收而最终散射岀表面的光进行…

盐边县高堰沟灌区综合信息化管理系统及平台建设-案例分享

项目背景 盐边县南部降雨逐年减少&#xff0c;可用水源有限&#xff0c;部分村庄的水源取自仅20亩的山坪塘&#xff0c;常常因降雨量小而蓄不满水&#xff0c;出现“人争水、地缺水”的现象&#xff0c;且支渠及以下渠系基本为土渠&#xff0c;渗漏损失严重。为解决不同程度的工…

解决魔兽世界wow中鼠标莫名其妙消失或自动跳回屏幕中间等类似问题整理

魔兽世界已经离开中国大陆~~&#xff0c;最近在玩xxx&#xff0c;咳咳&#xff0c;突然发现一个远古问题&#xff0c;一直以为是自己的鼠标问题&#xff0c;但这么多年换了这么多台电脑&#xff0c;这个问题也一直存在&#xff0c;今天突发奇想查了一下&#xff0c;结果竟然有答…

能聊天、会学习,远不是GPT的终局

自然语言处理&#xff08;NLP&#xff09;技术的发展和运用&#xff0c;使得计算机性能增长速度一举跃过摩尔定律瓶颈&#xff0c;将AI拱入属于它的高光时代。而象征技术融合的ChatGPT一夜爆红&#xff0c;仿佛给整个商业社会带来了一次“技术革命”。 微软、谷歌、百度、华为…

C++ 23 实用工具(二)绑定工具

C 23 实用工具&#xff08;二&#xff09;绑定工具 Adaptors for Functions std::bind、std::bind_front、std::bind_back和std::function这四个函数非常适合一起使用。 其中&#xff0c;std::bind、std::bind_front和std::bind_back可以让您即时创建新的函数对象&#xff0c…

一文! 解决镜像法,电轴法在电磁场中的应用

目录 镜像法原理 例题 模型一&#xff1a;无限大导体平面 一些理解 模型二&#xff1a;球面镜像 情况一&#xff1a;球壳接地 同样的几点思考&#xff1a; 情况二&#xff1a;球壳不接地 球壳不接地&#xff0c;但是点电荷放置在内部 镜像法在双层介质中的作用 电轴法…

C++017-C++指针及其应用

文章目录C017-C指针及其应用C指针及其应用CSP-J目标1. 指针1.指针变量的定义、赋值2.指针的引用与运算2. 基于指针的数组访问3. 指针与字符串4. 结构体与指针在练习&#xff1a;总结C017-C指针及其应用 在线练习&#xff1a; http://noi.openjudge.cn/ https://www.luogu.com.c…

设计师都在用的6个免费设计素材网站~

本期给大家推荐几个设计师都在用的素材网站&#xff0c;免费下载&#xff0c;赶紧收藏起来吧~ 1、菜鸟图库 https://www.sucai999.com/?vNTYwNDUx 菜鸟图库是我推荐过很多次的网站&#xff0c;主要是站内素材多&#xff0c;像平面、UI、电商等设计素材都能找到&#xff0c;还…

零售数据可视化|人、货、场、供、财报表分享

有没有零售数据可视化的例子&#xff0c;让大家看看BI零售数据可视化的效果&#xff1f;有&#xff0c;奥威BI零售标准方案提供了数十张BI数据可视化报表&#xff0c;覆盖人、货、场、供、财等核心业务&#xff0c;既可以让大家一次性体验零售数据可视化报表效果&#xff0c;也…

vLive带你走进虚拟直播世界

虚拟直播是什么&#xff1f; 虚拟直播是基于5G实时渲染技术&#xff0c;在绿幕环境下拍摄画面&#xff0c;通过实时抠像、渲染与合成&#xff0c;再推流到直播平台的一种直播技术。尽管这种技术早已被影视工业所采用&#xff0c;但在全民化进程中却是困难重重&#xff0c;面临…

GEE:Gmeans

G-means是一种聚类算法,它是基于K-means算法的改进版本。K-means算法的一个主要缺点是需要事先指定聚类的数量,而G-means算法则可以自动确定聚类的数量。 G-means算法使用了类似于K-means的迭代过程,但在每次迭代时,它会检查每个聚类是否可以继续细分为两个子聚类。这个检…

怎么免费制作logo?logo免费设计在线生成,从此设计不求人

你有没有因为Logo制作而烦恼过&#xff1f;对于很多人来说&#xff0c;logo制作是一项比较大的工程&#xff0c;需要专门的设计师才能完成。但是请人设计费用高还很费时间&#xff0c;还需多次沟通修改。其实&#xff0c;我们可以自己免费制作logo&#xff0c;下面&#xff0c;…

pytorch2.0 起步

参考&#xff1a;https://pytorch.org/get-started/pytorch-2.0/#ask-the-engineers-20-live-qa-series 总览 特性 fastermore pythonicas dynamic as ever torch.compile&#xff0c;部分零件由C迁移到Python,加强torch.compile的新技术有TorchDynamo, AOTAutograd, PrimT…

第十八章 React中的样式模块化处理

在React中组件如何使用本地的样式&#xff0c;而不对其他组件产生影响呢&#xff1f;我们这里需要使用样式的模块化处理&#xff0c;使得组件的样式只在该组件内部起作用。 这里我们通过两个组件应用说明。 定义组件 定义Hello组件与自定义样式 Hello/index.css .title{co…

Win 11 上在VMware 15安装时Ubuntu20.04注意事项(避坑必看)

遇到的问题 https://zhuanlan.zhihu.com/p/141033713 win11不兼容vm–VMware Workstation 与 Device/Credential Guard 不兼容。 https://zhuanlan.zhihu.com/p/428362751 打开控制面板-程序-启用或关闭Windows功能&#xff0c;发现win11没有Hyper-V&#xff0c;别慌&#xf…

算法设计 - 二分法和三分法,洛谷P3382

二分法 二分查找&#xff1a;找目标值位置 二分法是一种适用于特殊场景下的分治算法。 这里的特殊场景指的是&#xff0c;二分法需要作用在一个具有单调性的区间内。 比如&#xff0c;我们熟知的二分查找&#xff0c;就是一种二分法的具体实现&#xff0c;二分查找必须在一…

【云原生】阿里云ACK部署MySQL 数据持久化存储

思路图 一、概述 ACK介绍 阿里云容器服务Kubernetes版(Alibaba Cloud Container Service for Kubernetes,简称容器服务ACK)是全球首批通过Kubernetes一致性认证的服务平台,提供高性能的容器应用管理服务,支持企业级Kubernetes容器化应用的生命周期管理,轻松高效地在云端…

MAE论文阅读《Masked Autoencoders Are Scalable Vision Learners》

文章目录动机方法写作方面参考Paper: https://arxiv.org/pdf/2111.06377.pdf 动机 首先简要介绍下BERT&#xff0c;NLP领域的BERT是基于Transformer架构&#xff0c;并采取无监督预训练的方式去训练模型。它提出的预训练方法在本质上是一种masked autoencoding&#xff0c;也就…

【CSS】定位 ⑤ ( 子元素绝对定位 父元素相对定位 | 代码示例 )

文章目录一、子元素绝对定位 父元素相对定位二、代码示例一、子元素绝对定位 父元素相对定位 绝对定位 要和 带有定位 的 父容器 搭配使用 ; 子元素 使用绝对定位 , 父元素要使用 相对定位 ; 子元素使用 绝对定位 , 在布局中不会保留其位置 , 子元素完全依赖 父容器 的位置 ,…

阿里巴巴春招的后端面经来啦~

操作系统 一个操作系统&#xff0c;我们在衡量它的内存占用的时候&#xff0c;它一般会有哪些内存的部分&#xff1f; 读者答&#xff1a;堆和栈 补充&#xff1a; 这个其实是问你对free命令的理解。 主机的内存做一些清理的动作。你知道这里面会涉及到对哪些内存区域进行操…