Zenefits 面经

zen test 3
开始去网上搜了搜,发现是stock maximize 和good node. 进去一看发现是string chain 和n queens… … 太连清

  1. string chain: 给一个library,包含一堆words. 从其中一个开始,每次remove掉一个字符,如果新word还在library里面就继续. 问最长有多长.
    比如:
    a
    ab
    abc
    adc
    abcd
    chain: abcd->abc->ab->a, 等于4
    很简单,用一个hashmap<string, Integer>,既当library又保存已经算出的结果,然后就bfs 递归

  2. n-queens 找threat. 就是找每个皇后在斜线上被几个皇后threat. 当然最多4个.
    往四个方向找就行,比如right-top方向: findThreat(row,col, 1, -1) .
    用了2个数组记录斜线,来剪枝. 因为<=2的时候就不需要遍历了

最后加了一点注释

店面:印度小哥
1. 中缀表达式求值
2. LC find peak
劳资的店面怎么都这么难。。。。

onsite
1.判断有向图是不是一棵树. 拓扑排序 follow-up是一堆图论的问题
两个日期之间的week 数
2.generate parenthesis的变种. follow up是如果这个大量调用. 思路是dp
3.culture fit


本来以为的题
hackerrank
1. stock maximize: 每天能买入最多一笔,可以卖出任意笔,手上可以同时持有任意笔.

import java.io.*;
import java.util.*;
import java.text.*;
import java.math.*;
import java.util.regex.*;

public class Solution {

    public static void main(String[] args) {
        /* Enter your code here. Read input from STDIN. Print output to STDOUT. Your class should be named Solution. */
        Scanner stdin=new Scanner(System.in);
        int n=stdin.nextInt();
        for(int k=0;k<n;k++)
        {
            int days=stdin.nextInt();
            if(days<=1)System.out.println(0);
            int[] arr=new int[days];
            for(int i=0;i<days;i++)arr[i]=stdin.nextInt();
            long max=(long)arr[days-1], profit=0;
            for(int i=days-2;i>=0;i--)
            {
                max=Math.max(max,arr[i]);
                profit+=Math.max(0, max-arr[i]);
            }
            System.out.println(profit);
        }
    }
}
  1. good node: 第一个node是good node,叫做tail. 指向tail的也是good node. 指向good node也是good node. 问最少需要改几条边让所有都是good node
    输入:一个数组array, array[i]代表node[i]指向node[array[i]]
    输出:一个integer

并查集(disjoint-set) 版本[code]

import java.util.*;

public class GoodNode {
    public static int find(int[] parent, int x) {
        if(x == 0) return 0;
        if(parent[x] == -1 || parent[x] == x) {
            return x;
        }
        return find(parent, parent[x]);
    }

    public static void union(int[] parent, int x, int y) {
        int xp = find(parent, x);
        int yp = find(parent, y);
        parent[xp] = yp;
    }

    public static int minChanges(int[] A) {
        int n = A.length;
        int[] parent = new int[n];
        Arrays.fill(parent, -1);
        for(int i=0; i<n; i++) {
            union(parent, i, A[i]);
        }
        int cnt = 0;
        for(int i=1; i<n; i++) {
            if(find(parent, i) == i)
                cnt++;
        }
        return cnt;
    }

    public static void main(String args[] ) throws Exception {
        Scanner s = new Scanner(System.in);
        int n = s.nextInt();
        int[] A = new int[n];
        for(int i=0; i<n; i++) {
            A[i] = s.nextInt()-1;
        }
        s.close();
        System.out.println(minChanges(A));
    }
}

不用并查集的版本

import java.util.*;


public class GoodNode {

    HashMap<Integer, Node>graph;

    void input()
    {
        Scanner stdin=new Scanner(System.in);
        int n=stdin.nextInt();
        graph=new HashMap<Integer, Node>();
        Node tail=new Node(1);
        graph.put(1, tail);
        stdin.nextInt();
        for(int i=2;i<=n;i++)
        {

            int next=stdin.nextInt();
            if(graph.containsKey(i)==false)graph.put(i, new Node(i));
            if(graph.containsKey(next)==false)graph.put(next, new Node(next));
            Node node=graph.get(i);
            Node neighbor=graph.get(next);
            if(node.neighbors.contains(neighbor)==false)node.neighbors.add(neighbor);
            if(neighbor.neighbors.contains(node)==false)neighbor.neighbors.add(node);
        }
        stdin.close();
    }

