👀 문제
https://programmers.co.kr/learn/courses/30/lessons/72411
👊 도전
1. 설계
- orders[i]의 조합을 구한다. 이때 조합의 길이는 course 값을 이용한다.
- 구한 조합은 combMap에 저장한다. 조합한 메뉴 길이가 가장 긴 것을 리턴해야하므로(같은 값이 있으면 여러 개 리턴) sizeMap에 메뉴 길이의 발생 횟수의 최댓값을 저장한다.
- combMap, sizeMap이 완료하면, entrySet()로 순회하며, 조합 i의 개수가 2 이상이고, 조합들 중 i 문자열 길이와 같은 것 중 최댓값 개수인 것만 result에 저장한다.
- 배열 형태로 리턴해야하므로 result(ArrayList)를 Array로 변환해서 리턴한다.
2. 구현
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
import java.util.*;
/**
*
* @author HEESOO
*
*/
import java.util.*;
class Solution {
Map<String, Integer> combMap;
Map<Integer, Integer> sizeMap;
public String[] solution(String[] orders, int[] course) {
String[] answer = {};
combMap=new HashMap<>();
sizeMap=new HashMap<>();
for(String order:orders){
char[] array=order.toCharArray();
Arrays.sort(array);
for(int c:course){
comb(0, new StringBuilder(), array, c);
}
}
List<String> result=new ArrayList<>();
for(Map.Entry<String, Integer> entry:combMap.entrySet()){
if(entry.getValue()>1 && entry.getValue()==sizeMap.get(entry.getKey().length())){
result.add(entry.getKey());
}
}
Collections.sort(result);
answer=result.toArray(new String[result.size()]);
return answer;
}
public void comb(int idx, StringBuilder sb, char[] array, int depth){
if(sb.length()==depth){
combMap.put(sb.toString(), combMap.getOrDefault(sb.toString(), 0)+1);
sizeMap.put(sb.length(), Math.max(sizeMap.getOrDefault(sb.length(), 0), combMap.get(sb.toString())));
return;
}
for(int i=idx;i<array.length;i++){
comb(i+1, sb.append(array[i]), array, depth);
sb.deleteCharAt(sb.length()-1);
}
}
}
3. 결과
🤟 성공 🤟
4. 설명
- 조합을 구한다
- comb()
- idx: array 순회 인덱스. array[idx]를 선택할지 말지 체크한다.
- sb: 조합 생성하는 StringBuilder. 문자열 삽입이 빈번히 일어나므로 String보다 StringBuilder를 사용하는 것이 낫다.
- array: 조합할 문자 배열 대상
- depth: 만들 조합의 길이
- “XY”, “YX”는 같은 것으로 생각하므로, solution()에서 comb()를 호출하기 전 Arrays.sort()로 조합할 char 배열을 오름차순 정렬한다.
- 조합 생성이 완료되면 combMap에 sb를 넣는다. value는 조합을 통해 생성된 sb의 횟수이다.
- sizeMap에 sb.length()의 max를 저장한다. 조합 문자열의 길이가 같은 것 중 max만 리턴할 수 있으므로, 이를 체크하기 위해 사용할 것이다.
- 재귀로 조합을 찾는다. 이때 array[i]를 선택하거나 하지 않는 경우를 생각한다. 선택한 경우로 재귀를 돌고 오면, sb에는 array[i]가 아직 들어가있으므로 deleteCharAt()으로 array[i]를 삭제해야 한다.
- 조합 중 조건에 맞는 값을 리턴한다
- 조합 횟수가 2 이상이고 길이가 최댓값인 것만 result에 넣는다.
- 오름차순으로 정렬하여 리턴한다.