문제 정의
정수로만 이루어진 배열 arr을 첫 번째이자 유일한 인자로 받는 JavaScript 함수를 작성해야 합니다.
이 배열에는 흥미로운 조건이 숨어 있습니다. 배열을 이루는 모든 수는 같은 홀짝성을 공유하되, 단 하나의 요소만 나머지와 다릅니다. 즉, 전부 짝수 가운데 홀수가 딱 하나 섞여 있거나, 전부 홀수 가운데 짝수가 딱 하나 섞여 있는 형태입니다. 함수는 바로 이 '이질적인' 요소 하나를 찾아 반환해야 합니다.
입력 · 출력 예시
예를 들어 함수에 아래와 같은 배열이 주어졌다고 가정해 보겠습니다.
입력
const arr = [5, 9, 7, 11, 34, 23, 77];
출력
const output = 34;
출력 설명
배열의 나머지 요소(5, 9, 7, 11, 23, 77)는 모두 홀수이지만, 34만 유일한 짝수이기 때문입니다.
풀이 접근 방법
핵심 아이디어는 단순합니다. 배열을 한 번 순회하면서 요소들을 짝수 그룹과 홀수 그룹으로 나누어 담고, 요소가 하나뿐인 그룹의 값을 반환하면 됩니다.
코드 구현
const arr = [5, 9, 7, 11, 34, 23, 77];
const findDifferent = (arr = []) => {
const evens = [];
const odds = [];
for (let i = 0; i < arr.length; i++) {
// 음수도 올바르게 판별하기 위해 Math.abs() 사용
if (Math.abs(arr[i] % 2) === 1) {
odds.push(arr[i]);
} else {
evens.push(arr[i]);
}
}
// 요소가 하나뿐인 그룹의 값을 반환
return evens.length === 1 ? evens[0] : odds[0];
};
console.log(findDifferent(arr));출력 결과
34
코드 설명
먼저 짝수를 담을 evens 배열과 홀수를 담을 odds 배열을 준비합니다. 이후 for 반복문으로 배열을 순회하며 각 요소를 2로 나눈 나머지를 확인하고, 해당하는 그룹에 push합니다.
여기서 한 가지 주의할 점이 있습니다. JavaScript에서 음수에 % 연산자를 적용하면 결과가 음수로 나옵니다. 예를 들어 -3 % 2의 결과는 1이 아니라 -1입니다. 따라서 Math.abs()로 절댓값을 취한 뒤 1과 비교하면 음수인 홀수도 정확하게 판별할 수 있습니다.
마지막으로 두 그룹의 length를 비교합니다. 요소가 하나뿐인 그룹이 곧 정답이므로, 삼항 연산자를 이용해 해당 그룹의 첫 번째(유일한) 요소를 반환합니다.
filter()를 활용한 더 간결한 풀이
배열 내장 메서드를 활용하면 같은 로직을 훨씬 선언적으로 표현할 수 있습니다.
const findDifferent = (arr = []) => {
const evens = arr.filter(num => num % 2 === 0);
// 짝수가 하나뿐이면 짝수를, 그렇지 않으면 홀수를 반환
return evens.length === 1 ? evens[0] : arr.find(num => num % 2 !== 0);
};
console.log(findDifferent([5, 9, 7, 11, 34, 23, 77])); // 34filter()로 짝수만 추출한 뒤 그 개수를 확인하고, 짝수가 하나면 그 값을, 아니라면 find()로 홀수를 찾아 반환합니다. 코드가 짧아져 가독성이 크게 향상됩니다.
마무리
두 풀이 모두 배열을 한 번만 순회하므로 시간 복잡도는 O(n)입니다. 홀짝성 판별 문제에서는 이렇게 요소를 그룹으로 나누고 개수를 비교하는 접근이 가장 직관적이면서도 실수하기 어려운 방법입니다. 실무에서는 filter()와 find()를 조합한 두 번째 풀이처럼 의도가 명확히 드러나는 코드를 작성하는 것을 권장합니다.