2019,2020年ebay校招的笔试题目。会持续更新。

公司简介

eBay 公司成立于1995 年9 月,目前是全球最大的网络交易平台之一,为个人用户和企业用户提供国际化的网络交易平台。eBay.com 是一个基于互联网的社区,买家和卖家在一起浏览、买卖商品,eBay 交易平台完全自动化,按照类别提供拍卖服务,让卖家罗列出售的东西,买家对感兴趣的东西提出报价。

超过九千五百万来自世界各个角落的eBay 会员,在这里形成了一个多元化的社区,他们买卖上亿种商品,从电器到电脑,到家居用品,到各种独一无二的收藏品。eBay 还有定价拍卖模式,买家和卖家按照卖家确立的固定价格进行交易。

eBay 在全球的服务站点包括在美国的主站点和在奥地利、澳大利亚、比利时、巴西、加拿大、中国、法国、德国、中国香港、印度、爱尔兰、意大利、韩国、马拉西亚、墨西哥、荷兰、新西兰、菲律宾、波兰、新加坡、西班牙、瑞典、瑞士、中国台湾、英国和阿根廷的26个全球站点。eBay 总部设在美国加利福尼亚州,目前拥有4000 名员工,在英国、德国、韩国、澳大利亚、中国和日本等地都设有分公司。

eBay 一成立就开始盈利,从1998 年股票上市开始,eBay 股票一直是纳斯达克前十名之一,众多投资者都看好它的盈利模式。
eBay于1995年9月4日由Pierre Omidyar以Auctionweb的名称创立于加利福尼亚州圣荷西。

Omidyar第一件贩卖的物品是一只坏掉的雷射指示器,以14.83元成交。他惊讶地询问得标者:“您难道不知道这玩意坏了吗?” Omidyar接到了以下的回复信:“我是个专门收集坏掉的雷射指示器玩家。”(更常被传颂的故事则是一则1997年一位公关经理向媒体所杜撰的故事:eBay的创立是为了帮助Omidyar的未婚妻交换一些PEZ Candy的玩具。该故事后来在2002年在亚当斯科汉的书中揭露并经eBay官方确认。)

杰夫史科尔(Jeff Skoll)在1996年被聘雇为该公司首任总裁及全职员工。1997年9月该公司正式更名为ebay。起初该网站属于Omidyar的顾问公司Echo Bay Technology Group。Omidyar曾经尝试注册一个EchoBay.com的网址,却发现该网址已被Echo Bay矿业注册了,所以他将EchoBay.com改成他的第二备案:Ebay.com

编程题

  1. diagonals sort
    将给定的矩阵按照对角线排序
class Main {
    public static void diagSort(int[][] mat) {
        int n = mat.length;
        for (int d = n-1; d >= -(n-1); d--) {
            int start = Math.max(0, -d);
            List<Integer> list = new ArrayList();
            for (int i = start; i < n && i+d < n && i+d >= 0; i++) {
                int j = i+d;
                list.add(mat[i][j]);
            }
            Collections.sort(list);
            for (int i = start; i < n && i+d < n && i+d >= 0; i++) {
                int j = i+d;
                mat[i][j] = list.get(0);
                list.remove(0);
            }
        }
    }
    
    
    public static void main(String[] args) {
        int n = 4;
        int[][] mat = new int[n][n];
        int[] arr = new int[] {8,4,1,4,4,1,4,8,9, 1,3,2,4,5,6,7};
        int cnt = 0;
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                mat[i][j] = arr[cnt++];
            }
        }
        diagSort(mat);
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                System.out.print(mat[i][j] + " ");
            }
            System.out.println();
        }
    }
    
}
  1. 约瑟夫问题I
    输入n和k,n个人循环报数,报到k这个人出列,再从1开始报,直到队列中只剩一个人, 输出出列人的顺序
    e.g. n=5, k=3, 输出就是[3, 1, 5, 2]
    解题思路:如果只需要输出最后一个留在队列的是谁,是可以运用数学进行简化的。但是这道题要求记住出列人的顺序,则必须模拟游戏过程。
class Main {

    public static List<Integer> getResult(int n, int m) {
        LinkedList<Integer> list = new LinkedList<Integer>();
        LinkedList<Integer> res = new LinkedList<Integer>();
        for (int i = 1; i <= n; i++)
            list.add(i);

        int start = 0;
        while (list.size() > 1) {
            int delPos = (start + m - 1) % list.size();
            res.add(list.remove(delPos));
            start = delPos;
        }
        return res;
    }

    public static void main(String[] args) {
        List<Integer> list = getResult(5, 3);
        System.out.println(list);
    }
}
  1. maxArithmeticLength
    给定两个数组A,B。问从B中最多选几个数字(可以不选)能让A成为一个等差数列。返回处理后A长度。注意,处理过后A必须是一个等差数列。如果不是一个等差数列,返回-1。
