Find the City With the Smallest Number of Neighbors at a Threshold Distance
There are n
cities numbered from 0
to n-1
. Given the array edges
where edges[i] = [fromi, toi, weighti]
represents a bidirectional and weighted edge between cities fromi
and toi
, and given the integer distanceThreshold
.
Return the city with the smallest number of cities that are reachable through some path and whose distance is at most distanceThreshold
, If there are multiple such cities, return the city with the greatest number.
Notice that the distance of a path connecting cities i and j is equal to the sum of the edges' weights along that path.
Example 1:
Input: n = 4, edges = [[0,1,3],[1,2,1],[1,3,4],[2,3,1]], distanceThreshold = 4 Output: 3 Explanation: The figure above describes the graph. The neighboring cities at a distanceThreshold = 4 for each city are: City 0 -> [City 1, City 2] City 1 -> [City 0, City 2, City 3] City 2 -> [City 0, City 1, City 3] City 3 -> [City 1, City 2] Cities 0 and 3 have 2 neighboring cities at a distanceThreshold = 4, but we have to return city 3 since it has the greatest number.
思路:dijkstra algorithm,tricky的地方还是visited不能直接加入visited,要用pop的来判断;否则失去最优解; 对于1个node是ElogV, 那么所有node就是VElogV, 由于E ~ V2, 那么这题就是V3logV.
class Solution {
private class Node {
public int cost;
public int city;
public Node(int city, int cost) {
this.cost = cost;
this.city = city;
}
}
private class NodeComparator implements Comparator<Node> {
@Override
public int compare(Node a, Node b) {
if(a.cost != b.cost) {
return b.cost - a.cost;
} else {
return b.city - a.city;
}
}
}
public int findTheCity(int n, int[][] edges, int distanceThreshold) {
if(edges == null || edges.length == 0 || edges[0].length == 0) {
return -1;
}
// build graph
HashMap<Integer, HashMap<Integer, Integer>> graph = new HashMap<Integer, HashMap<Integer, Integer>>();
for(int i = 0; i < n; i++) {
graph.putIfAbsent(i, new HashMap<Integer, Integer>());
}
for(int i = 0; i < edges.length; i++) {
int from = edges[i][0];
int to = edges[i][1];
int cost = edges[i][2];
graph.get(from).put(to, cost);
graph.get(to).put(from, cost);
}
// find adjectent list for each city;
HashMap<Integer, HashSet<Integer>> nodeAdjMap
= new HashMap<Integer, HashSet<Integer>>();
// return minsize city number;
int minsize = n ;
int maxnode = -1;
for(int i = 0; i < n; i++) {
Queue<Node> queue = new PriorityQueue<Node>(new NodeComparator());
HashSet<Integer> visited = new HashSet<Integer>();
queue.offer(new Node(i, distanceThreshold));
int count = 0;
while(!queue.isEmpty()) {
Node node = queue.poll();
int city = node.city;
int cost = node.cost;
if(!visited.contains(city)) {
visited.add(city);
count++;
}
HashMap<Integer, Integer> neighborsMap = graph.get(city);
if(!neighborsMap.isEmpty()) {
for(Integer neighbor: neighborsMap.keySet()) {
if(cost - neighborsMap.get(neighbor) >= 0) {
if(!visited.contains(neighbor)) {
queue.offer(new Node(neighbor, cost - neighborsMap.get(neighbor)));
}
}
}
}
}
if(count <= minsize) {
minsize = count;
maxnode = i;
}
}
return maxnode;
}
}
思路2 用floyd-warshall算法 dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j]); time complexity: O(V^3)
class Solution {
public int findTheCity(int n, int[][] edges, int distanceThreshold) {
int[][] dis = new int[n][n];
int res = 0;
int smallcount = n;
for(int[] row: dis) {
Arrays.fill(row, 10000);
}
for(int[] e: edges) {
dis[e[0]][e[1]] = dis[e[1]][e[0]] = e[2];
}
for(int i = 0; i < n; i++) {
dis[i][i] = 0;
}
for(int k = 0; k < n; k++) {
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++) {
dis[i][j] = Math.min(dis[i][j], dis[i][k] + dis[k][j]);
}
}
}
for(int i = 0; i < n; i++) {
int count = 0;
for(int j = 0; j < n; j++) {
if(dis[i][j] <= distanceThreshold) {
count++;
}
}
if(count <= smallcount) {
smallcount = count;
res = i;
}
}
return res;
}
}
上一篇: java中Runtime类详细介绍
下一篇: 快速幂取模快速算法超级详细介绍