名企面试零距离

来源:互联网 发布:网络推广人员工作要求 编辑:程序博客网 时间:2024/04/19 17:08

又到春招季了,小编相信,许多即将走出校园的应届生,都梦寐以求地想挤进企鹅、杭研、脸书等等大厂。尤其是贵邮的学子,更是深深的BAT和FLAG情结。因为,这些大厂不仅能提供一流的薪水和丰厚的package,还能提供理想的工作环境和神一样的队友。

那么问题来了,IT名企对应聘者有什么样的要求呢?以JavaWeb工程师为例,小编相信,对于Java基础、三大框架、数据库、Ajax、Linux等等常用技能,大家已经掌握的比较熟练了,但很多人依然有这么一个短板——数据结构与算法;甚至一些领域的专家,一不小心跪在某道面试题上面的事情,也常有发生。

这不,Homebrew的作者Max Howell就收到了谷歌的拒信:

90% of our engineers use the software you wrote (Homebrew), but you can’t invert a binary tree on a whiteboard so fuck off.

原贴链接:

https://twitter.com/mxcl/status/608682016205344768

程序测试地址:

https://leetcode.com/problems/invert-binary-tree/

这件事情在国内外各大社区也是炸开了锅,有兴趣的同学可以去twitter、知乎、v2ex等论坛讨论。

不会反转二叉树,十年经验也枉然!

废话不多说,我们直接来做题。题目非常简短,就一句话:反转二叉树,或者叫做二叉树的镜像。


变成


二叉树节点的定义如下:

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

其实就是交换所有的左右子树啊!先、中、后、层这四个无节操的模板,均可以毫无压力地解决这道题。

一、使用后序遍历模板,考虑根节点4:

1、假设左子树2和右子树7已经反转完毕,即:递归处理2和7


2、交换2和7,算法完成


代码:

public class Solution {public TreeNode invertTree(TreeNode root) {postOrder(root);return root;}public void postOrder(TreeNode p) {if (p != null) {postOrder(p.left);postOrder(p.right);TreeNode temp = p.left;p.left = p.right;p.right = temp;}}}

时间复杂度为O(N),空间复杂度为O(logN)。

二、使用先序遍历模板,考虑根节点4:

1、交换左孩子2和右孩子7


2、递归处理2和7,算法完成


代码:

public class Solution {public TreeNode invertTree(TreeNode root) {preOrder(root);return root;}public void preOrder(TreeNode p) {if (p != null) {TreeNode temp = p.left;p.left = p.right;p.right = temp;preOrder(p.left);preOrder(p.right);}}}

时间复杂度为O(N),空间复杂度为O(logN)。

三、使用序遍历模板,中序遍历需要注意:递归左子树、交换左右孩子之后,原来的右孩子已经变成了现在的左孩子,所以第三步仍然是递归左子树,同样,考虑根节点4:

1、递归处理左孩子2


2、交换左孩子2和右孩子7


3、递归处理左孩子7,算法完成


代码:

public class Solution {public TreeNode invertTree(TreeNode root) {inOrder(root);return root;}public void inOrder(TreeNode p) {if (p != null) {inOrder(p.left);TreeNode temp = p.left;p.left = p.right;p.right = temp;inOrder(p.left);}}}

时间复杂度为O(N),空间复杂度为O(logN)。

四、使用序遍历模板,层序遍历需要借助于队列,在循环体当中,使用先交换、再入队,或者先入队、再交换两种策略均可,代码如下:

public class Solution {public TreeNode invertTree(TreeNode root) {if (root == null) {return null;} else {Queue<TreeNode> queue = new LinkedList<TreeNode>();queue.offer(root);while (!queue.isEmpty()) {TreeNode p = queue.poll();if (p.left != null) {queue.offer(p.left);}if (p.right != null) {queue.offer(p.right);}TreeNode temp = p.left;p.left = p.right;p.right = temp;}return root;}}}

其实吧,写完以上四种算法就经很有逼格了,包括LeetCode官方也只给出了先序型的递归算法和层序型的非递归算法。其实下面一种算法是最牛X的,能秒杀谷歌Offer!

五、使用先序遍历非递归模板,借助于栈实现。最关键的步骤就是addLeft方法,将右孩子的最左边路径所经过的节点依次压栈,这样,弹栈顺序和先序遍历就是一模一样的,代码如下:

public class Solution {     private void addLeft(TreeNode p,Stack<TreeNode> stack){   while(p!=null){   stack.push(p);   p=p.left;   }     }     public TreeNode invertTree(TreeNode root) {   TreeNode p=null;       Stack<TreeNode> stack=new Stack<TreeNode>();       addLeft(root, stack);       while(!stack.isEmpty()){       p=stack.pop();       addLeft(p.right, stack);       TreeNode t=p.left;   p.left=p.right;   p.right=t;       }       return root;   }}

想不AC都难啊!


另外,数据结构与算法类面试题远远不止这一道,大家想要举一反三、融会贯通地应对名企面试,还需多翻一翻《编程之美》、《剑指offer》、《编程之法》等指导书,多刷一刷LeetCode、PAT等OJ,多搜一搜BAT和FLAG等公司的面经;熟练了之后,你会发现,考来考去,无非是数组、链表、字符串、栈和队列、二分查找、二叉树、矩阵、排序、并查集、堆、哈希、位运算、图论、贪心、分治、动态规划、NP完全......

当然,熟练掌握以上知识点,并不是一朝一夕的事情,总要有个过程,甚至有可能很艰辛,但为了进名企、为了遇到神队友、为了将来的高薪,何不拿出高三时候的勤奋与刻苦,趁年轻的时候拼一拼?

最后,小编是一个上升星座为白羊的男生,非常喜欢我司的打开IDE,更新GIT、写代码、编译运行、测试、提交、上线、发工资、拿年终奖这种简单粗暴的工作方式,什么Maven下载速度为10K/S、IDE注册码马上过期、VPN被禁、分页插件不兼容、中文乱码之类的问题,统统见鬼!所以,面试是个双向选择过程,应聘者需要通过面试官的提问判断职位是否适合自己,而各个大厂的面试题侧重点又稍有不同,大家要多看面经,选择匹配自己的公司和职位。比如:

1、阿里巴巴偏重业务和运营,所以算法题(除了某些特殊岗位之外)不会太难,但涉及面就非常广,设计模式、Linux、操作系统、DB、Spring原理等以及项目经验都会问到。像什么“Servlet生命周期、ClassLoader加载顺序、Spring和Struts的优缺点、TCP三次握手”之类的概念型面试题,感觉是在浪费生命,完全无爱啊!

2、腾讯的算法题难度中等,最典型的是2014年校招笔试,题量适中,质量也非常高,难怪许多人(包括小编在内)说互联网格局是TAB

3、百度、谷歌、FB的少部分题目还挺虐心,已经远远超出了《剑指offer》的总体难度,不过仔细分析的话,并未超纲。

4、还有喜欢聊dota、聊动漫、聊网红、聊马哲的面试官,比如我司。

参考资料:

前中后层模板:http://www.jikexueyuan.com/course/2669_2.html

反转二叉树:http://www.jikexueyuan.com/course/2714_4.html

1 0
原创粉丝点击