【问题标题】:The Travel Tickets Problem旅行票问题
【发布时间】:2010-06-23 12:06:45
【问题描述】:

您将获得一叠各种交通工具的旅行票,这些交通工具将带您从 A 点到 B 点,途经几个站点。所有的票都坏了,你不知道你的旅程从哪里开始,也不知道它在哪里结束。按正确的顺序对票进行排序以完成您的旅程。

门票 = [
  {从:“巴塞罗那”,到:“纽约”}
  {从:“巴塞罗那”,到:“赫罗纳”},
  {从:“马德里”,到:“巴塞罗那”},
  {从:“赫罗纳”,到:“巴塞罗那”}
]

我想,正确的顺序是:

门票 = [
  {从:“马德里”,到:“巴塞罗那”},
  {从:“巴塞罗那”,到:“赫罗纳”},
  {从:“赫罗纳”,到:“巴塞罗那”},
  {从:“巴塞罗那”,到:“纽约”}
]

因为没有去马德里的机票,也没有去纽约的机票。

该任务的最佳算法是什么?

语言是 JavaScript,但与语言无关的解决方案就足够了。

更新:我更改了示例数据,以免与 One-way flight trip problem 混淆。

【问题讨论】:

  • 你必须走遍所有的城市吗?你必须使用所有的票吗?
  • 是的。此外,必须使用所有门票。
  • 您是手头有太多机票的懒惰旅行社吗? ;-)
  • 可能最简单的方法是在航班开始时间后对机票进行排序。虽然那会有点作弊;)
  • 我已投票决定重新开放。这不是同一个问题。

标签: algorithm language-agnostic sorting


【解决方案1】:

如果您可以多次访问一个节点(一个城市),这是eulerian path problem。

Here 是解决它的两种简单算法,具体取决于您拥有的图形类型。您在第 3 页 here 上有一个递归实现。

【讨论】:

    【解决方案2】:

    这不就是一个双向链表吗?将每个项目添加到列表中,并酌情链接每个项目;完成后,您将有两个带有未连接链接的条目(一个没有任何连接到它的“从”节点,一个在其“到”节点没有连接。这些是起点和终点链,然后您从缺少“来自”链接的条目开始依次读出它们,然后按照链接从一个条目到下一个条目。

    【讨论】:

    • 只有在保证每个城市最多访问一次的情况下才成立。
    • 是的 - 我的建议是基于给出的示例,而不是适应更多未指定的条件。
    【解决方案3】:

    你得到的是一个有向图,你希望在其中找到一个Eulerian Path。链接的文章描述了找到一个的算法,基本上是:

    1. 查找进出路线较少的城市(如果没有,从任何地方开始)
    2. 通过一张票(边)旅行,如果它不存在,它不会使图表断开连接;除非不存在此类票证,否则请使用该票证。
    3. 删除工单(边缘)并重复

    您最终应该已经使用了所有的票,并且在最终目的地。

    【讨论】:

      【解决方案4】:
      1. 根据您的工单创建有向图。
      2. 找到入度为 0 的节点
      3. 通过图边遍历所有节点以创建结果

      更新:使用原始帖子中添加的信息,此解决方案无法解决正确的问题。看看 IVLad 的 response。

      【讨论】:

      • 一些问题:你在考虑拓扑排序吗?如果是这样,您如何使用所有边缘?如果没有,你能详细说明 3. 吗? 如何进行迭代?
      • 他们是否有花哨的技术演讲“在from 列表中查找未出现在to 列表中的城市,然后开始追踪您的路线”? ;-)
      • @IVlad 我可能从帖子中的示例数据中假设了太多,但是如果有多个票共享同一个源节点,那么是的,它需要一个拓扑排序,这将使我的第 3 步不太明显:-)
      • @scunliffe 几乎...我可能会使用散列来构建有向图,给我一个 O(n) 解决方案,而不是 O(n^2) 的嵌套循环。
      【解决方案5】:

      以下是 javascript 实现的示例。

      var un  =
      [
       { from:'c',to:'d'},
       { from:'a',to:'b'},
       { from:'b',to:'c'},
       { from:'z',to:'a'},
       { from:'d',to:'m'},
      ]
      
      function buildTable( un ){
      return un.reduce(function(previousValue, currentValue, currentIndex ){
      
      //build the table.
          previousValue.from[currentValue['from']] = currentValue;
          previousValue.to[currentValue['to']] = currentValue;
      
      //to find start and end.    
          if( !previousValue.from[currentValue['to']] )  previousValue.from[currentValue['to']]= false;
          if(!previousValue.to[currentValue['from']])  previousValue.to[currentValue['from']]= false;
      
          return previousValue;
      
      },{to:{},from:{}} );
      
      
      }
      
      function getStart(nodes){
      //find start node indx.
          for(var i  in nodes)
          if( !nodes[i] )return i;
      }
      
      
      function print(start,nodes ){
      
      
      var sorted = [];
      //while detecting false from buildTable structure.
          while(start){
              var  node = nodes[start];
              sorted.push(node)
              start = node['to'];
      //console.log(start)
          }
      
      return sorted;
      }
      
      var sorted = buildTable(un);
      console.log(print(getStart(sorted.to),sorted.from));
      

      【讨论】:

        【解决方案6】:
            function fullPath(path) {
            let startingPoints = [];
            let endingPoints = [];
            let result = [];
        
            for (let i = 0; i < path.length; i++) {
                startingPoints.push(path[i].from);
                endingPoints.push(path[i].to);
            }
        
            for (let i = 0; i < path.length; i++) {
                if (!endingPoints.includes(path[i].from)) {
                    result.push(path[i].from);
                    break;
                }
            }
        
            for (let i = 0; i < path.length; i++) {
                if (startingPoints.includes(result[i])) {
                    let indexOfPoint = startingPoints.indexOf(result[i]);
                    result.push(endingPoints[indexOfPoint]);
                }
            }
            return result;
        
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2011-02-07
          • 2021-07-09
          • 2021-08-27
          • 2018-03-26
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多