名企面试零距离

又到春招季了,小编相信,许多即将走出校园的应届生,都梦寐以求地想挤进企鹅、杭研、脸书等等大厂。尤其是贵邮的学子,更是深深的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
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值