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

46 阅读2分钟

问题描述

在一个班级中,每位同学都拿到了一张卡片,上面有一个整数。有趣的是,除了一个数字之外,所有的数字都恰好出现了两次。现在需要你帮助班长小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 ≤ cards.length ≤ 1001
  • 0 ≤ cards[i] ≤ 1000
  • 班级人数为奇数
  • 除了一个数字卡片只出现一次外,其余每个数字卡片都恰好出现两次

解题思路

  1. 问题分析

    • 目标是找到在一个数组中只出现一次的数字,而数组中除了一个数字之外,其余的数字都恰好出现了两次。
    • 考虑到数组的长度为n,我们需要设计一个时间复杂度为O(n)的算法。
    • 空间复杂度应该尽可能优化,尽量减少额外空间的使用。
  2. 思路设计

    • 使用哈希表(HashMap)记录每个数字出现的次数,遍历数组时更新哈希表。
    • 遍历结束后,查找哈希表中出现次数为1的数字,即为我们需要的结果。
    • 但是,根据题目要求,我们还需要考虑空间优化。虽然HashMap提供了便利,但理论上我们只需要一个定长的数组来记录数字出现的次数(假设数字范围在0到8之间,这是一个简化的假设,实际使用时需要根据数字范围调整数组大小)。
    • 如果我们假设数字范围在0到某个固定值M之间,可以创建一个长度为M+1的数组来计数,这样就不需要额外的哈希表开销。
  3. 实现细节

    • 如果使用HashMap,代码较为直观,但空间复杂度为O(n)(哈希表的开销)。
    • 如果使用定长数组,需要预先知道数字的范围。假设数字范围已知且不大,这种方法能有效减少空间使用。

最终代码:

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
public class Main {
    public static int solution(int[] inp) {
        Map<Integer,Integer> map=new HashMap<>();
        int[] nums = new int[9];
        Arrays.fill(nums,0);
        for (int i : inp) {
            if(map.containsKey(i) != true){
                map.put(i,1);
            }else {
                map.put(i,map.get(i) + 1);
            }
        }

        return map.entrySet().stream()
                .filter(entry -> entry.getValue() == 1)
                .map(Map.Entry::getKey)
                .findFirst()
                .map(key -> (int) key)
                .orElse(0);
    }
}