面试最常见算法1—树—基础篇

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了面试最常见算法1—树—基础篇相关的知识,希望对你有一定的参考价值。

前言

关于树的算法基本解法就三类:递归,队列,栈

刷题网站推荐:

1.二叉树遍历(前序)

public List<Integer> preorderTraversal(TreeNode root) 
// 1.递归实现
/**
List<Integer> res = new ArrayList<>();
if (null == root)
return res;

res.add(root.val);
res.addAll(preorderTraversal(root.left));
res.addAll(preorderTraversal(root.right));
return res;
*/
// 2.使用栈实现
List<Integer> res = new ArrayList<>();
if (null == root)
return res;

TreeNode head = root;
Stack<TreeNode> stack = new Stack<>();
while (null != head || !stack.isEmpty())
if (null != head)
res.add(head.val);
stack.push(head);
head = head.left;
else
head = stack.pop().right;


return res;

前序遍历 ​https://leetcode.cn/problems/binary-tree-preorder-traversal/submissions/

中序遍历 ​https://leetcode.cn/problems/binary-tree-inorder-traversal/

后序遍历 ​https://leetcode.cn/problems/binary-tree-postorder-traversal/

2.二叉树层次遍历

public List<List<Integer>> levelOrder(TreeNode root) 
List<List<Integer>> res = new ArrayList<>();
if (root == null)
return res;

Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
while (!queue.isEmpty())
int len = queue.size();
List<Integer> item = new ArrayList<>();
while(len > 0)
//从队列中取出数据
TreeNode node = queue.poll();
item.add(node.val);
//边读边取
if(node.left != null)
queue.offer(node.left);

if(node.right != null)
queue.offer(node.right);

len--;

res.add(item);

return res;

https://leetcode.cn/problems/binary-tree-level-order-traversal/submissions/

其余的Z形打印或者锯齿打印都是它的变种

3.二叉树深度

public int maxDepth(TreeNode root) 
if (root == null)
return 0;
else
int left = maxDepth(root.left);
int right = maxDepth(root.right);
return left > right ? left + 1 : right + 1;

https://leetcode.cn/problems/er-cha-shu-de-shen-du-lcof/

4.二叉树宽度

使用队列,层次遍历二叉树。在上一层遍历完成后,下一层的所有节点已经放到队列中,此时队列中的元素个数就是下一层的宽度。以此类推,依次遍历下一层即可求出二叉树的最大宽度。

public int widthOfBinaryTree(TreeNode root) 
if (root == null)
return 0;
Queue queue = new ArrayDeque();
int maxwitdth = 1; // 最大宽度
queue.add(root); // 入队
while (true)
int len = queue.size(); // 当前层的节点个数
if (len == 0)
break;
while (len > 0) // 如果当前层,还有节点
TreeNode t = (TreeNode) queue.poll();
len--;
if (t.left != null)
queue.add(t.left); // 下一层节点入队
if (t.right != null)
queue.add(t.right);// 下一层节点入队

maxwitdth = maxwitdth > queue.size() ? maxwitdth : queue.size();

return maxwitdth;

5.判断一棵树是否为另一棵树的子树

public boolean isSubtree(TreeNode root, TreeNode subRoot) 
if (root == null || subRoot == null)
return false;

return isSameTree(root, subRoot) || isSubtree(root.left, subRoot) || isSubtree(root.right, subRoot);

public boolean isSameTree(TreeNode s, TreeNode t)
if (t == null && s == null)
return true;

if (s == null || t == null)
return false;

return s.val == t.val && isSameTree(s.left, t.left) && isSameTree(s.right, t.right);

https://leetcode.cn/problems/subtree-of-another-tree/submissions/

6.二叉树的右视图

public List<Integer> rightSideView(TreeNode root) 
int cnt=0,tmp=0;
TreeNode node;
List<Integer> res = new LinkedList<>();
if(root==null)
return res;

Queue<TreeNode> queue=new LinkedList<>();
queue.add(root);
while(!queue.isEmpty())
cnt=queue.size();
while(cnt>0)
node=queue.poll();
if(node.left!=null)queue.offer(node.left);
if(node.right!=null)queue.offer(node.right);
cnt--;
tmp=node.val;

