【力扣算法题每日一刷】剑指 Offer 56 - II. 数组中数字出现的次数 II(中等)

46 阅读1分钟

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

一、题目描述

在一个数组 nums 中除一个数字只出现一次之外,其他数字都出现了三次。请找出那个只出现一次的数字。

示例 1:

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

示例 2:

输入:nums = [9,1,7,9,7,9,7]
输出:1

限制:

1 <= nums.length <= 10000
1 <= nums[i] < 2^31

来源:力扣(LeetCode)

二、思路分析

题目给定条件:数组中只有一个元素出现 1 次,其余均会出现 3 次。利用这个条件,我们可以有多种解法。

解法一:排序遍历

  • 将数组从小到大进行排序,然后开始遍历;
  • 在数组范围内,将第一个元素与下一个元素进行对比,如果相同则可以跳到下3个元素;如果不同则可以获取该元素,然后直接结束遍历;
  • 获取到的元素就是我们要 return 的答案。

解法二:map 查找

  • 遍历nums数组,将每个元素存进map中,keynums中的元素,value 为元素的个数;
  • 遍历map,找到其中value === 1key,即是我们要的答案。

需要注意的是,map的遍历有多种实现方式

  1. forEach 遍历:
map.forEach(function (value,key) {

});

函数中第一个参数是属性值,第二个参数是属性

  1. for-of 遍历:
for(let item of map) {

}
遍历结果是数组

②for(let item of map.values()) {

}
遍历属性值

③for(let item of map.keys()) {

}
遍历属性
  1. entries 遍历:
for(let item of map.entries()){

}

遍历结果同forEach

三、AC 代码

解法一:排序遍历

var singleNumber = function(nums) {
    nums.sort((a, b) => a - b);
    let res = 0;
    for (let i = 0; i < nums.length; i += 3) {
        if (nums[i] === nums[i + 1] && i < nums.length) {
            continue;
        } else {
            res = nums[i];
            break;
        }
    }
    return res;
};

解法二:map 查找

var singleNumber = function(nums) {
    let map = new Map();
    let res = 0;
    for (const num of nums) {
        let val = map.has(num) ? map.get(num) : 0;
        map.set(num, ++val);
    }
    map.forEach(function (value, key) {
        if (value === 1) {
            res = key;
        }
    })
    return res;
};