코테/프로그래머스

[프로그래머스/Level2] 메뉴 리뉴얼 (JAVA)

imname1am 2024. 2. 19. 23:28
반응형

📖 문제

 

프로그래머스

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

programmers.co.kr

 

 

 

💡  풀이 방식

• DFS

1. 각 손님이 주문한 단품메뉴들을 오름차순으로 정렬한다.

(여기서 향상형 for문으로 orders 원소 값 받고 오름차순한 결과 저장하려다가 틀렸다....)

for(int i = 0 ; i < orders.length ; i++) {
    char[] ch = orders[i].toCharArray();
    Arrays.sort(ch);

    orders[i] = String.valueOf(ch); // 정렬 결과 저장
}

 

 

2. 각 주문을 기준으로 course 배열의 단품메뉴들의 갯수 길이(courseLen) 만큼의 조합을 만든다.

for (int courseLen : course) {
    for(String order : orders)
        comb(order, courseLen, "");     
}

 

private static void comb(String order, int cnt, String tmp) {
    if (cnt == 0) {
        map.put(tmp, map.getOrDefault(tmp, 0) + 1);
        return;
    }

    // 0부터 len까지의 조합
    for (int i = 0; i < order.length(); i++) {
        comb(order.substring(i + 1), cnt - 1, tmp + order.charAt(i));
    }
}

 

3. 가장 많이 주문된 횟수가 최소 2번 이상이고, 해당 조합이 주문된 횟수와 가장 많이 주문된 횟수가 일치한다면, 정답 리스트에 해당 조합을 추가한다.

if(!map.isEmpty()) {
    List<Integer> cntList = new ArrayList<>(map.values());
    int max = Collections.max(cntList); // 가장 많이 주문된 횟수

    if(max > 1) // 최소 2번 이상 주문된 조합
        for(String key : map.keySet())
            if(map.get(key) == max)
                result.add(key);

    map.clear();
}

 

 

4. 정답 리스트를 오름차순으로 정렬한 후, 배열로 변환한다.

Collections.sort(result);
return result.toArray(new String[0]);	// int형 리스트를 int형 배열로 변환

 

 

 

🔺 코드

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
51
52
53
import java.util.*;
 
class Solution {
    static List<String> result = new ArrayList<>();
    static Map<String, Integer> map = new HashMap<>();
    
