算法初探LeetCode-只出现一次的数字III

93 阅读2分钟

LeetCode260-只出现一次的数字III

给你一个整数数组 nums,其中恰好有两个元素只出现一次,其余所有元素均出现两次。 找出只出现一次的那两个元素。你可以按 任意顺序 返回答案。

你必须设计并实现线性时间复杂度的算法且仅使用常量额外空间来解决此问题。

示例 1:

输入: nums = [1,2,1,3,2,5]
输出: [3,5]
解释: [5, 3] 也是有效的答案。

示例 2:

输入: nums = [-1,0]
输出: [-1,0]

示例 3:

输入: nums = [0,1]
输出: [1,0]

提示:

  • 2<=nums.length<=31042 <= nums.length <= 3 * 10^4
  • 231<=nums[i]<=2311-2^{31} <= nums[i] <= 2^{31} - 1
  • 除两个只出现一次的整数外,nums 中的其他数字都出现两次

思路分析

先将数组排序,因为除了出现一次的元素其他元素都只出现两次,所以我们可以遍历数组,判断当前nums[i]是否等于nums[i+1],如果相等说明是出现两次的元素,如果不等说明是出现一次的元素。先将数组排序,因为除了出现一次的元素其他元素都只出现两次,所以我们可以遍历数组,判断当前nums[i]是否等于nums[i+1],如果相等说明是出现两次的元素,如果不等说明是出现一次的元素。

1、由于题目需要得到仅出现一次的数字,且要求在线性时间内得到,因此我们首先想到的就是利用hashmap来储存数组nums。 2、首先我们遍历数组nums,将hashmap的键值对k设为nums[i],k设为nums[i]元素出现的次数。 3、最后遍历hash,将v等于1的结果存入result。

算法代码

public int[] singleNumber(int[] nums) {
    HashMap < Integer, Integer > hashMap = new HashMap < Integer, Integer > ();
    for (int i = 0; i < nums.length; i++) {
        int r = hashMap.getOrDefault(nums[i], 0);
        hashMap.put(nums[i], r + 1);
    }
    Iterator < Integer > iteK = hashMap.keySet().iterator();
    Iterator < Integer > iteV = hashMap.values().iterator();
    List < Integer > list = new ArrayList < Integer > ();
    while (iteK.hasNext() && iteV.hasNext()) {
        int v = iteV.next();
        int k = iteK.next();
        if (v == 1) {
            list.add(k);
        }
    }
    int result[] = new int[list.size()];
    for (int i = 0; i < list.size(); i++) {
        result[i] = list.get(i);
    }
    return result;
}

结果详情

Snipaste_2023-05-10_22-46-18.png

算法复杂度

  • 空间复杂度:O(1)O(1)
  • 时间复杂度:O(n)O(n)

掘金(JUEJIN)一起进步,一起成长!