Возвращает число, которое не повторяется четное количество раз

#javascript

#javascript

Вопрос:

Я пытаюсь выполнить следующую задачу…

Учитывая массив целых чисел, найдите то, которое появляется нечетное число раз.

Всегда будет только одно целое число, которое появляется нечетное число раз.

Это мое текущее решение, которое не работает. Я полагаю, что где-то есть логическая ошибка, но я не уверен. Также приветствуются любые альтернативные способы подхода к решению, которые подходят для начинающих.

Я довольно новичок в JavaScript, поэтому, пожалуйста, полегче!

 function findOdd(A) {
  for (let i = 0; i < A.length; i  ) {
    let arrayCount = [];
    let num = A[i]
    for (let x = 0; x < A.length; x  )
        if (A[i] === num) {
        arrayCount.push(num);
        //console.log(arrayCount);
        i  ;
        }
    if (arrayCount.length % 2 !== 0) {
      return num;
    }
  }
}

const checkList = [1, 1, 2, 2, 3, 4, 4];

console.log(findOdd(checkList)); 

Комментарии:

1. не могли бы вы иметь три или более одинаковых значения?

2. @NinaScholz Да, любое нечетное число раз, но только для одного целого числа.

3. я спрашивал из-за темы и «дважды»

4. @NinaScholz Извините, я не уверен, что вы имеете в виду.

5. @HaoWu Это, вероятно, отличное решение! Но я понятия не имею, что это значит как новичок!

Ответ №1:

Поскольку все они являются числами, вы можете переключать число с помощью побитового XOR:

 0 ^ 1                 -->  1
0 ^ 1 ^ 1             -->  0
0 ^ 1 ^ 1 ^ 2         -->  2
0 ^ 1 ^ 1 ^ 2 ^ 2     -->  0
0 ^ 1 ^ 1 ^ 2 ^ 2 ^ 3 -->  3
 
 const findOdd = arr => {
  let num = 0;
  for(let i of arr) {
    num ^= i;
  }
  return num;
};

console.log(findOdd([1, 1, 2, 2, 3, 4, 4])); 


Если вы не имеете дело с числами, вы все равно можете переключать их с помощью объектных клавиш:

 const findOdd = arr => {
  const obj = {};
  
  for(let i of arr) {
    // "toggle" the element, if i exists, add it to the object, otherwise remove it
    if(obj[i]) {
      delete obj[i];
    } else {
      obj[i] = true;
    }
  }
  
  return Object.keys(obj)[0];
};

console.log(findOdd(['a', 'a', 'b', 'b', 'c', 'd', 'd'])); 

Комментарии:

1. Просто предупреждаю, что трюк с XOR не сработает для чисел больше 2 ** 31 - 1 (и меньше -(2 ** 31) ), так как число будет больше 32 бит, а побитовые операции усекаются только до 32 бит.

2. В качестве отдельного примечания логику переключения во втором случае проще выразить как obj[i] = !obj[i] отсутствие необходимости в if / else . Затем вы можете взять единственное, в котором есть значение true .

Ответ №2:

Проблема с вашим подходом заключается в том, что вы помещаете любые дубликаты любого числа в arrayCount , и поэтому оно length не будет длиной одного повторяющегося числа. Вот как я бы подошел к этому:

 function findOdd(A) {
  const counts = {};
  A.forEach(function (number) {
    const currentCount = counts[number];
    if (!currentCount) {
      counts[number] = 1;
    } else {
      counts[number] = currentCount   1;
    }
  });
  
  return Object.entries(counts).find(([_, count]) => count % 2 !== 0)[0];
}

const checkList = [1, 1, 2, 2, 3, 4, 4];

console.log(findOdd(checkList)); 

Комментарии:

1. Object.entries(counts).forEach(function ([number, count]) { if (count % 2 !== 0) { oddCountNumber = number; }); — это намного короче выражается как Object.entries(counts).find(([, count]) => count % 2 !== 0)[0];