Computer >> 컴퓨터 >  >> 프로그래밍 >> JavaScript

JavaScript로 두 배열 사이의 아나그램 매핑 구현하기

아나그램 배열이란?

한 배열의 요소들을 임의로 재배열했을 때 다른 배열과 완전히 동일해진다면, 두 배열은 서로의 아나그램(anagram)이라고 합니다.

예를 들어 다음과 같습니다.

[1, 2, 3]과 [2, 1, 3]은 서로 아나그램 관계입니다.

두 배열 arr1arr2가 서로 아나그램 관계라고 가정해 봅시다. 이때 필요한 것은 두 배열을 입력받아 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에서 어느 인덱스에 위치하는지 정확히 대응시키는 것이라는 점을 기억하세요.