丢失的数字(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;
}

虽然上述代码可以解决问题,但是时间复杂度为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;
}

上述代码的时间复杂度为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;
}

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

  • 17
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值