【Leetcode】面试题17.04. 消失的数字

题目来源:

来源:力扣(LeetCode)                                                                                                                  链接:https://leetcode.cn/problems/missing-number-lcci/

题目描述:

数组nums包含从0n的所有整数,但其中缺了一个。请编写代码找出那个缺失的整数。你有办法在O(n)时间内完成吗?

示例:

  • 示例一:

输入:[3, 0, 1]

输出:2

  • 示例二:

输入:[9, 6, 4, 2, 3, 5, 7, 0, 1]

输入:8

解题思路与代码:

方法一:排序+查找

如案例所示,给我们的数组可以是无序的,而这种方法的思路就是先对无序数组进行排序(这里使用的是冒泡排序)得到一个有序数组。使用if语句判断前一个数加1是否等于后一个数,若不等于则代表有缺失的数,那么nums[z]+1就是我们要找的数,返回即可。

#include <stdio.h>

int missingNumber(int* nums, int numsSize) {
	int tmp = 0;  //中间数-用于交换

    //数组排序——冒泡排序思想

	for (int i = 0; i < numsSize - 1; i++)
	{
		for (int j = 0; j < numsSize - i - 1; j++)
		{
			if (nums[j] > nums[j + 1])
			{
				int temp = nums[j + 1];
				nums[j + 1] = nums[j];
				nums[j] = temp;
			}
		}
	}

	//找出缺失的数——前一个数++是否等于后一个数
	for (int z = 0; z < numsSize; z++)
	{
		if (nums[z] + 1 != nums[z + 1])
		{
			return nums[z] + 1;
		}
	}

	return 0;
}

但是这种方法存在缺陷,这种方法可在visual studio上测试出来,但是在leetcode上却提交不过去。这种方法不符合时间复杂度的要求,即使使用的是快速排序也需要O(N*logN)的时间复杂度。故这种方法不是最优方法。

方法二:完整数组求和 - 缺失数组求和

这个方法的思路为:缺失的数 = 完整数组之和 - 缺失数组之和

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

完整数组是一个等差数列,其求和即为等差数列求和。

方法三:异或

按位异或是C语言的一个操作符,它的讲解可以看这一篇文章:【C语言】操作符总结(一)

按位异或的规则是:相同为0,相异为1。由此可知:两个相同的数异或到一起就变成0了。例如3与3进行异或:

00000000 00000000 00000000 00000011  —3

00000000 00000000 00000000 00000011  —3

3^3
00000000 00000000 00000000 00000000

因此我们可以让0-n的数字和数组内的数字全部放在一起异或,并且异或满足交换律,即:

0 ^ 1 ^ 2 ^ 3 ^ 3 ^ 0 ^ 1     等价于     0 ^ 0 ^ 1 ^ 1 ^ 3 ^ 3 ^ 2

我们前面说到相同的数异或得到0,即最后为0^2 = 2,得到缺失的数为2。

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

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值