알고리즘 문제 풀기

프로그래머스: 무지의 먹방 라이브 - javascript(반복문 구현)

Fo_rdang 2024. 8. 6. 14:33
반응형

문제 출처 

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

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

문제 풀이 

1. 총 음식 시간을 계산 

const total = food_times.reduce((a,c) => a+c , 0)
if(total<=k) return -1

 

- food_times 배열의 모든 요소를 더해서 총 음식을 먹는 시간을 계산한다. 

- 총 시간이 k보다 작거나 같으면 모든 음식을 다 먹었기 때문에 -1을 반환한다. 

2. 음식 시간과 인덱스를 페어로 저장 및 정렬 

food_times = food_times.map((v,i) => [v,i+1])
food_times.sort((a,b) => b[0]-a[0])

 

- 각 음식의 남은 시간 v와 인덱스 i+1를 쌍으로 저장해서 새로운 배열을 만든다. 

- 내림차순으로 정렬해서 pop 연산이 가장 작은 시간 값을 가져오도록 한다. 효율적으로 음식 제거 위함. 

 

예시) 

[3,1,2] -> [[3,1],[1,2],[2,3]] -> [[3,1],[2,3],[1,2]]

3. 남은 음식 시간을 차로 변환

for(let i = 0 ; i < food_times.length-1 ; i++){
    food_times[i][0] -= food_times[i+1][0]
}

- 각 음식의 남은 시간에서 다음 음식의 남은 시간을 빼서 각 음식이 얼마나 줄어들 수 있는지 계산한다. 

- 이렇게 하면 반복적으로 빼는 과정을 줄일 수 있다. 

예시) 

[[3,1],[2,3],[1,2]] -> [[1,1],[1,3],[1,2]]

 

4. 시간을 차감하면서 음식 제거 

while(1){
    if(!food_times.length) break
    const min = food_times[food_times.length-1][0]
    if(k < min * food_times.length) break
    k -= min * food_times.length
    food_times.pop()
    while(food_times.length && !food_times[food_times.length-1][0]) food_times.pop()
}

 

- 남은 음식 시간이 있는 동안 반복 

- 현재 남은 음식 중 가장 적은 시간을 min으로 설정 

- k가 min*food_times.length 보다 작으면 현재 상태에서 멈춘다. 

- k에서 min * food_times.length를 차감한다. 

- 음식 시간을 모두 소진한 음식을 배열에서 제거한다. 

- 배열에서 0이 된 부분도 제거해서 최솟값이 같은 경우를 처리한다. 

5. 나머지 연산을 통해 남은 음식의 순서 계산 

k = k % food_times.length

- k를 남은 음식 개수로 나눈 나머지 값으로 업데이트하여 몇 번째 접시인지를 구한다. 

6. 남은 음식을 원래 순서로 정렬 후 결과 반환 

return food_times.sort((a,b) => a[1]-b[1]).filter((v,idx)=> idx===k)[0][1]

- 음식 인덱스를 기준으로 오름차순 정렬 

- k번째 음식을 반환한다. 

정답 코드 

function solution(food_times, k) {
    const total = food_times.reduce((a,c) => a+c , 0)
    if(total<=k) return -1
    
    food_times = food_times.map((v,i) => [v,i+1])
    food_times.sort((a,b) => b[0]-a[0])
    
    for(let i = 0 ; i < food_times.length-1 ; i++){
        food_times[i][0] -= food_times[i+1][0]
    }
    
    while(1){
        if(!food_times.length) break
        const min = food_times[food_times.length-1][0]
        if(k < min * food_times.length) break
        k -= min * food_times.length
        food_times.pop()
        while(food_times.length && !food_times[food_times.length-1][0]) food_times.pop()
    }
    
    k = k % food_times.length
    return food_times.sort((a,b) => a[1]-b[1]).filter((v,idx)=> idx===k)[0][1]
   
}
반응형