    int components()
    {
        int r=0,n=graph.size();

        for(int i=1;i<=n;i++)
        {
            if(graph.containsKey(i))
            {
                bfs(graph.get(i));
                r++;
            }
        }
        return r;
    }

    void bfs(Node root)
    {
        if(graph.containsKey(root.value)==false)return;
        graph.remove(root.value);
        for(Node next:root.neighbors)
        {
            if(graph.containsKey(next.value))
            {
                bfs(next);
            }
        }
    }

    public static void main(String[] args) {
        GoodNode test=new GoodNode();
        test.input();
        System.out.println(test.components()-1);
    }

}


class Node 
{
    int value;
    LinkedList<Node> neighbors;
    Node(int x)
    {
        value=x;
        neighbors=new LinkedList<Node>();
    }
}

online test过了,接下来是skype面
总结一下网上的面经
zenefits面经

  1. 面试官是个三哥,人蛮好,也没啥口音。
    就问了一道题:
    String s1 = “waeginsapnaabangpisebbasepgnccccapisdnfngaabndlrjngeuiogbbegbuoecccc”;
    String s2 = “a+b+c-“;

s2的形式是一个字母加上一个符号,正号代表有两个前面的字符,负号代表有四个,也就是说s2其实是”aabbcccc”,不考虑invalid。
在s1中,找出连续或者不连续的s2,也就是说从s1中找出”aa….bb…..cccc”,abc顺序不能变,但是之间可以有零个或多个字符,返回共有多少个。在上面这个例子中,有四个。

solution:LC distinct subsequence

2.两题leetcode原题,excel column number 和 word search
和地里其他人发的面经比似乎简单很多。。。

电面两题:1.Median of two sorted array; 2. Excel Sheet Column Title.

3.2015(4-6月) 码农类 硕士 全职@Zenefits – 网上海投 – 技术电面 |Other在职跳槽
Given array of whole numbers and a starting index, find out if you can win
Winning means ending up at an array value of 0
If you are at a position that has a value that is not a 0, you can move value times to the left or to the right
[1, 3, 0, 2, 2], i == 0 -> true
[1, 1], i == 1 -> false

Solution:
注意没有0和多个0的情况.
if x[i]<=abs(index-i)比较显然, index是0的index
if x[i]>abs(index-i), return ( x[i]-abs(index-i) )%2

4.有点像 reverse polish notation 的变种,计算一个表达式的值的。要求自行设计表达式的数据结构并计算表达式的值。

有几种特殊情况
1. 单输入一个数,比如 [0],是合法,结果为0;. From 1point 3acres bbs
2. 单输入一个运算符也是合法的。 无数字运算的 ‘+’, ‘-‘, ‘/’ 结果为 0, 单个 ‘*’ 的结果为 1.
3. 一个运算符可以有好几个计算数字。 比如输入为 [‘+’, 1, 2, 3],结果为1 + 2 + 3 = 6.
4. 表达式可嵌套,[‘+’, 1, 2, [‘‘, 1, 3]],这样结果为 1 + 2 + 1 2 = 5.

输入一定合法,不用考虑给了两个连续数字却没有运算符的情况,也不用考虑除数为0的情况。

Solution:
存储的数据结构就用string就行,然后逆序用栈:
1.是操作符,一直出栈until碰到操作符
2.是数字,进栈
3.是括号。右括号进栈,左括号跳过,并且把右括号出栈

5.coding 一道题,板上以前出现过,我也看过,但是当时感觉不难,没有认真想
Input: A binary search tree, consisting of integers. And a number k
Output: True if there are two nodes a and b in the tree, such that a.value + b.value = k
False otherwise

给了 time: O(n), space: O(n) 和一个 time: O(nlogn), space: O(logn) 的方法,都不满意,让我给 time: O(n), space: O(logn)的
我想到用inorder和reverse inorder traversal 同时做,然后前后各一个pointer,但是还没想清楚怎么存中间值时间就到了,要我问他问题,面试结束之后20min内发email给他写好的code。
最后10min问他做什么的,他说frontend 和backend 同时都做,然后balabala没仔细听了。。。
结束后我就按照http://www.geeksforgeeks.org/find-a-pair-with-given-sum-in-bst/ 的思路写了发过去了= = 随缘

solution, 我自己的code: O(n) time, O(lgn) space

