文章目录
二叉树
1.二叉树的前序遍历
描述:给你二叉树的根节点 root ,返回它节点值的 前序 遍历。
代码如下(示例):
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
* @param root TreeNode类
* @return int整型一维数组
*/
public int[] preorderTraversal (TreeNode root) {
// write code here
List<Integer> list = new ArrayList();
preOrder(list,root);
int[] res = new int[list.size()];
for(int i = 0; i < list.size(); i++){
res[i] = list.get(i);
}
return res;
}
private void preOrder(List<Integer> list, TreeNode root){
if(root == null){
return ;
}
list.add(root.val);
preOrder(list,root.left);
preOrder(list,root.right);
}
2.二叉树的中序遍历
描述:给定一个二叉树的根节点root,返回它的中序遍历结果。
代码如下(示例):
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param root TreeNode类
* @return int整型一维数组
*/
public int[] inorderTraversal (TreeNode root) {
// write code here
List<Integer> list = new ArrayList<>();
inOrder(list,root);
int[] res = new int[list.size()];
for(int i = 0; i < list.size(); i++){
res[i] = list.get(i);
}
return res;
}
private void inOrder(List<Integer> list, TreeNode root){
if(root == null){
return;
}
inOrder(list,root.left);
list.add(root.val);
inOrder(list,root.right);
}
3.二叉树的后序遍历
描述:给定一个二叉树的根节点root,返回它的后序遍历结果。
代码如下(示例):
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
* @param root TreeNode类
* @return int整型一维数组
*/
public int[] postorderTraversal (TreeNode root) {
// write code here
List<Integer> list = new ArrayList();
postOrder(list,root);
return list.stream().mapToInt(i->i).toArray();
}
private void postOrder(List<Integer> list, TreeNode root){
if(root == null){
return;
}
postOrder(list,root.left);
postOrder(list,root.right);
list.add(root.val);
}
4.二叉树的最大深度
描述:求给定二叉树的最大深度,深度是指树的根节点到任一叶子节点路径上节点的数量。最大深度是所有叶子节点的深度的最大值。(注:叶子节点是指没有子节点的节点。)
代码如下(示例):
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
* @param root TreeNode类
* @return int整型
*/
public int maxDepth (TreeNode root) {
if(root == null){
return 0;
}
return Math.max(maxDepth(root.left),maxDepth(root.right)) + 1;
}
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
* @param root TreeNode类
* @return int整型
*/
public int maxDepth (TreeNode root) {
// write code here
if(root == null){
return 0;
}
int left = maxDepth(root.left);
int right = maxDepth(root.right);
return left > right ? left + 1 : right + 1;
}
5.二叉搜索树与双向链表
描述:输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。如下图所示:
注意:
1.要求不能创建任何新的结点,只能调整树中结点指针的指向。当转化完成以后,树中节点的左指针需要指向前驱,树中节点的右指针需要指向后继
2.返回链表中的第一个节点的指针
3.函数返回的TreeNode,有左右指针,其实可以看成一个双向链表的数据结构
4.你不用输出双向链表,程序会根据你的返回值自动打印输出
代码如下(示例):
public class Solution {
public TreeNode Convert(TreeNode pRootOfTree) {
List<TreeNode> list = new ArrayList();
inOrder(list,pRootOfTree);
if(list.size() == 0){
return null;
}
for(int i = 1; i < list.size(); i ++){
list.get(i-1).right = list.get(i);
list.get(i).left = list.get(i-1);
}
return list.get(0);
}
private void inOrder(List<TreeNode> list,TreeNode root){
if(root == null){
return;
}
inOrder(list,root.left);
list.add(root);
inOrder(list,root.right);
}
6.合并二叉树
描述:已知两颗二叉树,将它们合并成一颗二叉树。合并规则是:都存在的结点,就将结点值加起来,否则空的位置就由另一个树的结点来代替。
代码如下(示例):
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
* @param t1 TreeNode类
* @param t2 TreeNode类
* @return TreeNode类
*/
public TreeNode mergeTrees (TreeNode t1, TreeNode t2) {
// write code here
if(t1 == null || t2 == null){
return t1 == null ? t2 : t1;
}
t1.val = t1.val + t2.val;
t1.left = mergeTrees(t1.left, t2.left);
t1.right = mergeTrees(t1.right, t2.right);
return t1;
}
7.二叉树的镜像
描述:操作给定的二叉树,将其变换为源二叉树的镜像。
代码如下(示例):
方法一:
public class Solution {
/**
* @param pRoot TreeNode类
* @return TreeNode类
*/
public TreeNode Mirror (TreeNode pRoot) {
// write code here
if(pRoot == null){
return pRoot;
}
TreeNode temp = pRoot.left;
pRoot.left = pRoot.right;
pRoot.right = temp;
Mirror(pRoot.left);
Mirror(pRoot.right);
return pRoot;
}
方法二:
public class Solution {
/**
* @param pRoot TreeNode类
* @return TreeNode类
*/
public TreeNode Mirror (TreeNode pRoot) {
// write code here
if(pRoot == null){
return pRoot;
}
TreeNode left = Mirror(pRoot.left);
TreeNode right = Mirror(pRoot.right);
pRoot.right = left;
pRoot.left = right;
return pRoot;
}
8.判断是不是二叉搜索树
描述:给定一个二叉树根节点,请你判断这棵树是不是二叉搜索树。二叉搜索树满足每个节点的左子树上的所有节点均小于当前节点且右子树上的所有节点均大于当前节点。
代码如下(示例):
方法一:
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
* @param root TreeNode类
* @return bool布尔型
*/
public boolean isValidBST (TreeNode root) {
// write code here
if(root == null){
return false;
}
List<Integer> list = new ArrayList();
inOrder(list,root);
for(int i = 1; i < list.size(); i++){
if(list.get(i-1) > list.get(i)){
return false;
}
}
return true;
}
//中序遍历
private void inOrder(List<Integer> list, TreeNode root){
if(root == null){
return;
}
inOrder(list,root.left);
list.add(root.val);
inOrder(list,root.right);
}
方法二:
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
* @param root TreeNode类
* @return bool布尔型
*/
int pre = Integer.MIN_VALUE;
public boolean isValidBST (TreeNode root) {
// write code here
if(root == null){
return true;
}
if(!isValidBST(root.left)){
return false;
}
if(root.val < pre){
return false;
}
pre = root.val;
return isValidBST(root.right);
}
9.判断是不是二叉搜索树
描述:给定一个二叉树,确定他是否是一个完全二叉树。完全二叉树的定义:若二叉树的深度为 h,除第 h 层外,其它各层的结点数都达到最大个数,第 h 层所有的叶子结点都连续集中在最左边,这就是完全二叉树。
代码如下(示例):
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
* @param root TreeNode类
* @return bool布尔型
*/
public boolean isCompleteTree (TreeNode root) {
// write code here
if(root == null){
return true;
}
boolean flag = true;
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
while(!queue.isEmpty()){
TreeNode node = queue.poll();
if(node == null){
flag = false;
}else {
if(flag == false){
return false;
}
//[null,node.right],队列里面是可以存放null,左子树的为null,右子树不为null。
queue.offer(node.left);
queue.offer(node.right);
}
}
return true;
}
10. 判断是不是平衡二叉树
描述:输入一棵节点数为 n 二叉树,判断该二叉树是否是平衡二叉树。
在这里,我们只需要考虑其平衡性,不需要考虑其是不是排序二叉树
平衡二叉树(Balanced Binary Tree),具有以下性质:它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。
代码如下(示例):
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
* @param pRoot TreeNode类
* @return bool布尔型
*/
public boolean IsBalanced_Solution (TreeNode pRoot) {
// write code here
if(pRoot == null){
return true;
}
return Math.abs(depth(pRoot.left) - depth(pRoot.right)) <= 1
&& IsBalanced_Solution(pRoot.left) && IsBalanced_Solution(pRoot.right);
}
private int depth(TreeNode root){
if(root == null){
return 0;
}
return Math.max(depth(root.left), depth(root.right)) + 1;
}
11. 判断是不是平衡二叉树
描述:给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。
1.对于该题的最近的公共祖先定义:对于有根树T的两个节点p、q,最近公共祖先LCA(T,p,q)表示一个节点x,满足x是p和q的祖先且x的深度尽可能大。在这里,一个节点也可以是它自己的祖先.
2.二叉搜索树是若它的左子树不空,则左子树上所有节点的值均小于它的根节点的值; 若它的右子树不空,则右子树上所有节点的值均大于它的根节点的值
3.所有节点的值都是唯一的。
4.p、q 为不同节点且均存在于给定的二叉搜索树中。
代码如下(示例):
由于这是一棵二叉排序树,因此根节点的值大于左节点,小于右节点。 如果需要找到最近公共祖先,那么这个祖先一定满足条件p<=root.val<=q 并且只存在三种情况如下图,可根据每种情况进行递归处理:
public class Solution {
/**
* 递归
* @param root TreeNode类
* @param p int整型
* @param q int整型
* @return int整型
*/
public int lowestCommonAncestor (TreeNode root, int p, int q) {
// write code here
if(p < root.val && q < root.val){
return lowestCommonAncestor(root.left,p,q);
}
if(p > root.val && q > root.val){
return lowestCommonAncestor(root.right,p,q);
}
return root.val;
}
12. 在二叉树中找到两个节点的最近公共祖先
描述:给定一棵二叉树(保证非空)以及这棵树上的两个节点对应的val值 o1 和 o2,请找到 o1 和 o2 的最近公共祖先节点。
代码如下(示例):
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
* @param root TreeNode类
* @param o1 int整型
* @param o2 int整型
* @return int整型
*/
public int lowestCommonAncestor (TreeNode root, int o1, int o2) {
// write code here
if(root == null){
return -1;
}
if(o1 == root.val || o2 == root.val){
return root.val;
}
int left = lowestCommonAncestor(root.left,o1,o2);
int right = lowestCommonAncestor(root.right, o1,o2);
if(left == -1){
return right;
}else if(right == -1){
return left;
}else{
return root.val;
}
}
13. 重建二叉树
描述:给定节点数为 n 的二叉树的前序遍历和中序遍历结果,请重建出该二叉树并返回它的头结点。
例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建出如下图所示。
提示:
1.vin.length == pre.length
2.pre 和 vin 均无重复元素
3.vin出现的元素均出现在 pre里
4.只需要返回根结点,系统会自动输出整颗树做答案对比
代码如下(示例)
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
* @param preOrder int整型一维数组
* @param vinOrder int整型一维数组
* @return TreeNode类
*/
public TreeNode reConstructBinaryTree (int[] preOrder, int[] vinOrder) {
// write code here
if(preOrder.length == 0 || vinOrder.length == 0){
return null;
}
TreeNode root = new TreeNode(preOrder[0]);
for (int i = 0; i < vinOrder.length; i ++){
if(preOrder[0] == vinOrder[i]){
root.left = reConstructBinaryTree(Arrays.copyOfRange(preOrder,1,i+1),
Arrays.copyOfRange(vinOrder,0,i));
root.right = reConstructBinaryTree(Arrays.copyOfRange(preOrder,i+1,preOrder.length),
Arrays.copyOfRange(vinOrder,i+1,vinOrder.length));
break;
}
}
return root;
}
14. 输出二叉树的右视图
描述:请根据二叉树的前序遍历,中序遍历恢复二叉树,并打印出二叉树的右视图
如输入[1,2,4,5,3],[4,2,5,1,3]时,通过前序遍历的结果[1,2,4,5,3]和中序遍历的结果[4,2,5,1,3]可重建出以下二叉树:
代码如下(示例):
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
* 求二叉树的右视图
* @param preOrder int整型一维数组 先序遍历
* @param inOrder int整型一维数组 中序遍历
* @return int整型一维数组
*/
public int[] solve (int[] preOrder, int[] inOrder) {
// write code here
TreeNode tree = bulidTree(preOrder,inOrder);
List<Integer> list = rightView(tree);
return list.stream().mapToInt(Integer::valueOf).toArray();
}
//重建二叉树
private TreeNode bulidTree(int[] pre, int[] in){
if(pre.length == 0 || in.length == 0){
return null;
}
TreeNode root = new TreeNode(pre[0]);
for(int i = 0; i < pre.length; i++){
if(pre[0] == in[i]){
root.left = bulidTree(Arrays.copyOfRange(pre,1,i+1),
Arrays.copyOfRange(in,0,i));
root.right = bulidTree(Arrays.copyOfRange(pre,i+1,pre.length),
Arrays.copyOfRange(in,i+1,in.length));
}
}
return root;
}
//二叉树的层级遍历
private List<Integer> rightView(TreeNode root){
Queue<TreeNode> queue = new LinkedList<TreeNode>();
queue.add(root);
List<Integer> list = new ArrayList<>();
while(!queue.isEmpty()){
int l = queue.size();
int v = 0;
for(int i = 0; i < l; i++){
TreeNode node = queue.poll();
//层次遍历,最后一个赋值后跳出for循环
v = node.val;
if(node.left != null){
queue.add(node.left);
}
if(node.right != null){
queue.add(node.right);
}
}
//将队列最后一个值添加到list里,即最右侧值
list.add(v);
}
return list;
}
15. 二叉树的层序遍历
描述:给你二叉树的根节点 root ,返回其节点值的 层序遍历 。 (即逐层地,从左到右访问所有节点)。
代码如下(示例):
class Solution {
public List<List<Integer>> levelOrder(TreeNode root) {
List<List<Integer>> result = new ArrayList<>();
Queue<TreeNode> queue = new LinkedList<>();
if(root != null){
queue.add(root);
}
while(!queue.isEmpty()){
List<Integer> temp = new ArrayList<>();
int l = queue.size();
for(int i = 0; i < l; i ++){
TreeNode node = queue.remove();
temp.add(node.val);
if(node.left != null){
queue.add(node.left);
}
if(node.right != null){
queue.add(node.right);
}
}
result.add(temp);
}
return result;
}
}
16. 二叉树的锯齿形层序遍历
描述:给你二叉树的根节点 root ,返回其节点值的 锯齿形层序遍历 。(即先从左往右,再从右往左进行下一层遍历,以此类推,层与层之间交替进行)。
代码如下(示例):
class Solution {
public List<List<Integer>> zigzagLevelOrder(TreeNode root) {
List<List<Integer>> result = new ArrayList<>();
Queue<TreeNode> queue = new LinkedList<>();
if(root != null){
queue.add(root);
}
while(!queue.isEmpty()){
List<Integer> temp = new ArrayList<>();
int len = queue.size();
for (int i =0; i < len; i ++){
TreeNode node = queue.poll();
temp.add(node.val);
if(node.left != null){
queue.add(node.left);
}
if(node.right != null){
queue.add(node.right);
}
}
if(result.size() % 2 == 1){
Collections.reverse(temp);
}
result.add(temp);
}
return result;
}
}
总结
刷题第5天!!!