美文网首页
二叉树实战 22 题,速度收藏吧!

二叉树实战 22 题,速度收藏吧!

作者: 程序人生a | 来源:发表于2019-06-27 15:11 被阅读0次

    先上二叉树的数据结构:

    classTreeNode{

    intval;

    //左孩子

    TreeNode left;

    //右孩子

    TreeNode right;

    }

    二叉树的题目普遍可以用递归和迭代的方式来解

    1. 求二叉树的最大深度

    intmaxDeath(TreeNode node){

    if(node==null){

    return0;

    }

    intleft = maxDeath(node.left);

    intright = maxDeath(node.right);

    returnMath.max(left,right) +1;

    }

    2. 求二叉树的最小深度

    intgetMinDepth(TreeNode root){

    if(root ==null){

    return0;

    }

    returngetMin(root);

    }

    intgetMin(TreeNode root){

    if(root ==null){

    returnInteger.MAX_VALUE;

    }

    if(root.left ==null&&root.right ==null){

    return1;

    }

    returnMath.min(getMin(root.left),getMin(root.right)) +1;

    }

    3. 求二叉树中节点的个数

    intnumOfTreeNode(TreeNode root){

    if(root ==null){

    return0;

    }

    intleft = numOfTreeNode(root.left);

    intright = numOfTreeNode(root.right);

    returnleft + right +1;

    }

    4. 求二叉树中叶子节点的个数

    intnumsOfNoChildNode(TreeNode root){

    if(root ==null){

    return0;

    }

    if(root.left==null&&root.right==null){

    return1;

    }

    returnnumsOfNodeTreeNode(root.left)+numsOfNodeTreeNode(root.right);

    }

    5. 求二叉树中第k层节点的个数

    intnumsOfkLevelTreeNode(TreeNode root,intk){

    if(root ==null||k<1){

    return0;

    }

    if(k==1){

    return1;

    }

    intnumsLeft = numsOfkLevelTreeNode(root.left,k-1);

    intnumsRight = numsOfkLevelTreeNode(root.right,k-1);

    returnnumsLeft + numsRight;

    }

    6. 判断二叉树是否是平衡二叉树

    booleanisBalanced(TreeNode node){

    returnmaxDeath2(node)!=-1;

    }

    intmaxDeath2(TreeNode node){

    if(node ==null){

    return0;

    }

    intleft = maxDeath2(node.left);

    intright = maxDeath2(node.right);

    if(left==-1||right==-1||Math.abs(left-right)>1){

    return-1;

    }

    returnMath.max(left, right) +1;

    }

    7.判断二叉树是否是完全二叉树

    什么是完全二叉树呢?参见

    booleanisCompleteTreeNode(TreeNode root){

    if(root ==null){

    returnfalse;

    }

    Queue queue =newLinkedList();

    queue.add(root);

    boolean result =true;

    boolean hasNoChild =false;

    while(!queue.isEmpty()){

    TreeNode current = queue.remove();

    if(hasNoChild){

    if(current.left!=null||current.right!=null){

    result =false;

    break;

    }

    }else{

    if(current.left!=null&¤t.right!=null){

    queue.add(current.left);

    queue.add(current.right);

    }elseif(current.left!=null&¤t.right==null){

    queue.add(current.left);

    hasNoChild =true;

    }elseif(current.left==null&¤t.right!=null){

    result =false;

    break;

    }else{

    hasNoChild =true;

    }

    }

    }

    returnresult;

    }

    8. 两个二叉树是否完全相同

    booleanisSameTreeNode(TreeNode t1,TreeNode t2){

    if(t1==null&&t2==null){

    returntrue;

    }

    elseif(t1==null||t2==null){

    returnfalse;

    }

    if(t1.val != t2.val){

    returnfalse;

    }

    booleanleft = isSameTreeNode(t1.left,t2.left);

    booleanright = isSameTreeNode(t1.right,t2.right);

    returnleft&&right;

    }

    9. 两个二叉树是否互为镜像

    booleanisMirror(TreeNode t1,TreeNode t2){

    if(t1==null&&t2==null){

    returntrue;

    }

    if(t1==null||t2==null){

    returnfalse;

    }

    if(t1.val != t2.val){

    returnfalse;

    }

    returnisMirror(t1.left,t2.right)&&isMirror(t1.right,t2.left);

    }

    10. 翻转二叉树or镜像二叉树

    TreeNodemirrorTreeNode(TreeNode root){

    if(root ==null){

    returnnull;

    }

    TreeNode left = mirrorTreeNode(root.left);

    TreeNode right = mirrorTreeNode(root.right);

    root.left = right;

    root.right = left;

    returnroot;

    }

    11. 求两个二叉树的最低公共祖先节点

    TreeNodegetLastCommonParent(TreeNode root,TreeNode t1,TreeNode t2){

    if(findNode(root.left,t1)){

    if(findNode(root.right,t2)){

    returnroot;

    }else{

    returngetLastCommonParent(root.left,t1,t2);

    }

    }else{

    if(findNode(root.left,t2)){

    returnroot;

    }else{

    returngetLastCommonParent(root.right,t1,t2)

    }

    }

    }

    // 查找节点node是否在当前 二叉树中

    booleanfindNode(TreeNode root,TreeNode node){

    if(root ==null|| node ==null){

    returnfalse;

    }

    if(root == node){

    returntrue;

    }

    booleanfound = findNode(root.left,node);

    if(!found){

    found = findNode(root.right,node);

    }

    returnfound;

    }

    12. 二叉树的前序遍历

    迭代解法

    ArrayList preOrder(TreeNode root){

    Stackstack=newStack();

    ArrayListlist=newArrayList();

    if(root == null){

    returnlist;

    }

    stack.push(root);

    while(!stack.empty()){

    TreeNode node =stack.pop();

    list.add(node.val);

    if(node.right!=null){

    stack.push(node.right);

    }

    if(node.left != null){

    stack.push(node.left);

    }

    }

    returnlist;

    }

    递归解法

    ArrayListpreOrderReverse(TreeNode root){

    ArrayList result =newArrayList();

    preOrder2(root,result);

    returnresult;

    }

    voidpreOrder2(TreeNode root,ArrayList<Integer> result){

    if(root ==null){

    return;

    }

    result.add(root.val);

    preOrder2(root.left,result);

    preOrder2(root.right,result);

    }

    13. 二叉树的中序遍历

    ArrayList inOrder(TreeNode root){

    ArrayListlist=newArrayList<();

    Stackstack=newStack();

    TreeNode current = root;

    while(current != null|| !stack.empty()){

    while(current != null){

    stack.add(current);

    current = current.left;

    }

    current =stack.peek();

    stack.pop();

    list.add(current.val);

    current = current.right;

    }

    returnlist;

    }

    14.二叉树的后序遍历

    ArrayList postOrder(TreeNode root){

    ArrayListlist=newArrayList();

    if(root ==null){

    returnlist;

    }

    list.addAll(postOrder(root.left));

    list.addAll(postOrder(root.right));

    list.add(root.val);

    returnlist;

    }

    15.前序遍历和后序遍历构造二叉树

    TreeNodebuildTreeNode(int[] preorder,int[] inorder){

    if(preorder.length!=inorder.length){

    returnnull;

    }

    returnmyBuildTree(inorder,0,inorder.length-1,preorder,0,preorder.length-1);

    }

    TreeNodemyBuildTree(int[] inorder,intinstart,intinend,int[] preorder,intprestart,intpreend){

    if(instart>inend){

    returnnull;

    }

    TreeNode root =newTreeNode(preorder[prestart]);

    intposition = findPosition(inorder,instart,inend,preorder[start]);

    root.left = myBuildTree(inorder,instart,position-1,preorder,prestart+1,prestart+position-instart);

    root.right = myBuildTree(inorder,position+1,inend,preorder,position-inend+preend+1,preend);

    returnroot;

    }

    intfindPosition(int[] arr,intstart,intend,intkey){

    inti;

    for(i = start;i<=end;i++){

    if(arr[i] == key){

    returni;

    }

    }

    return-1;

    }

    16.在二叉树中插入节点

    TreeNodeinsertNode(TreeNode root,TreeNode node){

    if(root == node){

    returnnode;

    }

    TreeNode tmp =newTreeNode();

    tmp = root;

    TreeNode last =null;

    while(tmp!=null){

    last = tmp;

    if(tmp.val>node.val){

    tmp = tmp.left;

    }else{

    tmp = tmp.right;

    }

    }

    if(last!=null){

    if(last.val>node.val){

    last.left = node;

    }else{

    last.right = node;

    }

    }

    returnroot;

    }

    17.输入一个二叉树和一个整数,打印出二叉树中节点值的和等于输入整数所有的路径

    voidfindPath(TreeNode r,inti){

    if(root == null){

    return;

    }

    Stackstack=newStack();

    intcurrentSum =0;

    findPath(r, i,stack, currentSum);

    }

    voidfindPath(TreeNode r,inti,Stackstack,intcurrentSum){

    currentSum+=r.val;

    stack.push(r.val);

    if(r.left==null&&r.right==null){

    if(currentSum==i){

    for(intpath:stack){

    System.out.println(path);

    }

    }

    }

    if(r.left!=null){

    findPath(r.left, i,stack, currentSum);

    }

    if(r.right!=null){

    findPath(r.right, i,stack, currentSum);

    }

    stack.pop();

    }

    18.二叉树的搜索区间

    给定两个值 k1 和 k2(k1 < k2)和一个二叉查找树的根节点。找到树中所有值在 k1 到 k2 范围内的节点。即打印所有x (k1 <= x <= k2) 其中 x 是二叉查找树的中的节点值。返回所有升序的节点值。

    ArrayList result;

    ArrayListsearchRange(TreeNode root,intk1,intk2){

    result =newArrayList();

    searchHelper(root,k1,k2);

    returnresult;

    }

    voidsearchHelper(TreeNode root,intk1,intk2){

    if(root ==null){

    return;

    }

    if(root.val>k1){

    searchHelper(root.left,k1,k2);

    }

    if(root.val>=k1&&root.val<=k2){

    result.add(root.val);

    }

    if(root.val

    searchHelper(root.right,k1,k2);

    }

    }

    19.二叉树的层次遍历

    ArrayList> levelOrder(TreeNode root){

    ArrayList> result =newArrayList>();

    if(root == null){

    returnresult;

    }

    Queuequeue=newLinkedList();

    queue.offer(root);

    while(!queue.isEmpty()){

    intsize =queue.size();

    ArrayList< level =newArrayList():

    for(inti =0;i < size ;i++){

    TreeNode node =queue.poll();

    level.add(node.val);

    if(node.left != null){

    queue.offer(node.left);

    }

    if(node.right != null){

    queue.offer(node.right);

    }

    }

    result.add(Level);

    }

    returnresult;

    }

    20.二叉树内两个节点的最长距离

    二叉树中两个节点的最长距离可能有三种情况:

    1.左子树的最大深度+右子树的最大深度为二叉树的最长距离

    2.左子树中的最长距离即为二叉树的最长距离

    3.右子树种的最长距离即为二叉树的最长距离

    因此,递归求解即可

    privatestaticclassResult{

    intmaxDistance;

    intmaxDepth;

    publicResult(){

    }

    publicResult(intmaxDistance,intmaxDepth){

    this.maxDistance = maxDistance;

    this.maxDepth = maxDepth;

    }

    }

    intgetMaxDistance(TreeNode root){

    returngetMaxDistanceResult(root).maxDistance;

    }

    ResultgetMaxDistanceResult(TreeNode root){

    if(root ==null){

    Result empty =newResult(0,-1);

    returnempty;

    }

    Result lmd = getMaxDistanceResult(root.left);

    Result rmd = getMaxDistanceResult(root.right);

    Result result =newResult();

    result.maxDepth = Math.max(lmd.maxDepth,rmd.maxDepth) +1;

    result.maxDistance = Math.max(lmd.maxDepth + rmd.maxDepth,Math.max(lmd.maxDistance,rmd.maxDistance));

    returnresult;

    }

    21.不同的二叉树

    给出 n,问由 1…n 为节点组成的不同的二叉查找树有多少种?

    intnumTrees(intn ){

    int[] counts =newint[n+2];

    counts[0] =1;

    counts[1] =1;

    for(inti =2;i<=n;i++){

    for(intj =0;j

    counts[i] += counts[j] * counts[i-j-1];

    }

    }

    returncounts[n];

    }

    22.判断二叉树是否是合法的二叉查找树(BST)

    一棵BST定义为:

    节点的左子树中的值要严格小于该节点的值。

    节点的右子树中的值要严格大于该节点的值。

    左右子树也必须是二叉查找树。

    一个节点的树也是二叉查找树。

    publicintlastVal = Integer.MAX_VALUE;

    publicbooleanfirstNode =true;

    publicbooleanisValidBST(TreeNode root){

    // write your code here

    if(root==null){

    returntrue;

    }

    if(!isValidBST(root.left)){

    returnfalse;

    }

    if(!firstNode&&lastVal >= root.val){

    returnfalse;

    }

    firstNode =false;

    lastVal = root.val;

    if(!isValidBST(root.right)) {

    returnfalse;

    }

    returntrue;

    }

    深刻的理解这些题的解法思路,在面试中的二叉树题目就应该没有什么问题,甚至可以怼他,哈哈。

    相关文章

      网友评论

          本文标题:二叉树实战 22 题,速度收藏吧!

          本文链接:https://www.haomeiwen.com/subject/ggrrcctx.html