我正在解决以下问题:
在与人共处的房间中,我们将定义两个人,如果他们是朋友 是直接或间接的朋友。如果A是B的朋友,而B是 是C的朋友,那么A也是C的朋友。一群朋友是一个 该组中的任何两个人都是朋友的一组人。给定 直接是朋友的人的名单,找到最小的一群 的朋友。
示例: 输入:
1<->6
2<->7
3<->8
4<->9
2<->6
3<->5
组:
1-6-2-7
3-8-5
4-9
最小组中的人数为2,即4-9,因此我们应该返回2。
我想出了以下代码,但是现在我不明白如何使用此holder
映射来获取所需的输出。我有点困惑。解决此问题的最佳方法是什么?
private static int findGroups(final List<List<Integer>> inputs) {
if (inputs == null || inputs.isEmpty()) {
return 0;
}
int count = Integer.MAX_VALUE;
Map<Integer, List<Integer>> holder = new HashMap<>();
for (List<Integer> input : inputs) {
// storing it in bidirectional way in the map
List<Integer> l =
holder.containsKey(input.get(0)) ? holder.get(input.get(0)) : new ArrayList<Integer>();
l.add(input.get(1));
holder.put(input.get(0), l);
List<Integer> l1 =
holder.containsKey(input.get(1)) ? holder.get(input.get(1)) : new ArrayList<Integer>();
l1.add(input.get(0));
holder.put(input.get(1), l1);
}
System.out.println(holder);
// use holder map to get the smaller group here?
return count;
}
好像我需要在这里使用递归来获得较小的组?
答案 0 :(得分:8)
有没有更好的方法来解决这个问题?
更好的方法是使用disjoint-set data structure:
顺便说一句,您正在执行的操作的技术名称是 transitive closure :“是朋友”关系是“是直接朋友”关系的传递闭包。 (但是,维基百科文章中描述的算法并不是针对您的问题的最佳算法,因为它们没有利用您的关系为symmetric的事实。)
答案 1 :(得分:0)
这是一些代码,出于对您问题的好奇,我已经写了。我对图了解不多,但是它像您所要求的那样使用递归。
基本上,您会检查输入内容,并为每个人创建一个ArrayList<Integer>
。在那个阵列中是那个人的直接朋友的人。例如,对于1: {6}, for 2: {7, 6}, for 3: {8, 5}
。然后,要获得人2的所有所有朋友,请通过将人7和6的数组(不包括重复项)聚集在一起来创建一个ArrayList<Integer>
数组。因此,可以以某种方式使用递归,即函数getAllFriends(Integer person)
也必须为该人的直接朋友返回getAllFriends(Integer person2)
。
因此,代码看起来像这样:
public class Test {
public static void main(String[] args) throws Exception {
String input = "1<->6\n" +
"2<->7\n" +
"3<->8\n" +
"4<->9\n" +
"2<->6\n" +
"3<->5";
HashMap<Integer, ArrayList<Integer>> friends = processInput(input); //getting data from the input string and storing it in a structured way
System.out.println(getAllFriends(1, friends, new ArrayList<Integer>(){{add(1);}})); //output: [1, 6, 2, 7]. Double brackets create an anonymous inner class, you add to the result the id of a person whose friends you're collecting
}
public static HashMap<Integer, ArrayList<Integer>> processInput(String input) throws Exception {
HashMap<Integer, ArrayList<Integer>> result = new HashMap<>();
BufferedReader bufReader = new BufferedReader(new StringReader(input));
String line=null;
while( (line=bufReader.readLine()) != null )
{
Integer personLeft = Integer.valueOf(line.substring(0, line.indexOf("<")));
Integer personRight =Integer.valueOf(line.substring(line.indexOf(">")+1, line.length()));
System.out.println(personLeft + ": " + personRight);
if (!result.containsKey(personLeft)) {
result.put(personLeft, new ArrayList<Integer>());
}
result.get(personLeft).add(personRight);
if (!result.containsKey(personRight)) {
result.put(personRight, new ArrayList<Integer>());
}
result.get(personRight).add(personLeft);
}
return result;
}
public static ArrayList<Integer> getAllFriends(Integer person, HashMap<Integer, ArrayList<Integer>> friends, ArrayList<Integer> result) {
for (Integer personFriend: friends.get(person)) {
if (!result.contains(personFriend)) {
result.add(personFriend); //add a person, if it wasn't added before
getAllFriends(personFriend, friends, result); //check out that person's friends
}
}
return result;
}
}