📣 独立日限时特惠: VIP通行证立减$68
查看: 16604| 回复: 48
跳转到指定楼层
上一主题 下一主题
收起左侧

Google面经题密码箱问题解法求问

全局:

注册一亩三分地论坛,查看更多干货!

您需要 登录 才可以下载或查看附件。没有帐号?注册账号

x
求问这道题的算法,看不懂代码,求大神解释一下~
一堆密码箱,每个密码都是四位0-9之间,算一个暴力破解序列,包含所有可能的四位序列,让这个序列尽量短
用的是DeBruijn,代码如下

  1. public class DeBruijn {
  2.         public static String generateDeBruijnSequence(int k, int n) {
  3.                 StringBuilder sequence = new StringBuilder();
  4.                 generateLyndonWords(1, 1, k, new int[n+1], sequence);
  5.                 return sequence.toString();
  6.         }

  7.         private static void generateLyndonWords(int t, int p, int k, int[] a, StringBuilder sequence) {
  8.                 if (t > a.length-1) {
  9.                         if((a.length-1)%p==0) {
  10.                                 for(int i = 1; i < p+1;i++) {
  11.                                         sequence.append(a[i]);
  12.                                 }
  13.                         }
  14.                 } else {
  15.                         a[t] = a[t-p];
  16.                         generateLyndonWords(t+1,p, k, a, sequence);
  17.                         for(int j=a[t-p]+1; j<=k-1; j++) {
  18.                                 a[t] = j;
  19.                                 generateLyndonWords(t+1,t, k, a, sequence);
  20.                         }
  21.                 }
  22.         }
  23.         public static void main(String[] args){
  24.                 System.out.println(generateDeBruijnSequence(10, 4).length());
  25.         }
  26. }
复制代码

上一篇:请教Graph Coloring的问题
下一篇:到底应该怎么刷LC?

本帖被以下淘专辑推荐:

推荐
coolidgelyt 2016-1-26 08:30:23 | 只看该作者
全局:
这里有个贴子说得很清楚:http://xwk.iteye.com/blog/2129621
回复

使用道具 举报

推荐
dietpepsi 2016-1-25 14:08:14 | 只看该作者
全局:
本帖最后由 dietpepsi 于 2016-1-25 14:46 编辑

这个写法更好,复杂度完全是O(E)了,不过对(10,4)还是会stackoverflow。设置-Xss2m或以上就可以,貌似不是啥大问题。
  1. public class EulerSolution {
  2.     int n, k, v;
  3.     int[] edge;
  4.     StringBuilder sequence;

  5.     public String crackSequence(int k, int n) {
  6.         this.n = n;
  7.         this.k = k;
  8.         v = 1; for (int i = 0; i < n - 1; ++i) v *= k; // vertices are n-1 bit radix k number.
  9.         edge = new int[v]; // edge list
  10.         sequence = new StringBuilder();
  11.         dfs(0);
  12. //        for (int i = 0; i < n - 1; ++i) sequence.append(0);
  13.         return sequence.reverse().toString();
  14.     }

  15.     // Hierholzer's algorithm
  16.     private void dfs(int u) {
  17.         while (edge[u] != k) {
  18.             int i = edge[u]++;
  19.             dfs((u * k + i) % v);
  20.             sequence.append(i);
  21.         }
  22.     }

  23.     public static void main(String[] args) {
  24.         System.out.println(new EulerSolution().crackSequence(9, 4).length());
  25.     }
  26. }
复制代码
回复

使用道具 举报

推荐
dietpepsi 2016-1-25 09:47:08 | 只看该作者
全局:
本帖最后由 dietpepsi 于 2016-1-25 10:01 编辑

