N

(프로그래머스 JS KAKAO)표 편집 본문

프로그래머스 알고리즘/KAKAO

(프로그래머스 JS KAKAO)표 편집

naeunchan 2022. 4. 12. 11:03
728x90
반응형

https://programmers.co.kr/learn/courses/30/lessons/81303

 

코딩테스트 연습 - 표 편집

8 2 ["D 2","C","U 3","C","D 4","C","U 2","Z","Z"] "OOOOXOOO" 8 2 ["D 2","C","U 3","C","D 4","C","U 2","Z","Z","U 1","C"] "OOXOXOOO"

programmers.co.kr

 

Node class를 선언하여, 양방향 리스트 형태로 문제를 풀었다.

 

Node class는 val, prev, next를 갖는다.

생성자로 val은 매개변수로 받아오며, prev와 next는 null을 가지도록 한다.

 

n개의 크기로 answer와 node를 선언한다.

answer는 "O"로 초기화,

node는 new Node()로 초기화 한다.

 

이후 node를 순회하면서 val을 갱신한다.

또한, next와 prev를 인덱스에 맞춰서 양방향 리스트로 이어지게 한다.

 

다음은 cmd를 순회하면서 명령어를 처리하도록 한다.

cmd[i]를 " "으로 split 하여 splited라는 배열에 저장했다.

만약 "U" 또는 "D"가 나온다면 splited는 2의 크기를 가질 것이며, splited[1] = 움직이는 횟수(move)를 나타낼 것이다.

 

명령어를 switch로 처리.

"U" or "D'인 경우, k를 move 만큼 이동시킨다.

이동시킬 때는 node[k]의 next나 prev를 이용하여 k를 갱신시키도록 한다.

(양방향 리스트로 처리했기 때문에 가능)

 

"C"인 경우, 현재 k에 있는 노드를 지우고, k를 아래로 이동시켜야 한다.

삭제한 노드는 deleted라는 배열에 스택 형태로 저장한다.

또한, node[k]에 있는 next와 prev를 새롭게 이어주어야 한다.

 

node[prev]가 null이 아닌 경우,

node[prev] = next.

 

node[next]가 null이 아닌 경우,

node[next] = prev.

 

null 처리를 하는 이유는 현재 k가 양 끝에 있는 경우를 처리하기 위함이다.

만약 k가 0이면 prev는 없기 때문이며, k가 가장 끝에 있는 경우 next가 없기 때문이다.

 

새롭게 이어준 후 k = next ? next : prev로 갱신.

삼항 연산자로 처리한 이유는 k가 가장 끝에 있는 경우 아래로 이동할 수 없기 때문에, 바로 윗 행으로 이어줘야 한다.

 

마지막으로 "Z".

deleted에 스택 형태로 저장되어있기 때문에 pop을 통해 하나씩 복구 시키면 된다.

restore 변수로 꺼내온 후,

restore에서 val, prev, next를 꺼낸다.

 

복구하는 과정에 "C" 명령어와 비슷하다.

null 여부를 확인해서 원래대로 이어주면 된다.

 

모든 명령어 작업이 끝나면 deleted에 남아있는 노드의 val을 확인하여 answer[val] = "X"로 처리한 후,

리턴은 answer.join("")으로 하여 하나의 문자열로 만들면 끝!

 

class Node{
    constructor(val){
        this.val = val;
        this.prev = null;
        this.next = null;
    }
}

function solution(n, k, cmd) {
    const answer = Array.from({length: n}).fill("O");
    const node = Array.from({length: n}, () => new Node());
    const deleted = [];
    
    for(let i = 0; i < n; i++){
        node[i].val = i;
        
        if(i < n - 1){
            node[i].next = i + 1;
        }
        
        if(i > 0){
            node[i].prev = i - 1;
        }
    }
    
    for(let i = 0; i < cmd.length; i++){
        const splited = cmd[i].split(" ");
        let move = parseInt(splited[1]);
        
        switch(splited[0]){
            case "U":{
                while(move--){
                    k = node[k].prev;
                }
                
                break;
            }
                
            case "D":{
                while(move--){
                    k = node[k].next;
                }
                
                break;
            }
                
            case "C":{
                const {prev, next} = node[k];
                
                deleted.push(node[k]);
                
                if(node[prev]){
                    node[prev].next = next;
                }
                
                if(node[next]){
                    node[next].prev = prev;
                }
                
                k = next ? next : prev;
                
                break;
            }
                
            case "Z":{
                const restore = deleted.pop();
                const {val, prev, next} = restore;
                
                if(node[prev]){
                    node[prev].next = val;
                }
                
                if(node[next]){
                    node[next].prev = val;
                }
                
                break;
            }
        }
    }
    
    for(let i = 0; i < deleted.length; i++){
        const num = deleted[i].val;
        
        answer[num] = "X";
    }
    
    return answer.join("");
}
728x90
반응형