剑指offer(四)树

转载 2018年04月15日 21:19:16

面试题6:重建二叉树

题目:输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
解题思路:递归构建左右子树。

TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> vin) {
    int length = pre.size();
    return constructCore(pre,vin,0,length-1,0,length-1);
}
TreeNode* constructCore(vector<int> pre,vector<int> vin, int preL, int preR, int inL, int inR){
    int rootValue = pre[preL];
    TreeNode* root = new TreeNode(rootValue);
    int rootInOrder = inL;
    while(rootInOrder <= inR && vin[rootInOrder] != rootValue)
        rootInOrder++;
    int leftLength = rootInOrder - inL;
    if(leftLength > 0){
        root->left = constructCore(pre,vin,preL+1,preL+leftLength,inL,rootInOrder-1);
    }
    if(leftLength < preR-preL){
        root->right = constructCore(pre,vin,preL+leftLength+1,preR,rootInOrder+1,inR);
    }
    return root;
}

面试题18:树的子结构

题目:输入两棵二叉树A,B,判断B是不是A的子结构。(ps:我们约定空树不是任意一个树的子结构)
解题思路:递归,但是要注意检查树是否为空。

class Solution {
public:
    bool HasSubtree(TreeNode* pRoot1, TreeNode* pRoot2)
    {
        bool result = false;
        if(pRoot1 != NULL && pRoot2 != NULL){
            if(pRoot1->val == pRoot2->val)
                result = DoesTree1HasTree2(pRoot1, pRoot2);
            if(!result)
                result = HasSubtree(pRoot1->left, pRoot2);
            if(!result)
                result = HasSubtree(pRoot1->right, pRoot2);
        }
        return result;
    }
    bool DoesTree1HasTree2(TreeNode* pRoot1, TreeNode* pRoot2){
        if(pRoot2 == NULL)
            return true;
        if(pRoot1 == NULL)
            return false;
        if(pRoot1->val != pRoot2->val)
            return false;
        return DoesTree1HasTree2(pRoot1->left,pRoot2->left) && DoesTree1HasTree2(pRoot1->right,pRoot2->right);
    }
};

面试题19:二叉树的镜像

题目:操作给定的二叉树,将其变换为源二叉树的镜像。
解题思路:交换所有的左右子树,直至遍历完所有的非叶子结点。

class Solution {
public:
    void Mirror(TreeNode *pRoot) {
        if(pRoot==NULL)
            return;
        if(pRoot->left==NULL && pRoot->right==NULL)
            return;
        TreeNode *tmp = pRoot->right;
        pRoot->right = pRoot->left;
        pRoot->left = tmp;
        if(pRoot->left != NULL)
            Mirror(pRoot->left);
        if(pRoot->right != NULL)
            Mirror(pRoot->right);
    }
};

面试题23:从上到下打印二叉树

题目:从上往下打印出二叉树的每个节点,同层节点从左至右打印。
解题思路:队列

class Solution {
public:
    vector<int> PrintFromTopToBottom(TreeNode* root) {
        vector<int> result;
        if(root == NULL)
            return result;
        queue<TreeNode*> treeQueue;
        treeQueue.push(root);
        while(!treeQueue.empty()){
            TreeNode *tmp = treeQueue.front();
            treeQueue.pop();
            result.push_back(tmp->val);
            if(tmp->left != NULL)
                treeQueue.push(tmp->left);
            if(tmp->right != NULL)
                treeQueue.push(tmp->right);
        }
        return result;
    }
};

面试题24:二叉搜索树的后序遍历序列

题目:输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则输出Yes,否则输出No。假设输入的数组的任意两个数字都互不相同。
解题思路:后序遍历的话,最后一个数是根结点,因为是二叉搜索树,左子树都比根结点小,右子树都比根结点大。

class Solution {
public:
    bool VerifySquenceOfBST(vector<int> sequence) {
        return PostBST(sequence,0,sequence.size()-1);
    }
    bool PostBST(vector<int> sequence, int start, int end){
        if(end < start)
            return false;
        //int len = end - start + 1;
        int root = sequence[end]; //找到根结点
        int i = start;
        //在二叉搜索树中左子树的结点小于根结点
        for(;i<end;i++){
            if(sequence[i] > root)
                break;
        }
        int j = i;
        //在二叉搜索树中右子树的结点大于根结点
        for(;j<end;j++){
            if(sequence[j] < root)
                return false;
        }
        //判断左子树是不是二叉搜索树
        bool left = true;
        if(i>start)
            left = PostBST(sequence,start,i-1);
        //判断右子树是不是二叉搜索树
        bool right = true;
        if(i<end-1)
            right = PostBST(sequence,i,end-1);
        return (left && right);
    }
};

面试题25:二叉树中和为某一值的树

题目:输入一颗二叉树和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。
解题思路:画出遍历二叉树的过程,寻找规律:如果是叶节点,判断该路径上的和是否等于目标值;如果不是叶节点,则继续遍历它的孩子节点;路径的保存用栈,因为路径要与递归调用状态一致。

class Solution {
public:
    vector<vector<int> > FindPath(TreeNode* root,int expectNumber) {
        if(root != NULL){
            int currentSum = 0;
            vector<int> path;
            find(root, expectNumber, currentSum, path);
        }
        return result;
    }
    void find(TreeNode* root,int expectNumber,int currentSum,vector<int>& path){
        currentSum += root->val;
        path.push_back(root->val);
        bool isLeaf = (root->left == NULL && root->right == NULL);
        if(isLeaf && currentSum == expectNumber){
            result.push_back(path);
        }
        if(root->left != NULL)
            find(root->left, expectNumber, currentSum, path);
        if(root->right != NULL)
            find(root->right, expectNumber, currentSum, path);
        path.pop_back();
    }
private:
    vector<vector<int>> result;
};

