leetcode problem #787 "cheapest flights within k stops"

huangapple go评论98阅读模式
英文:

leetcode problem #787 "cheapest flights within k stops"

问题

I am trying to solve LeetCode problem #787, "Cheapest Flights Within K Stops."

>"There are n cities connected by some number of flights. You are given an array flights where flights[i] = [fromi, toi, pricei] indicates that there is a flight from city fromi to city toi with cost pricei. You are also given three integers src, dst, and k, return the cheapest price from src to dst with at most k stops. If there is no such route, return -1."

However, I am encountering an issue with a specific testcase:

flights = [[0,1,5],[1,2,5],[0,3,2],[3,1,2],[1,4,1],[4,2,1]],
n = 5,
src = 0,
dst = 2,
k = 2

The expected answer is 7, but my code is returning 9. I have spent the last 2 hours debugging the code, but I cant seem to find the issue. I would appreciate if someone can point out whats wrong with the code.

code:

class minHeap {
    constructor() {
        this.nodes = []
    }

    enqueue(node, priority, stopsCount) {
        if(this.isEmpty()) {
            this.nodes.push([node, priority, stopsCount])
        } else {
            let added = false;

            for(let i = 0; i < this.nodes.length; i++) {
                if(this.nodes[i][1] > priority) {
                    this.nodes.splice(i, 0, [node, priority, stopsCount])
                    added = true
                    break;
                }
            }

            if(!added) {
                this.nodes.push([node, priority, stopsCount])
            }
        }
    }

    dequeue() {
        return this.nodes.shift()
    }

    isEmpty() {
        return this.nodes.length === 0
    }
}

var findCheapestPrice = function(n, flights, src, dst, k) {
    const graph = {}
    const prices = {}
    for(let i = 0; i < n; i++) {
        graph[i] = []
        if (i == src) {
            prices[i] = 0
        } else {
            prices[i] = Infinity
        }
    }

    for(let [ from, to, price ] of flights) {
        graph[from].push([ to, price ])
    }


    const heap = new minHeap()
    heap.enqueue(src, 0, 0)
    
    while (!heap.isEmpty()) {
        const [ airport, price, stopsCount ] = heap.dequeue()
        
        for (let neighbor of graph[airport]) {
            const [ neighborAirport, neighborPrice ] = neighbor
            const priceToNeighbor = neighborPrice + price
            
            if (prices[neighborAirport] > priceToNeighbor && stopsCount <= k) {
                prices[neighborAirport] = priceToNeighbor
                heap.enqueue(neighborAirport, priceToNeighbor, stopsCount+1)
            }

        }
    }

    
    return prices[dst] == Infinity ? -1 : prices[dst]
};
英文:

I am trying to solve LeetCode problem #787, "Cheapest Flights Within K Stops."

>"There are n cities connected by some number of flights. You are given an array flights where flights[i] = [fromi, toi, pricei] indicates that there is a flight from city fromi to city toi with cost pricei. You are also given three integers src, dst, and k, return the cheapest price from src to dst with at most k stops. If there is no such route, return -1."

However, I am encountering an issue with a specific testcase:

flights = [[0,1,5],[1,2,5],[0,3,2],[3,1,2],[1,4,1],[4,2,1]], 
n = 5, 
src = 0, 
dst = 2, 
k = 2

The expected answer is 7, but my code is returning 9. I have spent the last 2 hours debugging the code, but I cant seem to find the issue. I would appreciate if someone can point out whats wrong with the code.

code:

class minHeap {
constructor() {
this.nodes = []
}
enqueue(node, priority, stopsCount) {
if(this.isEmpty()) {
this.nodes.push([node, priority, stopsCount])
} else {
let added = false;
for(let i = 0; i &lt; this.nodes.length; i++) {
if(this.nodes[i][1] &gt; priority) {
this.nodes.splice(i, 0, [node, priority, stopsCount])
added = true
break;
}
}
if(!added) {
this.nodes.push([node, priority, stopsCount])
}
}
}
dequeue() {
return this.nodes.shift()
}
isEmpty() {
return this.nodes.length === 0
}
}
var findCheapestPrice = function(n, flights, src, dst, k) {
const graph = {}
const prices = {}
for(let i = 0; i &lt; n; i++) {
graph[i] = []
if (i == src) {
prices[i] = 0
} else {
prices[i] = Infinity
}
}
for(let [ from, to, price ] of flights) {
graph[from].push([ to, price ])
}
const heap = new minHeap()
heap.enqueue(src, 0, 0)
while (!heap.isEmpty()) {
const [ airport, price, stopsCount ] = heap.dequeue()
for (let neighbor of graph[airport]) {
const [ neighborAirport, neighborPrice ] = neighbor
const priceToNeighbor = neighborPrice + price
if (prices[neighborAirport] &gt; priceToNeighbor &amp;&amp; stopsCount &lt;= k) {
prices[neighborAirport] = priceToNeighbor
heap.enqueue(neighborAirport, priceToNeighbor, stopsCount+1)
}
}
}
return prices[dst] == Infinity ? -1 : prices[dst]
};

答案1

得分: 2

我感觉你的排队优先级可能出了问题,但我没有足够的时间来精确调试。删除了这个优化后,程序可以正常工作:

class minHeap {
    constructor() {
        this.nodes = []
    }

