12
返回列表 发新帖
楼主: ImGoingSSJ
跳转到指定楼层
上一主题 下一主题
收起左侧

925 Zenefits 电面

🔗
lcysjw 2015-10-15 09:46:14 | 只看该作者
全局:
aiuou 发表于 2015-10-15 00:29
如何efficient的比较两个集合是否相等?

我没考虑到这个点,貌似也没有特别好的方法,不知楼主是怎么做的
回复

使用道具 举报

🔗
aiuou 2015-10-15 12:03:46 | 只看该作者
全局:
我想了个方法,同时从左右两边走,用两个set分别记录prefix set和surfix set。同时maintain一个diffset。如果prefix或surfix有一个新的element, 现查看是否diffset里是否有这个值,如果没有就把这个新elment加入,如果有就把这个值从diffset里剪掉。如果diffset为空,说明目前的prefix set 和 surfix set相同,把这时的prefix/surfix set的长度记录下来放在一个set里,叫pairSet。我还用了两个array分别记录 长度为i的prefixset出现的次数,比如{1,1,1} prefix set就是[1]那么义工出现了3次{1},{1,1},{1,1,1}
最后过一遍pairSet,然后把相应的prefix set出现的次数 * surfix set 出现的次数就可以了。
整个算法复杂度应该是O(n)
  1. package zenefits;
  2. import java.util.*;
  3. public class PrefixSurfixArray {

  4.         public static long getPrefixSurfixPair(int [] a){
  5.                 if(a==null||a.length==0) return 0;
  6.                 int[] leftSetCount = new int[a.length];
  7.                 int[] rightSetCount = new int[a.length];
  8.                 int left=0,right=0;
  9.                 long result=0;
  10.                 HashSet<Integer> diff = new HashSet<Integer> ();
  11.                 HashSet<Integer> leftSet = new HashSet<Integer> ();
  12.                 HashSet<Integer> rightSet = new HashSet<Integer> ();
  13.                 HashSet<Integer> pairIndex = new HashSet<Integer> ();
  14.                 while(left<a.length||right<a.length){
  15.                         int temp=0;
  16.                         if(leftSet.size()<=rightSet.size()&&left<a.length){
  17.                                 temp=a[left];
  18.                                 if(!leftSet.contains(temp)){
  19.                                         leftSet.add(temp);
  20.                                         leftSetCount[leftSet.size()-1]=1;
  21.                                         if(diff.contains(temp)){
  22.                                                 diff.remove(temp);
  23.                                         }else{
  24.                                                 diff.add(temp);
  25.                                         }                       
  26.                                 }else{
  27.                                         leftSetCount[leftSet.size()-1]++;       
  28.                                 }                       
  29.                                 left++;
  30.                         }else {
  31.                                 temp=a[a.length-1-right];
  32.                                 if(!rightSet.contains(temp)){
  33.                                         rightSet.add(temp);
  34.                                         rightSetCount[leftSet.size()-1]=1;
  35.                                         if(diff.contains(temp)){
  36.                                                 diff.remove(temp);
  37.                                         }else{
  38.                                                 diff.add(temp);
  39.                                         }
  40.                                 }else{
  41.                                         rightSetCount[rightSet.size()-1]++;
  42.                                 }                               
  43.                                 right++;
  44.                         }
  45.                         if(diff.isEmpty()&&!pairIndex.contains(leftSet.size())){
  46.                                 pairIndex.add(leftSet.size());
  47.                         }
  48.                 }       
  49.                 for(Integer i: pairIndex){
  50.                         result+=leftSetCount[i-1]*rightSetCount[i-1];
  51.                 }
  52.                 return result;
  53.         }
  54.         public static void main(String[] args) {
  55.                 // TODO Auto-generated method stub
  56.                 int[][] tests={
  57.                                 {1,1,1},
  58.                                 {1,2, 3, 1, 2},
  59.                                 {1,2,3,4,5}
  60.                 };
  61.                 for(int[] test:tests){
  62.                         System.out.println("The number of prefix-surfix pair for array " +Arrays.toString(test)+" is "+getPrefixSurfixPair(test));
  63.                 }
  64.         }

  65. }
复制代码
回复

使用道具 举报

🔗
ymne06 2015-10-15 12:57:40 | 只看该作者
全局:
darkwowgamer 发表于 2015-10-15 08:52
"左边集合为1的数量为2" 这里还是要用hashmap做记录吧?

如果用hashmap怎么做呢?是定义map<set<int>, int>吗?能用set<int>作为map的key吗?
回复

使用道具 举报

🔗
lcysjw 2015-10-15 22:18:40 | 只看该作者
全局:
aiuou 发表于 2015-10-15 12:03
我想了个方法,同时从左右两边走,用两个set分别记录prefix set和surfix set。同时maintain一个diffset。如 ...

