[Programmers/프로그래머스] #3. JAVA 위장

2019. 8. 2. 20:06알고리즘

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

  • clothes의 각 행은 [의상의 이름, 의상의 종류]로 이루어져 있습니다.

  • 스파이가 가진 의상의 수는 1개 이상 30개 이하입니다.

  • 같은 이름을 가진 의상은 존재하지 않습니다.

  • clothes의 모든 원소는 문자열로 이루어져 있습니다.

  • 모든 문자열의 길이는 1 이상 20 이하인 자연수이고 알파벳 소문자 또는 '_' 로만 이루어져 있습니다.

  • 스파이는 하루에 최소 한 개의 의상은 입습니다.

입출력 예

clothes return

[[yellow_hat, headgear], [blue_sunglasses, eyewear], [green_turban, headgear]]

5

[[crow_mask, face], [blue_sunglasses, face], [smoky_makeup, face]]

3

입출력 예 설명

예제 #1
headgear에 해당하는 의상이 yellow hat, green turban이고 eyewear에 해당하는 의상이 blue_sunglasses이므로 아래와 같이 5개의 조합이 가능합니다.

1. yellow_hat 2. blue_sunglasses 3. green_turban 4. yellow_hat + blue_sunglasses 5. green_turban + blue_sunglasses

예제 #2
face에 해당하는 의상이 crowmask, bluesunglasses, smoky_makeup이므로 아래와 같이 3개의 조합이 가능합니다.

1. crow_mask 2. blue_sunglasses 3. smoky_makeup


[풀이]

이번 알고리즘 문제는 생각을 많이 잠기게 했다. 경우의 수의 합산을 구하기위해선 종류의 갯수에 따라 곱셈을 해야하는데 문제는 종류가 어떤이름으로 몇개가 들어올지 미지수였기 때문이다.

30분을 머리를 싸매다가 다른 사람들이 해놓은 해법을 보았더니 HashMap을 이용해 구하는 방법들이 많이보였다.

HashMap을 이용해 key값에 종류를 넣고 value값에 갯수를 넣어 최종으로 계산할때 value값을 이용해 계산을 하면 된다.

import java.util.*;

class Solution {
    public int solution(String[][] clothes) {
        HashMap<String,Integer> map = new HashMap<>();
        int answer = 0;
        int cnt =1;
        
        for(int i=0; i<clothes.length;i++)
        {
            String key = clothes[i][1];
            if(!(map.containsKey(key)))
                map.put(key,1);
            else
                map.put(key,(map.get(key))+1);
        }
        
        //키값을 전부 받아옴
        for(String str : map.keySet())
        {
            if(map.size()==1)
                return map.get(str);
            else {
                int temp = map.get(str)+1;
                cnt*=temp;
            }
        }
        
        answer=cnt-1;
        
        return answer;
    }
}

 

map에 대한 함수를 확인하고 싶으면 oracle사의 java api를 확인하면 된다.

 

하지만 이 문제를 풀면서 나름 이해(?)하기 힘든점이 몇부분 있었다.

1) 본인은 모든 경우의 수를 구하기 위해 맨처음 종류 한개만 입는 경우의 수를 각각 더하고  옷을 섞어서 입는 경우의 수를 체크했다. 그 다음 마지막에 그 둘을 더하는 방법으로 접근했다.

2) 기본으로 보여주는 테스트케이스 두종류에서는 통과가 됬지만 나머지 테스트케이스에서는 입구컷당하는 어마무시한 결과가 나왔다.... 테스트케이스를 확인할 수 없어서 어디서 잘못됬는지 감이 오지않지만 테스트케이스만 봤을때는 문제가 없는 설계였다.

3) 그래서 다른사람들의 코드를 보니 옷을 안입는다는(처음 착각했던게 이문장만 보고 아무옷도 입지않는다고? 분명 옷은 한가지이상은 입는데..? 이랬는데 이옷을 선택안한다는 말이였다...) 가정을 한다음,

value값이 +1씩 한후 최종 결과에 전부 안입는다는 전제를 뺀값을 리턴하면 된다는 것이다.

 

3번의 말을 듣고 적용해보니 올클리어.... 대체 왜 1번이 문제가됬는지 아직도 의문이다....