    enqueue(node, priority, stopsCount) {
        // 这个现在不需要优先级了。
        this.nodes.push([node, priority, stopsCount]);
    }

    dequeue() {
        return this.nodes.shift()
    }

    isEmpty() {
        return this.nodes.length === 0
    }
}

var findCheapestPrice = function(n, flights, src, dst, k) {
    const graph = {}
    const prices = {}
    for(let i = 0; i < n; i++) {
        graph[i] = []
        if (i == src) {
            prices[i] = 0
        } else {
            prices[i] = Infinity
        }
    }

    for(let [ from, to, price ] of flights) {
        graph[from].push([ to, price ])
    }


    const heap = new minHeap()
    heap.enqueue(src, 0, 0)

    while (!heap.isEmpty()) {
        const [ airport, price, stopsCount ] = heap.dequeue()
        
        for (let neighbor of graph[airport]) {
            const [ neighborAirport, neighborPrice ] = neighbor
            const priceToNeighbor = neighborPrice + price
            
            if (prices[neighborAirport] > priceToNeighbor && stopsCount <= k) {
                prices[neighborAirport] = priceToNeighbor
                heap.enqueue(neighborAirport, priceToNeighbor, stopsCount+1)
            }

        }
    }

    
    return prices[dst] == Infinity ? -1 : prices[dst]
};

const
  flights = [[0,1,5],[1,2,5],[0,3,2],[3,1,2],[1,4,1],[4,2,1]], 
  n = 6, 
  src = 0, 
  dst = 2, 
  k = 2;
console.log(findCheapestPrice(n, flights, src, dst, k));

我尝试将上述代码提交到LeetCode(对此很抱歉,我不是故意抄袭的,只是想测试一下),它通过了所有的测试用例。

更新:这个修复可能是幸运的,尽管我还没有找到一个反例。实际上,我认为没有优先级,它应该对所有情况都有效(请参阅下面的评论和其他答案)。即使在这个复杂的图中,这段代码也可以工作。

英文:

I don't have enough time to debug exactly what's wrong but I feel something is wrong with your enqueuing priority. Removing that optimization causes the program to work correctly:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

class minHeap {
constructor() {
this.nodes = []
}
enqueue(node, priority, stopsCount) {
// This now work without the priority.
this.nodes.push([node, priority, stopsCount]);
}
dequeue() {
return this.nodes.shift()
}
isEmpty() {
return this.nodes.length === 0
}
}
var findCheapestPrice = function(n, flights, src, dst, k) {
const graph = {}
const prices = {}
for(let i = 0; i &lt; n; i++) {
graph[i] = []
if (i == src) {
prices[i] = 0
} else {
prices[i] = Infinity
}
}
for(let [ from, to, price ] of flights) {
graph[from].push([ to, price ])
}
const heap = new minHeap()
heap.enqueue(src, 0, 0)
while (!heap.isEmpty()) {
const [ airport, price, stopsCount ] = heap.dequeue()
for (let neighbor of graph[airport]) {
const [ neighborAirport, neighborPrice ] = neighbor
const priceToNeighbor = neighborPrice + price
if (prices[neighborAirport] &gt; priceToNeighbor &amp;&amp; stopsCount &lt;= k) {
prices[neighborAirport] = priceToNeighbor
heap.enqueue(neighborAirport, priceToNeighbor, stopsCount+1)
}
}
}
return prices[dst] == Infinity ? -1 : prices[dst]
};
const
flights = [[0,1,5],[1,2,5],[0,3,2],[3,1,2],[1,4,1],[4,2,1]], 
n = 6, 
src = 0, 
dst = 2, 
k = 2;
console.log(findCheapestPrice(n, flights, src, dst, k));

<!-- end snippet -->

I tried submitting the above code to LeetCode (sorry about that, I didn't mean to plagarize, just want to test), it passes all test cases.

Update: this fix may work by luck though I cannot find a counter example yet. In fact, I think without the priority, it should work for all cases (see comments below and the other answer). Even with this complicated graph this code works:

leetcode problem #787 "cheapest flights within k stops"

答案2

得分: 1

更新和仅排队按成本优先的站点的方案在这个特定示例中不起作用,因为到达机场4的成本在3个站点(包括最后一个)后被设置为5:[0,3,2] -> [3,1,2] -> [1,4,1]。但为了最优地到达机场2,我们需要中间状态,在这个状态下,我们以成本6到达机场4,但优先级方案阻止了这一点:

[0,1,5] -> [1,4,1]

我不认为Dijkstra算法通常可以用来优化到达目的地的边缘成本,其中边的数量受限制。其他动态规划或图算法可以帮助处理这个问题。

英文:

The scheme to update and only enqueue stops prioritised by cost doesn't work in this particular example because the cost to get to airport 4 is set as 5 after 3 stops (including the last): [0,3,2] -&gt; [3,1,2] -&gt; [1,4,1]. But in order to reach airport 2 optimally, we need the interim state where we reach airport 4 with cost 6 but the priority scheme prevents this:

[0,1,5] -&gt; [1,4,1]

I don't believe Dijkstra can be used generally to optimise edge cost to a destination where the number of edges is restricted. Other dynamic programming or graph algorithms can assist with that.

huangapple
  • 本文由 发表于 2023年7月18日 12:43:18
  • 转载请务必保留本文链接:https://go.coder-hub.com/76709586.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定