class Main {
    public static int maxArithmeticLength(int[] a, int[] b) {
        int res = 0;
        Set<Integer> factors = new HashSet();
        Set<Integer> nums = new HashSet();
        for (int num: a)
            nums.add(num);
        for (int num: b)
            nums.add(num);
        
        // 思路是求出等差数列可能的公差,一个个去试验
        int n = a.length;
        int gcd = -1;
        if (n == 1)
            factors.add(a[0]);
        else {
            gcd = a[1] - a[0];
            for (int i = 2; i < n; i++)
                gcd = gcd(gcd, a[i] - a[i-1]);
        }
        for (int i = 1; i <= gcd; i++) {
            if (gcd % i == 0)
                factors.add(i);
        }
        for (int factor: factors) {
            int cur = a[0] + factor;
            int length = 1;
            while (nums.contains(cur)) {
                length++;
                cur += factor;
            }
            // see if can be expanded on the left side
            if (cur >= a[n-1]) {
                cur = a[0] - factor;
                while(nums.contains(cur)) {
                    cur -= factor;
                    length++;
                }
                // only update length here because a now is guaranteed to be an arithmetic array
                res = Math.max(res, length);
            }
        }
        
        return res;
    }
    
    private static int gcd(int num1, int num2) {
        num1 = Math.abs(num1);
        num2 = Math.abs(num2);
        while (num1 != num2) {
            if (num1 > num2)
                num1 = num1 - num2;
            else 
                num2 = num2 - num1;
        }
        return num1;
    }

    public static void main(String[] args) {
        int[] a = {0, 4, 8, 20};
        int[] b = {5, 7, 12, 16, 22};
//        int[] a = {1};
//        int[] b = { -2, -1, 0, 16, 22};
        int res = maxArithmeticLength(a, b);
        System.out.println(res);
    }
}
  1. sum to k
    input: int[] a, int m, int k
    一个array a, 要求在a中找出所有满足条件的continuous subarray,要求
    (1) subarray长度为m
    (2) subarray中有int pair(不能是相同元素)sum to k
    ex: a = [2, 6, 4, 7, 1, 3, 5], m = 4, k = 6,output=2
    explain:
    [2, 6, 4, 7]: 2+4=6
    [6, 4, 7, 1]: 没有
    [4, 7, 1, 3]: 没有
    [7, 1, 3, 5]: 1+5=6
    所以return 2
class Main {
    private static int sumToK(int[] arr, int m, int k) {
        int res = 0;
        int n = arr.length;
        if (n < m)
            return 0;
        HashMap<Integer, Integer> map = new HashMap();
        for (int r = 0; r < m - 1; r++)
            map.put(arr[r], map.getOrDefault(arr[r], 0) + 1);
        for (int r = m - 1; r < n; r++) {
            int l = r - m;
            if (l >= 0) {
                int front = map.get(arr[l]);
                if (front == 1)
                    map.remove(arr[l]);
                else
                    map.put(arr[l], front - 1);
            }
            map.put(arr[r], map.getOrDefault(arr[r], 0) + 1);
            for (int key : map.keySet()) {
                int val = map.get(key);
                if (key * 2 == k && val > 1 || key * 2 != k && map.containsKey(k - key)) {
                    res++;
                    break;  // 即便数组中有多个满足条件的数对,只能算作一次
                }
            }

        }
        return res;
    }

    public static void main(String[] args) {
        int[] a = {2, 6, 4, 7, 1, 3, 5};
        System.out.println(sumToK(a, 4, 6));
    }
}
  1. queryRange
    给一个数组arr,再给一串query(二维数组形式),每个query都是[l,r,x]形式,寻找arr[l:r+1]之间x出现的次数。所有次数加总之后返回。
class Main {
  
    private static int queryRange(int[]arr, int[][] queries) {
        int res = 0;
        // HashMap: key is target, val is range
        // TreeMap: key is excluded end point (arr[:key]), val is how many times this target appears 
        HashMap<Integer, TreeMap<Integer, Integer>> map = new HashMap();
        for (int[] query: queries) {
            int l = query[0];
            int r = query[1];
            int val = query[2];
            TreeMap<Integer, Integer> range = map.getOrDefault(val, new TreeMap());
            // 统计在arr[:l]中,target出现的次数
            int cnt = 0;
            Integer start = range.floorKey(l);
            if (start == null) 
                start = 0;
            else
                cnt = range.get(start);
            for (int i = start; i < l; i++)
                if (arr[i] == val)
                    cnt++;
            range.put(l, cnt);
            res -= cnt;
            // 统计在arr[:r+1]中,target出现的次数
            cnt = 0;
            Integer end = range.floorKey(r+1);
            if (end == null) 
                end = 0;
            else
                cnt = range.get(end);
            for (int i = end; i <= r; i++)
                if (arr[i] == val)
                    cnt++;
            range.put(r+1, cnt);            
            map.put(val, range);
            res += cnt;
        }
        return res;
    }

    public static void main(String[] args) {
        int[] a = {1,1,2,3,2};
        int[][] queries = {{1,2,1}, {2,4,2}, {0,3,1}};
        System.out.println(queryRange(a, queries));
    }
}
  1. deleteToMakeSmall
    Given two strings S and T consisting of digits and lowercase letters, you are allowed to remove only one digit from either string, count how many ways of removal to make S lexicographically smaller than T.
    从给定的字符串s,t中删除一个数字(不是字母),使得s的字典序更小。返回有多少种这样的删除方法。
