Skip to content

Instantly share code, notes, and snippets.

@Deviad
Last active February 4, 2023 23:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Deviad/7a1ea99780e12baf8b80a7e2c4a133b5 to your computer and use it in GitHub Desktop.
Save Deviad/7a1ea99780e12baf8b80a7e2c4a133b5 to your computer and use it in GitHub Desktop.
Cheapest Flights Within K Stops
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.PriorityQueue;
/*
Fixed, clear solution which I have created after studying the problem that works in the expected time
on Leetcode and is easy to understand and remember
*/
class Solution {
public int findCheapestPrice(int n, int[][] flights, int src, int dst, int k) {
Map<Integer, List<DirectedEdge>> adj = new HashMap<>();
Set<Integer> stopsStore = new HashSet<>();
for (int[] flight : flights) {
var neighbors = adj.getOrDefault(flight[0], new ArrayList<>());
neighbors.add(new DirectedEdge(flight[0], flight[1], flight[2], 0));
adj.put(flight[0], neighbors);
}
PriorityQueue<DirectedEdge> pq = new PriorityQueue<>((a, b) -> a.w - b.w);
//src, to, weight/cost, stops
var root = new DirectedEdge(src, src, 0, 0);
pq.offer(root);
//List is a pair of destination and weight/cost
Map<DirectedEdge, Integer> visited = new HashMap<>();
//adding src and stop
visited.put(root, 0);
while (!pq.isEmpty()) {
DirectedEdge curr = pq.poll();
int w1 = curr.w;
int from = curr.src;
int to = curr.to;
int stops = curr.stops;
//k+1 because the max number of stops is numbered starting from 0 in the problem,
//as though it was the index of an array, which it is not.
if (to == dst && stops <= k + 1 ) {
return w1;
}
for (DirectedEdge edge : adj.getOrDefault(to, new ArrayList<>())) {
int w2 = edge.w;
boolean isPresent = visited.containsKey(new DirectedEdge(from, edge.to, w2, 0));
if (!isPresent || stops + 1 < visited.get(new DirectedEdge(from, edge.to, w2, 0)) ) {
visited.put(new DirectedEdge(from, edge.to, w2, 0), stops + 1);
pq.offer(new DirectedEdge(from, edge.to, w1 + w2, stops + 1));
}
}
}
return -1;
}
public static class DirectedEdge {
int src;
int to;
int w = Integer.MAX_VALUE;
int stops;
DirectedEdge(int src, int to, int w, int stops) {
this.src = src;
this.to = to;
this.w = w;
this.stops = stops;
}
@Override
public boolean equals(Object o) {
if(this == o) return true;
if (!o.getClass().equals(this.getClass())) return false;
DirectedEdge e = (DirectedEdge)o;
return src == e.src && to == e.to && w == e.w && stops == e.stops;
}
@Override
public int hashCode() {
int result = to;
result = 31 * result + src;
result = 31 * result + w;
result = 31 * result + stops;
return result;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment