当前位置:   article > 正文

丢失的数字(MissNumber)

丢失的数字(MissNumber)

丢失的数字
给定一个包含 [0, n] 中 n 个数的数组 nums ,找出 [0, n] 这个范围内没有出现在数组中的那个数。
示例 1:

输入:nums = [3,0,1]
输出:2
解释:n = 3,因为有 3 个数字,所以所有的数字都在范围 [0,3] 内。2 是丢失的数字,因为它没有出现在 nums 中。
示例 2:

输入:nums = [0,1]
输出:2
解释:n = 2,因为有 2 个数字,所以所有的数字都在范围 [0,2] 内。2 是丢失的数字,因为它没有出现在 nums 中。
示例 3:

输入:nums = [9,6,4,2,3,5,7,0,1]
输出:8
解释:n = 9,因为有 9 个数字,所以所有的数字都在范围 [0,9] 内。8 是丢失的数字,因为它没有出现在 nums 中。
示例 4:

输入:nums = [0]
输出:1
解释:n = 1,因为有 1 个数字,所以所有的数字都在范围 [0,1] 内。1 是丢失的数字,因为它没有出现在 nums 中。


对于上述题目我们有几种解法

1.将数组中的数据进行升序排序用后一个数据-上一个数据不等于1,则用后面的数据减1找到丢失的数字。

void Bubble_sort(int* arr, int sz)
{
	int i = 0;
	for (i = 0; i < sz - 1; i++)//确定排序的趟数
	{
		int j = 0;
		int flag = 1;//如果arr[j]<arr[j+1],就不用进入循环,加快效率
		for (j = 0; j < sz - 1 - i; j++)
		{//两两比较,交换排序
			if (arr[j] > arr[j + 1])
			{
				flag = 0;//发生交换就说明无序
				int tmp = arr[j + 1];
				arr[j + 1] = arr[j];
				arr[j] = tmp;
			}
			if (flag == 1)//没有进入循环
				break;
		}
	}
}
void FindMissNum(int* arr, int n)
{
	Bubble_sort(arr , n);
	for (int i = 0; i < n; ++i)
	{
		if (i + 1 == n)//防止越界
		{
			break;
		}
		if ((arr[i + 1]- arr[i])!=1 )
		{
			printf("丢失的数字为%d\n", arr[i + 1]-1);
			break;
		}	
	}
}
int main()
{
	int num[] = { 3,1,0,2,4,9,5,6,7,10 };
	int sz = sizeof(num)/sizeof(num[0]);
	FindMissNum(num, sz);
	return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44

虽然上述代码可以解决问题,但是时间复杂度为O(n),效率低


2.将数组中0-(n-1)的数据相加得到num1,再将0-n的数据相加得到num2,将num2-num1得出的结果就是丢失的数字。

void FindMissNum2(int* arr, int sz)
{
	int i = 0;
	int j = 0;
	int sum1 = 0; 
	int sum2 = 0;
	for (i = 0; i < sz; i++)//将数组中的所以数据相加
	{
		int tmp1 = arr[i];
		sum1 = tmp1 + sum1;
	}
	for (j = 0; j < sz +1; j++)//将0~n的数字相加
	{
		int tmp2 = j;
		sum2 = tmp2+sum2;
	}
	int missnum = sum2 - sum1;
	printf("丢失的数字是%d\n",missnum);
}
int main()
{
	int num[] = { 3,1,0,2,4,9,5,6,7,10 };
	int sz = sizeof(num)/sizeof(num[0]);
	FindMissNum2(num, sz);
	return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

上述代码的时间复杂度为O(1),空间复杂度为O(n),不推荐


3.将数组中的数据全部异或,再与0-n全部异或,得出的结果就是丢失的数字。
原理:任何数字异或自己之后就会抵消,异或的交换律)

void FindMissNum3(int* arr, int sz)
{
	int tmp1  =  0;
	int tmp2  =  0;
	for (int i = 0; i < sz; ++i)
	{
		tmp1 = tmp1 ^ arr[i];
	}
	for (int j = 0; j < sz + 1; j++)
	{
		tmp2 = tmp2 ^ j;
	}
	int missnum = tmp1 ^ tmp2;
	printf("丢失的数字是%d\n", missnum);
}
int main()
{
	int num[] = { 3,1,0,2,4,9,5,6,8,10 };
	int sz = sizeof(num)/sizeof(num[0]);
	FindMissNum3(num,sz);
	return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

上述代码的时间复杂度为O(1),且空间复杂度也为O(1),推荐使用

本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号