题目
在一个班级中,每位同学都拿到了一张卡片,上面有一个整数。有趣的是,除了一个数字之外,所有的数字都恰好出现了两次。现在需要你帮助班长小C快速找到那个拿了独特数字卡片的同学手上的数字是什么。
要求: 设计一个算法,使其时间复杂度为 O(n),其中 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 是班级中唯一一个不重复的数字卡片。
题目解析
在这个班级卡片数字的情境里,给定了一组整数,其中除了一个数字仅出现一次外,其余数字都恰好出现两次。这就相当于在众多数字构成的数据集合中,去精准地找出那个与众不同、独一无二出现的数字。并且题目有着明确的效率要求,时间复杂度需达到 O(n),意味着算法处理时间要和班级人数(也就是数字个数)呈线性关系,同时还要尽量减少额外空间的使用,这对算法的简洁性和高效性提出了较高挑战,不能采用那些会大量占用额外空间或者有着高时间复杂度的常规查找、排序等简单粗暴的办法来解题。
代码展示
def solution(inp):
# Edit your code here
res = 0
for x in inp:
res = res ^ x
return res
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)
思路分析
此处运用异或运算( ^ )来巧妙解决问题,核心是基于异或运算的几个关键性质。首先是交换律,意味着数字参与异或运算的先后顺序并不影响最终结果;其次是结合律,方便我们对多个数字连续进行异或操作;再者是归零律,相同的两个数字进行异或运算结果为 0;还有恒等律,任何数与 0 进行异或运算,其结果就是该数本身。基于这些性质,当遍历输入的数字列表 inp 时,那些成对出现的数字经过异或就会变为 0,最终整个列表所有数字异或完后,就只剩下那个只出现一次的独特数字,将其存储在变量 res 中并返回即可,这样通过一次简单的循环遍历就能解决问题,时间复杂度刚好为 O(n),而且仅用了一个额外变量 res ,空间复杂度也很低,完美契合题目要求。
知识总结
- 异或运算性质:对异或运算的交换律、结合律、归零律和恒等律要有清晰且深刻的理解,这是实现高效算法的基础,在处理数字重复性相关逻辑以及一些位运算优化场景中经常能派上用场。
- 算法复杂度考量:切实掌握时间复杂度和空间复杂度的概念与计算方法,明白不同算法策略在处理数据规模变化时的效率表现,以便在解决问题时能选择出既能满足功能需求,又在性能方面表现出色的最优算法。
- 巧用逻辑运算解决问题:要意识到像异或这样的逻辑运算,在特定数据规律场景下,能替代传统的复杂数据结构和多层嵌套循环等方式,成为简洁高效解决问题的关键手段。、
学习心得
通过解决这一问题,深刻体会到深入分析问题特性的重要性,不能一上来就盲目用常规手段去尝试解决,而是要先挖掘数据内在规律。就像本题中数字出现次数的特点,刚好可以与异或运算性质相结合来高效求解。同时,也让我更加注重算法性能方面的优化,在日常学习和实践中,不能只关注代码能否跑通,更要思考怎样让算法在面对大量数据时也能快速准确地执行,合理利用好类似异或运算这种基础但强大的工具,逐步提升自己设计高效算法、解决复杂问题的能力,为应对更具挑战性的编程任务积累经验和思路。