楼主: wnbaicai
跳转到指定楼层
上一主题 下一主题
收起左侧

G家实习电面挂经

🔗
zzgzzm 2016-11-9 12:00:47 | 只看该作者
全局:
第二面:这个题等价于求string s中的最长subsequence found in dictionary(注意是subsequence,不是substring)。其实可对string s用DP。DP的一个维度就是从某 index=j 开始的子串s.subtr(j)对j = N, j>=0, j-- DP. 另一个维度是字典的prefix,每次匹配了一个字母时就只看字典中以该字母为首的单词,所以要用Trie建立字典。那么DP状态转移方程就容易写了:定义dp[j][TrieNode* x] := s.substr(j)的最长的能在Trie字典 x 找到的subsequence长度,那么:
dp[j][TrieNode* x] = max(dp[j+1][x], dp[j+1][x->next[s[j]-'a']]+1 or 0);
就是说在寻找s.substr(j)在字典 x的subsequence时,若不匹配char s[j],那么就是在寻找s.substr(j+1)在字典 x的最长subsequence;否则就是匹配s[j],然后在寻找s.substr(j+1)在字典 x->next[s[j]-'a']的最长subsequence,然后再根据结果和Trie node x->next[s[j]-'a']本身是否代表一个单词来决定+1或不加。最后要求的答案就是dp[0][root], root为原始字典的TrieNode root.
时间复杂度为O(Ns*Nt),Ns=s.length(), Nt=TrieNode个数(这个比单词长度总和是可以远远得小的,因为合并了相同的prefix)。所以比用暴力比较s和每个单词的时间O(Ns*Nd)比还是快很多的 (Nd=字典单词长度总和)
  1. struct Node { // Trie node for dictionary
  2.     int isWord; // 1 if representing a word; otherwise 0
  3.     vector<Node*> next;
  4.     Node():isWord(0),next(vector<Node*>(26)) {}
  5. };

  6. Node* createTrie(const vector<string>& dict) {
  7.   auto r = new Node(), cur = r;
  8.   for (const auto& s:dict) {
  9.     for (char c:s) {
  10.       int i = c - 'a';  
  11.       if (!cur->next[i]) cur->next[i] = new Node();
  12.       cur = cur->next[i];
  13.     }
  14.     cur->isWord = 1;
  15.   }
  16.   return r;
  17. }

  18. void postOrder(Node* r, vector<Node*>& post) {
  19.   if (!r) return;
  20.   for (auto x:r->next) postOrder(x, post);
  21.   post.push_back(r);
  22. }

  23. int longestSubsequence(string& s, const vector<string>& dict) {
  24.   int len = s.length(); if (!len) return 0;
  25.   auto r = createTrie(dict);   
  26.   vector<Node*> post; postOrder(r, post);
  27.   // dp[i][x] = length of longest subsequence of s.substr(i)
  28.   // found in dictionary defined by trie node x
  29.   auto dp = vector<unordered_map<Node*, int>>(len+1); // default all 0's
  30.   for (int i = len - 1; i >= 0; --i) {
  31.     for (auto x:post) {
  32.       auto y = x->next[s[i] - 'a'];
  33.       if (y) dp[i][x] = dp[i+1][y]? (dp[i+1][y]+1) : y->isWord;
  34.       dp[i][x] = max(dp[i][x], dp[i+1][x]);
  35.     }  
  36.   }
  37.   return dp[0][r];
  38. }
复制代码
回复

使用道具 举报

🔗
 楼主| wnbaicai 2016-11-9 12:05:37 | 只看该作者
全局:
delly224 发表于 2016-11-9 05:21
请问楼主多久知道的结果?

结果两周内公布,自我感觉肯定跪了
回复

使用道具 举报

🔗
 楼主| wnbaicai 2016-11-9 12:06:32 | 只看该作者
全局:
zzgzzm 发表于 2016-11-9 06:52
用hashset 分別存两个list 就行了。时间O(m+n) one pass.

恩,我也说的set
回复

使用道具 举报

🔗
 楼主| wnbaicai 2016-11-9 12:09:42 | 只看该作者
全局:
坨坨 发表于 2016-11-9 07:00
请问第二题list里的number是任意的么还是只是0-9?

给的例子是0~9,这些条件都可以自己假定
回复

使用道具 举报

🔗
 楼主| wnbaicai 2016-11-9 12:10:07 | 只看该作者
全局:
xiaozhuxiaozhu 发表于 2016-11-9 07:01
第1轮,第2题,就是combination sum的小变形,加个小于target就行了吧。

对,最后我说了这个思路她说是对的,但是没时间写了T_T
回复

使用道具 举报

🔗
 楼主| wnbaicai 2016-11-9 12:13:11 | 只看该作者
全局:
何打发123 发表于 2016-11-9 07:05
感谢楼主的分享!~~  我在想第二题为什么lz的方法不行呢? 是不是用一个HashMap 记录每个字符的位置 然后找 ...

对,就是记录字符的位置,但是不行,他给了个例子,比如 a: 0, 1, 2, 3, …, 1000000 然后b:999999,需要找aba的话找了b之后扫描a的时间还是太长
回复

使用道具 举报

🔗
 楼主| wnbaicai 2016-11-9 12:15:25 | 只看该作者
全局:
Jasonyuan 发表于 2016-11-9 09:23
楼主你好,请问你的timeline大概是怎么样的呢,我被内推后3周了一直没消息

我是星期天找人推的然后星期一一早上就来了邮件叫做OA约电面,但并不是本人简历厉害,因为其他找的内推,校招还有海投的其他公司一个回复的都没,所以还是看运气?
回复

使用道具 举报

🔗
Jasonyuan 2016-11-9 12:16:34 | 只看该作者
全局:
wnbaicai 发表于 2016-11-9 12:15
我是星期天找人推的然后星期一一早上就来了邮件叫做OA约电面,但并不是本人简历厉害,因为其他找的内推, ...

能麻烦给下recruiter邮箱吗,想问一下,一直没消息。。怕是被漏了
回复

使用道具 举报

🔗
 楼主| wnbaicai 2016-11-9 12:26:45 | 只看该作者
全局:
zzgzzm 发表于 2016-11-9 12:00
第二面:这个题等价于求string s中的最长subsequence found in dictionary(注意是subsequence,不是substr ...

给跪了,我能说我扫了一遍没看懂么,等有空了再研究下...
回复

使用道具 举报

🔗
 楼主| wnbaicai 2016-11-9 12:27:10 | 只看该作者
全局:
Jasonyuan 发表于 2016-11-9 12:16
能麻烦给下recruiter邮箱吗,想问一下,一直没消息。。怕是被漏了

发你站内信了
回复

使用道具 举报

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

本版积分规则

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