import java.util.Stack;
public class MJ {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        TreeNode n1=new TreeNode(15);
        TreeNode n2=new TreeNode(10);
        TreeNode n3=new TreeNode(20);
        TreeNode n4=new TreeNode(8);
        TreeNode n5=new TreeNode(12);
        TreeNode n6=new TreeNode(16);
        TreeNode n7=new TreeNode(25);
        n1.left=n2;n1.right=n3;
        n2.left=n4;n2.right=n5;
        n3.left=n6;n3.right=n7;
        for(int i=18;i<=45;i++)MJ.findK(i, n1);
    }

    static boolean findK(int k, TreeNode root)
    {
        TreeNode left=root, right=root;
        Stack<TreeNode> stack1=new Stack<TreeNode>(), stack2=new Stack<TreeNode>();
        while(left!=null)
        {
            stack1.push(left);
            left=left.left; 
        }
        while(right!=null)
        {
            stack2.push(right);
            right=right.right;
        }
        left=stack1.peek();
        right=stack2.peek();
        while(left.val <= right.val && left!=right)
        {
            if(left.val+right.val==k)
            {
                System.out.println(k+"="+left.val+"+"+right.val);
                return true;
            }
            if(left.val+right.val<k)
            {
                stack1.pop();
                if(left.right!=null)
                {
                    left=left.right;
                    while(left!=null)
                    {
                        stack1.push(left);
                        left=left.left;
                    }
                }
                if(stack1.isEmpty())return false;
                else left=stack1.peek();
            }
            else
            {
                stack2.pop();
                if(right.left!=null)
                {
                    right=right.left;
                    while(right!=null)
                    {
                        stack2.push(right);
                        right=right.right;
                    }
                }
                if(stack2.isEmpty())return false;
                else right=stack2.peek();
            }
        }
        return false;
    }


}


class TreeNode
{
    int val;
    TreeNode left, right;
    TreeNode(int x)
    {
        val=x;
        left=right=null;
    }
}

  1. Our app is about showing interesting people around a location. Interesting people are those who share a lot of friends and interests with you..

Input:.
N – number of commands. Followed by N lines, each of the format:
Op args

Op can either be ‘Q’ or ‘W’.
Q is a query operation which takes two args:
user_id miles

miles is always one of the 3 values: 1, 5 or 30.

W is the insertion operation, which takes args of the form:
user_id lat lng interest_id1 weight1 interest_id2 weight2 …

interest_ids are the set of all interests that user cares about. This could be his facebook friends or interests, each of them having a specific weight.

Output:

For each query operation, output a single line containing the top 10 (or less) user_id’s who are within the ‘miles’ radius of the user and have the highest scalar product of common interest weights. These must be sorted in the order of the weights highest to lowest, tie broken by user_id lowest to highest.

Constraints:

Test case will have one densely populated university (Stanford) - 500 people, one city (Bay Area) - 50K people, and one sparsely populated country (US) - 500K people.

Each person has on average 5K interest_ids, which is a random number between 1 and 10K (interest_ids are not necessarily numbered 1 to 10K). Number of people who have a specific interest_id tends to follow power law distribution, with 20% of interests having 80% of user_ids, recursively.

solution:暂时的想法是interest用hashmap, 坐标转成GeoHash之后建一个B-tree索引

7.
1. implements API return unique Integer Identifier,对return的结果要求就是integer, unique, 如果两个server同时调用这个函数怎么办
solution: 从1开始自增就行, 关键是多线程 全局id依然unique.
如果最后生成的id都保存在一个数据结构里, 把它synchronized.
更好的方法是id分段: 给每个服务器分配一个前缀唯一标识,让服务器自己管理自己的ID后缀. 这样并发程度更高

  1. 实现一个数据结构包含三个功能,push, pop, getmin,time complexity均要为O(1), 不可以调用API,自己实现了double linkedlist,而且要求只用一个list
    **solution:**LC minstack

8.
第一次电面:1.找peak,可能是min peak,也可能是max peak
// [23, 40, 50, 60, 80, 75, 74, 35] - 80
// [90, 80, 70, 60, 65, 75] - 60

  1. {23, 90, 50, 60, 80, 75, 74, 35};
    返回第一个peak,O(n)的方法就行了.

Solution: lc find peak

9.给出一组数,判断可不可能是一个bst的preorder遍历
Solution: a[0]是root,后面比a[0]小的都是left subtree, 大的都是right subtree, 如果他们混在一起了return false。 然后recursively…