    public String[] solution(String[] orders, int[] course) {
        
        // 1. 각 주문 정렬
        for(int i = 0 ; i < orders.length ; i++) {
            char[] ch = orders[i].toCharArray();
            Arrays.sort(ch);
            
            orders[i] = String.valueOf(ch); // 🔔 정렬된 문자형 배열을 문자열로 변환해 저장
        }
        
        // 2. 각 주문을 기준으로 courseLen만큼의 조합 만들기
        for (int courseLen : course) {
            for(String order : orders)
                comb(order, courseLen, "");
            
            // 3. 가장 많은 조합을 answer에 저장
            if(!map.isEmpty()) {
                List<Integer> cntList = new ArrayList<>(map.values());
                int max = Collections.max(cntList); // 가장 많이 주문된 횟수
                
                if(max > 1// 최소 2번 이상 주문된 조합
                    for(String key : map.keySet())
                        if(map.get(key) == max)
                            result.add(key);
                
                map.clear();
            }
        }
        
        Collections.sort(result);
        
        return result.toArray(new String[0]);
    }
    
    private static void comb(String order, int cnt, String tmp) {
        if (cnt == 0) {
            map.put(tmp, map.getOrDefault(tmp, 0+ 1);
            return;
        }
        
        // 0부터 len까지의 조합
        for (int i = 0; i < order.length(); i++) {
            comb(order.substring(i + 1), cnt - 1, tmp + order.charAt(i));
        }
    }
}
 
cs

 

 

 

➕ 다른 풀이 방식

- 멋진 풀이...

 

[level2] 프로그래머스 - 메뉴 리뉴얼(JAVA)

전체 코드는 맨 하단에 있습니다. [ 문제 풀이 방법 ] 1. 각 손님이 주문한 메뉴(order)를 course개의 조합으로 만들 수 있는 모든 조합을 모두 만듭니다. 2. course[j]개의 조합 중, 가장 많이 선택 받은

jisunshine.tistory.com

 

 

- 멋진 풀이.. Map 관련 메소드를 까먹었다면 쓰기 좋은 풀이..

 

[알고리즘 문제풀이] 프로그래머스 - 메뉴 리뉴얼 / JAVA(자바)

https://programmers.co.kr/learn/courses/30/lessons/72411 코딩테스트 연습 - 메뉴 리뉴얼 레스토랑을 운영하던 스카피는 코로나19로 인한 불경기를 극복하고자 메뉴를 새로 구성하려고 고민하고 있습니다. 기

cano721.tistory.com


💦 어려웠던 점

- 문제를 이해하는 데 15분 정도 걸린 듯하다

- 순서를 제대로 세우지 못했다! 담엔 꼭 순서를 먼저 적어두고 코드를 작성하자ㅠㅠ

- 자료구조 한참 고민하다가 결국은 틀렸다는 슬픈ㅇ ㅣ야기.

틀린 코드 확인하기
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
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
import java.util.*;
 
class Solution {
    static List<Character> candidates = new ArrayList<>();
    static boolean[] visited;
    static List<String> result = new ArrayList<>();
    
    public String[] solution(String[] orders, int[] course) {
        Map<Character, Integer> map = new HashMap<>();
        
        // 등장 횟수가 2번 이상인 요리 후보 생성
        for (String order : orders) {
            for (char c : order.toCharArray()) {
                map.put(c, map.getOrDefault(c, 0+ 1);
            }
        }
        
        for (char key : map.keySet()) {
            if (map.get(key) >= 2) {
                candidates.add(key);
            }
        }
        
        Collections.sort(candidates);
        
        // 코스 조합 생성
        for (int c : course) {
            visited = new boolean[candidates.size()];
            dfs(00, c, "");
        }
        
        Collections.sort(result);
        
        // 최소 2명 이상의 손님에게 주문된 코스 조합 선택
        List<String> realAns = new ArrayList<>();
        for (String cook : result) {
            int[] cntArr = new int[cook.length()];
            for (String order : orders) {
                for (int i = 0; i < cook.length(); i++) {
                    if (order.contains(cook.substring(i, i + 1))) {
                        cntArr[i]++;
                    }
                }
            }
            boolean b = true;
            for (int i = 0; i < cntArr.length; i++) {
                if (cntArr[i] < 2) {
                    b = false;
                    break;
                }
            }
            
            if (b) realAns.add(cook);
        }
        
        return realAns.toArray(new String[0]);
    }
    
    private static void dfs(int idx, int depth, int targetCnt, String str) {
        if (depth == targetCnt) {
            result.add(str);
            return;
        }
        
        for (int i = idx; i < candidates.size(); i++) {
                visited[i] = true;
                dfs(i + 1, depth + 1, targetCnt, str + candidates.get(i));
                visited[i] = false;
            }
        }
    }
}
 
cs

 

 

 

🧐 새로 알게 된 내용

- HashMap의 value들을 리스트에 저장하고, 오름차순 정렬해 그 중 최댓값 가져오기

 List<Integer> cntList = new ArrayList<>(map.values());

 Collections.max(cntList);

 

- Integer형 리스트를 배열로 변환 (람다식 활용)

  result.toArray(new String[0]); 

 

① 조합 만들 땐 정렬을 고려하자

② HashMap의 기본 형태 = <Name, Cnt>

1회독 2회독 3회독 4회독 5회독
V        

(참고)

 

[2021 카카오 코딩테스트] 메뉴 리뉴얼 - 자바 java

0. 자세한 설명은 YouTube 영상으로 1. Hash를 활용한 solution import java.util.*; class Solution { List answerList = new ArrayList(); Map hashMap = new HashMap(); public String[] solution(String[] orders, int[] course) { // 1. 각 Order 정렬

coding-grandpa.tistory.com

 

[프로그래머스,Level 2] 메뉴 리뉴얼 (JAVA 구현)

- 첫 풀이 및 정답풀이 이 문제를 처음 읽고 좀 복잡하여 완벽히 이해할 수 없었다. 문제를 풀기 전에 문제를 이해해보기로 하였다. 우선 문제에서 주어지는 배열은 2가지이다. orders는 문자열 배

fbtmdwhd33.tistory.com

https://youtu.be/Jb34jY91450?feature=shared

 

반응형