【问题标题】:Finding a friend of a friend of a friend寻找朋友的朋友的朋友
【发布时间】:2015-10-21 02:29:17
【问题描述】:

假设我有一个包含朋友属性的用户对象。这个friends 属性是其他用户对象的数组,因此是您的朋友。最快的算法是找到不是你朋友的朋友的朋友,然后更进一步,找到既不是你的朋友又不是你朋友的朋友的朋友的朋友。

下面是一个例子,以防上面的内容令人困惑:

鲍勃是瑞恩的朋友。 瑞恩是雅各布的朋友。 雅各布是哈利的朋友。 Bob 不是 Jacob 的朋友。 鲍勃和哈利不是朋友。 瑞恩不是哈利的朋友。 雅各布有资格成为朋友的朋友。 哈利有资格成为朋友的朋友的朋友。

我正在考虑一个 BFS,但我很想知道是否其他人都解决了这样的问题?

【问题讨论】:

  • 如果您的friend of a friend of a friend 也是您的friend,您是否要将他添加到结果中?

标签: algorithm search depth-first-search breadth-first-search


【解决方案1】:

我认为 BFS 方法最适合解决这个问题。

我们来看看这个简单的朋友树:

             David
           /
       Bob
     /     \ 
    /        Carl
Adam         
    \        Jim
     \     /
      Carl 
           \
             Sam

如果我们要对这个问题采取 DFS 方法,我们将首先遍历 Bob 并查看他是 David 和 Carl 的朋友。由于我们对这个问题采用了 DFS 方法,因此我们还不知道 Carl 是 Adam 的直接朋友。

如果我们采用 BFS 方法,我们将能够确定 Bob 的朋友是否已经是 Adam 的朋友。

【讨论】:

    【解决方案2】:

    我认为这可以通过过滤器和三级循环来完成:

    friends = user.friends        # first- or second-level friends
    friends3 = []                 # third-level friends
    for friend in user.friends:
        for friend2 in friend.friends:    # friends of friends
            if friend2 not in friends:    # filter out existing friends
                friends.add(friend2)
                for friend3 in friend2.friends:    # friends of friends of friends
                    if friend3 not in friends:     # filter out existing friends (of friends)
                        friends3.add(friend3)      # these match the criteria
    

    【讨论】:

      【解决方案3】:
      int levels = 3;
      HashSet<User>[] friendsPerLevel = new HashSet<User>[levels];
      
      // set the 0 level with your immediate friends
      friendsPerLevel[0] = new HashSet<User>(currentUser.Friends);
      
      // fill the rest of the levels
      for(int i = 1; i < levels; i++) {
        friendsPerLevel[i] = new HashSet<User>();
      
        // get all friends from the previous level
        foreach(User previousFriend in friendsPerLevel[i - 1]) {
      
          // loop through their friends list
          foreach(User friend in previousFriend.Friends) {
      
            // check if friend already exists in previous levels
            bool exists = false;
            for(int j = 0; j < i; j++) {
              if(friendsPerLevel[j].Contains(friend)) {
                exists = true;
                break;
              }
            }
      
            // add the new friend
            if(exists == false) {
              friendsPerLevel[i].Add(friend)
            }
          }
        }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-08-10
        • 1970-01-01
        • 1970-01-01
        • 2013-08-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多