10.第一题是leetcode上面的Unique Paths II。
第二题是给定n个nodes,判断可以改变最少多少个node可以使得全部n个都是好的node。定义满足如下条件就是好的node:1)如果它是tail node,2)如果它指向tail node,3)如果它是一个好的node。满足这三种情况中任意一个就可。

11.randomize inner word, 给一个string, for example, “you are beautiful”, 需要对每个 Word 中 char 的位置打乱, 除了第一个和最后一个 Char。
所以“you are beautiful” 可能变成 “you are bfutaieul”

12.
1个dictionary, 里边有很多单词, a, apple, about, book, beats.. 要求查询的时候输入字母后 返回dictionary里有多少个单词符合查询要求,比如输入”a”, 就返回3, 接着输入”p” 就变成 “ap”, 返回 1.
问用什么data structure, 然后写出来, 外加写一个insert function to popuate the data structure

13.
输入(A,B) (A,C) (B,G) (C,H) (E,F) (B,D) (C,E)
转成(A(B(D)(G))(C(E(F))(H)))
Error Code Type of error
E1 More than 2 children
E2 Duplicate Edges
E3 Cycle present
E4 Multiple roots
E5 Any other error

14.
input就是总共有多少个叶子。牌号为1,2,3,。。。,N
还会告诉你多少个虫子,比如K个。
每个虫子的跨步。比如[2,3,5,4];这里代表有4个虫子,第一个是间隔2步,第二个间隔3步,第三个间隔5步,第四个间隔4步。. visit 1point3acres.com for more.
more specifically, 第一个会吃的叶子是2,4,6,8,…
第二个会吃的叶子是3,6,9,12….
第三个就这个性质
solution: LCM+集合的 inclusive-exclusive, 比如[1,24], 虫子是[2,3,4].
第一轮[2,3,4]加 24/2+24/3+24/4
第二轮[6,4,12]减 24/6+24/4+24/12
第三轮[12]加 24/12
12+8+6-4-6-2+2=16 吃掉16还剩8

15.bits flip. 大意就是有一串0,1的数组,find 0的数目减1的数目最多的子串
solution: shift 然后 &1,localmax 和 global maxmax

16.
Onsite:
1, 第一轮两个年轻国人,每人一道题
1.1, 首先是一个coding题,问给一个 Node* 数组,怎么判断是不是一个valid的 binary tree。
solution: 树得定义就是 连通,无环的简单图。 只要检查 边数目是n-1即可

1.2, 为现在的电梯有什么问题?怎么设计下一代的电梯。
国人小哥说这是一个开放思维的题,说什么的可以。无奈英语太差,思维也不够发散,没答好。.

2, 一个阿三大叔。给一个 int 数组,判断是否是一个可能的 BST preorder 访问顺序.
各种c++ java常识问题,OO 问题, 测试相关问题
solution recursive判断 左边一半小于root,且右边一半大于root

17。
1.good node
2.stock on hackerrank
3.lc number of islands
4.有一个String输入,其实是一个sentence, 例如“I want to buy a cup of water” 输出为 “I wnat to buy a cup of wtear”, shuffle chars except for head and tail for each word.
solution: perfect shuffle. note Random(n)=[0, n-1]

18
第一轮:求每个元素到guaraded room的最短距离
0: closed room
1: open room
2: guarded room

例如input. from: 1point3acres.com/bbs
1 2 1
1 0 1
1 2 1
那么output是
1 0 1
2 -1 2
1 0 1. more info on 1point3acres.com
第二轮:类似min window的题,但是比他难很多. str和query,找min window包含query, 但是要保持顺序。
solution: O(n)
input array = [1,43,4,23,1,3,5,9,1,12,4,3,4]
Query array = [1,4,3]
建一个hash map,query的字母和他们在str里的index: [[0,4,8],[2,10,12],[5,11]]
然后三个pointers, 改变第一个pointer,用贪心找出min window

第三轮:solve Sudoku
第四轮:非常简单的coding问题,各种behavior加闲扯
最后(算是第五轮吗),CTO亲自来聊,各种欢乐瞎扯。。

19 merge k sorted array. 注意是array。。直接merge sort好了

20 lc distinct subsequence.
solution直接dp, dp[i][j]=dp[i-1][j]+ {(if s[i]==t[j]) dp[i-1][j-1]}

  1. 实现 skip list
    1.通过数组创建
    2.查询一个数
    3.插入一个数
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值