753 Cracking the Safe

方法一 Hierholzer’s Algorithm
相关概念:
1 欧拉路径:在无向图中,每个边只经过一次,形成的路径。在有向图中,是指每条有向边只使用一次,形成的路径。
2 欧拉回路:欧拉路径是一个环。
3 在无向图中,存在欧拉路径的条件是:每个顶点的边是偶数。或者图中有两个是奇数条边的顶点。
4 在图中找欧拉回路的算法Hierholzer’s Algorithm。算法描述是:选择开始顶点v,沿着顶点v的边一直访问直到访问到顶点v。这个访问是不可能卡在其他节点停止的,因为图中所有节点的边是偶数。从一个顶点进去,就要从一个顶点出来,直到顶点v。这个路径是一个欧拉回路,但可能没有覆盖了图中所有的边。在前面一个路径中如果存在节点u,u有邻边还没有访问,从顶点u继续访问得到一个欧拉回路,将该回路接到上之前访问的路径后,得到新的访问路径。直到所有顶点的边都访问完,得到完整的欧拉回路。
这里注意:新的路径接到前面的路径不是简单的放在后面,而是可能插在中间的。具体细节查看《数据结构与算法分析Java语言描述》第2版的第266,267页。

翻译到这都题目是这样的。所有答案的组合数是k^n。那么我们把前n-1个字符串看做是节点,最后一个字符是边。例如n=2,k=2,所有可能的组合是00,01,10,11。那么可以把0,1看做节点。0节点有两条边,分别为0,1,得到组合00,01。
753 Cracking the Safe_第1张图片
欧拉回路是:从节点0开始,0,1,1,0;
最后答案将节点0补上 :00110。参考官网解决方案一中提出了post-order概念。
自己的思想:用map构建图,实现Hierholzer’s算法。

DFS
想法:为了符合要求,最后返回的字符串answer应该包含所有可能的组合。可能的组合数应该是k^n。为了让answer最短,直觉上应该是使得answer的最后n-1个字符可以重用。
例如:n=2,k=2,所有可能的组合是00,01,10,11。answer=(00110)。
DFS的实现是:
目标:找到包含所有组合的最短字符串
创建图:节点是所有可能的组合,例如:00,01,10,11;边:如果node1的最后n-1个字符加上[0,k-1]范围内的任何一个数可以得到node2,则node1和node2之间有条边。例如 (00)+1=>(01),则00和01之间有条边。
转移:对每一个节点,取最后n-1位,如果能够有边,成功转移到另外一个未被访问的节点,则继续DFS。退出条件是:所有的组合都访问完成。
来自网页
代码实现:

方法二:Inverse Burrows-Wheeler Transform
1 Lyndon Word:Lyndon word 是一个非空字符串,在字典顺序上,比它的所有旋转都要(严格地)小。
Lyndon word的性质:一个Lyndon word 被分为左右两部分,左边的字符串在字典顺序上严格小于右边的字符串。 w=uv,u<v w = u v , u < v 。如果v尽可能的长,则将u,v称为标准分解(standard factorization)
举例来讲,用{0,1}可以组成的Lyndon word 可能有:0,1,01,001,011,0001,0011,0111…
来自wiki
2 de Bruijn sequences
将长度为n的Lyndon word 按字典顺序链接起来,形成de Bruijn sequences。这个视频中有讲解。
753 Cracking the Safe_第2张图片
753 Cracking the Safe_第3张图片
这两张图片来源于视频中。
3 Inverse Burrows-Wheeler Transform
IBWT算法生成可以形成de Bruijn 序列的Lyndon word。

你可能感兴趣的:(leetcode-java,DFS)