首页 > 编程语言 >剑指offer——Day07搜索与回溯算法(简单)

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

时间:2022-11-15 15:44:12浏览次数:49  
标签:right TreeNode recur offer Day07 回溯 return NULL root

Day7 2022.11.13 树的子结构

26.树的子结构

自己实现

应该是用递归,具体没有思路,直接看题解了

题解

用两个函数isSubStructure()recur()来解决。就不断去递归比较A的子树与B即可。看代码应该就能理解(注意空树不是任意一个树的子结构)

代码如下:

class Solution {
public:
    bool isSubStructure(TreeNode* A, TreeNode* B) {
        return (A!=NULL&&B!=NULL) && (recur(A, B) || isSubStructure(A->left, B) || isSubStructure(A->right, B));
    }
    bool recur(TreeNode* A, TreeNode* B)
    {
        if(B==NULL) return true;
        if(A==NULL || A->val!=B->val)return false;
        return recur(A->left,B->left) && recur(A->right, B->right);
    }
};

代码实现

时间不稳定 正常的

hint:

  • 递归设置好出口就最关键。

27.二叉树的镜像

自己实现

这个和斜堆的过程是基本一样的,就不详细说了(递归实现)

代码如下:

class Solution {
public:
    TreeNode* mirrorTree(TreeNode* root) {
        if(root==NULL)return root;
        recur(root);
        return root;
    }
    void recur(TreeNode* root)
    {
        if(root==NULL)return;
        recur(root->left);
        recur(root->right);
        swap(root);
    }
    void swap(TreeNode* root)
    {
        TreeNode* tmp=root->left;
        root->left=root->right;
        root->right=tmp;
    }
};

代码表现

时间不稳定,但是递归挺好用的

题解

题解就是正向地不断入栈、交换、出栈。比较巧妙的一点在于入栈时先左儿子再右儿子,然后马上交换(左儿子变成右儿子,右儿子变成左儿子),这样出栈的时候仍然是先出左儿子再出右儿子。(但其实好像这个顺序没啥关系...)

代码如下:

class Solution {
public:
    TreeNode* mirrorTree(TreeNode* root) {
        if(root==NULL)return root;
        vector<TreeNode*> vec;
        vec.push_back(root);
        while(vec.size()!=0)
        {
            TreeNode* now=vec[vec.size()-1];
            vec.pop_back();
            if(now->left!=NULL)vec.push_back(now->left);
            if(now->right!=NULL)vec.push_back(now->right);
            TreeNode* tmp=now->left;
            now->left=now->right;
            now->right=tmp;

        }
        return root;
    }
};

代码表现

时间不稳定,又能0ms,有鬼了...

hint:

  • 递归的思想要多练习多去想,会自然很多
  • 之前没有接触过正向地使用栈的思路,可以体验下,巧妙点可以看上文题解描述

28.对称的二叉树

自己实现

题目里其实给了思路了。先用递归复制一棵树出来,然后用这棵树递归得到其镜像树,再用递归比较镜像树和原来的树是否相等

代码如下

  class Solution {
  public:
	  bool isSymmetric(TreeNode* root) {
		  if (root == NULL)return true;
		  TreeNode* root0 = new TreeNode(root->val);
		  TreeNode* now0 = root0;
		  copy_recur(root, now0);
		  recur(root);
		  return comp_recur(root, root0);
	  }
	  void copy_recur(TreeNode* root, TreeNode* root0)
	  {
		  if (root == NULL)return;
		  if (root->left != NULL)root0->left = new TreeNode(root->left->val);
		  if (root->right != NULL)root0->right = new TreeNode(root->right->val);
		  copy_recur(root->left, root0->left);
		  copy_recur(root->right, root0->right);
	  }
	  void recur(TreeNode* root)
	  {
		  if (root == NULL)return;
		  recur(root->left);
		  recur(root->right);
		  swap(root);
	  }
	  void swap(TreeNode* root)
	  {
		  TreeNode* tmp = root->left;
		  root->left = root->right;
		  root->right = tmp;
	  }
	  bool comp_recur(TreeNode* root, TreeNode* root0)
	  {

		  if (root == NULL && root0 == NULL)return true;
		  if ((root == NULL && root0 != NULL) || (root != NULL && root0 == NULL))return false;
		  if (root->val != root0->val)return false;
		  if(!comp_recur(root->left, root0->left))return false;
		  if(!comp_recur(root->right, root0->right))return false;
		  return true;
	  }
  };

