행렬 테두리 회전하기

Happhee·2022년 2월 12일
0

[ Lv2 ] programmers

목록 보기
23/32
post-thumbnail

📝 행렬 테두리 회전하기

🖥 나의 JS 코드

첫번째 시도

이동된 사각형판을 가져와서 지나가는 경로에 위치한 원소들 중 가장 작은 숫자를 반환하는 함수 getMin( )을 작성하였다

function getMin(rectangle, start_x, start_y, end_x, end_y){
    let top = rectangle[start_x].slice(start_y, end_y+1);
    let bottom =  rectangle[end_x].slice(start_y, end_y+1);
    let min = Math.min(...top, ...bottom);
    
    for(let i = start_x+1 ; i < end_x ; i++)
        if(min > rectangle[i][start_y])
            min = rectangle[i][start_y]
    
    for(let i = start_x+1 ; i < end_x ; i++)
        if(min > rectangle[i][end_y])
            min = rectangle[i][end_y]
    
    return min
}

우선, 사각형 보드에 숫자를 넣기 위해 new Array생성자 함수를 통해서 1부터 순서대로 값을 넣어준다

이후 윗변, 우변, 아랫변, 좌변 순으로 각각의 요소들을 이동시킨다.

최종적인 코드는 다음과 같다👇

function solution(rows, columns, queries) {
    var answer = [];
    let rectangle = new Array(rows);
    let number = 1;
    for(let j = 0 ; j < rows ; j++){
        rectangle[j] = new Array(columns)
        for(let i = 0 ; i < columns ; i++){
            rectangle[j][i] = number;
            number++;
        }
    }
    for(const query of queries){
        let [start_x, start_y, end_x, end_y] = query
        start_x -=1;
        start_y -=1;
        end_x -=1;
        end_y -=1;
        
        let min = rectangle[start_x][start_y]
        // 윗변이동
        let tmp = rectangle[start_x][end_y];
        for(let i = end_y  ; i > start_y ; i--){
            rectangle[start_x][i] =  rectangle[start_x][i-1];
        }
        
        // 우변 이동
        let tmp2 = rectangle[end_x][end_y];
        for(let i = end_x ; i > start_x+1 ; i--){
            rectangle[i][end_y] =  rectangle[i-1][end_y];
        }
        rectangle[start_x+1][end_y] = tmp;
        
        // 밑변 이동
        tmp = rectangle[end_x][start_y];
        for(let i = start_y ; i <= end_y-2 ; i++){
            rectangle[end_x][i] =  rectangle[end_x][i+1];
        }
        
        // 좌변이동
        for(let i = start_x  ; i <= end_x-2 ; i++){
            rectangle[i][start_y] =  rectangle[i+1][start_y];
        }
        rectangle[end_x][end_y-1] = tmp2;
        rectangle[end_x-1][start_y] = tmp;
        
        
        answer.push(getMin(rectangle, start_x, start_y, end_x, end_y));
    }
    return answer;
}

두번째 시도

첫번째에 수행했던 코드에서 만족스럽지 못한 부분이 너무 많은 반복문을 정신없이 사용해서 코드를 구현하는 나도 헷갈려 문제 해결까지 시간이 오래걸렸다

변경할 값을 다른 tmp에 저장하고 이를 가져와서 다시 넣어주는 로직이 꼬이면 문제를 해결할 수 없다

따라서 나는 스택을 사용하여 조금더 간편한 방식으로 문제를 다시 해결하였다

최종 코드는 다음과 같다👇

function solution(rows, columns, queries) {
    const answer = [];
    // 행렬 생성 및 초기화
    const board = new Array(rows)
        .fill(0)
        .map(() => new Array(columns))

    let num = 1;
    for (let i = 0; i < rows; i++) {
        for (let j = 0; j < columns; j++) {
            board[i][j] = num;
            num += 1;
        }
    }
    // 쿼리 실행
    queries.forEach((query) => {
        // 각 좌표들은 query가 가진 data -1 의 인덱스로 변환시켜주기
        const [x1, y1, x2, y2] = query.map(data => data - 1);
        const moveBoard = [];
        // 이동해야할 행렬의 데이터들 담아오기 상단 -> 우변 -> 하단 -> 좌변
        for (let y = y1; y <= y2; y++) moveBoard.push(board[x1][y]);
        for (let x = x1 + 1; x <= x2; x++) moveBoard.push(board[x][y2]);
        for (let y = y2 - 1; y >= y1; y--) moveBoard.push(board[x2][y]);
        for (let x = x2 - 1; x > x1; x--) moveBoard.push(board[x][y1]);
        // 마지막 값을 맨 앞으로 이동
        const lastData = moveBoard.pop();
        moveBoard.unshift(lastData);
        // 이동하는 데이터들 중 가장 작은값을 결과에 넣어주고
        answer.push(Math.min(...moveBoard))
        // 행렬의 값 변경
        for (let y = y1; y <= y2; y++) board[x1][y] = moveBoard.shift();
        for (let x = x1 + 1; x <= x2; x++) board[x][y2] = moveBoard.shift();
        for (let y = y2 - 1; y >= y1; y--)board[x2][y] = moveBoard.shift();
        for (let x = x2 - 1; x > x1; x--) board[x][y1] = moveBoard.shift();
    })
    return answer;
}
profile
즐기면서 정확하게 나아가는 웹프론트엔드 개발자 https://happhee-dev.tistory.com/ 로 이전하였습니다

0개의 댓글