剑指offer--搜索与回溯算法(简单)

本文详细分析了三种基于搜索与回溯算法的二叉树问题:一是判断树的子结构,通过前序遍历和递归判断子树;二是实现二叉树的镜像,通过递归交换左右子节点;三是检查二叉树的对称性,利用深度优先搜索逐层比较节点。这些算法展示了回溯在解决树形结构问题中的应用。
摘要由CSDN通过智能技术生成


搜索与回溯算法(简单)

一、剑指 Offer 26. 树的子结构

代码如下(示例):

【C++代码】

/**
 * 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 ||!B) return false;
        if(isPart(A,B)) return true;
        return isSubStructure(A->left,B)||isSubStructure(A->right,B);
    }

    bool isPart(TreeNode*p1,TreeNode *p2){
        if(!p2) return true;
        if(!p1||p1->val !=p2->val) return false;
        return isPart(p1->left,p2->left)&&isPart(p1->right,p2->right);
    }
};

【分析】
若树B是树A的子结构,则子结构的根节点可能为树A的任意一个节点。因此,判断树B是否是A的子结构,需要完成以下两步骤工作:

  1. 前序遍历树A中的每个节点nA;(对应于isSubStucture(A,B));
  2. 判断树A中以nA为根节点的子树是包含树B.(对应于函数isPart(A,B))

【算法流程】:
名词规定:树A的根节点记作节点A,树B的根节点称为节点B
isPart(A,B)函数

 bool isPart(TreeNode*p1,TreeNode *p2){
        if(!p2) return true;
        if(!p1||p1->val !=p2->val) return false;
        return isPart(p1->left,p2->left)&&isPart(p1->right,p2->right);
    }
 //1、终止条件:
 	//1、当节点B为空,说明树B已经匹配完成
 	//2、当节点A为空,说明已经越过树A叶子节点,即匹配失败,返回false
 	//3、当节点A和B的值不同:说明匹配失败,返回false
//2、返回值
	//1、判断A和B的左子节点是否相等,即isPart(p1->left,p2->left)
	//2、判断A和B的右子节点是否相等,即isPart(A->right,B->right);

isSubStructure(A,B)函数:

//1、	特例处理:当树A为空或树B为空时,直接返回false;
//2、	返回值:若树B是树A的子结构,则必须满足以下三种情况之一,因此用或连接
	//1、	以节点A为根节点的子树包含树B,对应isPart(A,B);
	//2、	树B是树A左子树的子结构,对应isSubStructure(A->left,B)
	//3、	树B是树A右子树的子结构,对应isSubStructure(A->right,B);
 bool isSubStructure(TreeNode* A, TreeNode* B) {
        if(!A ||!B) return false;
        if(isPart(A,B)) return true;
        return isSubStructure(A->left,B)||isSubStructure(A->right,B);
    }

二、剑指 Offer 27. 二叉树的镜像

【C++代码】

/**
 * 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) return nullptr;
        mirrorTree(root->left);
        mirrorTree(root->right);
        swap(root->left,root->right);
        return root;
    }
};

【分析】
在这里插入图片描述


三、剑指 Offer 28. 对称的二叉树

【C++代码】

/**
 * 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) {
        if(!root) return true;
        return dfs(root->left,root->right);
    }
    bool dfs(TreeNode*p,TreeNode*q){
        if(!p||!q) return !q&&!p;
        if(p->val !=q->val) return false;
        return dfs(p->left,q->right) &&dfs(p->right,q->left);
    }
};

[分析]
解题思路:
对称二叉树定义:对于树中任意两个对称节点L和R,一定有
1、L->val = R->val;即对称节点值相等
2、L->>left->val = r->right->val;即L的左子节点和R的右子节点对称;
3、L->right->val = R->left->val;即L的右子节点和R的左子节点对称。
根据以上规律,考虑从顶至底层递归,判断每对节点是否对称,从而判断树是否为对称二叉树。
在这里插入图片描述
【算法流程】:

/*isSymmetric(root):
特例处理:若根节点root为空,则直接返回true.
返回值:即dfs(root->left,root->right);

*/
 bool isSymmetric(TreeNode* root) {
        if(!root) return true;
        return dfs(root->left,root->right);
    }

/*dfs(left,right):
终止条件:
	当left和right同时越过叶节点:此树从顶至底的节点都对称,因此返回ture;
	当left和right中有一个越过叶节点:此树不对称
	当节点L值不等于节点R值:此树不对称
递推工作:
	判断两节点L->left和R->right是否对称,即dfs(L->left,R->right);
	判断两节点L->right和R->left是否对称,即dfs(L->right,R->left);
返回值 :两节点都对称时,才是对称树,因此用与逻辑&&连接
*/
bool dfs(TreeNode*p,TreeNode*q){
        if(!p||!q) return !q&&!p;
        if(p->val != q->val) return false;
        return dfs(p->left,q->right) &&dfs(p->right,q->left);
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值