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

这篇具有很好参考价值的文章主要介绍了(C语言版)力扣(LeetCode)面试题 17.04. 消失的数字5种解法。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

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

题目介绍

该题目取自力扣(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 作为最小有效位的数。这个问题和前面的有什么不同?

第一种解法:按位异或

这个解法我们先看一张图:
(C语言版)力扣(LeetCode)面试题 17.04. 消失的数字5种解法
这种算法的思路主要是先设临时变量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)

第二种解法:公式运算

(C语言版)力扣(LeetCode)面试题 17.04. 消失的数字5种解法
我们可以先看一张图,我们知道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)

第三种解法:临时数组

(C语言版)力扣(LeetCode)面试题 17.04. 消失的数字5种解法
这里的思路就是用空间换时间,首先我们建立一个临时数组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们的观看是我坚持下去的动力
在时间的催化剂下,让我们彼此都成为更优秀的人吧!!!文章来源地址https://www.toymoban.com/news/detail-413442.html

到了这里,关于(C语言版)力扣(LeetCode)面试题 17.04. 消失的数字5种解法的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • (C语言版)力扣(LeetCode)189. 轮转数组官方3种解法分析

    题目链接:轮转数组 给定一个整数数组 nums,将数组中的元素向右轮转 k 个位置,其中 k 是非负数。 示例 1: 示例 2: 提示: 1 = nums.length = 105 -231 = nums[i] = 231 - 1 0 = k = 105 进阶: 尽可能想出更多的解决方案,至少有 三种 不同的方法可以解决这个问题。 你可以使用空间复杂度为

    2024年02月05日
    浏览(42)
  • 【LeetCode力扣】面试题 17.14. 最小K个数(top-k问题)

    目录 1、题目介绍 2、解题思路 2.1、优先队列解法 2.2、top-k问题解法 原题链接: 面试题 17.14. 最小K个数 - 力扣(LeetCode)  题目要求非常简短,也非常简单,就是求一组数中的k个最小数。         如果在正常刷题过程中遇到这种题,那么这道题毋庸置疑是秒杀题,使用最

    2024年01月25日
    浏览(42)
  • (C语言版)力扣(LeetCode)栈和队列面试题

    给定一个只包括 ‘(’,‘)’,‘{’,‘}’,‘[’,‘]’ 的字符串 s ,判断字符串是否有效。 有效字符串需满足: 左括号必须用相同类型的右括号闭合。 左括号必须以正确的顺序闭合。 每个右括号都有一个对应的相同类型的左括号。 题目链接: 有效的括号 代码如下:

    2024年02月05日
    浏览(39)
  • 力扣--268丢失的数字(三种解法)

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 给定一个包含 [0, n] 中 n 个数的数组 nums ,找出 [0, n] 这个范围内没有出现在数组中的那个数。 示例 1: 输入:nums = [3,0,1] 输出:2 解释:n = 3,因为有 3 个数字,所以所有的数字都在范围 [0,3] 内。2 是丢

    2024年02月04日
    浏览(37)
  • (C语言版)力扣(LeetCode)数组相关面试题OJ题解析

    给你一个 升序排列 的数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。然后返回 nums 中唯一元素的个数。 考虑 nums 的唯一元素的数量为 k ,你需要做以下事情确保你的题解可以被通过: ★更

    2024年02月03日
    浏览(53)
  • 【leetcode 力扣刷题】移除链表元素 多种解法

    题目链接:203.移除链表元素 题目内容: 理解题意:就是单纯的删除链表中所有值等于给定的val的节点。上一篇博客中介绍了链表的基础操作,在删除链表中节点时,需要注意的是头节点: 如果没有虚拟头节点,那么对头节点的删除需要做不同的处理,head = head-next; 如果有

    2024年02月12日
    浏览(48)
  • 【算法萌新闯力扣】:找到所有数组中消失对数字

      这两天刚交了蓝桥杯的报名费,刷题的积极性高涨。算上打卡题,今天刷了10道算法题了,题目都比较简单,挑选了一道还不错的题目与大家分享。   把数组先排序,然后利用桶排来统计数组中存在的元素,对于数量为0的元素则存入list集合中,最后返回list集合   如果这

    2024年02月04日
    浏览(41)
  • 2235.两整数相加:19种语言解法(力扣全解法)

    力扣题目链接:https://leetcode.cn/problems/add-two-integers/ 给你两个整数  num1 和 num2 ,返回这两个整数的和。   示例 1: 示例 2:   提示: -100 = num1, num2 = 100 时间复杂度 O ( 1 ) O(1) O ( 1 ) 空间复杂度 O ( 1 ) O(1) O ( 1 ) AC代码 C++ C Python Python2 Java C# Javascript Ruby Swift Go Scala Kotlin Rust PHP

    2024年02月12日
    浏览(37)
  • leetcode刷题:消失的数字

    数组 nums 包含从 0 到 n 的所有整数,但其中缺了一个。请编写代码找出那个缺失的整数。你有办法在O(n)时间内完成吗? 注意: 本题相对书上原题稍作改动 示例 1: 示例 2: 针对于这道题,我们提供了三种解法: 首先使用快排对数组进行排序,使其变成有序数组,由题意得

    2024年01月24日
    浏览(39)
  • 【leetcode】消失的数字

    大家好,我是苏貝,本篇博客带大家刷题,如果你觉得我写的还不错的话,可以给我一个赞👍吗,感谢❤️ 点击查看题目 通过2个for循环,遍历查找0-n中缺少的数字,比较简单,不写,时间复杂度为O(N^2) 点击去了解异或,位置在④.3 异或:两个整数的相同位置:相同为0,不

    2024年01月22日
    浏览(43)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包