프로그래머스

Hash-위장(프로그래머스)

mozzi329 2022. 4. 2. 17:10
728x90

문제

스파이들은 매일 다른 옷을 조합하여 입어 자신을 위장합니다.

예를 들어 스파이가 가진 옷이 아래와 같고 오늘 스파이가 동그란 안경, 긴 코트, 파란색 티셔츠를 입었다면 다음날은 청바지를 추가로 입거나 동그란 안경 대신 검정 선글라스를 착용하거나 해야 합니다.

스파이가 가진 의상들이 담긴 2차원 배열 clothes가 주어질 때 서로 다른 옷의 조합의 수를 return 하도록 solution 함수를 작성해주세요.

종류 이름
얼굴 동그란 안경, 검정 선글라스
상의 파란색 티셔츠
하의 청바지
겉옷 긴 코트

제한사항

  • clothes의 각 행은 [의상의 이름, 의상의 종류]로 이루어져 있습니다.
  • 스파이가 가진 의상의 수는 1개 이상 30개 이하입니다.
  • 같은 이름을 가진 의상은 존재하지 않습니다.
  • clothes의 모든 원소는 문자열로 이루어져 있습니다.
  • 모든 문자열의 길이는 1 이상 20 이하인 자연수이고 알파벳 소문자 또는 '_' 로만 이루어져 있습니다.
  • 스파이는 하루에 최소 한 개의 의상은 입습니다.

아이디어

종류 A와 종류 B가 있을 때 가능한 옷 조합의 경우의 수는 A의 개수 x B의 개수 이다. 거기에 종류 A만 입는 경우의 수와 종류 B만 입는 경우의 수를 더해주어야 한다. 이렇게 나오는 경우의 수는 (종류 A의 개수 + 1) * (종류 B의 개수 + 1) 이며 여기에 스파이는 하루에 최소 한 개 이상의 의상을 입어야하기 때문에 A와 B 모두 입지 않은 경우의 수를 빼주어야 한다. 따라서 최종적인 총 경우의 수는

총 경우의 수 = (종류 A의 개수 + 1) * (종류 B의 개수 + 1) - 1

코드구현(자바)

같은 의상은 존재하지 않고 종류별로 의상의 개수만 카운트하면 되므로 Map에서 카운트하기 위해 주로 사용되는 getOrDefault 함수로직을 사용해 종류에 대한 의상의 개수를 카운트했다.

Map<String, Integer> map = new HashMap<String, Integer>();
for (int i = 0; i < clothes.length; i++) {
    map.put(clothes[i][1], map.getOrDefault(clothes[i][1], 0)+ 1);
}

getOrDefault 를 통해 map에서 clothes[i][1](종류) 를 키로 가지는 값이 없을 때는 0을, 있을 경우 값을 가져온다. map의 처음에는 값이 없으므로 getOrDefault에 의해 0이되고 거기에 1을 더하면 종류의 개수가 더해진다. for 문을 모두 돌면서 getOrDefault 함수를 통해 있을 경우 값을 가져와 1을 더해주는 식으로 키에 대한 밸류의 개수를 카운트할 수 있다. 

for (String part: map.keySet()) answer *= (map.get(part)+1);
return answer - 1;

map.keySet으로 for문을 돌려 answer(int형 1로 선언)에 종류의 개수+1 씩 곱해주었다. 거기에 모든 의상을 안입었을 경우(1)을 빼주어 최종적으로 리턴해주었다.

전체 코드

public int solution(String[][] clothes) {
    int answer = 1;

    Map<String, Integer> map = new HashMap<String, Integer>();
    for (int i = 0; i < clothes.length; i++) {
        map.put(clothes[i][1], map.getOrDefault(clothes[i][1], 0)+ 1);
    }

    for (String part: map.keySet()) answer *= (map.get(part)+1);
    return answer - 1;
}