LeetCode 算法:只出现一次的数字

71 阅读1分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第 30 天,点击查看活动详情

只出现一次的数字

原题地址

给你一个整数数组 nums ,除某个元素仅出现 一次 外,其余每个元素都恰出现 三次 。请你找出并返回那个只出现了一次的元素。

示例 1:

输入:nums = [2,2,3,2]
输出:3

示例 2:

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

  提示:

  • 1 <= nums.length <= 3 *10410^4
  • 231-2^{31}<= nums[i] <=23112^{31} - 1
  • nums 中,除某个元素仅出现 一次 外,其余每个元素都恰出现 三次  

进阶:

  • 你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?

思路分析

方法一

  1. 通俗粗暴的方法,就是先统计数组中每个元素出现的次数,然后判断次数;
  2. 因此定义 res 来存储数组中每个元素出现的次数,key 为元素,value 为元素出现的次数;
  3. 然后遍历 res,寻找出现次数为1的元素,返回其 key 即可。

方法二

  1. 方法一中,我们是统计了所有元素的次数,然后寻找只出现一次的元素;
  2. 题目要求只是寻找只出现一次的元素即可,因此我们换一种思路来解决,首先定义 map 来存储元素是否出现过,然后定义一个 Setres 来存储只出现一次的元素;
  3. 判断过程为在 map 中存在的话,就将 res 中的该元素删除。若不存在,则将 map 中的元素置为 true,将 res 中添加该元素;
  4. 最后取出 res 中的元素即可。

AC 代码

方法一

/**
 * @param {number[]} nums
 * @return {number}
 */
var singleNumber = function(nums) {
    const res = {}
    nums.forEach(item => {
        res[item] ? res[item] += 1 : res[item] = 1
    })
    const keys = Object.keys(res)
    for(let i = 0; i < keys.length; i++) {
        if(res[keys[i]] === 1) return keys[i]
    }
};

结果:

  • 执行结果: 通过
  • 执行用时:76 ms, 在所有 JavaScript 提交中击败了25.81%的用户
  • 内存消耗:42.5 MB, 在所有 JavaScript 提交中击败了40.73%的用户
  • 通过测试用例:14 / 14

方法二

/**
 * @param {number[]} nums
 * @return {number}
 */
var singleNumber = function(nums) {
    const map = {}
    const res = new Set()
    nums.forEach(item => {
        if (map[item]) {
            res.delete(item)
        } else {
            map[item] = true
            res.add(item)
        }
    })
    return [...res][0]
};

结果:

  • 执行结果: 通过
  • 执行用时:60 ms, 在所有 JavaScript 提交中击败了88.15%的用户
  • 内存消耗:43.6 MB, 在所有 JavaScript 提交中击败了14.34%的用户
  • 通过测试用例:14 / 14

END