我觉得这道题在题意明确的情况下,把所有状态看成点,状态之间的转移看成边是比较自然的。
这样就有两种看法,一种就是把4位看成状态,一种就是把3位看成状态。
把4位看成状态的图上面找Hamilton回路,很显然是本题的答案,因为访问了每一个节点一次且只有一次。
把3位看成状态的图上面找欧拉回路可能需要给面试官解释一下。但我觉得还是比较好解释的。
因为每一条边其实代表了一种4位的状态,于是就很好解释了。
那么上面的DFS找欧拉回路的算法就是相当简单有效的解法了。在删除边和查找下一个没有访问的边的复杂度是O(1)的情况下这个算法的复杂度是O(E)的,也就是O(k^n)的,de Buijin构造算法不会比这个复杂度更好。
我这个实现没有用LinkedList或者Hash来保存边的信息,所以每次都是循环所有可能的边,也就是O(k)查找边,所以总的复杂度是O(k^(n+1))。
考虑到
k = 10 n = 4
我觉得没啥问题。




回复

使用道具 举报

全局:
我也是面的这道题- -
回复

使用道具 举报

🔗
 楼主| 神罗天征 2016-1-22 07:55:53 | 只看该作者
全局:

请问你知道求解得吗
回复

使用道具 举报

全局:
神罗天征 发表于 2016-1-22 07:55
请问你知道求解得吗

我就是因为这道题跪了- -
回复

使用道具 举报

🔗
 楼主| 神罗天征 2016-1-22 08:02:14 | 只看该作者
全局:
战栗的百香果 发表于 2016-1-22 07:56
我就是因为这道题跪了- -

好吧,我就是看了面经看到了这道题,觉得太难了,google了解法,但是也不看懂……
回复

使用道具 举报

全局:
神罗天征 发表于 2016-1-22 08:02
好吧,我就是看了面经看到了这道题,觉得太难了,google了解法,但是也不看懂……

我当时听到这道题写了个暴力然后就蒙了
回复

使用道具 举报

🔗
 楼主| 神罗天征 2016-1-22 08:38:31 | 只看该作者
全局:
战栗的百香果 发表于 2016-1-22 08:18
我当时听到这道题写了个暴力然后就蒙了

这面得太难了吧,gg太变态了。那暴力求解怎么做呀
回复

使用道具 举报

🔗
nlx 2016-1-22 11:50:39 | 只看该作者
全局:
这个题目有些难了。主要是很多人没有见过Lyndon word。可以参考 https://en.wikipedia.org/wiki/Lyndon_word
这样的题目其实回答的时候要和面试官讨论,首先说只有1个箱子,每个密码只有1位,每位密码都只有2个值可去,然后开始向上逐一构造,比方说,先变化成2位密码,看看怎么写。好像GOOGLE非常喜欢问这类构造性的问题。

评分

参与人数 1大米 +5 收起 理由
163 + 5 感谢分享!

查看全部评分

回复

使用道具 举报

全局:
神罗天征 发表于 2016-1-22 08:38
这面得太难了吧,gg太变态了。那暴力求解怎么做呀

dfs生成所有四位数啊- -
回复

使用道具 举报

🔗
蛀牙jj 2016-1-22 14:36:39 | 只看该作者
全局:
战栗的百香果 发表于 2016-1-22 12:35
dfs生成所有四位数啊- -

我能想到的也是暴力破解啊,四个for循环嵌套
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册账号
隐私提醒:
  • ☑ 禁止发布广告,拉群,贴个人联系方式:找人请去🔗同学同事飞友,拉群请去🔗拉群结伴,广告请去🔗跳蚤市场,和 🔗租房广告|找室友
  • ☑ 论坛内容在发帖 30 分钟内可以编辑,过后则不能删帖。为防止被骚扰甚至人肉,不要公开留微信等联系方式,如有需求请以论坛私信方式发送。
  • ☑ 干货版块可免费使用 🔗超级匿名:面经(美国面经、中国面经、数科面经、PM面经),抖包袱(美国、中国)和录取汇报、定位选校版
  • ☑ 查阅全站 🔗各种匿名方法

本版积分规则

>
快速回复 返回顶部 返回列表