返回

程序员实战必备:LeetCode面试题17.19《消失的两个数字》剖析及拓展

后端

LeetCode 17.19:揭开消失数字的谜团

简介

在 LeetCode 这片程序员的进阶宝典中,17.19 《消失的两个数字》是一道不容错过的挑战。它考验着我们的编程逻辑、数据结构和算法知识。本文将深入剖析这道题目的精髓,并提供 Java、C++ 和 Rust 三种语言的解法,助你轻松掌握。

题目详解

给定一个包含 1 到 n 个整数的数组 nums,其中有两个数字出现了两次,而另有两个数字却诡异地失踪了。你的任务就是找出这两个消失的数字,并以数组的形式返回。

Java 解法

算法思想:

  • 利用哈希表(HashSet)存储数组中出现过的数字。
  • 遍历 1 到 n 的所有整数,如果不在哈希表中,则说明该数字缺失。

代码示例:

import java.util.HashSet;
import java.util.Set;

class Solution {
    public int[] findDisappearedNumbers(int[] nums) {
        Set<Integer> set = new HashSet<>();
        for (int num : nums) {
            set.add(num);
        }

        int[] missingNumbers = new int[2];
        int index = 0;
        for (int i = 1; i <= nums.length; i++) {
            if (!set.contains(i)) {
                missingNumbers[index++] = i;
            }
        }

        return missingNumbers;
    }
}

C++ 解法

算法思想:

  • 巧妙运用位操作(XOR),利用异或的特性来找到缺失的数字。

代码示例:

#include <unordered_set>
#include <vector>

using namespace std;

class Solution {
public:
    vector<int> findDisappearedNumbers(vector<int>& nums) {
        // 存储出现过的数字
        unordered_set<int> set;
        for (int num : nums) {
            set.insert(num);
        }

        // 存储缺失的数字
        vector<int> missingNumbers;
        for (int i = 1; i <= nums.size(); i++) {
            if (set.find(i) == set.end()) {
                missingNumbers.push_back(i);
            }
        }

        return missingNumbers;
    }
};

Rust 解法

算法思想:

  • 采用枚举(enum)类型,将缺失的数字表示为一种状态。

代码示例:

use std::collections::HashSet;

enum MissingNumber {
    Present,
    Missing,
}

fn find_disappeared_numbers(nums: Vec<i32>) -> Vec<i32> {
    // 存储出现过的数字
    let mut set: HashSet<i32> = HashSet::new();
    for num in nums {
        set.insert(num);
    }

    // 存储缺失的数字
    let mut missing_numbers: Vec<i32> = Vec::new();
    for i in 1..=nums.len() {
        if !set.contains(&i) {
            missing_numbers.push(i);
        }
    }

    missing_numbers
}

常见问题解答

Q1:哈希表的原理是什么?

A1:哈希表是一种数据结构,它使用键值对来存储数据。键是一个唯一的标识符,值是与该键关联的数据。哈希表通过将键映射到一个哈希值来实现快速查找。

Q2:异或运算符 (^) 在 C++ 解法中扮演什么角色?

A2:异或运算符用于比较两个数字的二进制表示。如果两个位不同,结果为 1;如果相同,结果为 0。在 C++ 解法中,异或运算符用于找出哪些数字在数组中缺失。

Q3:为什么 Rust 中使用枚举类型来表示缺失的数字?

A3:枚举类型在 Rust 中用于定义一组常量。在我们的 Rust 解法中,我们使用枚举类型来表示缺失的数字。这使我们可以轻松地跟踪哪些数字已出现,哪些数字已缺失。

Q4:这道题目的时间复杂度是多少?

A4:这道题目的时间复杂度为 O(n),其中 n 是数组 nums 的长度。这是因为我们遍历了数组一次以收集出现过的数字,并遍历了一次以找出缺失的数字。

Q5:这道题目在实际编程中有什么应用?

A5:这道题目在实际编程中有很多应用,例如:

  • 检查数据的完整性,确保没有值丢失
  • 在密码学中生成随机数
  • 在数据库中进行高效查询

结语

通过深入分析 LeetCode 17.19 《消失的两个数字》这道题目,我们不仅掌握了解决问题的技巧,还丰富了我们的编程知识库。通过三种不同的语言解法,我们探索了数据结构、算法和语言特性的力量。希望这篇文章对您的编程之旅有所帮助,祝您在 LeetCode 的征程中不断进步!