문제 상황
두 개의 숫자 배열이 있고, 각 배열이 하나의 범위(range)를 나타낸다고 가정해 보겠습니다.
const arr1 = [2, 5];
const arr2 = [4, 7];
여기서 우리는 이러한 두 배열을 인수로 받는 JavaScript 함수를 작성해야 합니다. 함수는 입력된 두 범위가 겹치는 구간, 즉 교집합에 해당하는 새로운 범위 배열을 생성한 뒤 이를 반환해야 합니다.
따라서 위 입력값에 대한 출력 결과는 다음과 같습니다.
const output = [4, 5];
교집합 계산 원리
두 범위 [a1, b1]과 [a2, b2]의 교집합은 다음 두 가지 규칙만으로 간단히 구할 수 있습니다.
- 왼쪽 경계(leftLimit): 두 범위의 시작 값 중 더 큰 값 → Math.max(a1, a2)
- 오른쪽 경계(rightLimit): 두 범위의 끝 값 중 더 작은 값 → Math.min(b1, b2)
참고로, 계산된 leftLimit이 rightLimit보다 크다면 두 범위는 서로 겹치지 않는 것입니다. 필요에 따라 이 경우 빈 배열이나 null을 반환하도록 처리할 수 있습니다.
예제 코드
const arr1 = [2, 5];
const arr2 = [4, 7];
const findRangeIntersection = (arr1 = [], arr2 = []) => {
const [el11, el12] = arr1;
const [el21, el22] = arr2;
const leftLimit = Math.max(el11, el21);
const rightLimit = Math.min(el12, el22);
return [leftLimit, rightLimit];
};
console.log(findRangeIntersection(arr1, arr2));
코드 설명
- 구조 분해 할당(Destructuring)을 사용해 첫 번째 범위의 시작(el11)과 끝(el12), 두 번째 범위의 시작(el21)과 끝(el22)을 한 번에 추출합니다.
- Math.max()로 두 시작 값 중 큰 값을, Math.min()으로 두 끝 값 중 작은 값을 구해 교집합의 양쪽 경계를 결정합니다.
- 매개변수에 기본값 []을 지정하여 인수가 누락되더라도 오류 없이 안전하게 동작하도록 했습니다.
실행 결과
코드를 실행하면 콘솔에 다음과 같이 출력됩니다.
[ 4, 5 ]
[2, 5]와 [4, 7]이 겹치는 구간은 4부터 5까지이므로, 결과 배열 [4, 5]가 정확히 두 범위의 교집합을 나타냅니다. 이 방식은 시간 복잡도 O(1)로 매우 효율적이며, 일정 관리나 좌표 겹침 검사 등 다양한 실무 상황에서 활용할 수 있습니다.