1. 문제설명
코니는 매일 다른 옷을 조합하여 입는것을 좋아합니다.
예를 들어 코니가 가진 옷이 아래와 같고, 오늘 코니가 동그란 안경, 긴 코트, 파란색 티셔츠를 입었다면 다음날은 청바지를 추가로 입거나 동그란 안경 대신 검정 선글라스를 착용하거나 해야합니다.
종류 | 이름 |
얼굴 | 동그란 안경, 검정 선글라스 |
상의 | 파란색 티셔츠 |
하의 | 청바지 |
겉옷 | 긴 코트 |
- 코니는 각 종류별로 최대 1가지 의상만 착용할 수 있습니다.
- 예를 들어 위 예시의 경우 동그란 안경과 검정 선글라스를 동시에 착용할 수는 없습니다.
- 착용한 의상의 일부가 겹치더라도, 다른 의상이 겹치지 않거나,
- 혹은 의상을 추가로 더 착용한 경우에는 서로 다른 방법으로 옷을 착용한 것으로 계산합니다.
- 코니는 하루에 최소 한 개의 의상은 입습니다.
코니가 가진 의상들이 담긴 2차원 배열 clothes가 주어질 때 서로 다른 옷의 조합의 수를 return 하도록 solution 함수를 작성해주세요.
제한사항
- clothes의 각 행은 [의상의 이름, 의상의 종류]로 이루어져 있습니다.
- 코니가 가진 의상의 수는 1개 이상 30개 이하입니다.
- 같은 이름을 가진 의상은 존재하지 않습니다.
- clothes의 모든 원소는 문자열로 이루어져 있습니다.
- 모든 문자열의 길이는 1 이상 20 이하인 자연수이고 알파벳 소문자 또는 '_' 로만 이루어져 있습니다.
입출력 예 & 설명
2. 접근방식
2-1. 문제 단순화
- 예제 1 기준으로 생각 해 보자.
- 배열에 담긴 의상은 총 3가지로 헤드기어 2종, 아이웨어 1종이다.
- headwaer : yellow hat, green turban 으로 2개
- eyewear : blue sunglasses 1개
items | count |
headgear | 2 |
eyewear | 1 |
헤드웨어와 아이웨어를 착용하는 경우의 수를 생각 해 보면
✅ headgear (3가지)
- yellow hat 착용
- green turban 착용
- 착용 안 함
✅ eyewear (2가지)
- blue sunglasses
- 착용 안 함
✅ 위 두 가지를 아이템을 조합해서 착용하는 경우의 수는 2*3 = 6가지
- yellow hat
- green turban
- blue sunglasses
- yellow hat + blue sunglasses
- green turban + blue sunglasses
- 아무것도 착용 안함(제외대상)
하지만 아무것도 착용하지 않는 경우는 제외해야 하기 때문에 2*3-1 = 5가지가 된다.
2-2. 해결법
- 이차원 배열에서 각 요소의 1번 인덱스에 아이템의 종류가 담겨 있으므로
["yellow_hat", "headgear"], ["blue_sunglasses", "eyewear"], ["green_turban", "headgear"]
- 해시맵에 <String, Integer> 타입으로 종류와 등장횟수(count)를 매핑해서 집어 넣어 주면 된다.
- 이 때 (노란 모자 + 안입음) 도 고려해야 하기 때문에 어떤 아이템은 안 입는 경우를 생각해서 count에 +1씩을 해 준다.
- 아이템 종류별 등장횟수를 result 변수에 누적하면서 곱해준다.
- result 리턴하기 전에 모두 안 입는 경우는 제외 해 주어야 하므로 결과값에서 -1을 해준다.
3. 문제풀이
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
class Solution {
public int solution(String[][] clothes) {
// 1. 의상 종류, 카운트 담을 HashMap 선언
HashMap<String, Integer> map = new HashMap<>();
// 2. 결과값 담을 변수 선언
int result = 1;
// 3. clothes 를 순환하면서 의상 종류 가져와서 해시테이블에 넣기
for (String[] clothe : clothes){
String type = clothe[1];
map.put(type, map.getOrDefault(type,0)+1);
}
// 4. 해시맵의 value(count)만 순회하기
Iterator<Integer> iter = map.values().iterator();
// 5. 다음 요소에 값이 있으면 value 가져와서 1더한 후 result에 곱하기
while (iter.hasNext()){
result *= (iter.next().intValue()+1);
}
// 6. 모두 안입은 경우 제외하기 위해 최종 값에서 1을 빼고 리턴
return result-1;
}
}
- 2에서 int result 를 1로 선언한 이유는 누적 곱을 해 줄거라서 0으로 하면 계속 0값이기 때문이다.
map.put(type, map.getOrDefault(type, 0) + 1);
map에 type 값이 없으면 0으로 초기화, map에 type이 이미 존재하면 기존 값에서 1을 더한 후, 증가된 값으로 업데이트하는 메서드
Iterator next() 메서드
- 역할: iter.next() 메서드는 반복자의 현재 요소를 반환하고, 반복자의 위치를 다음 요소로 이동시켜주는 역할을 함. 예를 들면 첫 번째 호출 할 때, 반복자의 첫 번째 요소를 반환하고, 다음 호출에서는 두 번째 요소로 이동함.
- 예외: 만약 더 이상 반복할 요소가 없는데 next()를 호출하면 **NoSuchElementException**이 발생함. 이를 방지하기 위해 일반적으로 hasNext() 메서드를 함께 써서 반복자에 더 이상 요소가 남아있지 않은 경우 next()를 호출하지 않도록 해준다.
4. 동일유형 문제(해시)
https://awesomepossum.tistory.com/271
[프로그래머스] (Java) 코딩테스트 완주하지 못한선수 문제풀이 🚴♂️
❤️ 문제설명수많은 마라톤 선수들이 마라톤에 참여하였습니다. 단 한 명의 선수를 제외하고는 모든 선수가 마라톤을 완주하였습니다.마라톤에 참여한 선수들의 이름이 담긴 배열 participant와
awesomepossum.tistory.com
[프로그래머스] (Java) 전화번호 목록 해시 문제 풀이 (substring, starsWith 문자열 메서드)
1. 문제설명 전화번호부에 적힌 전화번호 중, 한 번호가 다른 번호의 접두어인 경우가 있는지 확인하려 합니다.전화번호가 다음과 같을 경우, 구조대 전화번호는 영석이의 전화번호의 접두사입
awesomepossum.tistory.com
[프로그래머스] (Java) 코딩테스트 폰켓몬 문제풀이 🐣
❤️ 문제설명 당신은 폰켓몬을 잡기 위한 오랜 여행 끝에, 홍 박사님의 연구실에 도착했습니다. 홍 박사님은 당신에게 자신의 연구실에 있는 총 N 마리의 폰켓몬 중에서 N/2마리를 가져가도 좋
awesomepossum.tistory.com
'코딩테스트 > 알고리즘베스트' 카테고리의 다른 글
[프로그래머스] (Java) K번째수 문제 풀이 (정렬) - Arrays.copyOfRange() 메서드 (5) | 2024.11.02 |
---|---|
[프로그래머스] (Java) 베스트앨범 문제 풀이 (해시) - containsKey, KeySet (2) | 2024.11.01 |
[프로그래머스] (Java) 전화번호 목록 문제 풀이 (해시) - substring, starsWith 메서드 (4) | 2024.10.31 |
[프로그래머스] (Java) 코딩테스트 완주하지 못한선수 문제풀이 🚴♂️ (해시) - map.getOrDefault() (2) | 2024.10.29 |
[프로그래머스] (Java) 코딩테스트 폰켓몬 문제풀이 🐣 (해시) (5) | 2024.10.28 |