ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [프로그래머스] 2019 KAKAO BLIND RECRUITMENT - 무지의 먹방 라이브 - 자바(JAVA)
    알고리즘/프로그래머스 2022. 5. 11. 00:01
    728x90

    https://programmers.co.kr/learn/courses/30/lessons/42891

     

    코딩테스트 연습 - 무지의 먹방 라이브

     

    programmers.co.kr


    문제 해석

    회전판에 먹어야 할 N개의 음식이 존재합니다.

    각 음식에는 1부터 N까지 번호가 붙어있으며, 각 음식을 섭취하는데 일정 시간이 소요됩니다.

     

    무지는 다음과 같은 방법으로 음식을 섭취합니다.

    • 무지는 1번 음식부터 먹기 시작하며, 회전판은 번호가 증가하는 순서대로 음식을 무지 앞으로 가져다 놓는다.
    • 마지막 번호의 음식을 섭취한 후에는 회전판에 의해 다시 1번 음식이 무지 앞으로 온다.
    • 무지는 음식 하나를 1초 동안 섭취한 후 남은 음식은 그대로 두고, 다음 음식을 섭취한다.
    • 다음 음식이란, 아직 남은 음식 중 다음으로 섭취해야 할 가장 가까운 번호의 음식을 말합니다.

    무지가 먹방을 시작한 지 K초 후에 네트워크 장애로 인해 방송이 잠시 중단되었습니다.

    무지는 네트워크 정상화 후 다시 방송을 이어갈 때, 몇 번 음식부터 섭취해야 하는지를 알고자 합니다.

     

    섭취해야 할 음식이 남아있다면 몇 번 음식부터 섭취해야 하는지를 반환합니다.

    만약 더 섭취해야 할 음식이 없다면 -1을 반환합니다.

    food_times는 각 음식을 모두 먹는데 필요한 시간이 음식의 번호 순서대로 들어있는 배열입니다.

     

    문제 풀이 전 설계

    효율성 테스트의 경우 k의 범위는 2 x  10^13입니다.

     

    가장 간단하게 생각해보면 Food 객체를 만들고 인자로 number와 remainTime을 통해 음식의 번호와 먹기 위해 남아있는 시간을 부여합니다.

     

    이후 Queue에 넣고 k번 반복을 수행하면서 remainTime을 -1씩 하면서 remainTime ==0에 도달한다면 해당 Food객체는 더 이상 Queue에 넣지 않습니다.

     

    이렇게 하면 O(N)만에 문제를 해결할 수 있지만 효율성 테스트의 경우에는 시간 복잡도를 O(log(N))까지 줄여야 할 것 같습니다.

     

    아래부터는 다음 영상을 해석한 풀이입니다.

    https://www.youtube.com/watch?v=4MWxAt4fx5I 

     

     

    1. 시간별로 정렬을 한다. (n log(n)인데 이는 k에 영향을 받지 않고 배열의 길이 200,000에 영향을 받는 시간 복잡도)

    문제를 설계할 때는 log(n)까지 줄여야 한다는 생각에 정렬을 아예 배제하 버렸습니다.

     

    2. 왼쪽 그림은 k번 탐색해야 하지만 오른쪽 그림은 정렬되어있기 때문에 3번의 연산만에 끝낼 수 있습니다.

     

    https://www.youtube.com/watch?v=4MWxAt4fx5I

     

    한 가지 예시를 더 보겠습니다.

    https://www.youtube.com/watch?v=4MWxAt4fx5I

    1. 남아있는 시간별로 정렬합니다.

    2. 가장 밑의 배열의 크기는 6이기 때문에 20-6 = 14입니다.

    3. 그 위에 2줄의 크기는 2 x 5 = 10입니다. 14- 10 = 4입니다.

    4. 그 위에 2줄의 크기는 6입니다. 이는 남아있는 k보다 더 큽니다.

    5. 2,5,4를 다시 원래대로인 2 -> 4 -> 5로 되돌린 후 남아있는 K(=4) 나머지 연산 (2,4,5)의 개수 (=3)을 합니다

    6. 4%3 = 1이므로 1번째 index를 가진 4번 음식을 먹을 차례입니다.

     

     

    코드

    import java.util.*;
     
    class Solution {
        public int solution(int[] food_times, long k) {
            List<Food> foods = new ArrayList<>();
            int len = food_times.length;
            for(int i = 0; i < len; i++) {
                foods.add(new Food(i + 1, food_times[i]));
            }
            foods.sort((o1, o2) -> o1.time - o2.time);
            
            int current_time = 0;
            int idx = 0;
            for(Food f : foods) {
                long diff = f.time - current_time;
                if(diff != 0) {
                    long spend = diff * len;
                    if(spend <= k) {
                        k -= spend;
                        current_time = f.time;
                    } else {
                        k %= len;                                        
                        foods = foods.subList(idx, food_times.length);
                        foods.sort((o1,o2) ->o1.num - o2.num);                    
                        return foods.get((int)k).num;
                        
                    }
                }
                idx++;
                len--;
            }
            return -1;
        }
        
        public class Food {
            int num, time;
            
            public Food(int num, int time) {
                this.num = num;
                this.time = time;
            }
            
        }
    }

    댓글

Designed by Tistory.