res.add(tmp);

return res;

https://leetcode.cn/problems/binary-tree-right-side-view/submissions/

7.给定n求二叉搜索树的个数

class Solution 
public int numTrees(int n)
//初始化 dp 数组
int[] dp = new int[n + 1];
//初始化0个节点和1个节点的情况
dp[0] = 1;
dp[1] = 1;
for (int i = 2; i <= n; i++)
for (int j = 1; j <= i; j++)
//对于第i个节点,需要考虑1作为根节点直到i作为根节点的情况,所以需要累加
//一共i个节点,对于根节点j时,左子树的节点个数为j-1,右子树的节点个数为i-j
dp[i] += dp[j - 1] * dp[i - j];


return dp[n];

https://leetcode.cn/problems/unique-binary-search-trees/

8.二叉树的镜像

public TreeNode Mirror(TreeNode root) 
if (root == null)
return root;
swap(root);
Mirror(root.left);
Mirror(root.right);
return root;


private void swap(TreeNode root)
TreeNode t = root.left;
root.left = root.right;
root.right = t;

https://www.nowcoder.com/practice/a9d0ecbacef9410ca97463e4a5c83be7?tpId=13&tqId=11171&tab=answerKey&from=cyc_github

9.对称的二叉树

boolean isSymmetrical(TreeNode pRoot) 
if (pRoot == null)
return true;
return isSymmetrical(pRoot.left, pRoot.right);


boolean isSymmetrical(TreeNode t1, TreeNode t2)
if (t1 == null && t2 == null)
return true;
if (t1 == null || t2 == null)
return false;
if (t1.val != t2.val)
return false;
return isSymmetrical(t1.left, t2.right) && isSymmetrical(t1.right, t2.left);

https://www.nowcoder.com/practice/ff05d44dfdb04e1d83bdbdab320efbcb?tpId=13&tqId=11211&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github

10.二叉搜索树的第K个节点

由于是二叉搜索树,采用中序遍历得到的第k个节点即第k小的值,判断输出是否是第k个就可以返回值了,使用栈来辅助遍历

public int KthNode (TreeNode proot, int k) 
if (proot == null) return -1;
//中序遍历,第k个节点
Stack<TreeNode> stack = new Stack<TreeNode>();
stack.push(proot);
TreeNode node = proot;
int i = 0;
while (!stack.isEmpty())
//遍历node下的所有左节点
while (node.left != null)
stack.push(node.left);
node = node.left;

i++;
if (i == k) return stack.pop().val;
TreeNode tmp = stack.pop();
//加入右子树
if (tmp.right != null)
stack.push(tmp.right);
node = tmp.right;


return -1;

https://www.nowcoder.com/practice/57aa0bab91884a10b5136ca2c087f8ff?tpId=13&tqId=2305268&ru=%2Fpractice%2F57aa0bab91884a10b5136ca2c087f8ff&qru=%2Fta%2Fcoding-interviews%2Fquestion-ranking&sourceUrl=

11.判断是不是平衡二叉树

private boolean isBalanced = true;

public boolean IsBalanced_Solution(TreeNode root)
getHeight(root);
return isBalanced;


public int getHeight(TreeNode root)
if(root == null)
return 0;

int left = getHeight(root.left);
int right = getHeight(root.right);

if(Math.abs(left - right) > 1)
isBalanced = false;


return 1 + Math.max(left, right);

https://www.nowcoder.com/practice/8b3b95850edb4115918ecebdf1b4d222?tpId=13&tqId=11192&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github

以上是关于面试最常见算法1—树—基础篇的主要内容,如果未能解决你的问题,请参考以下文章

leetcode 最常见的前端基础算法面试题汇总

leetcode 最常见的前端基础算法面试题汇总

leetcode 最常见的前端基础算法面试题汇总

数据结构二叉树相关面试题 Java版 LeetCode题 ------- 二叉树

leetcode 114二叉树转换成链表

常见面试中的算法解法