와드의 블로그

오픈채팅방 본문

PS/프로그래머스

오픈채팅방

Ward 2026. 4. 3. 21:11

문제

카카오톡 오픈채팅방에서는 누군가 들어오거나 나갈 때 관리자에게 메시지가 보입니다. 채팅방에 들어온 유저는 닉네임을 변경할 수 있으며, 닉네임을 변경할 경우 기존에 채팅방에 출력되어 있던 메시지의 닉네임도 전부 새로운 닉네임으로 변경되어야 합니다. 유저의 아이디(uid)와 닉네임의 변경 기록이 주어질 때, 모든 기록이 처리된 후 최종적으로 방을 개설한 사람이 보게 되는 메시지를 문자열 배열 형태로 반환하는 문제입니다.

  • 입력: 채팅방에 들어오고 나가거나, 닉네임을 변경한 기록이 담긴 문자열 배열 record (길이 1 이상 100,000 이하)
  • 출력: 모든 기록이 처리된 후의 최종 메시지 배열

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

풀이: HashMap을 활용한 Two-Pass 시뮬레이션

유저가 닉네임을 변경하면 과거의 메시지까지 모두 소급 적용되어야 하므로, 메시지를 실시간으로 생성하는 대신 모든 기록을 끝까지 확인하여 최종 닉네임을 확정한 뒤에 메시지를 생성하는 Two-Pass(두 번 순회) 방식이 필요합니다.

  • 1차 순회 (최종 닉네임 매핑): record 배열을 처음부터 끝까지 순회합니다.
    • 문자열을 공백을 기준으로 분리(split)하여 명령어(cmd), 유저 아이디(uid), 닉네임(nickname)을 추출합니다.
    • 명령어가 "Enter"(입장)이거나 "Change"(닉네임 변경)인 경우, 닉네임 정보가 갱신되거나 추가되므로 HashMap에 uid를 키로, nickname을 값으로 저장(put)합니다. 맵의 특성상 동일한 uid로 값을 넣으면 덮어씌워지므로 자연스럽게 최종 닉네임만 남게 됩니다.
  • 2차 순회 (최종 메시지 생성): 다시 한 번 record 배열을 순회하며 실제로 출력할 메시지를 만듭니다.
    • 명령어가 "Enter"인 경우: HashMap에서 해당 uid의 최신 닉네임을 꺼내어 "<닉네임>님이 들어왔습니다." 문자열을 만들어 리스트에 추가합니다.
    • 명령어가 "Leave"인 경우: 마찬가지로 최신 닉네임을 꺼내어 "<닉네임>님이 나갔습니다." 문자열을 추가합니다. ("Change" 명령어는 메시지를 출력하지 않으므로 무시합니다.)
  • 결과 변환: 리스트에 담긴 최종 메시지들을 String[] 배열로 변환하여 반환합니다.

코드

import java.util.*;

class Solution {
    public String[] solution(String[] record) {
        Map<String, String> map = new HashMap<>();
        
        // 1. 유저 아이디(uid)별 최종 닉네임 매핑
        for (String s : record) {
            String[] tmp = s.split(" ");
            String cmd = tmp[0];
            if (cmd.equals("Enter") || cmd.equals("Change")) {
                map.put(tmp[1], tmp[2]);
            }
        }
        
        // 2. 명령어에 따른 최종 출력 메시지 생성
        List<String> list = new ArrayList<>();
        for (String s : record) {
            String[] tmp = s.split(" ");
            if (tmp[0].equals("Enter")) {
                String nickname = map.get(tmp[1]);
                list.add(nickname + "님이 들어왔습니다.");
            } else if (tmp[0].equals("Leave")) {
                String nickname = map.get(tmp[1]);
                list.add(nickname + "님이 나갔습니다.");
            }
        }
        
        // 3. 리스트를 배열로 변환
        String[] ans = new String[list.size()];
        for (int i = 0; i < list.size(); i++) {
            ans[i] = list.get(i);
        }
        
        return ans;
    }
}

알고리즘 분류

자료 구조 (Data Structures), 해시를 사용한 맵 (Hash Map), 문자열 (String)

'PS > 프로그래머스' 카테고리의 다른 글

숫자 게임  (1) 2026.04.03
최고의 집합  (0) 2026.04.03
파일명 정렬  (0) 2026.04.03
주차 요금 계산  (0) 2026.04.03
숫자 변환하기  (0) 2026.04.03