Wish 二面

/*
# Suppose we have a series of people relationships that looks something like this:
#        [    ['Bart',  'brother',   'Lisa'    ],
#            ['Bart',  'son',      'Homer'    ],
#            ['Marge', 'wife',     'Homer'    ],
#            ['Lisa',  'daughter', 'Homer'   ]    ]
#    
#        i.e. inner lists have len == 3 and are in form name1, relationship, name2
#
# Given a series of relationships as a list of lists, and given two names, return
# all known "sequences" of relationships from name1 to name2
# 
# e.g. with the lists above as input, with input names 'Bart' and 'Homer', you should return:
#    ['Bart son Homer', 'Bart brother Lisa daughter Homer']
#

*/

给你一堆string 都是relationship 然后给你两个名字 找出两个人之间的所有关系 通过别人也好
面试官全程不怎么说话。。。。估计挂了。。

follow up1:
有cycle怎么办?建一个visited set 走过的存一下 走完了remove一下

follow up2:
如果一个人和另一个人可以有多个relationship

follow up3:
怎么优化? cached

今天recruiter告诉我 move forward with onsite

这题前两天在讨论啊,你看了没

没看啊 我题目写出来了。

再看看,题目其实不简单的

public class Solution {
    public static void main(String args[] ) throws Exception {
        List<List<String>> rel = new ArrayList<>();
        rel.add(Arrays.asList("Bart",  "brother",   "Lisa"));
        rel.add(Arrays.asList("Bart",  "friend",   "Lisa"));
        rel.add(Arrays.asList("Bart",  "son",   "Homer"));
        rel.add(Arrays.asList("Marge",  "wife",   "Homer"));
        rel.add(Arrays.asList("Lisa",  "daughter",   "Homer"));
        getRel(rel, "Bart", "Homer").forEach(x -> System.out.println(x));
    }

    private static List<String> getRel(List<List<String>> relations, String first, String second) {
        List<String> res = new ArrayList<>();
        if (relations == null || relations.size() == 0 || first == null ||first.length() == 0|| second == null || second.length() == 0) return res;
        if (first.equals(second)) return Arrays.asList(first+" self "+second);
        Map<String, List<String[]>> graph = new HashMap<>();
        for (List<String> rel: relations) {
            if (rel.get(0).equals(rel.get(2))) continue;
            graph.computeIfAbsent(rel.get(0), x -> new ArrayList<>()).add(new String[] {rel.get(2), rel.get(1)});
        }
        if (!graph.containsKey(first)) return res;
        dfs(first, second, graph, res, new StringBuilder(), new HashSet<>(), new HashMap<>());
        return res;
    }

    private static void dfs(String first, String second, Map<String, List<String[]>> graph, List<String> res, StringBuilder sb, Set<String> visited, Map<String, List<String>> cached) {
        if (!visited.add(first)) return; //if this person has been visited, means there is a loop
        if (cached.containsKey(first)) {
            int n = sb.length();
            for(String no: cached.get(first)) {
                res.add(sb.append(" "+no).toString());
                sb.setLength(n);
            }
            return;
        }
        if (first.equals(second)) {
            visited.remove(first);
            res.add(sb.append(first).toString());
            String[] arr = sb.toString().split(" ");
            for (int i = 0; i < arr.length;i+=2) {
                int ind = sb.indexOf(arr[i]);
                cached.computeIfAbsent(arr[i], x-> new ArrayList<>()).add(sb.toString().substring(ind, sb.length()));
            }
            return;
        }
        List<String[]> next = graph.get(first);
        if (next == null) return;
        sb.append(first);
        int len = sb.length();
        for (String[] n: next) {
            sb.append(" "+n[1]+" ");
            dfs(n[0], second, graph, res, sb, visited, cached);
            sb.setLength(len);
        }
        visited.remove(first);
    }
}

这题用DFS的话有个complication,如果你到了已经visited的node,因为我们并不是找最短路径,我们还需要加上这个path,举个例子

起点是A,终点是G
DFS 先找到一个可行路径
A -> B -> C -> D -> G

然后我们通过 A -> E -> F -> H -> D, 这个时候我们已经visited过D了,那么,A -> E -> F -> H -> D -> G 是否算到结果里呢?

remove一下就行了啊

remove什么

visited.remove(first);
看我最后一行代码

你这样感觉还是有问题,等于visited 过的,就忘了(全局)

不啊。。只remove当前这一层啊

就是要忘了,你要找出所有relationship 从a 到 b啊

e.g. with the lists above as input, with input names ‘Bart’ and ‘Homer’, you should return:

[‘Bart son Homer’, ‘Bart brother Lisa daughter Homer’]

类似于所有路劲

你这个visited set不是global的,你再想想我说的例子

起点是A,终点是G
DFS 先找到一个可行路径
A -> B -> C -> D -> G

然后我们通过 A -> E -> F -> H -> D, 这个时候我们已经visited过D了,那么,A -> E -> F -> H -> D -> G 是否算到结果里呢?

A->B->C->D->G

第一次走完D的时候 我已经把D从visited里面去掉了啊

A -> B -> C ->D -> G VISITED: A B C D G
A -> B -> C ->D VISITED: A B C D
A -> B -> C VISITED: A B C
A -> B VISITED: A B
A VISITED: A
A -> E Visited: A E
A -> E -> F visited: A E F
A -> E -> F -> H visited: A E F H
A -> E -> F -> H -> D visited: A E F H D
A -> E -> F -> H -> D -> G visited: A E F H D G

再改复杂一点

A -> B -> C ->D -> J -> G
A -> B -> C ->D -> K -> G
A -> E -> F -> H -> D -> J -> G
A -> E -> F -> H -> D -> K -> G
D 到 G 可以通过 J 和 K
起点是A,终点是G

上次到D的时候,你其实知道D到 G的路径了

所以有cache 我用到cache了

也报一个二面。内推的。
45分钟3题
第一题真的记不清了
第二题 LC 一七二
第三题 LC 二六五
过了准备约onsite了。