如何解决查找出现奇数次的整数
问题
给出一个整数数组,找到出现奇数次的整数。
总是只有一个整数出现奇数次。
我的尝试
function findOdd(A) {
let newArr = A.sort();
let altArr = [];
let count = 0;
let firstCharacter = newArr[0];
for (let i = 0; i < newArr.length; i++) {
if (newArr[i] == firstCharacter) {
count++;
} else {
let subArr = newArr.slice(newArr[0],count);
console.log(subArr);
altArr.push(subArr);
count = 0;
firstCharacter = newArr[i];
}
}
for (let i = 0; i < altArr.length; i++) {
if (altArr[i].length % 2 != 0) {
return altArr[i][0];
}
}
}
console.log(findOdd([20,1,-1,2,-2,3,5,4,20,5]))
问题
我使用了控制台日志,该日志显示出切片正在返回一个空数组,我认为这就是该算法被破坏的原因。但是为什么它返回一个空数组?还有我错过的其他错误吗?
解决方法
您使这个问题比实际复杂得多。天真的实现只使用一个对象来存储每个元素的频率,然后在其上进行迭代以找到出现奇数次的元素。
function findOdd(arr) {
const freq = {};
for(const num of arr){
freq[num] = (freq[num] || 0) + 1;
}
return +Object.keys(freq).find(num => freq[num] % 2 == 1);
}
更有效的实现可以利用按位XOR(^
)的属性,即a ^ a == 0
,a ^ 0 == a
以及运算是可交换和关联的事实,从而导致在数组的每个元素上应用XOR以获得答案的解决方案。
function findOdd(arr) {
return arr.reduce((a,c)=>a ^ c,0);
}
,
newArr.slice(newArr[0],count);
slice具有2个参数,它们需要是索引,而不是实际值。所以上面的代码肯定是不正确的。
我认为您可以使用字典来简化此算法。这是我的方法。
function findOdd(A) {
const appearances = {};
A.forEach(val => {
appearances[val] = (appearances[val] || 0) + 1;
});
const oddNumbers = Object.keys(appearances).filter(key => appearances[key] % 2 != 0);
return oddNumbers.length > 0 ? oddNumbers[0] : NaN;
}
,
排序后,您可以执行一个循环并对照最后一个值检查该值(初始化时不带值)。
function findOdd(array) {
let count = 0;
let last;
array.sort();
for (let i = 0; i < array.length; i++) {
if (array[i] === last) {
count++;
continue;
}
if (count % 2) return last;
last = array[i];
count = 1;
}
return last;
}
console.log(findOdd([20,1,-1,2,-2,3,5,4,20,5]))
.as-console-wrapper { max-height: 100% !important; top: 0; }
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。