아나그램 배열이란?
한 배열의 요소들을 임의로 재배열했을 때 다른 배열과 완전히 동일해진다면, 두 배열은 서로의 아나그램(anagram)이라고 합니다.
예를 들어 다음과 같습니다.
[1, 2, 3]과 [2, 1, 3]은 서로 아나그램 관계입니다.
두 배열 arr1과 arr2가 서로 아나그램 관계라고 가정해 봅시다. 이때 필요한 것은 두 배열을 입력받아 arr1과 같은 길이의 새로운 매핑 배열을 반환하는 JavaScript 함수입니다. 이 매핑 배열에는 arr1의 각 요소가 arr2에서 위치한 인덱스 값이 순서대로 담겨야 합니다.
입출력 예시
입력 배열이 다음과 같다면,
const arr1 = [23, 39, 57, 43, 61]; const arr2 = [61, 23, 43, 57, 39];
출력은 다음과 같아야 합니다.
const output = [1, 4, 3, 2, 0];
그 이유는 다음과 같습니다.
arr1의 0번 인덱스 요소(23)는arr2의 1번 인덱스에 위치합니다.arr1의 1번 인덱스 요소(39)는arr2의 4번 인덱스에 위치하며, 나머지 요소도 같은 방식으로 매핑됩니다.
방법 1: 이중 반복문 사용
가장 직관적인 접근方式은 중첩 반복문을 이용해 arr1의 각 요소가 arr2의 어느 위치에 있는지 하나씩 찾는 것입니다.
const arr1 = [23, 39, 57, 43, 61];
const arr2 = [61, 23, 43, 57, 39];
const anagramMappings = (arr1 = [], arr2 = []) => {
const res = [];
for(let i = 0; i < arr1.length; i++) {
for(let j = 0; j < arr2.length; j++) {
if(arr1[i] == arr2[j]) {
res.push(j);
}
}
}
return res;
};
console.log(anagramMappings(arr1, arr2));실행 결과
콘솔에 출력되는 결과는 다음과 같습니다.
[ 1, 4, 3, 2, 0 ]
방법 2: indexOf()로 간결하게
Array.prototype.indexOf() 메서드를 활용하면 내부 반복문을 없애고 코드를 한 줄로 줄일 수 있습니다.
const anagramMappings = (arr1 = [], arr2 = []) => arr1.map(el => arr2.indexOf(el)); console.log(anagramMappings(arr1, arr2)); // [ 1, 4, 3, 2, 0 ]
방법 3: Map 객체로 성능 최적화
위 두 방식은 모두 O(n²)의 시간 복잡도를 가지므로, 배열의 크기가 커지면 비효율적입니다. Map 객체를 사용해 각 요소의 인덱스를 미리 저장하면 시간 복잡도를 O(n)까지 개선할 수 있습니다.
const anagramMappings = (arr1 = [], arr2 = []) => {
const indexMap = new Map();
arr2.forEach((el, idx) => indexMap.set(el, idx));
return arr1.map(el => indexMap.get(el));
};
console.log(anagramMappings(arr1, arr2)); // [ 1, 4, 3, 2, 0 ]정리
작은 배열에서는 이중 반복문이나 indexOf()로 충분하지만, 실무에서 성능이 중요한 상황이라면 Map 기반 구현을 사용하는 것이 좋습니다. 문제의 핵심은 arr1의 각 요소가 arr2에서 어느 인덱스에 위치하는지 정확히 대응시키는 것이라는 점을 기억하세요.