강의로 돌아가기
howdyfrom2019

시간이 너무 많이 나온다(특히 11번) 하시는 분은 (코드 o)

큐 대신 우선순위 큐를 한 번 써보세요.
전 11번이 거의 9000ms 여서 이건 좀.. 그랬는데
혹시나 해서 우선 순위 큐로 자료구조 바꿨더니 11ms 나왔습니다.

이렇게 차이가 나네요. 이 두개가..ㅋㅋㅋㅋ

작성중인 코드―solution.js
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
function solution(board) {
    const heap = new MinHeap();
    const n = board.length;
    const costs = board.map(row => row.map(v => v === 1 ? [0, 0] : [Infinity, Infinity]));
    const dx = [1, 0, 0, -1];
    const dy = [0, 1, -1, 0];

    // queue value => x, y, cost 총합, 이전 방향(0: row, 1: col);
    heap.push({ x: 0, y: 0, cost: 0, prevDir: 0 });
    heap.push({ x: 0, y: 0, cost: 0, prevDir: 1 });

    while (!heap.isEmpty()) {
        const { x: x, y: y, cost: cost, prevDir: dir } = heap.pop();
        if (costs[x][y][dir] < cost) continue;
        costs[x][y][dir] = cost;

        if (x === n - 1 && y === n - 1) continue;

        for (let i = 0; i < 4; i++) {
            const nx = x + dx[i];
            const ny = y + dy[i];
            const nDir = Math.abs(dx[i]) === 1 ? 1 : 0;
            const nCost = nDir === dir ? cost + 100 : cost + 600;
            if (nx > -1 && ny > -1 && nx < n && ny < n && costs[nx][ny][nDir] >= nCost) {
                heap.push({x: nx, y: ny, cost: nCost, prevDir: nDir});
            }
        }
    }

    return Math.min(...costs[n - 1][n - 1]);
}

class MinHeap {
    constructor() {
        this.heap = [null];
    }

    push(val) {
        this.heap.push(val);
        let currentIndex = this.heap.length - 1;
        let parentIndex = Math.floor(currentIndex / 2);

        while (parentIndex !== 0 && this.heap[currentIndex].cost < this.heap[parentIndex].cost) {
            this._swap(currentIndex, parentIndex);
            currentIndex = parentIndex;
            parentIndex = Math.floor(currentIndex / 2);
        }
    }

    pop() {
        if (this.isEmpty()) return;
        if (this.heap.length === 2) return this.heap.pop();

        const val = this.heap[1];
        this.heap[1] = this.heap.pop();

        let currentIndex = 1;
        let leftIndex = 2;
        let rightIndex = 3;

        while (
            this.heap[leftIndex] && this.heap[currentIndex].cost > this.heap[leftIndex].cost ||
            this.heap[rightIndex] && this.heap[currentIndex].cost > this.heap[rightIndex].cost 
        ) {
            if (this.heap[leftIndex] === undefined) {
                this._swap(rightIndex, currentIndex);
            } else if (this.heap[rightIndex] === undefined) {
                this._swap(leftIndex, currentIndex);
            } else if (this.heap[leftIndex].cost > this.heap[rightIndex].cost) {
                this._swap(currentIndex, rightIndex);
                currentIndex = rightIndex;
            } else if (this.heap[leftIndex].cost <= this.heap[rightIndex].cost) {
                this._swap(currentIndex, leftIndex);
                currentIndex = leftIndex;
            }

            leftIndex = currentIndex * 2;
            rightIndex = currentIndex * 2 + 1;
        }

        return val;
    }

    isEmpty() {
        return this.heap.length === 1;
    }

    _swap(a, b) {
        [this.heap[a], this.heap[b]] = [this.heap[b], this.heap[a]];
    }
}
  • 김상표

    pq 구현 필요없이 continue 없애시고 배열을 q처럼 이용하신다면 shift사용하지말고 while절에 배열하나 더 만드시고 거기에 다음 경로 push하고 q배열에 덮어쓰시면 빨라질거에요

    김상표―2023.02.08 12:25
0 개의 답변
답변 쓰기
이 입력폼은 마크다운 문법을 지원합니다.