嗨!~ 大家好,我是YK菌 🐷 ,一个微系前端 ✨,爱思考,爱总结,爱记录,爱分享 🏹,欢迎关注我呀 😘 ~ [微信公众号:
YK菌
]
持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第 6 天,点击查看活动详情
今天继续来刷《剑指offer(专项突破版)》,原书是Java版本的,这里就是以JavaScript角度来看这些算法题。
剑指 Offer II 004. 只出现一次的数字
给你一个整数数组
nums
,除某个元素仅出现 一次 外,其余每个元素都恰出现 三次 。 请你找出并返回那个只出现了一次的元素。
本题与主站137. 只出现一次的数字 II相同。主站还有一题136. 只出现一次的数字:给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。今天我们先来分析136这道题。
分析
头脑风暴一下很容易想出来很多简单暴力的解法。
- 最简单想到的当然就是先排序,然后就直接遍历找出唯一的元素即可。
/**
* @param {number[]} nums
* @return {number}
*/
var singleNumber = function(nums) {
nums.sort((a,b)=>a-b)
for(let i = 0; i < nums.length; i++){
// 由于js的特性,数组越界得到的值是undefined,所以可以进行比较,也就可以通过测试用例,但是十分不推荐这样编写代码
if(nums[i] !== nums[i-1] && nums[i] !== nums[i+1]){
return nums[i]
}
}
};
由于js的特性,数组越界得到的值是undefined
,所以可以进行比较,也就可以通过测试用例,但是十分不推荐这样编写代码,所以需要考虑首个元素和末尾元素以及只有一个元素时的情况,对代码稍作修改:
var singleNumber = function(nums) {
nums.sort((a,b)=>a-b)
if(nums.length === 1 || nums[0] !== nums[1]) return nums[0]
if(nums[nums.length-1] !== nums[nums.length-2]) return nums[nums.length-1]
for(let i = 1; i < nums.length-1; i++){
if(nums[i] !== nums[i-1] && nums[i] !== nums[i+1]){
return nums[i]
}
}
};
- 还能想到的就是使用一个
set
储数字。遍历数组中的每个数字,如果集合中没有该数字,则将该数字加入集合,如果集合中已经有该数字,则将该数字从集合中删除,最后剩下的数字就是只出现一次的数字。
var singleNumber = function(nums) {
let set = new Set()
for(let i = 0; i < nums.length; i++){
if(set.has(nums[i])){
set.delete(nums[i])
}else{
set.add(nums[i])
}
}
let [result] = [...set]
return result
};
- 还可以使用一个
map
,key
用来记录元素,value
用来记录元素出现的次数,最后得到出现一次的元素即可。
var singleNumber = function(nums) {
let map = new Map()
for(let i = 0; i < nums.length; i++){
if(map.has(nums[i])){
map.set(nums[i], 2)
}else {
map.set(nums[i], 1)
}
}
let result = 0
map.forEach((value,key)=>{
if(value === 1){
result = key
}
})
return result
};
上面的解法都利用了新的空间,有没有一种线性的解法呢?这里可以采用位运算
的方法
题解
可以使用异或运算,异或运算有以下三条性质
- 任何数和 0 做异或运算,结果仍然是原来的数
- 任何数和其自身做异或运算,结果是 0
- 异或运算满足交换律和结合律
本题利用异或运算的性质2:任何数和其自身做异或运算,结果是 0。我们只需要从数组的第一个元素开始不断向后做异或操作,得到最后的答案就是只出现一次的数字。也就是说一次遍历即可,且不需要额外的空间。
/**
* @param {number[]} nums
* @return {number}
*/
var singleNumber = function(nums) {
let result = nums[0]
for(let i = 1; i < nums.length; i++){
result ^= nums[i]
}
return result
};
最后,欢迎关注我的专栏,和YK菌做好朋友