オープンチャットルーム



しょかい


ニックネームを変更するたびに、以前のログを変更します.
そこで、1回目の記録はどのプレイヤーについての情報で、記録が終わったら最終ニックネームに変更します.
マスタレコードは、リストニックネーム履歴は、変更時に既存の値を上書きする必要があるため、Map(鍵:ユーザーID,value:ニックネーム)に保存します.
import java.util.*;

class Solution {
    final String ENTER_MSG = "님이 들어왔습니다.";
    final String LEAVE_MSG = "님이 나갔습니다.";

    //중간 결과물 담을 List ({유저아이디, ENTER_MSG or LEAVE_MSG})
    //순서대로 결과 출력해야하니까 Queue 자료구조
    List<String[]> list;
    //<key : 아이디, value : 닉네임> 담을 맵
    //바뀔 때마다 업데이트
    Map<String, String> userIdNicknameMap;

    public String[] solution(String[] record) {

        list = new LinkedList<>();
        userIdNicknameMap = new HashMap<>();

        //유저 아이디 + 메시지로 list에 담은 1차 결과
        //닉네임은 계속 바뀌니까 분리해서 따로 map에서 업데이트
        //마지막으로 list의 유저 아이디를 map의 닉네임으로 변경하여 출력
        
        StringTokenizer st;
        String type;
        String uId;
        for(String info : record) {
            st = new StringTokenizer(info);
            type = st.nextToken();
            uId = st.nextToken();
            if(type.equals("Enter")) {
                //Enter
                //1. MSG 생성
                //2. 닉네임 업데이트
                list.add(new String[]{uId, ENTER_MSG});
                userIdNicknameMap.put(uId, st.nextToken());
            } else if(type.equals("Leave")) {
                //Leave
                //MSG 생성
                list.add(new String[]{uId, LEAVE_MSG});
            } else {
                //Change
                //닉네임 업데이트
                userIdNicknameMap.put(uId, st.nextToken());
            }//if~else end
        }//for end

        //queue 사이즈 = 정답 배열 사이즈
        int msgSize = queue.size();
        String[] answer = new String[msgSize];

        String[] temp;
        String finalNickname;
        String finalMsg;
        //map을 이용해 list의 유저 아이디를 최종 nickname로 매핑
        for(int i=0; i<msgSize; i++) {
            temp = list.get(i);
            finalNickname = userIdNicknameMap.get(temp[0]);
            finalMsg = finalNickname+temp[1];
            answer[i] = finalMsg;
        }//for end
        
        return answer;
    }//solution() end
}

論理的なプロセスはすべて正しいようですが、タイムアウトしました.

改善された解答1


最初のレコードリストをLinkedListではなくArrayListに変更します.
最終ニックネームにマッピングする場合list.get(index)では、ArrayListはすぐにアクセスできます.
LinkedListは順次アクセスしかできないので、ArrayListの方が高速です.
LinkedList vs ArrayList
ちなみにJavaではLinkedListが双方向接続リストとして実装されている.
list = new ArrayList<>();

テスト25から、長い時間、ArrayListを通過.
これは、情報数が急激に増え、リストのサイズが大きくなったためかもしれないと思います.

改善された解答2


リストではなくQueueが初記録を収録しています
メッセージを記録順に出力する必要があるため、FIFO Queueを使用した.
ニックネームマッピング時にqueueをナビゲートする必要はありません.Poll()は、必要な最初の記録を得ることができる.
Queue<String[]> queue;
    
public String[] solution(String[] record) {
 
    queue = new LinkedList<>();
   
   ...
 
    for(int i=0; i<msgSize; i++) {
        temp = queue.poll();
        
		...
        
    }//for end
 
    return answer;
}//solution() end