这是我参与11月更文挑战的第13天,活动详情查看:2021最后一次更文挑战
前言
每日js练习算法题,今天来一道只出现一次的数字的算法题,顾名思义就是数组中不重复的那个数字,听起来是不是很简单,好像和217题有点像,下面来看看题目
题目描述
给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
说明:
你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?
示例 1:
输入: [2,2,1]
输出: 1
示例 2:
输入: [4,1,2,1,2]
输出: 4
解题思路
- 题干非常的简练,只有短短的几句话,给的数组中只有一个数字是不重复的,其余的都重复了两次
- 这一题首先可以用一种很常见的方法,那就是把时输入数组进行排序,排序后的数组重复的数字肯定是相邻的,那么如果一个数组不和它相邻的项一样就说明它就是要找的那个数字
- 上面说的方法可以得到我们想要的结果,但我这里提供给大家另外一种方法,还是大家不常用的利用map集合的方法来解决这个问题
- 首先我们声明一个map集合,然后循环输入的数组, 当map集合中没有这一项的时候就set进去,如果存在了就更新map中相同键对应的值,也就是map.set(nums[i],2),这里之所以可以这样写是因为map集合中已经存在的项如果再set进来相同的键,那么就会更新这个键对应的值,写2的原因是题目说只有两个重复的项,所以可以直接写了
- 当我们把数组循环一遍之后,map集合中的内容就是所有不同的键组成的集合,这些键就是我们数组中不相同的数字,键对应的值就是数组中出现这个数字的次数
- 最后我们从map集合中找到键对应的值是1的那个键,这个键就是我们要找的那个不重复的数字,代码如下
/**
* @param {number[]} nums
* @return {number}
*/
var singleNumber = function (nums) {
let map = new Map()
const n = nums.length
for (let i = 0; i < n; i++) {
if (map.has(nums[i])) {//判断map中是否已经有这个键了,如果有就更新键对应的值
map.set(nums[i], 2)
} else {
map.set(nums[i], 1)//这里说明map中还没这个键,直接set进去键和值
}
}
for (let [key, value] of map) {//map集合的遍历用这种形式
if (value === 1) {
return key
}
}
};
总结
map集合这种数据结构不常用,没事还得多练习练习,gogogo