과제를 받은 루는 다음과 같은 순서대로 과제를 하려고 계획을 세웠습니다.
과제 계획을 담은 이차원 문자열 배열 plans가 매개변수로 주어질 때, 과제를 끝낸 순서대로 이름을 배열에 담아 return 하는 solution 함수를 완성해주세요.
| plans | result |
|---|---|
| [["korean", "11:40", "30"], ["english", "12:10", "20"], ["math", "12:30", "40"]] | ["korean", "english", "math"] |
| [["science", "12:40", "50"], ["music", "12:20", "40"], ["history", "14:00", "30"], ["computer", "12:30", "100"]] | ["science", "history", "computer", "music"] |
| [["aaa", "12:00", "20"], ["bbb", "12:10", "30"], ["ccc", "12:40", "10"]] | ["bbb", "ccc", "aaa"] |
O(N*logN)의 시간복잡도와, 과제를 진행하는 것을 계산하는 O(N)의 시간복잡도가 걸릴 것으로 보여서 최종적으로 O(N*logN)의 시간복잡도가 걸려서 N이 최대 1,000이기 때문에 알맞은 알고리즘으로 보인다.#include <string>
#include <vector>
#include <stack>
#include <algorithm>
using namespace std;
struct assignment{
string name;
int remaining;
};
int timeToInt(string s){
return stoi(s.substr(0,2)) * 60 + stoi(s.substr(3, 2));
}
vector<string> solution(vector<vector<string>> plans) {
vector<string> answer;
stack<assignment> assignStack;
// 과제 시작 시각을 기준으로 정렬
sort(plans.begin(), plans.end(), [](vector<string> a, vector<string> b){
return a[1] < b[1];
});
// 다음 과제 시작 시각까지 과제 진행
for(int i = 0; i < plans.size() - 1; i++){
int spendTime = timeToInt(plans[i + 1][1]) - timeToInt(plans[i][1]);
if (spendTime >= stoi(plans[i][2])){ // 시간 안에 과제를 진행할 수 있는 경우
spendTime -= stoi(plans[i][2]);
answer.push_back(plans[i][0]);
while(!assignStack.empty() && spendTime > 0){
assignment node = assignStack.top(); assignStack.pop();
if (node.remaining > spendTime){
node.remaining -= spendTime;
assignStack.push(node);
break;
} else {
spendTime -= node.remaining;
answer.push_back(node.name);
}
}
} else { // 시간 안에 과제를 진행할 수 없는 경우
assignStack.push({plans[i][0], stoi(plans[i][2]) - spendTime});
}
}
// 남아있는 과제 진행
answer.push_back(plans[plans.size() - 1][0]);
while(!assignStack.empty()){
assignment node = assignStack.top(); assignStack.pop();
answer.push_back(node.name);
}
return answer;
}