본문 바로가기

알고리즘/Lv. 2

프로그래머스 12981 영어 끝말잇기 자바 풀이

728x90

난이도 : Lv.2

풀이일 : 2409216

https://school.programmers.co.kr/learn/courses/30/lessons/12981

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr


문제


1차 풀이코드

import java.util.Set;
import java.util.HashSet;

class Solution {
    public int[] solution(int n, String[] words) {
        int[] answer = {0, 0};
        
        Set<String> check = new HashSet<>();
        check.add(words[0]);
        
        for (int i = 1; i < words.length; i++) {
            String word = words[i];
            if (check.contains(word) | word.charAt(0) != words[i-1].charAt(words[i-1].length() - 1)){
                answer = new int[]{check.size() % n + 1, check.size() / n + 1};
                System.out.println(answer);
                return answer;
            } else {
                check.add(word);
            }
        }
        return answer;
    }
}
  •  

2차 풀이코드

import java.util.Set;
import java.util.HashSet;

class Solution {
    public int[] solution(int n, String[] words) {
        int[] answer = {0, 0};
        
        // 나온 단어를 담을 Set 생성, 첫 단어 담기
        Set<String> check = new HashSet<>();
        check.add(words[0]);
        
        for (int i = 1; i < words.length; i++) {
            String word = words[i];
            // 이미 나온 단어 or 현 단어의 첫 단어가 전 단어의 마지막 단어와 다름
            if (check.contains(word) || word.charAt(0) != words[i-1].charAt(words[i-1].length() - 1)){
                answer = new int[]{i % n + 1, i / n + 1};
                return answer;
            }
            check.add(word);
        }
        return answer;
    }
}

이전 코드와의 변화

// 1차
if (check.contains(word) | word.charAt(0) != words[i-1].charAt(words[i-1].length() - 1)){
    answer = new int[]{check.size() % n + 1, check.size() / n + 1};
    System.out.println(answer);
    return answer;
} else {
    check.add(word);
}

// 2차 
if (check.contains(word) || word.charAt(0) != words[i-1].charAt(words[i-1].length() - 1)){
    answer = new int[]{i % n + 1, i / n + 1};
    return answer;
}
check.add(word);
  • if 절 내 | 부분 ||로 변경 : |는 비트연산자의 비교조건이어서 논리 연산자 비교조건으로 수정하였다.
  • answer 수 계산 하는 방식 변경 : check.size()를 구해 길이를 설정하던 방식에서, 반복문에 사용하는 i를 사용해 길이를 설저아하는 방식으로 수정하였다.
  • else 문 삭제 : if 문에 해당하면 return 되므로, 불필요한 else 문을 삭제하였다.

상세 풀이코드

int[] answer = {0, 0};
        
// 나온 단어를 담을 Set 생성, 첫 단어 담기
Set<String> check = new HashSet<>();
check.add(words[0]);
  • 탈락자없이 끝말잇기가 끝난다면, 반환할 [0, 0]으로 answer 설정
  • 중복을 허용하지 않는 Set을 사용해서 이미 나온 단어들을 담기위해 Set 생성, 첫 단어를 Set에 추가

 

for (int i = 1; i < words.length; i++) {
    String word = words[i];
    // 이미 나온 단어 or 현 단어의 첫 단어가 전 단어의 마지막 단어와 다름
    if (check.contains(word) || word.charAt(0) != words[i-1].charAt(words[i-1].length() - 1)){
        answer = new int[]{i % n + 1, i / n + 1};
        return answer;
    }
    check.add(word);
}
return answer;
  • 1부터 단어 배열의 길이까지 반복 수행
  • 현재 단어를 word로 정의하고 검사 시작
  • 탈락자가 발생하는지 검사
    • 조건 1 : 앞서 누군가 말했던 단어를 말할 경우 -> Set에 들어있는 단어인지 확인하는 것으로 검사한다.
    • 조건 2 : 앞 사람이 말한 마지막 문자로 시작하는 단어로 말하지 않은 경우 -> 문자열 비교로 검사한다.
    • 조건 3 : 한 글자 단어를 고려하려 했으나, 문제 조건에서 단어의 길이는 2이상 50이하라고 주어져 삭제
  • 만약, 현 단어가 조건 검사에서 걸리면, answer 재할당
    • 현재 단어를 말한 사람은 (지금 순서)를 (참여인원) 으로 나눈 나머지 + 1
    • 현재 단어를 말한 사람의 참여 횟수는 (지금 순서)를 (참여인원)으로 나눈 몫 + 1
  • answer 재할당 후, return
  • 만약, 리턴되지 않았다면, 현 단어를 check set에 추가한다.

배운점

  • 프로그래머스 내에서도 import를 할 수 있는지 몰랐다. 이전 코테에서는 그래서 당황스러워 했었는데....!
  • String.charAt : 문자열의 특정 자리수 문자를 추출. 파이썬이 익숙해서 문자열을 비교할 때 헤맸다.

느낀점

  • 오랜만에 알고리즘 푸니까 너무 재밌고, 내가 생각보다 말귀를 못알아듣는다.
  • 파이썬은 처음 했던 언어라 그런지 쉬어도 쉽게쉽게 풀리는데, 자바는 왜 이렇게 오랜만엔 다 헷갈리지ㅠ 조금 더 자주 풀어야지