Notice
Recent Posts
Recent Comments
Link
나의 GitHub Contribution 그래프
Loading data ...
«   2024/04   »
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
Tags
more
Archives
Today
Total
관리 메뉴

Code in Life

프로그래머스 메뉴 리뉴얼 본문

문제풀이

프로그래머스 메뉴 리뉴얼

퓨끼 2021. 10. 1. 23:44

문제 링크 : https://programmers.co.kr/learn/courses/30/lessons/72411 

 

코딩테스트 연습 - 메뉴 리뉴얼

레스토랑을 운영하던 스카피는 코로나19로 인한 불경기를 극복하고자 메뉴를 새로 구성하려고 고민하고 있습니다. 기존에는 단품으로만 제공하던 메뉴를 조합해서 코스요리 형태로 재구성해서

programmers.co.kr

해당 문제는 카카오 구현 문제라 그런지 푸는데 꽤나 애먹었다.
입출력 예 1번만 봤을 때는 가장 짧은 길이의 메뉴들인 "AC"와 "CDE"가 result에도 있기 때문에 길이가 작은 order에서 부터 재귀를 통해 메뉴 조합을 붙여간다고 생각했으나 입출력 2번과 3번을 보면 No.

입출력 예 2번에서는 orders에 짧은 조합에 "AD"가 없지만 result에는 "AD"가 있다. 즉, 각 order에 대해 모든 조합을 구해 가장 빈도가 높은 조합들을 선정하면 풀 수 있다.

이때 주의할 점은 orders 입출력 3번을 보면 알파벳순이 아니기 때문에 미리 정렬을 해준 배열을 넘겨야한다.
또한 최소 2명 이상의 손님에게서 주문된 구성만 답이 될 수 있음을 주의하자. 

Python

from itertools import combinations
from collections import Counter

def solution(orders, course):
    answer = []
    for menu_cnt in course:
        combi = [] 
        my_dict = dict();
        for order in orders:
            if len(order) >= menu_cnt:
                combi += list(map("".join,combinations(sorted(list(order)),menu_cnt)))
        if len(Counter(combi)) > 0: 
            maxCnt = max(Counter(combi).values())
            if maxCnt >= 2: 
                answer += [key for key, value in Counter(combi).items() if value == maxCnt]
    answer.sort()
    return answer

 

Java

import java.util.*;
import java.util.stream.*;

class Solution {
    private Map<String, Integer> map;
    private ArrayList<String> ans = new ArrayList<>();
    
    public String[] solution(String[] orders, int[] course) {
        for (int menuCnt : course) {
            map = new HashMap<>(); 
            for (String order : orders) {
                if (order.length() < menuCnt) continue;
                char[] arr = order.toCharArray();
                Arrays.sort(arr);
                boolean[] selected = new boolean[arr.length];
                combination(arr, selected, 0, menuCnt);
            }
            // 최대 고르고 저장하기
            if (map.size() > 0) {
                saveFrequentMenuCombo();
            }
        }
        Collections.sort(ans);
        return ans.toArray(new String[ans.size()]);
    }
    
    private void combination(char[] arr, boolean[] selected, int start, int r) {
        if (r == 0) {
            String s = "";
            for (int i = 0; i < arr.length; i++) {
                if (selected[i]) s += arr[i];
            }
            if(!s.equals("")) {
                if (map.containsKey(s)) {
                    map.put(s, map.get(s)+1);
                } else {
                    map.put(s, 1);
                }
            }
            return;
        }
        
        for (int i = start; i < arr.length; i++) {
            selected[i] = true;
            combination(arr, selected, i+1, r-1);
            selected[i] = false;
        }
    }
    private void saveFrequentMenuCombo() {
        int maxValue = Collections.max(map.values());
        if (maxValue < 2) return;
        List<String> frequentMenuCombo = map.entrySet().stream()
            .filter(m -> m.getValue() == maxValue)
            .map(Map.Entry::getKey)
            .collect(Collectors.toList());
        for (String menuCombo : frequentMenuCombo) {
            ans.add(menuCombo);
        }
    }
}

풀다가 알게 된건데 Java와 Python에서 Dictionary/Map의 최대값을 구하는 함수를 쓸 때, Dictionary/Map을 작업 이후에 새로 할당하거나 clear()를 시도한다면 
Python에서는 ValueError: max() arg is an empty sequence
Java에서는 메모리 참조(?) 에러(에러문구를 캡쳐 못했습니다 ㅎㅎ;)를 마주할 수 있다.

=> 입출력 예 3번의 경우 order의 길이가 course의 길이보다 작아서 Dictionary/Map이 채워지지 않고 비어있게 되는데 데이터가 없는 곳에서 최댓값을 구하려 했기 때문에 에러가 발생하는 것이다.
따라서 `size > 0` 인가? 를 확인해야한다.

'문제풀이' 카테고리의 다른 글

[python] 백준 1138번  (0) 2021.03.03
[python] 백준 1063번  (0) 2021.03.02
[python] 백준 1051번  (0) 2021.03.02
Comments