787. Cheapest Flights Within K Stops
广度优先搜索,
第一种解法超时:
class Solution {
public int findCheapestPrice(int n, int[][] flights, int src, int dst, int K) {
int f[][]=new int[n][n];
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
f[i][j]=Integer.MAX_VALUE;
for(int i=0;i<flights.length;i++)
f[flights[i][0]][flights[i][1]]=flights[i][2];
int cost=Integer.MAX_VALUE;
Queue<Point> queue=new LinkedList<Point>();
queue.offer(new Point(src,K,0));
while(queue.size()>0){
Point temp=queue.poll();
if(temp.k>=0 && f[temp.src][dst]!=Integer.MAX_VALUE)
cost=Math.min(cost,temp.cost+f[temp.src][dst]);
if(temp.k>0)
for(int i=0; i<n;i++)
if(f[temp.src][i]!=Integer.MAX_VALUE)
queue.offer(new Point(i,temp.k-1,temp.cost+f[temp.src][i]));
}
return cost==Integer.MAX_VALUE?-1:cost;
}
}
class Point{
int src;
int k;
int cost;
Point(int src,int k,int cost){
this.src=src;
this.k=k;
this.cost=cost;
}
}
第二种解法对第一种解法降低时间复杂度,首先是用哈希降低访问元素的时间复杂度;
然后是对while(queue.size()>0)何时退出进行分析,除去不必要的重复计算;
难点:何时退出 while(queue.size()>0),解法二显然遇到最优解便退出了,解法一就有很多不必要计算,再对问题进行分析,我们每次使用的是最小的cost去松弛路径,当遇到dst时说明后面的松弛对其已经没影响,所以当前解就是最优解。
思考:为什么每次使用最小的cost去松弛最终得到的解就是最优解,因为我们有bfs的扩展次数记录,假设一个最优解经过k次松弛后还未得到,那么肯定不符合题目要求,我所疑惑的是k,这里的k不是代表k只有k次松弛,而是说k次广度扩展,至于松弛几次,是未知的。
class Solution {
public int findCheapestPrice(int n, int[][] flights, int src, int dst, int K) {
Map<Integer,Map<Integer,Integer>> map=new HashMap();
for(int i=0;i<flights.length;i++){
if(map.getOrDefault(flights[i][0],null)==null)
map.put(flights[i][0],new HashMap<Integer,Integer>());
map.get(flights[i][0]).put(flights[i][1],flights[i][2]);
}
PriorityQueue<Node> queue=new PriorityQueue<Node>(new Comparator<Node>(){
public int compare(Node node1,Node node2){
return node1.cost-node2.cost;
}
});
queue.offer(new Node(0,src,K));
while(queue.size()>0){
Node temp=queue.poll();
if(temp.src==dst)
return temp.cost;
if(temp.k>=0){
Map<Integer,Integer> temp1=map.getOrDefault(temp.src,new HashMap<Integer,Integer>());
for(int key:temp1.keySet())
queue.offer(new Node( temp.cost+temp1.get(key) , key ,temp.k-1) );
}
}
return -1;
}
}
class Node{
int cost;
int src;
int k;
Node(int cost,int src,int k){
this.cost=cost;
this.src=src;
this.k=k;
}
}