💬 문제
https://school.programmers.co.kr/learn/courses/30/lessons/176962
💬 Idea
- Stack 구조를 사용한다.
- 진행하다가 멈춘 과제들을 Stack에 넣는다.
- Stack에서 마지막 원소를 꺼내어 현재 진행하고 있는 과제를 끝내는 시간보다 homework배열의 마지막 원소가 더 먼저 시작된다면
- 남은 시간을 계산하고 업데이트하여 현재 진행하고 있는 과제를 stack에 다시 넣고
- homework에서 새로 시작되어야할 과제도 stack에 넣어 마지막 원소가 되게끔 만든다.
- 그리고 현재 시간 또한 새로 시작되어야할 과제 시간으로 업데이트한다.
- 작거나 같다면 정답 배열에 현재 수행이 완료된 과제의 이름을 넣는다.
- 이 때 진행하던 과제는 더이상 없고 새로 해야하는 과제가 남아있다면, homework 배열의 마지막 원소를 꺼내 hwStack에 집어넣는다.
💬 풀이
import Foundation
structHomework{varname:StringvarstartHour:IntvarstartMinute:IntvarplayTime:Int}func solution(plans:[[String]])->[String]{varhomework:[Homework]=[]foriin plans {lettime=i[1].components(separatedBy:":").map({Int($0)! })
homework.append(Homework(name:i[0], startHour:time[0], startMinute:time[1], playTime:Int(i[2])!))}
// 정렬
homework = homework.sorted(by:{getTotalTime($0.startHour, $0.startMinute)>getTotalTime($1.startHour, $1.startMinute)})varhwStack:[Homework]=[homework.removeLast()]varcurrentHour:Int=hwStack[0].startHour
varcurrentMinute:Int=hwStack[0].startMinute
varans:[String]=[]while !hwStack.isEmpty {ifvar nowHW = hwStack.popLast(){
nowHW.startHour = currentHour
nowHW.startMinute = currentMinute
iflet nextHW = homework.last {
// 과제 진행 중 새 과제를 해야한다면
ifgetTotalTime(currentHour, currentMinute, nowHW.playTime)>getTotalTime(nextHW.startHour, nextHW.startMinute){
nowHW.playTime = nowHW.playTime - getIntervalTime(currentHour, currentMinute, nextHW.startHour, nextHW.startMinute)
hwStack.append(nowHW)removeLastHomework(nextHW)}else{
// 현재 과제가 마무리되었을 때
ans.append(nowHW.name)letdoneTime=getDoneHomeworkTime(currentHour, currentMinute, nowHW.playTime)
currentHour =doneTime[0]
currentMinute =doneTime[1]
// 만약 하던 과제가 없지만 새로 해야하는 과제가 남아있다면
if hwStack.isEmpty && !homework.isEmpty {removeLastHomework(nextHW)}}}else{
ans.append(nowHW.name)}}}func removeLastHomework(_ nextHW:Homework){
hwStack.append(homework.removeLast())
currentHour = nextHW.startHour
currentMinute = nextHW.startMinute
}return ans
}
// 총 시간을 구하는 메서드
func getTotalTime(_ startH:Int, _ startM:Int, _ playTime:Int?=nil)->Int{iflet playTime = playTime {if playTime + startM >60{return(startH +((playTime + startM)/60))*60+((playTime + startM)%60)}else{return(startH *60)+ playTime + startM
}}return startH *60+ startM
}
// 시간 차를 구하는 메서드
func getIntervalTime(_ startH:Int, _ startM:Int, _ endH:Int, _ endM:Int)->Int{if startH < endH {return(60- startM)+(endH -(startH +1))+ endM
}else{return endM - startM
}}func getDoneHomeworkTime(_ startH:Int, _ startM:Int, _ playTime:Int)->[Int]{if startM + playTime >60{return[startH +((playTime + startM)/60),(playTime + startM)%60]}else{return[startH, playTime + startM]}}소요시간 : 2시간
- 아이디어는 빨리 떠올렸으나, 구현 단계가 조금 오래 걸렸다… 구현 어렵다 !!
💬 문제https://school.programmers.co.kr/learn/courses/30/lessons/176962
💬 Idea💬 풀이소요시간: 2시간