数据结构 ——— 顺序表oj题:数组 nums 包含了从 0 到 n 的所有整数,但是其中缺失了一个,请编写代码找出缺失的整数,并且在O(N)时间内完成

目录

题目要求

代码实现

方法1(异或法):

异或算法的时间复杂度:

方法2(等差数列公式):

等差数列公式的时间复杂度:


题目要求

整型数组 nums 包含了从 0 到 n 的所有整数,但是其中缺失了一个,编写一个 missingNumber 函数,找出缺失的整数,并且将 missingNumber 函数的时间复杂度控制在 O(N) 内完成‘

nums 为:整型数组首元素地址

numsSize 为:nums 数组的元素个数


代码实现

方法1(异或法):

代码演示:

int missingNumber(int* nums, int numsSize)
{
	int x = 0;
	
	// 循环1
	for (int i = 0; i < numsSize; i++)
	{
		x = x ^ nums[i];
	}

	// 循环2
	for (int i = 0; i < numsSize + 1; i++)
	{
		x = x ^ i;
	}

	return x;
}

代码解析:

0 异或任何整数,结果为任何整数

0 ^ x = x

两个相同的整数异或,结果为0

a ^ a = 0

两个相同的整数异或 再 异或一个其他的整数,结果为其他的整数,且异或满足交换律

a ^ a ^ b = b   <===>   a ^ b ^ a = b

由以上的结论推导出代码的含义:

创建整型变量 x 并赋值为 0 ,因为 0 异或任何整数,结果为任何整数,所以再使用 x 异或 nums 数组中的所有整数,再利用 numsSize 遍历完整的 nums 数组,再和 x 异或,异或完之后的 x 就是缺失的那个值

举例说明:

nums 的元素为:[0, 1, 2, 3, 5]

x 为:0

循环1 为:0 ^ 1 ^ 2 ^ 3 ^ 5

循环2 为:0 ^ 1 ^ 2 ^ 3 ^ 4 ^ 5

由以上的代码得:

    0 ^ 0 ^ 1 ^ 2 ^ 3 ^ 5 ^ 0 ^ 1 ^ 2 ^ 3 ^ 4 ^ 5

=  0 ^ 0 ^ 0 ^ 1 ^ 1 ^ 2 ^ 2 ^ 3 ^ 3 ^ 5 ^ 5 ^ 4

=  0 ^ 0 ^ 0 ^ 0 ^ 0 ^ 0 ^ 0 ^ 4

=  4

代码验证:

异或算法的时间复杂度:

循环1 执行了 N 次,循环2 执行了 N+1 次

得出算法的时间复杂度函数式:

时间复杂度函数式:F(N) = N + N + 1 = 2 * N + 1

根据时间复杂度函数式和大O的渐进表示法规则得出:只保留最高项(去掉 1);如果最高阶项存在且不是1,则去除与这个项目相乘的常数(除去 F(N) 中的2 ),得出大O的渐进表示法: 

大O渐进表示法:O(N)


方法2(等差数列公式):

代码演示:

int missingNumber(int* nums, int numsSize)
{
	// 首项加尾项乘以项数除以2
	int x = (0 + numsSize) * (numsSize + 1) / 2;

	// 循环1
	for (int i = 0; i < numsSize; i++)
	{
		x = x - nums[i];
	}

	return x;
}

代码解析:

首项加尾项乘以项数除以2,根据这个公式就能求出完整的 nums 数组的所有数的和并存储到整型变量 x 中

最后再利用 循环1 遍历 nums 数组的中数,并用 x 依次递减,最后 x 的值就是 nums 数组缺失的数

代码验证:

等差数列公式的时间复杂度:

计算等差数列公式执行了1次(常数次),循环1 执行了 N 次

得出算法的时间复杂度函数式:

时间复杂度函数式:F(N) = 1 + N

由时间复杂度函数式直接推导出大O渐进表示法:

大O渐进表示法:O(N)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值