문제 이해하기
두 개의 요소를 가진 배열 [a, b]를 입력받아, a와 b 사이에 있는 모든 숫자의 합(a와 b 포함)을 반환하는 함수 sumBetween()을 작성해야 합니다.
예를 들면 다음과 같습니다.
[4, 7] → 4+5+6+7 = 22
[10, 6] → 10+9+8+7+6 = 40
해결 접근 방식
반복문으로 모든 숫자를 하나씩 더하는 대신, 등차수열의 합 공식을 활용하면 훨씬 효율적으로 문제를 해결할 수 있습니다. 1부터 n까지의 자연수 합은 다음 공식으로 구할 수 있습니다.
sum(n) = n × (n + 1) / 2
이 공식을 활용한 계산 순서는 다음과 같습니다.
- 두 수 중 큰 값까지의 합에서 작은 값까지의 합을 뺍니다.
- 이 과정에서 작은 값이 두 번 제외되므로, 마지막에 작은 값을 다시 한 번 더해줍니다.
코드 구현
const arr = [10, 60];
const sumUpto = (n) => (n*(n+1))/2;
const sumBetween = (array) => {
if(array.length !== 2){
return -1;
}
const [a, b] = array;
return sumUpto(Math.max(a, b)) - sumUpto(Math.min(a, b)) + Math.min(a,b);
};
console.log(sumBetween(arr));
console.log(sumBetween([4, 9]));
실행 결과
콘솔에 출력되는 결과는 다음과 같습니다.
1785
39
코드 상세 설명
sumUpto(n): 1부터 n까지의 자연수 합을 등차수열 공식으로 계산하는 함수입니다.
sumBetween(array): 먼저 배열의 길이가 2가 아니면 유효하지 않은 입력으로 판단하여 -1을 반환합니다. 이후 구조 분해 할당으로 두 값을 꺼내고, Math.max()와 Math.min()으로 큰 값과 작은 값을 구분한 뒤 공식을 적용합니다.
입력값 [10, 60]의 경우 sumUpto(60) − sumUpto(10) + 10 = 1830 − 55 + 10 = 1785가 계산되며, [4, 9]의 경우 sumUpto(9) − sumUpto(4) + 4 = 45 − 10 + 4 = 39가 출력됩니다.
이 방식은 배열의 크기와 무관하게 O(1)의 시간 복잡도로 결과를 얻을 수 있어, 반복문을 사용하는 방식보다 성능 면에서 큰 이점을 가집니다.