【问题标题】:List all link of friends between two given Friends列出两个给定好友之间的所有好友链接
【发布时间】:2023-03-15 14:41:01
【问题描述】:

据说所有人之间平均有六个或更少的社交联系。 创建一个应用程序,帮助您找到任何两个人之间的分离程度。 可以将其想象为在 Facebook 上选择两个用户并尝试了解这两个人的情况 已连接。

如果您选择任意两个人,您应该能够看到 它们之间的分离程度。 例如,如果您在系统中添加了以下关系...

  • Sameer 是 Aayushi 的朋友
  • Aayushi 是 Bhaskar 的朋友
  • Sameer 是 Kamalnath Sharma 的朋友
  • Kamalnath Sharma 是 Shanti Kumar Saha 的朋友
  • Shanti Kumar Saha 是 Bhaskar 的朋友

如果您选择两个人,比如 Sameer 和 Bhaskar,应用程序应显示学位 分离如下。

  • Sameer > Aayushi > Bhaskar
  • Sameet > Kamalnath Sharma > Shanti Kumar Saha > Bhaskar

我必须在 Node.js 应用程序中实现这个逻辑! 我尝试了使用图形链接列表的不同方法,但找不到实现此方法的解决方案。

【问题讨论】:

  • 你知道广度优先搜索吗?如果您想首先打印最短的连接,那将起作用。或者如果连接顺序无关紧要,则深度优先
  • 不,我不知道广度优先搜索。我想要所有可能的连接方式,以便它们连接起来。
  • 好吧,如果你只学过 2 种 Graph/Tree 算法,它们可能应该是广度优先搜索和深度优先搜索,因为这两种算法现在都可以解决你的问题,现在是选择一个和学习它。它们上有很多资源可以帮助您入门。当您执行 BFS/DFS 时,只需跟踪您到目前为止所采用的路径,每当您找到目标时,将您采用的路径添加到最后返回的结果数组中。当你找到你正在寻找的目标时,你经常会停止 BFS 或 DFS,但你可以继续前进,直到你处理整个图以找到所有路径。
  • 术语注释:BFS/DFS 通过查找从起始顶点到结束/目标顶点的路径来工作。因此,如果您正在寻找 Sameer 和 Bhaskar 之间的联系,Sameer 将是起点,而 Bhaskar 是目标。 “路径”只是指您连接两者的朋友链。

标签: javascript node.js graph tree


【解决方案1】:

阅读您发布的答案(将来您可能只是编辑您的帖子),您几乎明白了。您可以通过将 JSON 预处理为邻接列表图来提高 DFS 的效率,并且可以通过跟踪您之前访问过的朋友来避免无限循环(这样您就不会多次访问他们并无限循环)。

邻接列表 Graph 只是 Graph 的一种表示形式,您在对象中存储一个顶点列表作为键,并将它们相邻(连接)到的所有其他顶点的列表作为值存储。例如,图表将键 "sameer" 映射到列表 ["aayushi", "kamalnath"]。这使得每次调用find 时,您不必遍历所有Data 来查找value1。你可以通过Graph[value1]找到value1的朋友。 (为了清楚起见,我将 value1 重命名为 source 并将 value2 重命名为 target 以及以下代码中的一些其他变量名称更改)。

至于避免循环,您可以在一个简单的 javascript 对象(或集合)中跟踪您已经访问过的朋友,初始化为空并在递归调用开始时添加到每个新朋友,然后只需传递这个对象向下每个递归调用。您在每次通话开始时检查它以确保您没有进入循环。这对于您在树(根据定义为无环图)上执行的 DFS/BFS 搜索不是必需的,但对于可能具有循环/循环的一般图来说是必需的。

另一件小事是当你找到你的目标价值/朋友时,你就有了

if(Data[i].friends[j] == value2){
  path.push(Data[i].friends[j])
  break;
}

在这种情况下你不递归是对的,但如果你希望能够继续搜索你正在循环的其他朋友寻找替代路径,你可能不想中断(而不是仅仅中断和返回找到的第一条路径)。

另外,我不确定这是否是故意的,但在示例数据中,友谊似乎是单向的(例如,shanti 是 bhaskar 的朋友,但 bhaskar 没有列出的朋友)。如果它们是两种方式,您可能会稍微改变将连接列表预处理为图表的方式。无论如何,这是我提到的所有更改的代码。如果不清楚,请告诉我:

// preprocess a JSON list of connections to an adjacency list Graph
function connectionsListToGraph(connections) {
  const Graph = {}
  for (let { name, friends } of connections) {
    Graph[name] = friends // allow fast lookup of a given person's friends
  }
  return Graph
}

// return the list of connections between source and target
function getConnections(source, target, connections) {

  const Graph = connectionsListToGraph(connections)
  const connectionPaths = []

  function findConnectionsDFS(source, target, path = [source], visited = {}) {
    // Don't search/visit the same friend twice (to avoid infinite loops)
    if (visited[source]) return; 

    // mark that we've searched the current source friend
    visited[source] = true; 

    for (let friend of Graph[source]) {
      if (friend === target) {
        connectionPaths.push(path.concat(target));
      } else {
        findConnectionsDFS(friend, target, path.concat(friend), visited)
      }
    }
  }
  findConnectionsDFS(source, target);
  return connectionPaths;
}

let connections = [
  {
    "name": "sameer",
    "friends": ["aayushi", "kamalnath"]
  },
  {
    "name": "aayushi",
    "friends": ["bhaskar"]
  },
  {
    "name": "kamalnath",
    "friends": ["shanti"]
  },
  {
    "name": "shanti",
    "friends": ["bhaskar"]
  }
]

console.log('Sameer to Bhaskar:', getConnections('sameer', 'bhaskar', connections))
console.log('Kamalnath to Bhaskar:', getConnections('kamalnath', 'bhaskar', connections))

【讨论】:

  • 感谢帮助我目前正在学习 DSA,我什至还没有开始造树。您的解决方案确实帮助我更好地理解了这个问题,现在我不再害怕图表了。
【解决方案2】:

我使用了递归我尝试了 DFS,但我无法实现它
我以基本 JSON 格式获取数据并在旅途中更新它,因为如果问题未指定在 6 个朋友连接下会有您的目标值,此函数可能处于无限循环中。

[
  {
    "name": "samer",
    "friends": ["aayushi", "kamalnath"]
  },
  {
    "name": "aayushi",
    "friends": ["bhaskar"]
  },
  {
    "name": "kamalnath",
    "friends": ["shanti"]
  },
  {
    "name": "shanti",
    "friends": ["bhaskar"]
  }
]

function find(value1,value2,path){
if(count > 6)
  while(true){
  for(var i in Data){
   if(Data[i].name == value1){
     for(var j in Data[i].friends){
        if(Data[i].friends[j] == value2){
            path.push(Data[i].friends[j])
            break;
           }
        else{
            find(Data[i].friends[j],value2,path)
           }
        }
      }
    }
  }
}}
var path = [];
find("samer","bhaskar",path,6)

//Output --> [[aayushi],[kamalnath,shanti]]

【讨论】:

  • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center
猜你喜欢
  • 2020-02-09
  • 1970-01-01
  • 2017-06-28
  • 2012-09-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-03
相关资源
最近更新 更多