안녕하세요! 테크지니어22입니다.
오늘은 프로그래머스 알고리즘 메뉴 리뉴얼 을 풀어보도록 하겠습니다.
https://school.programmers.co.kr/learn/courses/30/lessons/72411
프로그래머스
코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.
programmers.co.kr
[문제 접근]
orders의 최대크기 20, orders각 원소의 크기를 10, course =[2,3,4,5,6,7,8,9,10]라 가정하면
연산 개수는 약 20*(10C2+10C3+10C4+ ... 10C10) 으로 시간복잡도가 크지 않음을 알 수 있습니다.
그래서 완전탐색으로 접근했고, 조합을 이용하여 모든 경우를 고려한 후, 해시 맵에 저장하여 중복 개수를 세었습니다.
[풀이 전략]
1. orders의 원소를 오름차순으로 문자열 정렬을 합니다.
2. 각 orders의 원소마다 course의 원소만큼 뽑아서 map 넣습니다.
3. map에서 정답에 해당되는 것들 선별합니다.
- 최소 2명이상
- 가장 많이 함께 주문한 단품메뉴들이 여러개면 모두 출력 배열에 삽입
[코드]
#include <string>
#include <vector>
#include <algorithm>
#include <unordered_map>
using namespace std;
vector<string> solution(vector<string> orders, vector<int> course) {
vector<string> answer;
unordered_map<string,int> m ;
for(auto cnt : course){
for(auto order : orders){
sort(order.begin(), order.end());
int N = order.size();
vector<int> a ;
if(cnt > N) continue;
for(int i = 0; i < N; ++i) a.push_back(i < cnt ? 0 : 1);
do{
string s = "" ;
for(int i = 0; i < N; ++i)
if(a[i] == 0) {
s += order[i];
}
m[s]++;
}while(next_permutation(a.begin(), a.end()));
}
int maxv = 0 ;
vector<string> maxStr;
for(auto e : m){
if(e.second < 2) continue;
if(e.first.size() != cnt) continue;
if(maxv < e.second){
maxv = e.second;
maxStr.clear();
maxStr.push_back(e.first);
} else if(maxv == e.second){
maxStr.push_back(e.first);
}
}
for(auto str : maxStr) answer.push_back(str);
}
sort(answer.begin(),answer.end());
return answer;
}
[배울 점]
- for문으로 구현하면서 초기화 문제 신경쓰기.
'알고리즘 > 프로그래머스' 카테고리의 다른 글
[프로그래머스/C++] 알고리즘 - 문자열 압축 (0) | 2024.07.13 |
---|---|
[프로그래머스/C++] 알고리즘 - 괄호 변환 (0) | 2024.05.26 |
[프로그래머스/C++] 알고리즘 - 주차 요금 계산 (0) | 2024.05.23 |
[프로그래머스/C++] 알고리즘 - 양궁대회 (0) | 2024.05.23 |
[프로그래머스/C++] 알고리즘 - 도넛과 막대 그래프 (0) | 2024.05.16 |