AI 刷题解析 1. 卡牌翻面求和问题 | 豆包MarsCode AI刷题

81 阅读3分钟

豆包MarsCode AI刷题记录——学习方法与心得

问题描述

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

要求:

  1. 设计一个算法,使其时间复杂度为 O(n),其中 n 是班级的人数。
  2. 尽量减少额外空间的使用,以体现你的算法优化能力。

题目解析

为了找到那个独特的数字,我们可以使用异或运算的性质。异或运算有以下特点:

  1. 任何数和0做异或运算,结果仍然是原来的数,即 a ⊕ 0 = a
  2. 任何数和其自身做异或运算,结果是0,即 a ⊕ a = 0
  3. 异或运算满足交换律和结合律,即 a ⊕ b ⊕ a = (a ⊕ a) ⊕ b = 0 ⊕ b = b

基于以上性质,我们可以将所有的数字进行异或运算。成对的数字在异或运算后会相互抵消,最终剩下的结果就是那个独特的数字。算法的核心思路是通过一个字典(count_dict)来跟踪每个数字出现的次数。当遍历输入列表(inp)时,算法会对每个数字进行计数。如果一个数字的计数达到2(意味着它已经成对出现),那么该数字将从字典中移除。由于题目条件保证了只有一个数字是独特的(即只出现一次),所以在遍历结束后,字典中只剩下一个键值对,其键就是那个独特的数字。

代码详解

def solution(inp):
    count_dict = {}
    for card in inp:
        if card in count_dict:
            count_dict[card] += 1
        else:
            count_dict[card] = 1

        # 如果计数达到 2,则移除这个数字
        if count_dict[card] == 2:
            del count_dict[card]

    # 返回字典中剩下的那个数字
    return list(count_dict.keys())[0]

if __name__ == "__main__":
    # Add your test cases here
    print(solution([1, 1, 2, 2, 3, 3, 4, 5, 5]) == 4)
    print(solution([0, 1, 0, 1, 2]) == 2)

知识点总结

  1. 数据结构

    • 字典(哈希表):用于存储和快速查找数字及其出现次数。
  2. 算法思想

    • 计数:通过计数来跟踪每个数字出现的次数。
    • 去除重复项:一旦一个数字的计数达到2,就将其从字典中移除,这样可以确保最后字典中只剩下一个唯一的数字。
  3. 编程技巧

    • 字典操作:如何向字典中添加键值对,如何更新键的值,以及如何删除键值对。
    • 列表与字典的转换:使用 list() 函数将字典的键转换为列表,并使用索引访问列表中的元素。

复杂度分析

这个算法的时间复杂度是 O(n),因为每个数字只被处理一次,并且字典操作(插入、查找、删除)的平均时间复杂度是 O(1)。然而,由于每次遇到成对的数字时,我们都会删除它,这可能会导致不必要的字典操作,因此这个算法的空间复杂度是 O(n),在最坏的情况下(即所有数字都是成对的,除了最后一个数字)。

AI刷题体验

AI刷题虽然不能完全代替我们思考,但是可以在我们没有思路或者遇到BUG时候把AI工具是做一个很好的启发或者灵感来源,拓宽我们的解题思路,而且也可以用AI一题多解,比较不同算法的优缺点,对于一个题目的理解更加深刻。