树的子结构之先序遍历+二叉树的镜像+对称二叉树

问题1:树的子结构剑指 Offer 26. 树的子结构 - 力扣(LeetCode)

思路:先序遍历

  isSubtree函数:遍历一遍a树的每一个节点,找到与b树匹配的根节点,即调用recur函数;

      否则递归调用自身,找下一个匹配的根节点。

  recur函数返回条件:直到 遍历完b树则成功,或者a树遍历完失败,或者节点不相等失败;

      否则说明相等,继续递归下一个左右子节点,并且是逻辑与的关系

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    bool isSubStructure(TreeNode* A, TreeNode* B) {
        if(A == nullptr || B == nullptr) return false;
        return recur(A,B) || isSubStructure(A->left,B) || isSubStructure(A->right,B);
    }
private:
    bool recur(TreeNode* a , TreeNode* b){
        if(b == nullptr) return true;
        if(a == nullptr) return false;
        if(a->val != b->val) return false;
        return recur(a->left,b->left) && recur(a->right,b->right);
    }
};

问题2:二叉树的镜像剑指 Offer 27. 二叉树的镜像(递归 / 辅助栈,清晰图解) - 二叉树的镜像 - 力扣(LeetCode)

思路:递归,从当前根节点开始,若为空,直接返回;

递归根节点的左子节点,一路递归下去,直到叶子节点为空返回本身,跳出最后一次的递归,接着执行右子节点镜像,也是返回本身,

交换当前两节点,(处于子树的末梢的两节点);

返回这两节点的父节点,跳出当前的递归,接着又执行这个父节点的右子节点,如此循环;

时间复杂度:O(N) ; 空间复杂度:O(N),递归栈的深度。

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    TreeNode* mirrorTree(TreeNode* root) {
        if(root == nullptr) return nullptr;
        TreeNode* left = mirrorTree(root->left);
        TreeNode* right = mirrorTree(root->right);
        root->left = right;
        root->right = left;
        return root;
    }
};

或者利用栈先入后出特性,pop父节点,将子节点压入栈,并交换父节点的左右子节点

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    TreeNode* mirrorTree(TreeNode* root) {
        if(root == nullptr) return nullptr;
        stack<TreeNode*>tmp;
        tmp.push(root);
        while(tmp.size()){
            TreeNode* node = tmp.top();
            tmp.pop();
            if(node->left != nullptr) tmp.push(node->left);
            if(node->right!= nullptr) tmp.push(node->right);
            TreeNode* t_node = node->left;
            node->left = node->right;
            node->right = t_node;
        }
        return root;
    }
};

 问题3:对称二叉树剑指 Offer 28. 对称的二叉树 - 力扣(LeetCode)

思路:递归,root为空直接返回true;

    recur函数:当L和R同时越过叶节点,此树结构对称返回true;当L 和 R不同时越过叶节点,不对称返回false;当节点值不相等也返回false;

      继续判定对应的子节点,并且要同时满足,逻辑与

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    bool isSymmetric(TreeNode* root) {
        return root == nullptr ? true : recur(root->left,root->right);
    }
private:
    bool recur(TreeNode* L ,TreeNode* R){
        if(L == nullptr && R == nullptr) return true;
        if(L == nullptr ||  R == nullptr || L->val != R->val) return false;//条件不能交换顺序
        return recur(L->left,R->right) && recur(L->right,R->left);
    }
};

 

posted @ 2023-02-16 11:26  QianFa01  阅读(34)  评论(0)    收藏  举报