1找单独的数 | 豆包MarsCode AI刷题

51 阅读3分钟

问题描述:

在一个班级中,每位同学都拿到了一张卡片,上面有一个整数。有趣的是,除了一个数字之外,所有的数字都恰好出现了两次。现在需要你帮助班长小C快速找到那个拿了独特数字卡片的同学手上的数字是什么。要求:1) 设计一个算法,使其时间复杂度为 O(n),其中 n 是班级的人数。2) 尽量减少额外空间的使用,以体现你的算法优化能力。

测试用例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 是班级中唯一一个不重复的数字卡片。

思路

由于在这个问题中只需要找出唯一单独的数,只有这个数字的个数为1,而其他数字的个数为2,因此可以通过巧妙的算法来实现需求。如果使用字典存储每个数字出现的次数,虽然可以较容易解决问题,但对空间的利用并不高效,因为并不考虑其他的数字是3次还是4次。因此,我们需要探索更优的解法。

一个简单而高效的方法是利用异或运算。异或运算的性质是:对于两个相同的数,异或后的结果是0;而任意数与0异或的结果仍是这个数。因此,将所有数字依次进行异或操作后,最终的结果就是那个只出现一次的数。这个方法只需遍历一遍数组,时间复杂度为 O(n),且不需要额外的存储空间,空间复杂度为 O(1)。

另一种思路是基于排序的特性。只需要将列表排序(从小到大或从大到小都可以),index从0开始,每次+2, 一对一对往后查,检查这一对元素是否相等。一旦发现这一对元素不相等时,第一个元素就是要找的单独元素,直接返回即可。如下面这种情况,此时4就是那个单独元素。

1,12,23,34,5,5

另一种情况是单独的元素在最后一个,此时在循环结束时返回列表最后一个元素即可。

1,12,23,34,4, 5

代码

def solution(inp):
    # Edit your code here
    inp.sort()
    n = len(inp)
    index = 0
    while index < n:
        if index == n - 1 or inp[index] != inp[index + 1]:
            return inp[index]
        index += 2
    return 0

这道题作为简单题还是很合适的,只要找到了数据的特点,最多遍历1遍就可以得到答案,满足时间复杂度为O(n)的要求,同时也没有用到额外的空间,空间复杂度为O(1)。