感谢set的对比思路,在你基础优化改进了一下,删去了pair这个存储结构,直接在循环的过程中求得答案
  1. def function(arry):
  2.     leftSetDiff = {}
  3.     rightSetDiff = {}
  4.     leftSet = {}
  5.     rightSet = {}
  6.     l = len(arry)
  7.     result = 0
  8.     leftIndex, rightIndex = 0, l - 1
  9.     while True:
  10.         m = 0
  11.         leftSet[arry[leftIndex]] = 1
  12.         while leftIndex < l and arry[leftIndex] in leftSet:
  13.             leftIndex += 1
  14.             m += 1
  15.         if arry[leftIndex-1] in rightSetDiff:
  16.             del rightSetDiff[arry[leftIndex-1]]
  17.         else:
  18.             leftSetDiff[arry[leftIndex-1]] = 1
  19.         n = 0
  20.         rightSet[arry[rightIndex]] = 1
  21.         while rightIndex >= 0 and arry[rightIndex] in rightSet:
  22.             rightIndex -= 1
  23.             n += 1
  24.         if arry[rightIndex+1] in leftSetDiff:
  25.             del leftSetDiff[arry[rightIndex+1]]
  26.         else:
  27.             rightSetDiff[arry[rightIndex+1]] = 1
  28.         if len(leftSetDiff) == 0 and len(rightSetDiff) == 0:
  29.             result += m*n
  30.         if rightIndex < 0 or leftIndex >= l:
  31.             break
  32.     return result
复制代码
回复

使用道具 举报

🔗
aiuou 2015-10-15 23:31:42 | 只看该作者
全局:
ymne06 发表于 2015-10-15 12:57
如果用hashmap怎么做呢?是定义map吗?能用set作为map的key吗?

在eclipse上试了一下,好像可以。那这道题简单多了
回复

使用道具 举报

🔗
Wizmann 2015-10-16 00:19:13 | 只看该作者
全局:
这题不是KMP的经典应用么。。。
回复

使用道具 举报

🔗
Wizmann 2015-10-16 00:39:58 | 只看该作者
全局:
和POJ 2752类似

题意是给你一字符串,找你找到一个子串。使得子串即是原串的前辍,又是原串的后辍。

这和我们这道题就是一模一样了。

代码如下:
  1. #include <cstdio>
  2. #include <cstdlib>
  3. #include <cstring>
  4. #include <string>
  5. #include <iostream>
  6. #include <algorithm>
  7. #include <vector>

  8. using namespace std;

  9. #define print(x) cout << x << endl
  10. #define input(x) cin >> x

  11. void get_next(const string& str, vector<int>& next) {
  12.     int n = str.size();
  13.     next = vector<int>(n + 1, -1);

  14.     for (int pre = -1, suf = 0; pre < n && suf < n; /* pass */) {
  15.         if (pre == -1 || str[pre] == str[suf]) {
  16.             pre++;
  17.             suf++;
  18.             next[suf] = pre;
  19.         } else {
  20.             pre = next[pre];
  21.         }
  22.     }
  23. }

  24. int main() {
  25.     string name;
  26.     vector<int> next;

  27.     while (input(name)) {
  28.         get_next(name, next);
  29.         int n = name.size();
  30.         int u = next[n];
  31.         vector<int> ans;
  32.         ans.push_back(n);
  33.         while (u) {
  34.             ans.push_back(u);
  35.             u = next[u];
  36.         }
  37.         reverse(ans.begin(), ans.end());
  38.         for (int i = 0; i < ans.size(); i++) {
  39.             if (i) {
  40.                 printf(" ");
  41.             }
  42.             printf("%d", ans[i]);
  43.         }
  44.         puts("");
  45.     }
  46.     return 0;
  47. }
复制代码
回复

使用道具 举报

🔗
lengyu 2015-10-16 04:07:44 | 只看该作者
全局:
ImGoingSSJ 发表于 2015-10-15 06:15
当时好像用的hashset,具体怎么样有点忘了,好像不是最优解,面试官说用hashmap

哦哦,好哒好哒,谢谢楼主,明白啦~
回复

使用道具 举报

🔗
ymne06 2015-10-16 12:24:49 | 只看该作者
全局:
Wizmann 发表于 2015-10-16 00:39
和POJ 2752类似

题意是给你一字符串,找你找到一个子串。使得子串即是原串的前辍,又是原串的后辍。

此面试题是要前缀字符串构成的集合与后缀字符串构成的集合相等,不是前缀、后缀字符串相等。
回复

使用道具 举报

🔗
Wizmann 2015-10-16 14:12:37 | 只看该作者
全局:
ymne06 发表于 2015-10-16 12:24
此面试题是要前缀字符串构成的集合与后缀字符串构成的集合相等,不是前缀、后缀字符串相等。

好吧。。。

那Hash就好咯。。。

还以为Z家这么变态直接上KMP呢,哈哈
回复

使用道具 举报

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

本版积分规则

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