题解 | 树的子结构

/*
struct TreeNode {
	int val;
	struct TreeNode *left;
	struct TreeNode *right;
	TreeNode(int x) :
			val(x), left(NULL), right(NULL) {
	}
};*/
class Solution {
	


public:
	bool HasSubTreeHelper(TreeNode* pRoot1, TreeNode* pRoot2) {
		if (pRoot1 == nullptr && pRoot2 != nullptr)
			return false;
		if (pRoot1 == nullptr || pRoot2 == nullptr)
			return true;
		if (pRoot1->val != pRoot2->val)
			return false;


		return HasSubTreeHelper(pRoot1->left, pRoot2->left) && HasSubTreeHelper(pRoot1->right, pRoot2->right);
	}
    bool HasSubtree(TreeNode* pRoot1, TreeNode* pRoot2) {

		if (pRoot2 == nullptr)
			return false;
		if(pRoot1 == nullptr && pRoot2 != nullptr)
            return false;
        if(pRoot1 == nullptr || pRoot2 == nullptr)
            return true;
		bool middle = HasSubTreeHelper(pRoot1, pRoot2);

		bool leftcmp = HasSubtree(pRoot1->left, pRoot2);
		bool rightcmp = HasSubtree(pRoot1->right, pRoot2);

		return leftcmp || middle || rightcmp;
		//空树
        // if(pRoot2 == NULL)
        //     return false;
        // //一个为空,另一个不为空
        // if(pRoot1 == NULL && pRoot2 != NULL)
        //     return false;
        // if(pRoot1 == NULL || pRoot2 == NULL)
        //     return true;
        // //递归比较
        // bool flag1 = HasSubTreeHelper(pRoot1, pRoot2); 
        // //递归树1的每个节点
        // bool flag2 = HasSubtree(pRoot1->left, pRoot2); 
        // bool flag3 = HasSubtree(pRoot1->right, pRoot2);
        // return flag1 || flag2 || flag3;
    }


};





///
// TreeNode* currRt1 = pRoot1;
		// TreeNode* currRt2 = pRoot2;
		// //empty tree is not the subtree of any
		//  if (currRt2 == NULL)
		// 	return false;

		// // if (currRt1->left == NULL && currRt1->right == NULL && currRt2->left == NULL && currRt2->right == NULL) {
		// // 	if (currRt1->val == currRt2->val)
		// // 		return true;
		// // 	else
		// // 	 	return false;
		// // }


		// if (currRt1->val != currRt2->val) {
		// 	if (currRt1->right == NULL && currRt1->left == NULL) 
		// 		return false;
		// 	else {
		// 		if (currRt1->left != NULL && currRt1->right != NULL)
		// 		return HasSubtree(currRt1->left, currRt2) || HasSubtree(currRt1->right, currRt2);
		// 		else if (currRt1->left == NULL && currRt1->right != NULL)
		// 			return HasSubtree(currRt1->right, currRt2);
		// 		else //if (currRt1->left != NULL && currRt1->right == NULL)
		// 			return HasSubtree(currRt1->right, currRt2);
		// 	}
			
			
		// } else {
		// 	if (currRt2->left != NULL && currRt1->left == NULL || currRt2->right != NULL && currRt1->right == NULL)
		// 		return false;
		// 	else {
		// 		if (currRt2->left == NULL && currRt2->right == NULL)
		// 			return true;
		// 		else {
		// 			if (currRt2->left == NULL && currRt2->right != NULL ) 
		// 				return HasSubtree(currRt1->right, currRt2->right);
		// 			else //if (currRt2->right == NULL && currRt2->left != NULL) 
		// 				return HasSubtree(currRt1->left, currRt1->left);
		// 		}
		// 	}
		// }

递归首先要明确base case。最明显的一个是pRoot2==nullptr,然后就是在pRoot1遍历完的时候pRoot2还没有遍历完返回false,唯有pRoot2和pRoot1(排除前面的情况之后)有一个都遍历完了或者pRoot2先遍历完的情况下返回true,然后再加上对应的递归#剑指offer#

全部评论

相关推荐

1. 嵌入式系统的组成嵌入式系统通常由以下几个部分组成:硬件平台:包括微处理器(如ARM、MIPS、x86等)、传感器、执行器、输入输出设备(如LCD、按键、LED等)。操作系统:嵌入式系统可以使用实时操作系统(RTOS)或裸机(bare-metal)开发。RTOS如FreeRTOS、uC/OS-II等,裸机编程通常指直接与硬件打交道,没有操作系统的介入。软件:包括驱动程序、应用程序、系统软件等。驱动程序负责硬件与软件的通信,应用程序则实现系统功能。2. 嵌入式开发工具链嵌入式开发通常需要一系列的开发工具:集成开发环境(IDE):常用的IDE有Keil、IAR Embedded Workbench、Eclipse等,它们提供了代码编辑、编译、调试等功能。编译器:常见的嵌入式编译器有GCC、ARM Compiler等,能够将源代码编译成适合嵌入式平台的机器代码。调试器:如JTAG调试器、ST-Link、OCD等,用于调试程序的执行,帮助开发者查看寄存器、内存等信息,实时诊断问题。仿真器:帮助开发者在没有实际硬件的情况下测试代码。3. 嵌入式编程语言嵌入式开发中,最常用的编程语言是:C语言:几乎所有嵌入式开发都使用C语言,因为它能够直接操作硬件,提供较高的执行效率,并且占用内存较少。嵌入式开发中,C语言常用于编写驱动、操作系统和应用层代码。汇编语言:对于需要极高性能和硬件控制的任务,汇编语言有时用于优化代码,直接操作硬件寄存器。C++:在一些复杂的嵌入式系统中,C++用于面向对象编程,尤其是在处理较为复杂的算法时。4. 嵌入式开发中的实时性要求实时性是嵌入式系统中至关重要的概念,特别是在处理信号采集、控制系统时。根据实时性要求,嵌入式系统可以分为:硬实时系统:对时间要求非常严格,任务必须在规定的时间内完成,否则将导致系统失败。例如,航空航天、医疗设备等。软实时系统:虽然有时间限制,但如果超时不会导致系统完全失败,系统仍然能正常工作。例如,视频播放、音频处理等。5. 基本的嵌入式开发流程嵌入式开发流程一般包括以下步骤:需求分析:明确系统的功能需求、硬件需求、性能要求等。硬件选择:选择适合的微控制器(MCU)或微处理器(MPU),并了解其硬件资源(如GPIO、UART、SPI、I2C等外设)。软件设计:根据需求设计嵌入式软件架构,包括驱动、RTOS配置、应用层逻辑等。编程与调试:在开发环境中编写代码,进行调试和测试,确保软件的正确性和性能。测试与验证:在目标硬件上进行系统测试,验证软件和硬件的协同工作。  c++/嵌入式面经专栏-牛客网 https://www.nowcoder.com/creation/manager/columnDetail/MJNwoM
点赞 评论 收藏
分享
评论
点赞
收藏
分享
牛客网
牛客企业服务