面试题39:二叉树的深度

题目:输入一棵二叉树,求该树的深度。从根结点到叶结点依次经过的结点(含根、叶结点)形成树的一条路径,最长路径的长度为树的深度。
解题思路:树常用的递归,父亲结点的深度是左右子树深度的较大值,停止条件是叶子结点的深度为1。

class Solution {
public:
    int TreeDepth(TreeNode* pRoot)
    {
        if(pRoot == NULL)
            return 0;
        return getDepth(pRoot);
    }
    int getDepth(TreeNode* pRoot){
        int leftDepth = 0, rightDepth = 0;
        if(pRoot->left != NULL)
            leftDepth = getDepth(pRoot->left);
        if(pRoot->right != NULL)
            rightDepth = getDepth(pRoot->right);
        return (leftDepth > rightDepth ? leftDepth : rightDepth) + 1;
    }
};

举一反三:判断一棵树是不是平衡二叉树。平衡二叉树的每个结点的左右子树的深度差不超过1。最直观的做法是先分别得到左右子树的深度,判断该结点符不符合平衡条件,若不符合返回false,若符合再判断它的左子树和右子树,这样做的坏处在于重复计算了结点深度。所以如果用后序遍历的方式遍历结点,在遍历每个结点之前我们就已经遍历过它的左右子树,只要在遍历每个结点的时候记录它的深度,就可以一边遍历一边判断这个结点是不是平衡的。

class Solution {
public:
    bool IsBalanced_Solution(TreeNode* pRoot) {
        if(pRoot == NULL)
            return true;
        int pDepth;
        return IsBalanced(pRoot,pDepth);
    }
    bool IsBalanced(TreeNode* pRoot, int &pDepth){  //pDepth不要忘记加&
        if(pRoot == NULL){
            pDepth = 0;
            return true;
        }
        int left,right;
        if(IsBalanced(pRoot->left,left) && IsBalanced(pRoot->right,right)){  //后序遍历的体现
            if((left-right)>=-1 && (left-right)<=1){
                pDepth = 1+(left>right?left:right);
                return true;
            }
        }
        return false;
    }
};

剑指offer----树的子结构----java实现

输入两颗二叉树A,B,判断B是不是A的子结构。 思路: (1)在树A中找到和数B的根节点相同的节点;    可以利用前序遍历A树中的节点,找到和B树的根节点相同的节点。 (2)在树A中找到...
  • snow_7
  • snow_7
  • 2016-07-07 09:36:13
  • 440

树的子结构(剑指offer)递归

树的子结构 参与人数:1611时间限制:1秒空间限制:32768K 通过比例:18.19% 最佳记录:0 ms|0K(来自  mearo) 题目描述 输入两颗二叉树A,B,判断B是不是A...
  • u010579068
  • u010579068
  • 2015-09-19 15:40:39
  • 1074

【剑指offer】二叉树深度

题目描述: 输入一棵二叉树,求该树的深度。从根结点到叶结点依次经过的结点(含根、叶结点)形成树的一条路径,最长路径的长度为树的深度。 输入: 第一行输入有n,n表示结点数,结点号从1到n。根结点为1。...
  • mmc_maodun
  • mmc_maodun
  • 2014-05-28 08:22:12
  • 3192

《剑指offer》重建二叉树

【 声明:版权所有,转载请标明出处,请勿用于商业用途。  联系信箱:libin493073668@sina.com】 题目链接:http://www.nowcoder.com/p...
  • libin1105
  • libin1105
  • 2015-09-14 14:00:35
  • 1173

剑指Offer面试题18(Java版):树的子结构

题目:输入两棵二叉树A和B,判断B是不是A的子结构。 例如图中所示的两棵二叉树,由于A中有一部分子树的结构和B 是一样的,因此B是A的子结构。 要查找树A中是否存在和树B结构一样的子树,我们可以分...
  • jsqfengbao
  • jsqfengbao
  • 2015-08-01 22:16:45
  • 1859

【面试题】剑指offer 4

实现一个函数将字符串中的空格替换为20% #include #include #include void myblank(char * str,int length) { if(str==NUL...
  • shangguan_1234
  • shangguan_1234
  • 2017-03-01 17:07:06
  • 103

《剑指offer》之回溯法专题

《剑指offer》之回溯法专题
  • qq_21688757
  • qq_21688757
  • 2017-01-10 19:10:47
  • 335

剑指offer-面试题58:二叉树的下一个结点

题目:给定一棵二叉树和其中的一个结点,如何找出中序遍历顺序的下一个结点?树中的结点除了有两个分别指向左右子结点的指针以外,还有一个指向父结点的指针。 思路:举一个例子,容易发现规律。这个问题可以分为两...
  • moses1213
  • moses1213
  • 2016-05-02 15:35:10
  • 359

剑指Offer之 - 最小的k个数

题目: 输入n个整数,找出其中最小的k个数。如输入4、5、1、6、2、7、3、8 这8个数字,则最小的 4 个数字是1、2、3、4 思路: 1、基于快排的思路,每排序一次可以确定一个数的位置,如果这个...
  • u012243115
  • u012243115
  • 2015-04-22 14:04:17
  • 318

【剑指offer】题目4

题目:给定一个字符数组,存放长度为len的字符,且数组还有很多剩余的空间,要求把数组中的空格替换为“%20”。 要求只在给定的数组上操作,不能另外增加数组。 一个简单的实现是,len位置开始生成新的数...
  • u010900754
  • u010900754
  • 2017-06-25 16:53:41
  • 111
收藏助手
不良信息举报
您举报文章:剑指offer(四)树
举报原因:
原因补充:

(最多只允许输入30个字)