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

JavaScript로 배열 회전하기: 요소를 n칸 이동시키는 방법

문제 이해하기

배열과 숫자 n을 인자로 받아, 배열의 요소들을 왼쪽으로 n칸 회전시키는 JavaScript 함수를 작성해야 한다고 가정해 보겠습니다.

예를 들어, 입력 배열이 다음과 같다면 —

const arr = [12, 6, 43, 5, 7, 2, 5];

여기서 n이 3이라면, 출력 결과는 다음과 같아야 합니다 —

const output = [5, 7, 2, 5, 12, 6, 43];

즉, 앞쪽의 3개 요소(12, 6, 43)가 배열의 끝으로 이동하고, 나머지 요소들은 앞으로 당겨지는 방식입니다.

구현 코드

다음은 이 기능을 구현한 전체 코드입니다 —

// 한 칸씩 회전하는 헬퍼 함수
const rotateByOne = arr => {
    for(let i = 0; i < arr.length - 1; i++){
        temp = arr[i];
        arr[i] = arr[i+1];
        arr[i+1] = temp;
    };
}

// Array 프로토타입에 rotateBy 메서드 추가
Array.prototype.rotateBy = function(n){
    const { length: l } = this;
    if(n >= l){
        return;
    };
    for(let i = 0; i < n; i++){
        rotateByOne(this);
    };
};

const a = [1,2,3,4,5,6,7];
a.rotateBy(2);
console.log(a);

출력 결과

콘솔에 출력되는 결과는 다음과 같습니다 —

[
 3, 4, 5, 6,
 7, 1, 2
]

코드 동작 원리

이 코드의 핵심 로직은 두 부분으로 나눌 수 있습니다.

1. rotateByOne 함수

배열 내에서 인접한 두 요소를 맞바꾸는(swap) 작업을 배열 끝까지 반복합니다. 이 과정을 한 번 거치면 첫 번째 요소가 마지막으로 이동하면서 배열 전체가 한 칸 왼쪽으로 회전됩니다.

2. rotateBy 메서드

Array.prototype에 추가된 이 메서드는 rotateByOne을 n번 호출하여 원하는 만큼 회전을 수행합니다. 단, n이 배열 길이보다 크거나 같으면 아무 작업도 하지 않고 종료됩니다.

주의할 점

위 구현에는 몇 가지 개선 여지가 있습니다.

  • n이 배열 길이보다 큰 경우: 현재 코드는 회전 없이 그대로 반환합니다. n % length 연산으로 나머지를 구하면 어떤 값이 들어와도 올바르게 처리할 수 있습니다.
  • 성능: 한 칸씩 반복 회전하는 방식은 시간 복잡도가 O(n×k)입니다. 더 효율적인 방법이 필요하다면 아래의 slice 활용법을 고려해 보세요.

더 간단한 대안: slice() 활용

원본 배열을 변경하지 않으면서 새 배열을 반환하는 방식을 선운다면, slice()를 사용하는 것이 훨씬 간결합니다.

const rotate = (arr, n) => {
    const k = n % arr.length;
    return [...arr.slice(k), ...arr.slice(0, k)];
};

console.log(rotate([1,2,3,4,5,6,7], 2)); // [3,4,5,6,7,1,2]
console.log(rotate([1,2,3,4,5,6,7], 9)); // [3,4,5,6,7,1,2]

이 방식은 n % length로 회전 횟수를 정규화하기 때문에 n이 배열 길이보다 커도 정확하게 동작하며, 불변성(immutability)을 유지한다는 장점도 있습니다.

마무리

배열 회전은 코딩 테스트와 실무에서 자주 등장하는 기본기 문제입니다. swap 기반의 반복 방식은 알고리즘 동작 원리를 이해하는 데 도움이 되고, slice 기반 방식은 실제 코드에서 가독성과 안정성 면에서 유리합니다. 상황에 맞게 두 가지 접근법을 선택해서 활용해 보세요.