JavaScript如何快速求出数组中出现一次的数字?
1.假设数组中只有一个数字出现一次,其他都出现两次,求这个数字是多少?
解法:相同数字异或(4^4=0)为0,所以对数组中每个数字异或最后得到的是出现一次的数字。
用异或操作时间复杂度为O(n),空间复杂度为O(1)。这题异或操作应该是最优解法了,其他用set()和数组、哈希表的解法空间复杂度都比异或高。
function findSingleNumbers(nums) {
// 对所有数字进行异或操作
let xor_result = 0;
for (let num of nums) {
result ^= num;
}
return [result]
}
// 示例用法
let nums = [1, 2, 3, 2, 4, 4, 1];
let result = findSingleNumbers(nums);
console.log(result); // 输出 [3]
2.假设数组中有两个数字出现一次,其他都出现两次,求这两个数字是多少?
解法:仍然采用异或。假设要求的两个数字分别为a和b,我们可以将所有数字进行异或操作,得到的结果就是a和b的异或值(记为xor_result)。由于a和b不相等,所以它们的二进制表示一定存在至少一个位上不相同,即在xor_result中对应为1的位。
我们可以通过这个位来将所有数字分成两组:一组是该位为1的数字集合,另一组是该位为0的数字集合。这样,a和b就一定被分到了不同的两组中,而其他数字都会被分到相同的两组中。
接下来,我们只需要分别对这两组数字进行异或操作,即可得到a和b的值。
下面是使用JavaScript实现的代码:
function findSingleNumbers(nums) {
// 对所有数字进行异或操作
let xor_result = 0;
for (let num of nums) {
xor_result ^= num;
}
// 用与操作找到异或结果中最低位的1
// 例如:4 & (-4):00000100 & (11111100) = 00000100
let lowest_bit = xor_result & (-xor_result);
// 初始化两个结果数
let num1 = 0, num2 = 0;
// 根据最低位的1将数字分组,并分别进行异或操作
for (let num of nums) {
if (num & lowest_bit) {
num1 ^= num;
} else {
num2 ^= num;
}
}
return [num1, num2];
}
// 示例用法
let nums = [1, 2, 3, 2, 4, 4, 5, 1];
let result = findSingleNumbers(nums);
console.log(result); // 输出 [3, 5]