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

[프로그래머스,자바] Level2:오픈채팅방

류창 2021. 9. 22. 22:18
반응형

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

 

코딩테스트 연습 - 오픈채팅방

오픈채팅방 카카오톡 오픈채팅방에서는 친구가 아닌 사람들과 대화를 할 수 있는데, 본래 닉네임이 아닌 가상의 닉네임을 사용하여 채팅방에 들어갈 수 있다. 신입사원인 김크루는 카카오톡 오

programmers.co.kr

문제분석

문제가 긴 이유로 링크로 대체합니다.

 

누군가 들어오면 [닉네임]이 들어왔습니다. 를 출력합니다.

누군가 나가면 [닉네임] 나갔습니다. 를 출력합니다.

 

누군가가 채팅방에서 닉네임을 바뀌거나 , 나간후 새로운 닉네임으로 들어오면 닉네임이 변경됩니다. 

 

닉네임은 중복이 가능하며,  중복된 닉네임은 입력 Record로 주어진 id로 구분합니다.

 

결과는 모든 Record를 순회한 채팅방 기록을 반환하면됩니다.

 

 

문제 자체는 심플하지만, 이 문제는 효율성체크를 내포하고있다.

 

Record를 순회하면서 Enter과 Leave의 기록을 남기는것까진 좋다.

 

하지만, Change명령이나 새로운 닉네임으로 Enter하는 명령이와서 

채팅방기록을 또 다시 반복하면서 변경하지 않았는가?

 

이 문제는 2차반복O(n^2)을 사용하는순간 효율성체크에 위반한다.

 

효율성에 위반되지않게 코딩하기위해서는, 나름의 전략이 필요하다.

 

일단, 문제가 닉네임을 ID로 구분한다는것에 Map의 Key, Value를 쓰기 최적화되어있다.

 

Key에다 ID를 Value에다 닉네임을 정하자.

 

우선 기록을 닉네임+들어왔습니다 형태로 저장하지말고, ID+들어왓습니다 형태로 저장한다.

 

모든 Record를 순회한후,

 

그다음, 채팅방기록을 순회하여, Id+들어왓습니다 를, 닉네임+들어왓습니다로

Map의 저장된 value로 바꿔줍니다.

 

이렇게 코딩하면 O(n)x2 의 연산으로 통과하게됩니다.

문제풀이

 

채팅방기록을 남길 리스트 result와 ID,닉네임을 저장할 Map을 선언합니다.

 

각각 Enter, Leave,Change의 명령어가 들어옴에따라, 채팅방기록과 ID에따른 value를 저장합니다.

 

Record순회를 마쳤다면, 변경된 닉네임을 ID 대신 입력합니다.

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
import java.util.*;
class Solution {
    public String[] solution(String[] record) {
        //기록을 남길 List 생성
        List<String> result = new ArrayList<>();
        // Key:Id  value:닉네임 을넣고 저장 
        Map<String,String> Id = new HashMap<>();
        for(int i=0;i<record.length;i++){
            String[] temp=record[i].split(" ");
            //Enter일경우
            if(temp[0].equals("Enter")){
                //동일한 Id가 다시들어왓다면, 닉네임 Change            
                Id.put(temp[1],temp[2]);
                result.add(temp[1]+"님이 들어왔습니다.");
            }
            //Leave인 경우
            else if(temp[0].equals("Leave")){
                result.add(temp[1]+"님이 나갔습니다.");
            }
            //Change 인경우
            else if(temp[0].equals("Change")){
                Id.replace(temp[1],temp[2]);
            }
        }
           
        // 아이디+문장 형식으로 저장된 List 배열을 
        // 닉네임+문장 으로 수정      
        String[] answer=new String[result.size()];      
        for(int i=0;i<result.size();i++){
            //id만 빼오기위해, 0부터 indexOf("님")까지 substring 
            int idx=result.get(i).indexOf("님");
            String id=result.get(i).substring(0,idx);
            answer[i]=Id.get(id)+result.get(i).substring(idx);
        }
        
        return answer;
    }
    
   
}
cs
반응형