티스토리 뷰

과제 진행하기

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

class Solution {
    public String[] solution(String[][] plansArr) {
        Plan[] plans = new Plan[plansArr.length];
        for(int i = 0; i < plansArr.length; i++) {
            plans[i] = new Plan(plansArr[i]);
        }
        Arrays.sort(plans, (a, b) -> a.start - b.start); 

        Stack<Plan> stop = new Stack<>();
        List<String> answer = new ArrayList<>();
        for(int i = 0; i < plans.length - 1; i++) {
            Plan curPlan = plans[i];
            Plan nextPlan = plans[i + 1];

            if(curPlan.getEndTime() > nextPlan.start) {
                curPlan.playTime = curPlan.getEndTime() - nextPlan.start;
                stop.push(curPlan);
                continue;
            }
            answer.add(curPlan.name);

            int restTime = nextPlan.start - curPlan.getEndTime();
            System.out.println(restTime);
            while(restTime > 0 && !stop.isEmpty()) {
                Plan stoppedPlan = stop.peek();
                int timeDiff = stoppedPlan.playTime - restTime;
                stoppedPlan.playTime = timeDiff;
                restTime = timeDiff * -1;
                if(timeDiff > 0) break;
                answer.add(stop.pop().name);
            }
        }

        answer.add(plans[plans.length - 1].name); // 마지막 index의 plan 처리
        while(!stop.isEmpty()) answer.add(stop.pop().name); // stack에 남아있던 plan들 넣기
        return answer.toArray(new String[answer.size()]);
    }
}

class Plan {
    String name;
    int start;
    int playTime;

    public Plan(String name, String start, String playTime) {
        this.name = name;
        String[] time = start.split(":");
        this.start = Integer.parseInt(time[0]) * 60 + Integer.parseInt(time[1]); // 시간 * 60 + 분
        this.playTime = Integer.parseInt(playTime);
    }

    public Plan(String[] plan) {
        this(plan[0], plan[1], plan[2]);
    }

    public int getEndTime() {
        return start + playTime;
    }
}

풀이 설명

  • Plan 객체를 생성해서 배열에 넣는다.
  • 배열을 정렬한다.
  • 배열을 plan의 마지막 전 인덱스까지 순회한다.
    • 현재 plan의 종료 시간이 다음 plan의 시작 시간 이후일 경우
      • 현재 plan의 playTime을 종료시간과의 차이만큼 빼고 stack에 넣는다.
    • 그 외
      • answer에 현재 plan 이름을 넣는다.
      • 다음 plan 시작 시간까지의 여유 시간있을 동안 && stack 빌 때까지 반복한다.
        • stack에서 요소를 빼서 남은 시간과 비교하여 처리해주면 된다.
  • 마지막 인덱스 plan와 stack에 남은 plan들을 answer에 넣고 출력한다.

실수

위의 정답 코드
while(restTime > 0 && !stop.isEmpty()) {
    Plan stoppedPlan = stop.peek();
    int timeDiff = stoppedPlan.playTime - restTime;
    stoppedPlan.playTime = timeDiff;
    restTime = timeDiff * -1;
    if(timeDiff > 0) break;
    answer.add(stop.pop().name);
}

틀렸던 코드
while(restTime > 0 && !stop.isEmpty()) {
    Plan stoppedPlan = stop.peek();
    stoppedPlan.playTime -= restTime;
    restTime -= stoppedPlan.playTime;
    if(stoppedPlan.playTime - restTime > 0) break;
    answer.add(stop.pop().name);
}

틀린 코드의 원인은 if(stoppedPlan.playTime - restTime > 0) break; 의 시점이다.
이미 stoppedPlan.playTimerestTime도 값이 달라졌기 때문에 원하던 값과 달라진다.
if문을 줄이다보니 어느 순간 이렇게 되있었는데 찾는데 한참 걸렸다..
어이없는 실수들을 줄여야지만 푸는 시간을 절약할 수 있을 것 같다.
아직은 레벨2 문제를 푸는데 시간이 너무 오래 걸린다.

처음에는 LocalTime으로 바꿔서 풀었었는데, 나쁘지는 않았지만 모르는 메소드가 너무 많아 실제 코테에서 사용하려면 공식문서가 지원이 되야할 것 같다. 그래서 다른 방법을 찾다가 연산할 때 편하게 (시간 * 60 + 분) 한 값을 start로 두는 아이디어를 아래 링크에서 얻었다.
아이디어 얻은 블로그

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/07   »
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 31
글 보관함