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;
}

代码解析:

  1. 使用两个变量 xy,分别用来存储数组中所有数字的异或和和 1 到 N 所有数字的异或和。
  2. 由于数组中缺少一个数字,并且有一个数字出现了两次,所以 xy 的异或结果 t 中,包含了两个缺失的信息:
    • 缺少的数字 a
    • 出现两次的数字 b
  3. 通过 ta 的位运算,可以得到 a 的值。
  4. 通过循环,将数组中每个数字与 a 进行位运算,如果结果不为零,则说明该数字是 b
  5. 最后,通过 t ^ b 计算出 a 的值。

示例说明:

假设输入为:2 3 4 1 3 6

  1. x = 2 ^ 3 ^ 4 ^ 1 ^ 3 ^ 6 = 1
  2. y = 1 ^ 2 ^ 3 ^ 4 ^ 5 ^ 6 = 5
  3. t = x ^ y = 1 ^ 5 = 4
  4. a = t & -t = 4 & -4 = 4
  5. 循环遍历数组,发现 b = 3
  6. a = t ^ b = 4 ^ 3 = 5

总结:

本篇博客介绍了如何使用C语言在O(N)时间复杂度和O(1)空间复杂度内,找出数组中被替换的两个数字。文章包含详细的代码解析和示例,适合初学者学习和参考。

注意:

本算法假设数组中只有一个数字被替换,并且只有一个数字出现了两次。如果出现其他情况,算法将无法正常工作。

C语言实现找出替换的数字,时间复杂度O(N) 空间复杂度O(1)

原文地址: https://www.cveoy.top/t/topic/ntKo 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录