前一段时间找人内推了微软苏州,职位是 Microsoft search team的 software engineer。 面试之前听说微软会狂怼算法, 然而平常算法刷的不多,所以花了几天时间临时抱佛脚突击刷了一些常见的算法(内心OS: 巨硬应该不会按照常规套路出招)。
面试用的是 M 家自带的 Microsoft team, 体验倒没有网上说的那么不堪, 感觉良好。面试官好像不是这个team 的, 但是说话很亲和, 也比较好沟通。上来先自我介绍了下, 然后就是问项目, 时间差不多了, 开始了写题时间。 开了一个共享的一个online编辑器 http://collabedit.com。emmm, 其实就是个白板。
第一题: 给一棵二叉树, 和一个 target(二叉树某节点), 找出所有与target距离为 k 的节点的值的集合。
这道题,我一开始居然卡住了,因为找距离为 k 的点的话需要往很多方向去找,还要处理 k 值过大的问题(不存在与target 距离 为 k 的点),而二叉树的节点只有指向左节点和右节点的两个指针, 如果还有个 parent 指针的话应该可以解决问题。和面试官确认了下确实节点只有两个指针(太紧张了没想到自己遍历的时候保存每个节点的父指针)。后来面试官提示了下,突然恍然大悟, 给出了自己的一个思路:
/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode(int x) { val = x; } * } */ classSolution{ HashMap<TreeNode, TreeNode> map = new HashMap<>(); Set<TreeNode> isVisited = new HashSet<>();
public List<Integer> distanceK(TreeNode root, TreeNode target, int K){ List<Integer> results = new ArrayList<>(); if (root == null || target == null) { return results; } int res = 0; traversal(root); Queue<TreeNode> queue = new LinkedList<>(); queue.offer(target);
while (!queue.isEmpty()) { int qSize = queue.size(); if (res == K) { for (int i = 0; i < qSize; i++) { int val = queue.poll().val; results.add(val); } return results; }
for (int i = 0; i < qSize; i++) { TreeNode cur = queue.poll(); isVisited.add(cur); if (cur.left != null && !isVisited.contains(cur.left)) { queue.add(cur.left); } if (cur.right != null && !isVisited.contains(cur.right)) { queue.add(cur.right); } if (map.get(cur) != null && !isVisited.contains(map.get(cur))) { queue.add(map.get(cur)); } } res++; } return results; }
privatevoidtraversal(TreeNode node){ if (node == null) { return; }
if (node.left != null) { map.put(node.left, node); }
if (node.right != null) { map.put(node.right, node); }