There are list of cities in an graph and you are given city's x-coordinate and y-coordinate. Find the nearest city for given city
where nearest city must share either x-coordinate or y-coordinate of given city. If two citys are with equal distance then return
city with their name in alphabetical order. If no city nearest to given city then return "NONE" otherwise return nearest city name.
Eg:
C1 --> [3,3]
C3 --> [1,3]
C4 --> [6,3]
Formula - Distance from C1
1. To C3 is -> |C1.x - C3.x| + |C1.y - C3.y| -> |3-1| + |3-3| = 2
2. To C4 is -> |C1.x - C4.x| + |C1.y - C4.y| -> |3-6| + |3-3| = 3
3. So C3 is nearest city from C1.
Input:
cityNames: ["c1","c2","c3","c4"]
x: [3,2,1,6]
y: [3,2,3,3]
queriedCities: ["c1","c2","c3"]
Output:
returnList: ["C3","NONE", "C1"]public class FindNearestCity {
public FindNearestCity(){}
public List<String> getNearestCities(List<String> cityNames, List<Integer> x, List<Integer> y, List<String> queriedCities){
List<String> returnList = new ArrayList<String>();
Map<Integer, Set<Integer>> xCorCities = new HashMap<Integer, Set<Integer>>();
Map<Integer, Set<Integer>> yCorCities = new HashMap<Integer, Set<Integer>>();
// Keep all the x-coordinate cities in xCorCities Map
// Keep all the y-coordinate cities in yCorCities Map
for(int cityIndex = 0; cityIndex < cityNames.size(); cityIndex++){
int cityXCor = x.get(cityIndex);
int cityYCor = y.get(cityIndex);
xCorCities.putIfAbsent(cityXCor, new HashSet<Integer>());
xCorCities.get(cityXCor).add(cityIndex);
yCorCities.putIfAbsent(cityYCor, new HashSet<Integer>());
yCorCities.get(cityYCor).add(cityIndex);
}
for(int queriedCityIndex = 0; queriedCityIndex < queriedCities.size(); queriedCityIndex++){
int originCityIndex = cityNames.indexOf(queriedCities.get(queriedCityIndex));
int originCityXCor = x.get(originCityIndex);
int originCityYCor = y.get(originCityIndex);
PriorityQueue<Integer> nearestCities = new PriorityQueue<Integer>((sortCity1Index, sortCity2Index)->{
// Calucate the distance from origin city to other cities.
int distance1 = Math.abs((x.get(sortCity1Index) - originCityXCor)) + Math.abs((y.get(sortCity1Index) - originCityYCor));
int distance2 = Math.abs((x.get(sortCity2Index) - originCityXCor)) + Math.abs((y.get(sortCity2Index) - originCityYCor));
if(distance1 == distance2)
return cityNames.get(sortCity1Index).compareTo(cityNames.get(sortCity2Index));
return distance1 - distance2;
});
nearestCities.addAll(xCorCities.get(originCityXCor));
nearestCities.addAll(yCorCities.get(originCityYCor));
// Since Origin city added in x-coordinate & y-coordinate to queue so poll them twice.
// And distance from origin city to origin city will be always zero so it will first element.
nearestCities.poll();
nearestCities.poll();
if(!nearestCities.isEmpty())
returnList.add(cityNames.get(nearestCities.poll()));
else
returnList.add("NONE");
}
return returnList;
}
}