오늘은 이중 우선순위 큐 문제에 도전했다가 처참하게 깨졌다.
토익스피킹을 16시 30분에 치고 집에 오니 18시였는데
대략 3~4시간 끝에 시간초과 엔딩이 되어버렸다.

힙을 두개 사용해서 진행했는데
힙을 사용하는게 아니라 이중연결리스트를 만들고 값을 넣으라는건지
왜 시간초과가 나는지 이해하기 어려웠다..

아래는 오늘 진행한 코드인데 시간복잡도의 문제가 발견되면 제보 바랍니다.

const input = `1
8
I 40
I 42
I 39
I 39
I 41
I 40
D 1
D -1`.split('\n')

const result = []

const getParent = (num) => {
    return Math.floor((num-1)/2)
}

//배열에 push한 다음 index를 저장하고 부모와 비교 후 교체
//while문으로 본인이 더 작은 경우에만 작동
const pushHeap = (heap, pushNum) => {
    let indexNow = heap.length
    heap.push(pushNum)
    while (heap[indexNow] < heap[getParent(indexNow)]) {
        const temp = heap[indexNow]
        heap[indexNow] = heap[getParent(indexNow)]
        heap[getParent(indexNow)] = temp
        indexNow = getParent(indexNow)
    }
}

//0번쨰 인덱스에 저장된 값을 리턴할 필요는 없는 문제고
//마지막 인덱스의 값을 pop해서 0번째에 넣어준 다음
//해당 인덱스에서 자식 인덱스들과 비교해 더 작은 숫자가 있는 경우
//둘 중 더 작은 숫자와 교체하고 그 위치에서 계속 자식과 비교
//생각해보니 값을 리턴해줘야 반대편 힙에서 제거해야 할 숫자를 알 수 있다.
const popHeap = (heap) => {
    const popedValue = heap[0]
    if(heap.length > 1){
        let indexNow = 0
        heap[indexNow] = heap.pop()
        while(heap[indexNow] > heap[indexNow*2 +1] || heap[indexNow] > heap[indexNow*2 +2]){
            const temp = heap[indexNow]
            if(heap[indexNow*2 +1] > heap[indexNow*2 +2]){
                heap[indexNow] = heap[indexNow*2 +2]
                heap[indexNow*2 +2] = temp
                indexNow = indexNow*2 +2
            }
            else{
                heap[indexNow] = heap[indexNow*2 +1]
                heap[indexNow*2 +1] = temp
                indexNow = indexNow*2 +1
            }
        }
    }
    else{
        heap.pop()
    }
    return popedValue
}

//다른 힙에서 제거된 값의 위치에 마지막 인덱스의 값을 넣고
//해당 값을 계속 자식들과 비교해가며 위치를 바꿔주기(pop과 유사작업)
const deletHeap = (heap, deleteValue) => {
    let indexNow = heap.indexOf(deleteValue)
    if(indexNow === heap.length-1){
        heap.pop()
        return
    }
    heap[indexNow] = heap.pop()
    
    while(heap[indexNow] > heap[indexNow*2 +1] || heap[indexNow] > heap[indexNow*2 +2]){
        const temp = heap[indexNow]
        if(heap[indexNow*2 +1] > heap[indexNow*2 +2]){
            heap[indexNow] = heap[indexNow*2 +2]
            heap[indexNow*2 +2] = temp
            indexNow = indexNow*2 +2
        }
        else{
            heap[indexNow] = heap[indexNow*2 +1]
            heap[indexNow*2 +1] = temp
            indexNow = indexNow*2 +1
        }
    }
}

for(let i = 1 ; i < input.length ; i++){
    const amount = Number(input[i])
    const maxHeap = []
    const minHeap = []
    
    for(let j = i+1 ; j <= i+amount ; j++){
        const [order, nums] = input[j].split(' ')
        if(order === "I"){
            pushHeap(minHeap, BigInt(nums))
            pushHeap(maxHeap, BigInt(nums)*-1n)
        }
        else if(nums === "1" && maxHeap.length){
            const popedNum = popHeap(maxHeap) * -1n
            deletHeap(minHeap, popedNum)
        }
        else if(nums === "-1" && maxHeap.length){
            const popedNum = popHeap(minHeap) * -1n
            deletHeap(maxHeap, popedNum)
        }
    }
    
    if(maxHeap.length > 0){
        result.push(`${String(popHeap(maxHeap)) * -1} ${popHeap(minHeap)}`)
    }
    else{
        result.push("EMPTY")
    }
    i += amount
}
console.log(result.join('\n'))


//1.최소 힙 구현
//값 추가 시 배열의 마지막에 추가 후 부모와 비교
//값 제거 시 index 0에서 꺼낸 다음 마지막 값 넣고 비교
//2.최대 힙 구현?
//입력 및 출력값 *-1로 최소힙 함수 사용
//3.특정 값 제거 및 힙 최소힙 유지 함수 생성
//indexOf로 찾은 index값을 기준으로 마지막 값을 넣고 값 제거 while문과 동일하게 사용
//4.heap의 길이가 0일경우 pop 무시
//5.최종 결과물 길이가 0인지 판별 후 출력





(1).백준 2914 저작권은 저작권이 있는 멜로디의 갯수를 구하는 문제로
앨범 숫자 * 평균 곡 숫자 - 앨범 숫자 + 1을 통해 해결할 수 있었다.

간단한 수학 관련 문제로 알고리즘이 관계가 있는지는 이해할 수 없었다.
4시간동안 문제 해결이 되지 않아 출석용으로 푼 문제다.

const [amount, average] = `38 24`.split(' ').map(Number)
console.log(amount*average - amount + 1)

'회고' 카테고리의 다른 글

[취업준비일지] - 145  (0) 2023.03.14
[취업준비일지] - 144  (0) 2023.03.13
[취업준비일지] - 142  (0) 2023.03.11
[취업준비일지] - 141  (0) 2023.03.10
[취업준비일지] - 140  (0) 2023.03.09

+ Recent posts