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

LaStella·2021년 12월 1일
0

- 문제

[문제링크]
채팅방에 들어오고 나가거나, 닉네임을 변경한 기록이 담긴 문자열 배열 record가 매개변수로 주어질 때, 모든 기록이 처리된 후, 최종적으로 방을 개설한 사람이 보게 되는 메시지를 문자열 배열 형태로 return 하도록 solution 함수를 완성하라.

  • 제한사항
record는 다음과 같은 문자열이 담긴 배열이며, 길이는 1 이상 100,000 이하이다.
다음은 record에 담긴 문자열에 대한 설명이다.
- 모든 유저는 [유저 아이디]로 구분한다.
- [유저 아이디] 사용자가 [닉네임]으로 채팅방에 입장 - "Enter [유저 아이디] [닉네임]" (ex. "Enter uid1234 Muzi")
- [유저 아이디] 사용자가 채팅방에서 퇴장 - "Leave [유저 아이디]" (ex. "Leave uid1234")
- [유저 아이디] 사용자가 닉네임을 [닉네임]으로 변경 - "Change [유저 아이디] [닉네임]" (ex. "Change uid1234 Muzi")
- 첫 단어는 Enter, Leave, Change 중 하나이다.
- 각 단어는 공백으로 구분되어 있으며, 알파벳 대문자, 소문자, 숫자로만 이루어져있다.
- 유저 아이디와 닉네임은 알파벳 대문자, 소문자를 구별한다.
- 유저 아이디와 닉네임의 길이는 1 이상 10 이하이다.
- 채팅방에서 나간 유저가 닉네임을 변경하는 등 잘못 된 입력은 주어지지 않는다.
  • 입출력 예

-전체코드

import java.util.*;

class Solution {
    public String[] solution(String[] record) {
        String[] answer = {};
        List<String> answerList = new ArrayList<>();
        HashMap<String, String> userMap = new HashMap<>(); // 유저 아이디는 고유 값이므로 HashMap의 key로 저장하기 적절하며, 닉네임은 value로 저장하면된다.
        
        for(String s : record) {
            String[] temp = s.split(" ");
            // 채팅방 입장 혹은 닉네임 변경일 경우 userMap에 추가하거나 새로운 value 값으로 업데이트한다.
            if(temp[0].equals("Enter")||temp[0].equals("Change")) {
                userMap.put(temp[1],temp[2]);
            }
        }
        
        for(String s : record) {
            String[] temp = s.split(" ");
            // 입장시와 퇴장시 유저 아이디를 통해 userMap에서 닉네임에 해당하는 value를 가져온다.
            if(temp[0].equals("Enter")) {
                answerList.add(userMap.get(temp[1])+"님이 들어왔습니다.");
            }
            else if(temp[0].equals("Leave")) {
                answerList.add(userMap.get(temp[1])+"님이 나갔습니다.");
            }
        }
        
        // ArrayList를 배열로 변경
        answer = new String[answerList.size()];
        int i = 0;
        for(String s : answerList) {
            answer[i++] = s;
        }
        
        return answer;
    }
}

- 막혔던 점 & 해결방법

  1. 유저 아이디와 닉네임을 저장하기위해 처음 사용한 것은 객체였습니다. Profile이라는 객체를 가지고 객체리스트로 만드는 방법입니다. 예제와 테스트 25번까지 통과하였으나 테스트 26번부터 시간 초과로 실패하였습니다. 우선 객체리스트에서 유저 아이디를 통해 해당하는 값의 위치를 찾고 객체리스트의 해당위치에 해당하는 값에서 다시 닉네임에 해당하는 값을 가져오기때문에 닉네임에 접근하는데 있어서 시간이 많이 소요된다고 생각했습니다. 객체 리스트가 아닌 좀더 나은 데이터 집합형태를 찾아보던 중 Key와 Value의 쌍으로 이루어진 Map을 찾게 되었습니다.[참고글] 학교에서 자료구조수업때 다뤄본적이 있던 HashMap을 이용하여 유저 아이디를 key값으로 닉네임을 value값으로 저장하여 다시 함수를 수정하여 문제를 해결하였습니다.[참고글]

- 느낀점

제가 처음 생각했던 객체리스트를 이용해 만든 함수와 HashMap을 이용한 함수의 테스트 1~25번까지는 실행 시간의 차이는 크지않았습니다만, 26번부터는 시간차이가 많이 나는 것을 보아 List와 Map의 차이를 생각하게 되었습니다. 사용할 데이터의 집합이 어떤 형태가 유리한지 고려하여 문제에서 요구하는 것에 적절한 형태를 고르는 것의 중요성을 깨닫게 되었습니다. 이번 문제는 HashMap을 이용하였으나 가장 빠른 접근 속도를 가진 HashSet을 사용하는 것이 실행 시간의 단축에 더 유리하다고 생각됩니다.

profile
개발자가 되어가는 중...

0개의 댓글