[Java] 12981 영어 끝말잇기
📝 영어 끝말잇기
1. 문제 요약
- [탈락자 번호, 탈락할 차례] 형태로 리턴
- 탈락자가 없으면 [0, 0]
2. 접근 방법
1) 누적 단어 저장 어떻게 할 것인지?
- 그동안 나온 단어를 저장하고 이미 있는 단어 나오면 탈락
- 이 때 단어 저장 할 자료구조는? HashSet<String>
2) 탈락 조건
- 이미 나온 단어 말함 → 아웃
- 끝말잇기 규칙 위반(이전단어 마지막글자 != 현재 단어 첫글자) → 아웃
3) 탈락자 정보 계산
- (탈락 단어 인덱스 % n) + 1 → 사람 번호 계산
- (탈락 단어 인덱스 / n) + 1 → 차례 계산
3. 정답코드
import java.util.*;
class Solution {
public int[] solution(int n, String[] words) {
Set<String> usedWords = new HashSet<>();
usedWords.add(words[0]);
for (int i = 1; i < words.length; i++) {
// 끝말 맞는지 확인
String prev = words[i - 1];
String curr = words[i];
if (usedWords.contains(curr) || prev.charAt(prev.length() - 1) != curr.charAt(0)) {
int player = (i % n) + 1;
int turn = (i / n) + 1;
return new int[]{player, turn};
}
usedWords.add(curr);
}
return new int[]{0, 0};
}
}
- Set선언하고 첫 번째 단어는 사용된 걸로 넣기
- 현재 단어가 Set에 포함되어 있거나, 이전 단어와 현재 단어의 첫번째 글자가 다르면 탈락자
- 탈락자 번호
- 탈락자 턴 계산
- {플레이어번호, 턴} 매핑해서 반환
3. 오답 / 어려웠던 점
1) usedWords.add(curr); 위치
→ 새 단어를 추가하는 부분을 탈락 검사 이후에 넣어야 함
만약 usedWords.add(curr)을 검사하기 전에 해버리면 어떤 문제가 생길까?
words = {"tank", "kick", "know", "kick"}
kick이 두 번 나오는데 usedWords.add(curr)을 먼저 했다면, kick은 이미 Set에 들어가 있으니까 검사 전에 넣어버려서 중복 여부 확인이 제대로 안 됨
2) 플레이어 번호 계산
플레이어번호는 (i % n) + 1이다. 처음에는 좀 이해가 안 됐는데 순서대로 하나씩 써 보니까 이해 됐다.
아래 패턴을 보면 i를 n으로 나눈 나머지가 0,1,2가 반복된다. 여기에 1씩 더하면 플레이어 번호가 된다.
i = 0 → 1번
i = 1 → 2번
i = 2 → 3번
i = 3 → 1번
i = 4 → 2번
i = 5 → 3번
i = 6 → 1번
...
3) 차례 계산
i i / 3
0 → 0
1 → 0
2 → 0 (0턴째 진행 중)
3 → 1
4 → 1
5 → 1 (1턴째 진행 중)
6 → 2
7 → 2
8 → 2 (2턴째 진행 중)
...
즉, i / n은 0부터 시작한다. 그래서 +1을 한다.