剑指offer---关于树的题目解答---第二弹

平衡二叉树

解题思路:

平衡二叉树是什么?基于二叉树,但是左右子树的高度差不能超过1

那么使用递归实现,首先每次求出左右子树的高度,如果左右子树的高度差小于等于1,继续进行递归,否则不是一个平衡树

代码实现:

public class IsBalanced_Solution {
    public boolean IsBalanced_Solution(TreeNode root) {
        if(root == null) {
            return true;
        }

        int left = getTreeDepth(root.left);
        int right = getTreeDepth(root.right);
        if(left - right < - 1 || left - right > 1) {
            return false;
        }

        return IsBalanced_Solution(root.left) && IsBalanced_Solution(root.right);
    }

    public int getTreeDepth(TreeNode root) {
        if(root == null) {
            return 0;
        }

        int left = getTreeDepth(root.left);
        int right = getTreeDepth(root.right);
        return Math.max(left, right) + 1;
    }
}

二叉树的下一个结点

解题思路:

首先,next为当前节点的父节点指针(这个是题中给出的结构)、、

中序遍历,即进行  左---根---右  的顺序进行遍历

如果当前节点有右孩子结点,那么寻找右孩子结点node,是否还有左孩子结点,如果有,那么node=node.left,最后返回node

如果当前节点node没有右孩子结点,那么找到自己的上一个结点n,判断自己是否为n的左孩子结点,如果是,返回n

否则,继续找n的上一个结点,执行同样的判断

代码实现:

public class GetNext {
    public TreeLinkNode GetNext(TreeLinkNode pNode) {
        if(pNode == null) {
            return null;
        }

        if(pNode.right != null) {
            pNode = pNode.right;
            while (pNode.left != null) {
                pNode = pNode.left;
            }

            return pNode;
        }

        while ( pNode.next != null) {
            TreeLinkNode pRoot = pNode.next;
            if(pRoot.left == pNode) {
                return pRoot;
            }

            pNode = pNode.next;
        }

        return null;
    }
}

二叉树搜索树的后续遍历序列

解题思路:

二叉搜索树:即二叉查找树,当前接结点总是大于左子节点,小于右子结点

后序遍历: 左---右---根   的遍历方式,那么最后一个节点总是根节点

代码实现:

public class VerifySquenceOfBST {
    public boolean VerifySquenceOfBST(int [] sequence) {
        if(sequence == null || sequence.length == 0) {
            return false;
        }
        if(sequence.length == 1) {
            return true;
        }
        return fun(sequence, 0, sequence.length - 1);
    }

    public boolean fun(int[] sequence, int start, int end) {
        if(start > end) {
            return true;
        }

        int i = end;
        while (i > start && sequence[i - 1] > sequence[end]) {
            i--;
        }

        for(int j = 0; j < i - 1; j++) {
            if(sequence[j] > sequence[end]) {
                return false;
            }
        }

        return fun(sequence, start, i - 1) && fun(sequence, i, end - 1);
    }
}

二叉树中和为某一值的路径

解题思路:

从根节点开始,不断向下遍历,并让目标值target减去当前节点的值,直至下一个节点为空,此时如果目标值target为0,将该list添加

代码实现:

import java.util.ArrayList;

public class FindPath {
    ArrayList<ArrayList<Integer>> resultList = new ArrayList<>();
    ArrayList<Integer> list = new ArrayList<>();
    public ArrayList<ArrayList<Integer>> FindPath(TreeNode root, int target) {
        if(root == null) {
            return resultList;
        }

        list.add(root.val);
        target -= root.val;
        if(target == 0 && root.left == null && root.right == null) {
            resultList.add(new ArrayList<>(list));
        }

        FindPath(root.left, target);
        FindPath(root.right, target);
        list.remove(list.size() - 1);
        return resultList;
    }
}

按之字形打印二叉树

解题思路:

在上一篇文章中,我们分别进行了从左向右打印二叉树,按层打印二叉树的操作

而按照之字形打印二叉树就是基于按层打印二叉树的,对于奇数层从左向右打印,偶数层,从右向左打印

可以利用list的反转

代码实现:

import java.util.ArrayList;
import java.util.Collections;

public class PrintTreeLikeS {
    ArrayList<ArrayList<Integer>> resultList = new ArrayList<>();
    public ArrayList<ArrayList<Integer>> Print(TreeNode pRoot) {
        if(pRoot == null) {
            return resultList;
        }

        ArrayList<TreeNode> layer = new ArrayList<>();
        ArrayList<Integer> list = new ArrayList<>();
        int start = 0;
        int end = 1;
        int layerCount = 3;
        layer.add(pRoot);
        while (!layer.isEmpty()) {
            TreeNode node = layer.remove(0);
            list.add(node.val);
            start++;
            if(node.left != null) {
                layer.add(node.left);
            }
            if(node.right != null) {
                layer.add(node.right);
            }

            if(start == end) {
                if(layerCount % 2 == 0) {
                    Collections.reverse(list);
                }
                resultList.add(list);
                list = new ArrayList<Integer>();
                layerCount++;
                start = 0;
                end = layer.size();
            }
        }

        return resultList;
    }
}

二叉搜索树与双向链表

解题思路:

二叉搜索树如果按照排序的方式,那么就是对这个树进行中序遍历

使用非递归的方式,对二叉搜索树进行遍历,并改变 left 和 right 的指向

最后就能得到排序的双向链表

代码实现:

import java.util.Stack;

public class ConvertTreeIntoLink {
    public TreeNode Convert(TreeNode pRootOfTree) {
        if(pRootOfTree == null) {
            return pRootOfTree;
        }

        Stack<TreeNode> stack = new Stack<>();
        TreeNode p = pRootOfTree;
        TreeNode pre = null;
        boolean isFirst = true;

        while (p != null || !stack.isEmpty()) {
            while (p != null) {
                stack.push(p);
                p = p.left;
            }

            p = stack.pop();
            if(isFirst) {
                pRootOfTree = p;
                pre = pRootOfTree;
                isFirst = false;
            } else {
                pre.right = p;
                p.left = pre;
                pre = p;
            }

            p = p.right;
        }

        return pRootOfTree;
    }
}

序列化二叉树

解题思路:

参照之前树的基础知识的博客https://blog.csdn.net/szy2333/article/details/88804090

其实就是进行树的创建和将树保存成字符串

代码实现:

public class SerializeTree {
    String Serialize(TreeNode root) {
        if(root == null) {
            return "";
        }

        StringBuffer sb = new StringBuffer();
        Serialize(root, sb);
        return sb.toString();
    }

    void Serialize(TreeNode root, StringBuffer sb) {
        if(root == null) {
            sb.append("#,");
            return;
        }

        sb.append(root.val);
        sb.append(",");
        Serialize(root.left, sb);
        Serialize(root.right, sb);
    }

    int index = -1;
    TreeNode Deserialize(String str) {
        if(str.length() == 0) {
            return null;
        }

        String[] strs = str.split(",");
        return Deserialize(strs);
    }

    TreeNode Deserialize(String[] strs) {
        index++;
        if(!strs[index].equals("#")) {
            TreeNode root = new TreeNode(0);
            root.val = Integer.parseInt(strs[index]);
            root.left = Deserialize(strs);
            root.right = Deserialize(strs);
            return root;
        }

        return null;
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值