![]() |
1
29
构建一个哈希表,并将每个机场添加到哈希表中。
如果机场是来源地或目的地,则机场计数将增加。因此,对于每个机场,计数将为2(SRC为1,DST为1),但您旅行的来源和目的地除外,该计数将为1。 你至少要看一次每张票。所以复杂性是O(n)。 |
![]() |
2
20
总结:下面给出了一个单通算法 . (也就是说,不仅仅是线性的,而是每张票的外观 确切地 一次,这当然是每张票的最佳访问次数)。我之所以总结,是因为有许多看似等效的解决方案,很难找出我添加另一个解决方案的原因。:) 我在一次采访中被问到这个问题。这个概念非常简单:每一张票都是一个单件清单,有概念上的两个元素,SRC和DST。 我们将每一个这样的列表用其第一个和最后一个元素作为键索引到哈希表中,这样,如果一个列表开始或结束于一个特定的元素(机场),我们可以在O(1)中找到它。对于每一张票,当我们看到它从另一张票结束的地方开始时,只需链接这些票(o(1))。类似地,如果它以另一个列表开始的位置结束,则另一个列表联接。当然,当我们链接两个列表时,我们基本上会销毁两个列表并获得一个列表。(n张票的链将在n-1这样的链接之后构建)。 需要注意保持不变,即哈希表键恰好是剩余列表的第一个和最后一个元素。 总而言之,O(N)。 是的,我当场回答了:) 编辑 忘了加一个要点。每个人都提到 二 哈希表,但也有一个这样的技巧,因为算法不变量最多包括它 一 票列表从任何一个城市开始或开始(如果有两个城市,我们将立即加入该城市的列表,并从哈希表中删除该城市)。渐进地没有区别,这只是简单的方法。 编辑2 同样有趣的是,与使用2个具有n个条目的哈希表的解决方案相比 每个 ,此解决方案使用一个哈希表 至多 N/2个条目(如果我们按顺序(例如,1、3、5等)看到票,就会发生这种情况)。因此,除了速度更快之外,它还使用了大约一半的内存。 |
![]() |
3
10
构造两个哈希表(或尝试),一个在SRC上键入,另一个在DST上键入。随机选择一个票据,并在SRC哈希表中查找其DST。对结果重复该过程,直到到达终点(最终目的地)。现在在DST键控哈希表中查找其SRC。对结果重复该过程,直到到达开始处。 构造散列表需要O(n),构造列表需要O(n),所以整个算法是O(n)。 编辑:实际上,您只需要构造一个哈希表。假设您构造了SRC键控哈希表。随机选择一张票,像以前一样,构建通向最终目的地的清单。然后从尚未添加到列表中的票据中选择另一个随机票据。沿着它的目的地走,直到你找到你最初开始使用的票为止。重复此过程,直到构建完整个列表。这仍然是O(N),因为最坏的情况是你以相反的顺序选择票。 编辑:在我的算法中交换了表名。 |
![]() |
4
5
它基本上是一个依赖关系图,其中每个票据表示一个节点,并且 SRC 和 DST 机场代表有向链接,因此使用拓扑排序来确定航班顺序。 编辑:尽管这是一张机票,而且你知道你实际上已经制定了一个你可以实际执行的行程,按照UTC中的出发日期和时间排序。 edit2:假设每个机场都有一张使用三个字符代码的机票,则可以使用此处描述的算法( Find three numbers appeared only once )通过将所有机场合并来确定这两个独特的机场。 EdTe3:这里有一些C++来使用XOR方法来实际解决这个问题。总体算法如下,假设从机场到整数的唯一编码(假设机场代码为三个字母,或者使用经纬度将机场位置编码为整数): 首先,xor把所有机场代码放在一起。这应该等于初始源机场或最终目的地机场。因为我们知道初始机场和最终机场是唯一的,所以这个值不应该是零。因为它不是零,所以该值至少有一个位集。该位对应于一个机场中设置的位,而不是另一个机场中设置的位;称之为指示符位。 接下来,设置两个bucket,每个bucket具有第一步中的xoled值。现在,对于每一张机票,根据是否设置了指示符位对每个机场进行桶式处理,并将机场代码与桶中的值进行异或处理。同时记录每一个航班的出发地机场和目的地机场的数量。 处理完所有的票后,选择其中一个桶。发送到该存储桶的源机场数应大于或小于发送到该存储桶的目标机场数。如果源机场的数量小于目的地机场的数量,则表示初始源机场(唯一唯一唯一的源机场)已发送到另一个bucket。这意味着当前bucket中的值是初始源机场的标识符!相反,如果目的地机场的数量小于源机场的数量,则最终目的地机场被发送到另一个bucket,因此当前bucket是最终目的地机场的标识符!
|
![]() |
5
3
创建两个数据结构:
然后:
|
![]() |
6
2
放入两个散列: 结束=src->des; 发送至“des”->SRC 选择任何机场作为起点。
S现在是您的最终目的地。重复另一张地图,找到你的起点。 如果没有正确的检查,这感觉是O(N),前提是您有一个合适的哈希表实现。 |
![]() |
7
2
散列表不适用于大尺寸(例如原始问题中的数十亿);任何与之合作的人都知道它们只适用于小的集合。相反,您可以使用二进制搜索树,这将给您带来复杂性O(n log n)。 最简单的方法是使用两个过程:首先将它们全部添加到树中,由SRC索引。第二个遍历树并将节点收集到一个数组中。 我们能做得更好吗?我们可以,如果我们真的想:我们可以一次完成。将每个票据表示为喜欢列表中的一个节点。最初,每个节点的 下一个 指针。对于每个票据,在索引中输入其SRC和DEST。如果发生冲突,这意味着我们已经拥有了相邻的票据;连接节点并从索引中删除匹配项。完成后,您将只通过一次,并且拥有一个空索引,以及一个按顺序排列的所有票的链接列表。 这个方法明显更快:它只通过一次,而不是两次;而且存储空间明显更小(最坏的情况是:n/2;最好的情况是:1;典型的情况是:sqrt(n)),因此您可以实际使用哈希而不是二进制搜索树。 |
![]() |
8
1
每个机场都是
或者你可以建立一个机场可索引的结构。每一张票你都会查到
另一种方法是,当您遇到每张票时,将一个可变长度的迷你旅行列表连接在一起。每次添加一张票时,您都会看到任何现有迷你旅行的结束是否与您的票的SRC或DEST匹配。如果没有,那么您当前的机票将成为自己的迷你旅行,并添加到列表中。如果是这样的话,那么新的票将被附加到它匹配的现有行程的末尾,可能将两个现有的小行程拼接在一起,在这种情况下,它将把小行程列表缩短一个。 |
![]() |
9
1
这是单路径状态机矩阵的简单情况。 抱歉,伪代码是C样式的,但是用对象来表达这个想法比较容易。 首先,构造一个收费高速公路矩阵。 请阅读我对收费矩阵是什么的描述(不要在意FSM的答案,只需解释收费矩阵)。 What are some strategies for testing large state machines? . 但是,您所描述的限制使案例成为一个简单的单路径状态机。它是最简单的状态机,可以完全覆盖。
对于5个机场的简单情况,
请注意,对于每一行以及每一列,不应该有多个转换。 要获得机器的路径,您需要将矩阵排序为
或者排序成对角正方形矩阵——有序对的特征向量。
其中,订购的是门票列表: A2:A1、A5:A2、A1:A3、A3:A4、A4:A5。 或者用更正式的符号,
六羟甲基三聚氰胺六甲醚。。订了一对吧?在Lisp中闻到递归的味道?
机器有两种模式,
我猜你的问题是关于旅行重建。所以,你从那堆票中随机挑选一张又一张。 我们推测这票堆的大小是不确定的。
其中0值表示未排序的票据。让我们将无序票据定义为其DST与另一票据的SRC不匹配的票据。 下一张罚单发现mnx(dst)=kul(src)匹配。
在您选择下一张机票的任何时候,它都有可能连接两个连续的机场。如果发生这种情况,您将从这两个节点中创建一个集群节点:
矩阵被约化,
在哪里?
这是主列表的子列表。 继续随机挑选下一张票。
将existent.dst与new.src匹配
以上拓扑练习仅用于视觉理解。下面是算法解。 这个概念是将有序对集群到子列表中,以减少我们用来存放票据的散列结构的负担。逐渐地,将会有越来越多的伪票(由合并的匹配票形成),每个伪票包含越来越多的有序目的地子列表。最后,将在其子列表中保留一个包含完整行程向量的伪票据。 正如你所看到的,也许这是最好的Lisp。 然而,作为链表和地图的练习… 创建以下结构:
所以实际上,
当一张票从一堆中随机挑选出来时,
检查是否存在DST:
检查是否存在源代码:
我有一种感觉,上面有相当多的打字错误,但概念应该是正确的。如果有错别字,有人可以帮你改正。 |
![]() |
10
0
最简单的方法是使用哈希表,但它没有最好的最坏情况的复杂性( O(n) 二 ) ) 而是:
总体: O(n log n) (对于这两种算法,我们假设字符串的长度可以忽略不计,即比较为O(1))。 |
![]() |
11
0
不需要散列或类似的东西。
这里的实际输入大小不一定是门票数量(例如
n
但是总的尺寸(比如
n
)票的总数
如果我们有一个字母表 K 字符(此处 K 大约是42)我们可以使用bucketsort技术对 n 总大小的字符串 n 用字母编码的 K 字符在 o(n+n+k) 时间。如果 n=n (琐碎)和 k=n (井) n 是几十亿,不是吗)
|
![]() |
12
0
如果您假设一个可以存储所有内容(可能在磁盘上)的可接合列表结构:
|
![]() |
13
0
在我看来,基于图的方法是基于这里的。 每个机场都是一个节点,每张票都是一个边缘。现在让我们把每一条边都弄直。 在第一个阶段,您将构建图表:对于每个票据,您将查找源和目标,并在它们之间构建一条边。 现在这个图被构造出来了,我们知道它是非循环的,并且只有一条路径通过它。毕竟,你只有旅行的票,而且你从来没有去过同一个机场。 在第二阶段,您将搜索图形:选择任意节点,然后在两个方向上启动搜索,直到您发现无法继续。这些是您的来源和目的地。 如果您需要明确指出哪一个是源,哪一个是目的地,请向每个边缘添加一个目录属性(但保持它是一个无向图)。一旦您有了候选源和目标,您就可以根据连接到它们的边来判断哪个是哪个。 此算法的复杂性将取决于查找特定节点所需的时间。如果你能得到O(1),那么时间应该是线性的。你有n张票,所以你需要O(n)个步骤来构建图表,然后O(n)个步骤来搜索,O(n)个步骤来重建路径。仍然O(n)。一个邻接矩阵会给你这个。 如果你不能腾出空间,你可以为节点做一个散列,这会给你在最优散列下的O(1)和所有的垃圾。 |
![]() |
14
0
注意,如果任务是 只有 为了确定源机场和目的地机场(而不是重建整个旅程),这个难题可能会变得更有趣。 也就是说,假设机场代码是以整数形式给出的,则可以使用O(1)个数据传递和O(1)个附加内存(即,不使用哈希表、排序、二进制搜索等)来确定源机场和目的机场。 当然,一旦找到了源,索引和遍历整个路径也就变成了一件无关紧要的事情,但从这一点来看,无论如何,至少需要O(n)个额外的内存(除非您可以对数据进行就地排序,这样,就可以用O(1)个额外的内存在O(n log n)时间内解决原始任务)。 |
![]() |
15
0
让我们暂时忘记数据结构和图表。 首先,我需要指出的是,每个人都假设没有循环。如果这条路线经过一个机场的时间比经过一个机场的时间长两倍,那问题就大得多。 但我们暂时保留这个假设。 实际上,输入数据已经是一个有序集。每一张票都是关系的一个元素,它为一组机场引入了秩序。(英语不是我的母语,所以这些可能不是正确的数学术语)
每张票上都有这样的信息:
现在让我们放弃“线性假设”。在这种情况下,不能定义订单关系。输入数据必须被视为正式语法的生产规则,其中语法的词汇集是一组ariport名称。 像这样的票:
实际上是一对作品:
从中你只能保留一个。 现在,您必须生成每个可能的句子,但是您可以使用每个生成规则一次。最长的句子只使用一次它的每一个生产是一个正确的解决方案。 |
![]() |
16
0
先决条件首先,创建一种包含路线一部分的子标题结构。
例如,如果您的整个行程是
现在,创建两个哈希表,将一个城市映射到包含该城市的子列表结构。因此,一个hashtable代表一个子字符串开始的城市,另一个代表一个子字符串结束的城市。这意味着,一个城市在一个哈希表中最多只能出现一次。 正如我们稍后将看到的,不是每个城市都需要存储,而是每个子条的开始和结束。 构造子脚本
现在,一张接一张地拿着票。我们假设票是从
处理子脚本应该使用一些特殊的“技巧”。
有了这个结构,对应一个城市的子脚本可以在摊销O(1)中完成。
在所有的票都完成之后,我们有一些子脚本。注意我们最多有
连接子脚本
现在,我们一个接一个地考虑这些子脚本。如果我们有秘密消息
我希望我没有忽视Somtehing,但是这个算法应该运行在:
因此,整个算法需要时间
|
![]() |
17
0
我编写了一个小型的python程序,使用两个哈希表,一个用于计数,另一个用于SRC到DST映射。 复杂性取决于字典的实现。如果字典有O(1),那么复杂度是O(n),如果字典有O(lg(n)),就像在stl映射中一样,那么复杂度是O(n lg(n))。
|
![]() |
18
0
我在此提供了一个更通用的问题解决方案: 你可以在同一个机场停几次,但每一张票只能用一次 您每次旅行的票可以多于一张。 每张机票包含SRC和DST机场。 你所有的票都是随机分类的。 你忘记了最初的出发机场(第一个SRC)和目的地(最后一个DST)。 我的方法返回包含所有指定城市的城市列表(向量),如果存在这样的链,则返回空列表。当有几种方法可以在城市中旅行时,该方法将返回词典中最小的列表。
以下是用法示例:
|
![]() |
danial · 如何在多个字符串的每个位置找到最频繁的字符 2 年前 |
![]() |
Manny · 如何比较Perl中的字符串? 2 年前 |
![]() |
Diret · 获取范围内每个数字的子倍数的算法 2 年前 |
![]() |
Saif · 排序时python如何决定何时调用比较器? 2 年前 |