题目解析:找单独的数| 豆包MarsCode AI刷题

116 阅读2分钟

问题描述

在一个班级中,每位同学都拿到了一张卡片,卡片上标有一个整数。有趣的是,除了一个数字之外,所有的数字都恰好出现了两次。现在需要找出唯一一个没有配对的数字是什么。

要求:

1.	设计一个时间复杂度为 O(n) 的算法,其中 n 是班级的人数(数组的长度)。
2.	尽量减少空间复杂度的使用,优化算法性能。

解题思路

该解法以集合的方式记录已遍历过的数字,并通过对集合的操作找出没有成对的数字。具体思路如下:

1.	使用两个集合 seen 和 repeated:
•	seen 用于存储遍历过的数字。
•	repeated 用于存储已经出现两次的数字。
2.	遍历数组:
•	如果数字在 seen 中,则将其添加到 repeated。
•	如果数字不在 seen 中,则将其添加到 seen。
3.	遍历完成后,seen 中保留的数字与 repeated 取差集,差集结果即为唯一没有成对的数字。

这种解法通过集合的高效查找特性,保证了算法的线性时间复杂度。

代码实现

截屏2024-11-25 23.53.46.png

运行分析

1.	时间复杂度:
•	遍历数组的时间复杂度为 O(n)。
•	集合的插入和查找操作在均摊情况下为 O(1)。

综合时间复杂度为 O(n)。 2. 空间复杂度: • 需要额外使用两个集合 seen 和 repeated,最坏情况下会存储数组中一半的数字,因此额外空间复杂度为 O(n)。

测试分析

样例 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 是班级中唯一的未配对卡片。

扩展总结

这种基于集合的解法提供了灵活且直观的实现方式,不仅可以高效解决问题,还易于理解和拓展。与传统的异或解法相比,虽然增加了空间复杂度,但在代码可读性和调试友好性方面表现更优。

建议: 对于初学者,推荐首先掌握类似的集合操作,理解差集等基本操作概念,再逐步探索更底层的位运算解法(如异或)。这种从易到难的学习方式更有助于建立扎实的算法基础。