【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 

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

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

方法三:异或

按位异或是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;
}

你可能感兴趣的:(Leetcode刷题专栏,leetcode,算法,职场和发展)