寻找独特数字卡片 | 豆包MarsCode AI刷题

53 阅读2分钟

寻找独特数字卡片 | 豆包MarsCode AI刷题

摘要

在一个班级中,除了一个数字之外,其余数字都恰好出现两次。通过使用异或运算,我们可以高效地找到这个独特的数字。该算法具有时间复杂度 O(n)O(n),并且只使用常数级别的额外空间。

问题描述

在一个班级中,每位同学都拿到了一张卡片,上面有一个整数。现在需要你帮助班长小C快速找到那个拿了独特数字卡片的同学手上的数字是什么。

输入与输出

  • 输入:一个整数数组 cards,其中每个数字表示同学的卡片。
  • 输出:唯一出现一次的数字。

测试样例

  • 样例1

    • 输入:cards = [1, 1, 2, 2, 3, 3, 4, 5, 5]
    • 输出:4
    • 解释:拿到数字 4 的同学是唯一一个没有配对的。
  • 样例2

    • 输入:cards = [0, 1, 0, 1, 2]
    • 输出:2
    • 解释:数字 2 只出现一次,是独特的卡片。
  • 样例3

    • 输入:cards = [7, 3, 3, 7, 10]
    • 输出:10
    • 解释:10 是班级中唯一一个不重复的数字卡片。

算法原理

要找到唯一的独特数字,可以使用异或运算(XOR)。这个方法的优点是它的时间复杂度为 O(n)O(n),并且只使用常数级别的额外空间。因为对于任何数 xx,有 xx=0x \oplus x = 0x0=xx \oplus 0 = x,并且异或操作满足交换律和结合律,即xy=yxx \oplus y = y\oplus xxyz=x(yz)x \oplus y\oplus z = x\oplus (y\oplus z) ,所以将所有数字进行异或操作后,成对出现的数字都会消去,只剩下那个独特的数字。

代码实现

Go 语言实现

package main

import "fmt"

func findUnique(cards []int) int {
    unique := 0
    for _, card := range cards {
        unique ^= card
    }
    return unique
}

func main() {
    cards := []int{1, 1, 2, 2, 3, 3, 4, 5, 5}
    result := findUnique(cards)
    fmt.Println(result) // 输出 4
}

代码解析

  1. 变量 unique 初始化为 0:用于存储异或结果。
  2. 遍历 cards 数组:对于数组中的每一个数字,执行异或操作。
  3. 返回结果:最终 unique 中保存的就是那个唯一的数字。

复杂度分析

  • 时间复杂度O(n)O(n),因为我们只遍历一次数组。
  • 空间复杂度O(1)O(1),只使用了一个额外的变量来存储结果。

Python 实现

def solution(cards):
    """
    该函数接受一个整数列表 'cards',返回其中唯一出现一次的元素。
    使用异或运算符来找出唯一元素,因为相同的元素异或结果为 0,
    最终剩下的就是唯一出现的元素。
    """
    unique = 0  # 初始化 unique 为 0
    for card in cards:
        unique ^= card  # 将每个元素与 unique 进行异或运算

    return unique  # 返回唯一元素


if __name__ == "__main__":
    # 添加测试用例
    print(solution([1, 1, 2, 2, 3, 3, 4, 5, 5]) == 4)  # 应输出 true
    print(solution([0, 1, 0, 1, 2]) == 2)              # 应输出 true
    print(solution([5, 5, 7, 7, 8, 8, 9]) == 9)       # 应输出 true
    print(solution([10, 10, 3, 3, 2, 2, 1]) == 1)     # 应输出 true