[프로그래머스] 메뉴 리뉴얼

jmjgirl·2024년 1월 2일
0

프로그래머스

목록 보기
42/47
post-thumbnail

📚 문제 설명

레스토랑을 운영하던 스카피는 코로나19로 인한 불경기를 극복하고자 메뉴를 새로 구성하려고 고민하고 있습니다.
기존에는 단품으로만 제공하던 메뉴를 조합해서 코스요리 형태로 재구성해서 새로운 메뉴를 제공하기로 결정했습니다. 어떤 단품메뉴들을 조합해서 코스요리 메뉴로 구성하면 좋을 지 고민하던 "스카피"는 이전에 각 손님들이 주문할 때 가장 많이 함께 주문한 단품메뉴들을 코스요리 메뉴로 구성하기로 했습니다.
단, 코스요리 메뉴는 최소 2가지 이상의 단품메뉴로 구성하려고 합니다. 또한, 최소 2명 이상의 손님으로부터 주문된 단품메뉴 조합에 대해서만 코스요리 메뉴 후보에 포함하기로 했습니다.

예를 들어, 손님 6명이 주문한 단품메뉴들의 조합이 다음과 같다면,
(각 손님은 단품메뉴를 2개 이상 주문해야 하며, 각 단품메뉴는 A ~ Z의 알파벳 대문자로 표기합니다.)

가장 많이 함께 주문된 단품메뉴 조합에 따라 "스카피"가 만들게 될 코스요리 메뉴 구성 후보는 다음과 같습니다.


문제

각 손님들이 주문한 단품메뉴들이 문자열 형식으로 담긴 배열 orders, "스카피"가 추가하고 싶어하는 코스요리를 구성하는 단품메뉴들의 갯수가 담긴 배열 course가 매개변수로 주어질 때, "스카피"가 새로 추가하게 될 코스요리의 메뉴 구성을 문자열 형태로 배열에 담아 return 하도록 solution 함수를 완성해 주세요.


🔎 입출력 예


💻 코드

import java.util.*;
class Solution {
    public boolean[] visited;
    public HashMap<String,Integer> map;
    public String[] solution(String[] orders, int[] course) {
        map = new HashMap<>();
        ArrayList<String> arr = new ArrayList<>();
        int[] list = new int[course.length];
        
        // Orders에 있는 요소들을 오름차순 정렬
        for (int i=0; i<orders.length; i++) {
            char[] c = orders[i].toCharArray();
            Arrays.sort(c);
            orders[i] = String.valueOf(c);
        }
        
        // DFS를 사용하여 조합들을 map에 저장
        for(int i=0; i<orders.length; i++) {
            visited = new boolean[orders[i].length()];
            dfs(orders[i], "", 0, 0);
        }
        
        
        // 각 course에 담긴 갯수별로 최대 주문 수 찾기
        for(int i=0; i<course.length; i++) {
            int max = 0;
            for(String key : map.keySet()) {
                int num = map.get(key);
                if(key.length() == course[i] && max <= num) {
                    max = num;
                }
            }
            if(max >= 2) list[i] = max;
        }

        // 최대 주문 수를 이용해 key 값 찾아 arr에 저장
        for(int i=0; i<course.length; i++) {
            for(String key : map.keySet()) {
                int num = map.get(key);
                if(key.length() == course[i] && num == list[i]) {
                    arr.add(key);
                }
            }
        }

        // 정렬 한 후 answer 배열에 담기
        Collections.sort(arr);
        String[] answer = new String[arr.size()];
        for(int i=0; i<arr.size(); i++) {
            answer[i] = arr.get(i);
        }

        return answer;
    }
    
    
    public void dfs(String order, String str, int dept, int index) {
        if(dept == order.length()) return ;
        
        for(int i=index; i<order.length(); i++) {
            if(!visited[i]) {
                visited[i] = true;
                dfs(order, str + order.charAt(i), dept+1, i+1);
                map.put(str + order.charAt(i), map.getOrDefault(str + order.charAt(i),0)+1);
                visited[i] = false;
            }
        }
    }
}

📖 Solution

2시간동안 고민해서 푼 문제! 포기하지 않고 내 힘으로 생각해서 풀어서 뿌듯하다...! 코드는 더러울 수 있어도 😅

처음에는 DFS를 사용해 조합들을 구해서 Map에 담고 value가 course 배열에 있으면 ArrayList에 담아서 오름차순으로 바꾼 후 최종 answer 배열에 담으면 해결이 될거라고 생각했다.

하지만 내가 문제를 잘못이해한건지 처음 orders에 있는 요소들은 오름차순 정렬이 필요했고 course 배열에는 key의 길이가 담겨있고 그중 key의 길이마다 value가 최대값인 key만 ArrayList에 담아야하는 것이 였다.

그리고 가장 시간을 많이 소요했던 DFS 🤨
DFS 문제들을 풀면서 조금은 감을 잡은거같다는 생각이 들었는데 내가 원하는 조합이 안나와서 멘붕

처음에는 index+1을 사용해서 풀었더니 원하는 값이 안나왔다

public void dfs(String order, String str, int dept, int index) {
    if(dept == order.length()) return ;
        
        for(int i=index; i<order.length(); i++) {
            if(!visited[i]) {
                visited[i] = true;
                dfs(order, str + order.charAt(i), dept+1, index+1);
                map.put(str + order.charAt(i), map.getOrDefault(str + order.charAt(i),0)+1);
                visited[i] = false;
            }
        }
    }

그래서 여러 방식을 사용해 보다 index+1 자리를 i+1로 바꾸어줬더니 원하는 조합이 나왔다.

public void dfs(String order, String str, int dept, int index) {
    if(dept == order.length()) return ;
        
        for(int i=index; i<order.length(); i++) {
            if(!visited[i]) {
                visited[i] = true;
                dfs(order, str + order.charAt(i), dept+1, i+1);
                map.put(str + order.charAt(i), map.getOrDefault(str + order.charAt(i),0)+1);
                visited[i] = false;
            }
        }
    }
profile
개발자로 가는 👣

0개의 댓글