目录
1,题目
2,代码
2.1哈希表
2.2 依次确定每一个二进制位
3,学习与总结
1. 左移运算符 (<<)
2. 有符号右移运算符 (>>)
3. 无符号右移运算符 (>>>)
1,题目
给你一个整数数组 nums
,除某个元素仅出现 一次 外,其余每个元素都恰出现 三次 。请你找出并返回那个只出现了一次的元素。
你必须设计并实现线性时间复杂度的算法且使用常数级空间来解决此问题。
2,代码
2.1哈希表
/**
* @param {number[]} nums
* @return {number}
*/
var singleNumber = function(nums) {
// 哈希表
const hashtable = new Map();
for(let num of nums){
hashtable.set(num,(hashtable.has(num)|| 0) + 1);
}
for(let [key,value] of hashtable){
if(value===1){
return key;
}
}
};
下次注意使用迭代器
for( const [num, occ] of freq.entries() )
2.2 依次确定每一个二进制位
/**
* @param {number[]} nums
* @return {number}
*/
var singleNumber = function(nums) {
// 依次确定每一个二进制位
let ans = 0;
for(let i=0;i<32;i++){
let total =0;
for(let num of nums){
total += (num >> i) & 1;
}
if(total%3 != 0){
ans |= (1 << i);
}
}
return ans;
};
((num >> i) & 1)
将
num
的第i
位移动到最低位,检查这一位是否为1
ans |= (1 << i)
ans |= (1 << i)
的作用是将ans
的第i
位设置为1
。这是通过创建一个只在第i
位为1
的数字(即1 << i
),然后将其与ans
进行按位或操作来实现的。如果ans
在第i
位原本就是1
,这个操作保持该位为1
;如果ans
在第i
位是0
,这个操作将其修改为1
。
假设
ans
当前的值是2
(二进制0010
),我们要将第2
位(从右向左数,从0
开始计数)设置为1
:
1 << 2
生成了一个在第2
位为1
的数字,即0100
(二进制)或4
(十进制)。- 接着,
ans |= (1 << 2)
相当于0010 | 0100
,结果是0110
(二进制),即6
(十进制)。
for (let i = 0; i < 32; ++i) { ... }
:外层循环遍历从 0 到 31 的整数i
,代表要检查的二进制位的位置。这是因为 JavaScript 中的数字是以 32 位整数形式存储的。
3,学习与总结
JavaScript 中有几种位移运算符
1. 左移运算符 (<<
)
- 语法:
x << n
- 作用:将
x
的二进制表示向左移动n
位,右边空出的位用0
填充。 - 示例:
4 << 1
的结果是8
,因为4
的二进制是100
,向左移一位变成1000
,即8
。
2. 有符号右移运算符 (>>
)
- 语法:
x >> n
- 作用:将
x
的二进制表示向右移动n
位,保持符号位不变(即正数左边填充0
,负数填充1
)。 - 示例:
-8 >> 2
的结果是-2
。-8
的二进制表示(假设是 8 位)是11111000
,向右移两位,填充最左边的符号位(1
),得到11111110
,即-2
。
3. 无符号右移运算符 (>>>
)
- 语法:
x >>> n
- 作用:将
x
的二进制表示向右移动n
位,左边空出的位用0
填充,不考虑符号位。 - 示例:
-8 >>> 2
的结果取决于你的 JavaScript 引擎如何处理 32 位整数,但它会将-8
视为一个很大的正数(因为二进制的最高位被视为值位而不是符号位)。
使用场景和注意事项:
- 性能优化:位移运算符通常用于性能敏感的低层代码,例如图形计算、加密算法等,因为它们直接操作二进制位,运行速度快。
- 逻辑操作:位移运算可以用来执行乘法或除法操作(例如,左移一位相当于乘以 2,右移一位相当于除以 2),但要注意符号和数值范围。
- 无符号右移:在处理无符号数或将负数以无符号的形式解释时特别有用。
- 类型转换:位移运算符会将操作数转换为 32 位整数,这可能会导致意外的行为,尤其是在使用无符号右移时。
示例
假设
num = 5
(二进制为0101
)和i = 2
,我们来看这行代码如何工作:
- 首先,
num >> i
是5 >> 2
,意味着将5
的二进制表示向右移动两位,得到0001
。- 接着,
(num >> i) & 1
是0001 & 0001
,结果为1
,因为最低位是1
。