基于异或和哈希表用于在由重复整数组成的数组中找到不重复整数的实现方法

只出现一次的数字

详细说明:给定一个整数数组,其中除了一个整数只出现一次外,其余所有数字都恰好出现两次。找到那个不重复的整数。

最坏的情况下的时间复杂度:O(n)

空间复杂度:O(1)

这个程序用于找出数组中唯一一个不重复的整数,利用异或运算的特性高效实现。以下是分块解释:

  1. 头文件引入

    • <cassert> 用于断言测试。

    • <iostream> 用于输入输出操作。

    • <vector> 用于存储整数数组。

  2. 命名空间

    • 使用嵌套命名空间 bit_manipulation::find_non_repeating_integer 组织代码,提高模块化。

  3. 核心函数

int64_t find_non_repeating_integer(const std::vector<int>& nums) {
    int _xor = 0;
    for (const int& num : nums) {
        _xor ^= num;
    }
    std::cout << _xor << std::endl;
    return _xor;
}
  • 功能:通过异或运算找出数组中唯一出现一次的数字。

  • 原理:利用异或运算的以下性质:

    • a ^ a = 0(相同数异或结果为0)。

    • 0 ^ b = b(任何数与0异或结果为其本身)。

二进制异或操作

异或操作是逐位进行的逻辑运算,我们先看几个简单的二进制异或的例子:

  1. 0 XOR 0 = 0:二进制位相同,结果为0。

  2. 0 XOR 1 = 1:二进制位不同,结果为1。

  3. 1 XOR 0 = 1:二进制位不同,结果为1。

  4. 1 XOR 1 = 0:二进制位相同,结果为0。

将数字转换为二进制并进行异或

我们用具体的数字来说明异或的过程:

  1. 数字1和1异或

    • 二进制表示:1 (01) 和 1 (01)

    • 异或结果:00(0)

  2. 数字1和2异或

    • 二进制表示:1 (01) 和 2 (10)

    • 异或结果:11(3)

在代码中的应用

现在,我们来看代码中的异或操作是如何实现的:

  1. 初始化一个变量_xor为0。

  2. 遍历数组中的每个元素,并将每个元素与_xor进行异或操作。

  3. 重复的元素在异或时会相互抵消,最终剩下的就是唯一的不重复元素。

我们以第一个测试用例nums_one = {1, 1, 2, 2, 4, 5, 5}为例,逐步模拟异或操作的过程:

  • 初始化_xor = 0

  • 遍历数组中的每个元素:

    • _xor ^= 1_xor变为1(二进制:01)

    • _xor ^= 1_xor变为0(二进制:00)

    • _xor ^= 2_xor变为2(二进制:10)

    • _xor ^= 2_xor变为0(二进制:00)

    • _xor ^= 4_xor变为4(二进制:100)

    • _xor ^= 5_xor变为1(二进制:001)

    • _xor ^= 5_xor变为4(二进制:100)

最终,_xor的值为4,这正是数组中唯一的不重复元素。其他测试用例的异或过程也是类似的,通过异或操作,所有重复的元素都被抵消,剩下的就是唯一的不重复元素。

  • 步骤

    1. 初始化 _xor 为0。

    2. 遍历数组,将所有元素依次与 _xor 异或。

    3. 最终 _xor 的值即为唯一不重复的数。

      4.测试函数

static void test() {
    std::vector<int> nums_one{1, 1, 2, 2, 4, 5, 5};
    std::vector<int> nums_two{203, 3434, 4545, 3434, 4545};
    std::vector<int> nums_three{90, 1, 3, 90, 3};
    
    assert(find_non_repeating_integer(nums_one) == 4);   // 测试用例1
    assert(find_non_repeating_integer(nums_two) == 203); // 测试用例2
    assert(find_non_repeating_integer(nums_three) == 1);  // 测试用例3
    
    std::cout << "All test cases passed!" << std::endl;
}
  • 验证函数在不同输入场景下的正确性。

  • 测试用例

    • nums_one 中 4 是唯一不重复数。

    • nums_two 中 203 是唯一不重复数。

    • nums_three 中 1 是唯一不重复数。

总结:程序通过异或运算高效找到数组中唯一出现一次的数字,时间复杂度为 O(n),空间复杂度为 O(1)。测试用例覆盖了不同场景,确保算法正确性。

基于哈希表的解决方法

#include <iostream>
#include <vector>
#include <unordered_map>

int find_non_repeating_integer(const std::vector<int>& nums) {
    std::unordered_map<int, int> num_count;
    // 遍历数组,统计每个数字出现的次数
    for (int num : nums) {
        num_count[num]++;
    }
    // 遍历哈希表,找出出现次数为 1 的数字
    for (const auto& a : num_count) {
        if (a.second == 1) {
            return a.first;
        }
    }
    return -1; // 如果没找到,返回 -1
}

int main() {
    std::vector<int> nums_one = { 1, 1, 2, 2, 4, 5, 5 };
    std::vector<int> nums_two = { 203, 3434, 4545, 3434, 4545 };
    std::vector<int> nums_three = { 90, 1, 3, 90, 3 };

    std::cout << find_non_repeating_integer(nums_one) << std::endl;
    std::cout << find_non_repeating_integer(nums_two) << std::endl;
    std::cout << find_non_repeating_integer(nums_three) << std::endl;

    return 0;
}

用哈希表去存储数组中的数据,并统计每个数字出现的次数,之后遍历哈希表找出出现次数为1的数字。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值