프론트엔드 개발자의 기록 공간

[프로그래머스 JavaScript] 오픈채팅방 본문

알고리즘_JS/프로그래머스_Level2

[프로그래머스 JavaScript] 오픈채팅방

[리우] 2021. 7. 22. 19:46

🚩 프로그래머스 Level2 오픈채팅방 -> 2019 KAKAO BLIND 채용문제

 

📖 문제 설명

말 그대로 카카오톡에서 사용되는 오픈채팅방의 기능을 구현하는 문제이다.

오픈채팅방에 들어오거나 나가게 되면 해당 닉네임이 로그로 남게 된다.

그리고 닉네임을 바꾸게 되면 모든 로그의 닉네임이 바뀐다.

사용자는 유저 아이디를 가지고 있기 때문에 이를 이용하여 구별한다.

 

 

👉 소스 코드  ⏰시간복잡도 O(n)

function solution(record) {
    var answer = [];
    let map = new Map();
    let result = [];
    
    for(let records of record){
        //record입력 띄어쓰기 기준 자르기
        let [check, uid, name] = records.split(" ");
        
        //채팅방 입장시
        if(check === "Enter"){
            //채팅방을 나간 후, 새로운 닉네임으로 다시 들어가는 경우도 map객체를 이용하면 자동으로 업데이트
            map.set(uid,name);
            //출입 상태 저장
            result.push([check, uid]);
        }
        
        //채팅방 나간 경우
        else if(check === "Leave"){
            result.push([check, uid]);
        }
        //닉네임 변경시
        else if(check === "Change"){
            //map객체를 이용하면 자동으로 업데이트
            map.set(uid,name);
        }
    }
    //위의 과정을 거치고 나면 result 배열에는 출입 리스트,
    //map객체에는 닉네임 변경이 전부 처리된 uid, name이 저장되어있다.
 
    
    //출입기록에 따라 닉네임 처리
    for(let x of result){
        let [check, uid] = x;
        //uid에 해당하는 name을 map객체에서 가져오기
        let nickname = map.get(uid);
        
        if(check === "Enter"){
            answer.push(`${nickname}님이 들어왔습니다.`);
        }
        else{
            answer.push(`${nickname}님이 나갔습니다.`);
        }
    }
    return answer;
}

👨‍💻 코드 설명

map 객체를 이용하여 유저 아이디에 대한 정보를 관리해준다.

이미 있는 유저 아이디가 새로 입장하거나, 닉네임 변경시 map객체를 이용하면 자동으로 업데이트 되기 때문이다.

그리고 채팅방 입장시, 나갈시의 상태정보를 result배열에 저장해준다.

위의 과정을 거치고 나면 result 배열에는 출입 리스트,

map객체에는 닉네임 변경이 전부 처리된 uid, name이 저장되어있다.

 

이후, 반복문을 통해 출입기록에 따라 닉네임을 처리해주면 된다.

 

 

실패코드  ⏰시간복잡도 O(n) -> 시간초과

function solution(record) {
    var answer = [];
    let map = [];
    
    for(let records of record){
        //record입력 띄어쓰기 기준 자르기
        let [check, uid, name] = records.split(" ");
        
        //채팅방 입장시
        if(check === "Enter"){
            //채팅방을 나간 후, 새로운 닉네임으로 다시 들어오는 경우
            //기존 uid에 해당하는 닉네임을 찾아 새로 변경해준다.
            map.map((el, idx) =>{
                if(el[1] === uid){
                    map[idx][2] = name;
                }
            })
            //채팅방 입장 기록
            map.push([check, uid, name]);
        }
        //패팅방 나간 경우
        else if(check === "Leave"){
            
            //나간 경우 이름 정보는 없으므로 uid로 해당 이름을 찾아서 넣어준다.
            let nickname = "";
            map.map((el, idx) =>{
                if(el[1] === uid){
                    nickname = el[2];
                }
            })
            map.push([check, uid, nickname]);
        }
        //닉네임 변경시
        else if(check === "Change"){
            map.map((el, idx) =>{
                if(el[1] === uid){
                    map[idx][2] = name;
                }
            })
        }
    }
    
    //위의 과정을 거치고 나면 출입기록, 아이디, 닉네임이 전부 처리된다.
    
    
    //처리된 후 출입기록에 따라 닉네임 처리
    for(let x of map){
        let [check, uid, name] = x;
       
        if(check === "Enter"){
            answer.push(`${name}님이 들어왔습니다.`);
        }
        
        else if(check === "Leave"){
            answer.push(`${name}님이 나갔습니다.`);
        }
    }
    return answer;
}

 

😥 처음에는 map객체에 대한 방법을 생각하지 못해 처음부터 배열에 저장했다.

그렇다보니 이미 들어와있는 유저가 있을 경우, 한번 더 반복문을 통해 중복된 유저를 찾는 과정에서

시간복잡도가 O(n^2)까지 높아져서 시간초과 문제가 생겼다... 확실히 Level2로 넘어가면서 어려워졌다.

728x90
Comments