经过两场大厂面试,面了四道算法题目,发现自己菜到连数据结构最基本的一些算法题目都无法快速写下来,这些基础题目延申出来的题目,简单到上去就基本有思路,但是在面试的时候,依然无法快速地把代码写出来。痛心疾首,有了这篇博文。
基础题目,5~10分钟,完成代码是最基本的能力
(题号是力扣的题号)
144:二叉树的前序遍历
//递归
public List<Integer> preorderTraversal1(TreeNode root) {
List<Integer> list = new LinkedList<Integer>();
if(root == null ) return list;
return preorderTraversalHelp(root,list);
}
public List<Integer> preorderTraversalHelp(TreeNode root,List<Integer> list){
if(root == null ) return list;
list.add(root.val);
preorderTraversalHelp(root.left,list);
preorderTraversalHelp(root.right,list);
return list;
}
//迭代
public List<Integer> preorderTraversal2(TreeNode root) {
LinkedList<Integer> list = new LinkedList<>();
LinkedList<TreeNode> stack= new LinkedList<>();
if(root == null ) return list;
stack.add(root);//入栈顺序为--根,出栈list保存,右左孩子入栈,最终求得前序--根左右
while(!stack.isEmpty()) {
TreeNode node =stack.removeLast();
list.add(node.val);
if(node.right !=null)
stack.add(node.right);
if(node.left !=null)
stack.add(node.left);
}
return list;
}
145:二叉树的后序遍历
递归基本一样,就不再贴代码了
//迭代
public List<Integer> postorderTraversal(TreeNode root) {
LinkedList<Integer> list = new LinkedList<Integer>();
LinkedList<TreeNode> stack= new LinkedList<>();
if(root == null ) return list;
stack.add(root);//入栈顺序为--根,出栈list保存,左右孩子入栈,右左孩子出栈,list逆序保存,最终求得--左右根
while(!stack.isEmpty()) {
TreeNode node =stack.pollLast();
list.addFirst(node.val); //前序遍历代码区别处1
if(node.left !=null) //前序遍历代码区别处2
stack.add(node.left);
if(node.right !=null) //前序遍历代码区别处3
stack.add(node.right);
}
return list;
}
94:二叉树的中序遍历
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> res= new LinkedList<Integer>();
LinkedList<TreeNode> stack= new LinkedList<TreeNode>();
while (true) {
while (root !=null) {
stack.add(root);
root= root.left;
}
if(stack.isEmpty()) return res;
root = stack.removeLast();
res.add(root.val);
root=root.right;
}
}
二叉搜索树,基本都是中序相关的变形题目
中序变形1---------230:二叉搜索树中第K小的元素
这道题目显然就是中序的变形
public int kthSmallest(TreeNode root, int k) {
if(root == null )return -1;
LinkedList<Integer> list = new LinkedList<Integer>();
order(root, list);
return list.get(k-1);
}
public LinkedList<Integer> order(TreeNode root,LinkedList<Integer> list) {
if(root == null ) return list;
order(root.left, list);
list.add(root.val);
order(root.right, list);
return list;
}
//用栈优化
public int kthSmallest(TreeNode root, int k) {
if(root == null )return -1;
LinkedList<TreeNode> stack = new LinkedList<TreeNode>();
while (true) {
while (root !=null) {//while (root !=null)完成根左的入栈
stack.add(root);
root= root.left;
}
root = stack.removeLast();
if(--k!=0) root=root.right;//每次出栈--k,当出栈到第K个元素的时候,return root.val
else {
return root.val;
}
}
}
中序变形2---------108.将有序数组转换为二叉搜索树
public TreeNode sortedArrayToBST(int[] nums) {
if(nums == null) {
return null;
}
return helper(nums, 0, nums.length-1);
}
//找根
public TreeNode helper(int[] nums,int left,int right) {
if(left>right) {
return null;
}
int mid = (left+right)/2;
TreeNode current = new TreeNode(nums[mid]);
current.left = helper(nums, left, mid-1);
current.right = helper(nums, mid+1, right);
return current;
}
中序变形3--------109.有序链表转换二叉搜索树
快慢指针找中点
public TreeNode sortedListToBST(ListNode head) {
if(head == null)return null;
return help(head, null);
}
public TreeNode help(ListNode head,ListNode tail){
if(head == tail || head ==null) {
return null;
}
ListNode fast = head;
ListNode slow = head;
while(fast.next!= tail&& fast.next.next !=tail) {
fast = fast.next.next;
slow = slow.next;
}
TreeNode treeNode = new TreeNode(slow.val);
treeNode.left = help(head, slow);
treeNode.right = help(slow.next, tail);
return treeNode;
}
中序变形4--------98:验证二叉搜索树
这个题目用中序递归,效率很低,但是自建栈,可以优化
//中序递归
public boolean isValidBST(TreeNode root) {
if(root == null) return true;
LinkedList<Integer> list = new LinkedList<Integer>();
inOrder(root, list);
for(int i =0;i<list.size()-1;i++) {
if(list.get(i)>=list.get(i+1))
return false;
}
return true;
}
public List<Integer> inOrder(TreeNode root,LinkedList<Integer> list){
if(root == null) return list;
inOrder(root.left, list);
list.add(root.val);
inOrder(root.right, list);
return list;
}
//中序迭代
public boolean isValidBST(TreeNode root) {
if(root == null) return true;
LinkedList<Integer> list = new LinkedList<Integer>();
LinkedList<TreeNode> stack = new LinkedList<TreeNode>();
while(true) {
int s =0;
while(root!=null) {
stack.add(root);
root = root.left;
}
if(!stack.isEmpty()) {
break;
}
root = stack.removeLast();
if(s ==0) {
list.add(root.val);
s++;
}else if(root.val<= list.getLast()) {
return false;
}else{
list.add(root.val);
root=root.right;
}
}
return true;
}
//普通递归
public boolean isValidBST(TreeNode root) {
return isValidBST(root, Long.MIN_VALUE, Long.MAX_VALUE);
}
public boolean isValidBST(TreeNode root, long minVal, long maxVal) {
if(root == null)
return true;
if(root.val >= maxVal || root.val <= minVal)
return false;
return isValidBST(root.left, minVal, root.val)&&isValidBST(root.right, root.val, maxVal);
}
107.二叉树的层次遍历II(逆序输出)
这个题目跟层次遍历没什么区别,就是注意下是逆序输出就行
public List<List<Integer>> levelOrderBottom(TreeNode root) {
List<List<Integer>> list=new LinkedList<List<Integer>>();
if(root == null)
return list;
LinkedList<TreeNode> queue = new LinkedList<>();
queue.add(root);
while(!queue.isEmpty()) {
int size = queue.size();//记录当前层的结点个数,并保存再curList
LinkedList<Integer> curList = new LinkedList<Integer>();
while(size>0) {
TreeNode curNode = queue.pollFirst();
if(curNode.left!=null) {
queue.add(curNode.left);
}
if(curNode.right!=null) {
queue.add(curNode.right);
}
curList.add(curNode.val);
size--;
}
list.add(0,curList);//不逆序的话就是list.add(curList);
}
return list;
}
110:平衡二叉树
//判断平衡=>递归求解二叉树的高度
public boolean isBalanced(TreeNode root) {
return getHeight(root)!=Integer.MAX_VALUE;
}
public int getHeight(TreeNode root) {
if(root == null) return 0;
int left = getHeight(root.left);
if(left == Integer.MAX_VALUE)
return Integer.MAX_VALUE;
int right = getHeight(root.right);
if(right == Integer.MAX_VALUE)
return Integer.MAX_VALUE;
if(Math.abs(left-right)>1) {
return Integer.MAX_VALUE;
}
return Math.max(left,right)+1;
}