C语言实现找出替换的数字,时间复杂度O(N) 空间复杂度O(1)
C语言实现找出替换的数字,时间复杂度O(N) 空间复杂度O(1)
题目描述:
有N个不同的数,分别是1到N,在随机打乱顺序的过程中,出现了一点小误差,其中一个数换成了另一个数。请你找出谁替换了谁,要求时间复杂度是O(N),辅助空间O(1),这意味不能使用数组、map、set、vector等。
输入:
N个数ai(1<=ai<=N),其中缺了一个,而又有一个数出现了2次,其它都出现了1次,数之间有一个空格。(N<2000)
输出:
两个整数a和b(a是缺的哪一个,b是出现两次的那一个),中间有一个空格,没有回车
输入样例:
2 3 4 1 3 6
输出样例:
5 3
代码实现:
#include <stdio.h>
int main() {
int n = 0, a = 0, b = 0, x = 0, y = 0, t = 0;
scanf('%d', &n);
for (int i = 1; i <= n; ++i) {
scanf('%d', &t);
x ^= t;
y ^= i;
}
y ^= n + 1;
t = x ^ y;
a = t & -t;
for (int i = 1; i <= n; ++i) {
if (i & a) {
b ^= i;
}
if (t & a) {
b ^= x;
}
x ^= i;
}
printf('%d %d', b, t ^ b);
return 0;
}
代码解析:
- 使用两个变量
x和y,分别用来存储数组中所有数字的异或和和 1 到 N 所有数字的异或和。 - 由于数组中缺少一个数字,并且有一个数字出现了两次,所以
x和y的异或结果t中,包含了两个缺失的信息:- 缺少的数字
a - 出现两次的数字
b
- 缺少的数字
- 通过
t和a的位运算,可以得到a的值。 - 通过循环,将数组中每个数字与
a进行位运算,如果结果不为零,则说明该数字是b。 - 最后,通过
t ^ b计算出a的值。
示例说明:
假设输入为:2 3 4 1 3 6
x= 2 ^ 3 ^ 4 ^ 1 ^ 3 ^ 6 = 1y= 1 ^ 2 ^ 3 ^ 4 ^ 5 ^ 6 = 5t=x^y= 1 ^ 5 = 4a=t& -t= 4 & -4 = 4- 循环遍历数组,发现
b= 3 a=t^b= 4 ^ 3 = 5
总结:
本篇博客介绍了如何使用C语言在O(N)时间复杂度和O(1)空间复杂度内,找出数组中被替换的两个数字。文章包含详细的代码解析和示例,适合初学者学习和参考。
注意:
本算法假设数组中只有一个数字被替换,并且只有一个数字出现了两次。如果出现其他情况,算法将无法正常工作。
原文地址: https://www.cveoy.top/t/topic/ntKo 著作权归作者所有。请勿转载和采集!