代码表现

题解

用递归简单地写出来了。用左儿子的左儿子和右儿子的右儿子比较&&用左儿子的右儿子和右儿子的左儿子比较。

代码如下:

class Solution {
public:
    bool isSymmetric(TreeNode* root) {
        return root==NULL?true:recur(root->left,root->right);
    }
    bool recur(TreeNode* L,TreeNode* R)
    {
        if(L==NULL && R==NULL)return true;  //排除了两个都为NULL的情况
        if(L==NULL || R==NULL || L->val!=R->val)return false;
        return recur(L->left, R->right) && recur(L->right, R->left);
    }
};

代码表现

hint:

  • 递归判断两棵树是否相等那里,Line38, 39卡了一下,可以记忆一下

标签:right,TreeNode,recur,offer,Day07,回溯,return,NULL,root
From: https://www.cnblogs.com/cspzyy/p/16892608.html

相关文章

  • 剑指offer——Day03字符串(简单)
    Day32022.11.9字符串(简单)05.替换空格自己实现遍历字符串中查找空格位置,erase空格,insert"%20"代码如下:classSolution{public:stringreplaceSpace(strings)......
  • 剑指 Offer 58 - II. 左旋转字符串
    剑指Offer58-II.左旋转字符串字符串的左旋转操作是把字符串前面的若干个字符转移到字符串的尾部。请定义一个函数实现字符串左旋转操作的功能。比如,输入字符串"ab......
  • 【剑指Offer学习】【面试题3 :二维数组中的查找】
    思路:规律从右上角开始,或左下开始。不能从左上角开始找,这样每次比较后向右和向下都是越来越大。publicclassP03_FindMaxInMatrix{/*规律从右上角开始:......
  • 拿下阿里自动化测试岗23k*14薪offer的全程面试记录解析以及总结
    一、自我介绍面试官您好!我叫xx,来自深圳,毕业之后一直从事于软件测试的工作,有做过保险、金融、电商等项目;有做过做功能测试、接口测试,自动化测试,在工作中积极主动、可以独立的......
  • 剑指 Offer 41. 数据流中的中位数 - 力扣(Leetcode)
    剑指Offer41.数据流中的中位数-力扣(Leetcode)分析维护两个堆,一个大根堆,一个小根堆。插入操作:当进行插入时,先判断大根堆中是否有元素,如果没有直接插入大根堆,若有......
  • 剑指 Offer 59 - I. 滑动窗口的最大值 - 力扣(Leetcode)
    剑指Offer59-I.滑动窗口的最大值-力扣(Leetcode)一.分析方法一:数组长度为1e5,k的大小为1e4,因此直接暴力计算会TLE。我们可以思考一个更复杂的问题:询问任意区间中的......
  • [回溯算法]leetcode40. 组合总和 II(c实现)
    题目给定一个候选人编号的集合 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。candidates 中的每个数字在每个组合中......
  • [回溯算法]leetcode216. 组合总和 III(c实现)
    题目找出所有相加之和为 n的 k 个数的组合,且满足下列条件:只使用数字1到9每个数字 最多使用一次 返回所有可能的有效组合的列表。该列表不能包含相同的组合两次......
  • 回溯算法解数独问题
    好久没写算法了,浅解个数独本篇代码以伪代码为主,主要讲解解题思路规则介绍:首先数独的游戏规则,每个九宫格每一行每一列每个数字只能出现一次(1-9)开局时会生成一些不......
  • 回溯算法dfs: lc46全排列 lc47全排列ll
    result=[] defbacktrack(路径,选择列表):if满足结束条件:result.add(路径)returnfor选择in选择列表:做选择backtrack(路径,选择列表)撤销选择 46全......