嗨!~ 大家好,我是YK菌 🐷 ,一个微系前端 ✨,爱思考,爱总结,爱记录,爱分享 🏹,欢迎关注我呀 😘 ~ [微信公众号:
YK菌]
持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第 7 天,点击查看活动详情
今天继续来刷《剑指offer(专项突破版)》,原书是Java版本的,这里就是以JavaScript角度来看这些算法题。
剑指 Offer II 004. 只出现一次的数字
给你一个整数数组
nums,除某个元素仅出现 一次 外,其余每个元素都恰出现 三次 。 请你找出并返回那个只出现了一次的元素。
本题与主站137. 只出现一次的数字 II相同。
分析
上一篇我们将重复两次的情况做出来了【剑指Offer】整数(四)二进制 - 只出现一次的数字I - JavaScript - 掘金 (juejin.cn),今天来看看重复三次的情况,这种情况稍微难一点。
如果不考虑空间复杂度,采用上一篇说的set或map也可以完成,但是使用异或运算就做不到了。相同的数字异或自己三次得到的还是自己,所以将数组中所有数字依次进行异或操作不能消除出现三次的数字。
题目中有一个条件,就是限制了,也就是说整数只有32位(在Java中整数类型int就是32位的,而在JavaScript中没有整型,只有Number类型,是64位的浮点数类型)
所以说数组中的元素都是由32位0或1组成的。可以将数组中所有数字的同一位的数位进行相加,如果是出现三次的数字,数位相加后一定是三的倍数( 或 )。
- 如果数组中所有数的第i个数位相加之和能被3整除,那么只出现一个的数字的第
i个数位一定是0 - 如果数组中所有数的第i个数位相加之和被3除余1,那么只出现一个的数字的第
i个数位一定是1
题解
-
通过位运算
((x >> i) & 1)得到x的第i个二进制位 -
|=表示按位进行或运算,所以可以通过位运算x |= (1 << i),将x与(1 << i)(将1左移i个位置)按位或,可以将x的第i位设置为1
/**
* @param {number[]} nums
* @return {number}
*/
var singleNumber = function(nums) {
let result = 0
for(let i = 0; i < 32; i++){
let bitSum = 0
for (num of nums){
bitSum += ((num >> i) & 1)
}
if (bitSum % 3 !== 0){
result |= (1 << i)
}
}
return result
};
最后,欢迎关注我的专栏,和YK菌做好朋友