private static int countWays(String s, String t) {
        int res = 0;
        StringBuilder sb = new StringBuilder();
        for(int i = 0; i < s.length(); i++){
            sb.setLength(0);
            sb.append(s);
            if(Character.isDigit(s.charAt(i))){
                sb.deleteCharAt(i);
                String sub = sb.toString();
                if(sub.compareTo(t) < 0) 
                    res++;
            }
        }

        for(int i = 0; i < t.length(); i++){
            sb.setLength(0);
            sb.append(t);
            if(Character.isDigit(t.charAt(i))){
                sb.deleteCharAt(i);
                String sub = sb.toString();
                if(s.compareTo(sub) < 0)
                    res++;
            }
        }
        return res;
    }
  1. close enough string
    compare 两个string,只有小写字母。 每个stirng 内部可以任意换位置,所以位置不重
    要。每个string 内部两个letter 出现的频率也可以互换,所以这题只需要两个string 每个
    frequency 出现的次数要一样。比如“babzccc” 和 “bbazzcz” 就返回“true”,因为z 和c 可
    以互换频率。 但是“babzcccm” 和 “bbazzczl” 就不一样,因为m 在第一个里出现过,第二个
    里没有出现过。
    If two strings are close enough.
    Given two rules to define two strings are close enough.
  • you can swap neighbor char any times. Ex. “abb” -> “bba”
  • If two strings have the same character, then you can change the character into
    another.
    Ex. If both strings contain “a” and “b”, you can change all "a"s in the first string or
    change all "b"s in the first string. same as the second string
    Ex.
    Input: S1 = “babzccc”, S2 = “abbzczz”
    Output: True
class Solution {
    
    public boolean closeString(String a, String b) {
        int n = a.length();
        if (b.length() != n) return false;
        int[] arr1 = new int[26];
        int[] arr2 = new int[26];
        for (char c: a.toCharArray())
            arr1[c-'a']++;
        for (char c: b.toCharArray())
            arr2[c-'a']++;
        List<Integer> freq1 = new ArrayList();
        List<Integer> freq2 = new ArrayList();
        for (int c = 0; c < 26; c++) {
            if (arr1[c] != 0 && arr2[c] == 0 || arr1[c] == 0 && arr2[c] != 0) 
                return false;
            freq1.add(arr1[c]);
            freq2.add(arr2[c]);
        }
        Collections.sort(freq1);
        Collections.sort(freq2);
        for (int i = 0; i < n; i++)
            if (freq1.get(i) != freq2.get(i))
                return false;
        return true;
    }
    
    public static void main(String[] args) {
       Solution sol = new Solution();
       String a,b;
       a = "babzccc";
       b = "abbzczz";
       System.out.println(sol.closeString(a, b));
       a = "babzcccm";
       b = "abbzczzl";
       System.out.println(sol.closeString(a, b));
    }

}
  1. LC525
class Solution {
    public int findMaxLength(int[] nums) {
        int n = nums.length;
        int res = 0;
        int score = 0;
        Map<Integer, Integer> pos = new HashMap();
        pos.put(0, -1);
        for (int i = 0; i < n; i++) {
            if (nums[i] == 1) score++;
            else score--;
            if (pos.containsKey(score))
                res = Math.max(res, i-pos.get(score));
            else
                pos.put(score, i);
        }
        return res;
    }
}
  1. coolFeature
    Give three array a, b and query.
    Input:
    a = [1, 2, 3]
    b = [3, 4]
    query = [[1, 5], [1, 1, 1], [1, 5]]
    Output:
    [2, 1]
    Explain:
    Just ignore every first element in sub-array in the query.
    So we will get a new query like this query = [[5], [1, 1], [5]]
    Only record the result when meet the single number in new query array.
    And the rule of record is find the sum of the single number.
    The example above is 5 = 1 + 4 and 5 = 2 + 3, there are two result.
    So currently the output is [2]
    When we meet the array length is larger than 1, such as [1, 1]. That means we will replace the
    b[x] = y, x is the first element, y is second element. So in this example, the b will be modify like
    this b = [1, 4]
    And finally, we meet the [5] again. So we will find sum again. This time the result is 5 = 1 + 4.
    So currently the output is [2, 1]
    note: Don’t have to modify the query array, just ignore the first element.
class Solution {
    public List<Integer> coolFeature(int[] a, int[] b, int[][] query) {
        List<Integer> res = new ArrayList();
        Map<Integer, Integer> cnt = new HashMap();
        for (int num: a)
            cnt.put(num, cnt.getOrDefault(num, 0)+1);
        for (int[] q: query) {
            if (q.length == 3)
                b[q[1]] = q[2];
            else {
                int cur = 0;
                for (int i = 0; i < b.length; i++) 
                    cur += cnt.getOrDefault(q[1]-b[i], 0);
                res.add(cur);
            }
        }
        return res;
    }
}