首页 > 编程语言 >代码随想录算法训练营第十五天| 层序遍历 10 ,226.翻转二叉树 101.对称二叉树 2

代码随想录算法训练营第十五天| 层序遍历 10 ,226.翻转二叉树 101.对称二叉树 2

时间:2023-08-11 19:55:29浏览次数:43  
标签:遍历 return root 随想录 right 二叉树 第十五天 节点 left

 

层序遍历 

    卡哥建议:看完本篇可以一口气刷十道题,试一试, 层序遍历并不难,大家可以很快刷了十道题。

    题目链接/文章讲解/视频讲解:https://programmercarl.com/0102.%E4%BA%8C%E5%8F%89%E6%A0%91%E7%9A%84%E5%B1%82%E5%BA%8F%E9%81%8D%E5%8E%86.html

    做题思路:

    层序遍历就是一层一层的遍历,从二叉树的第一层到最后一层。用栈先进后出适合模拟深度优先遍历也就是递归的逻辑。而这种层序遍历方式就是图论中的广度优先遍历,只不过我们应用在二叉树上。使用队列实现二叉树广度优先遍历。

    我们每遍历一层的元素,就用队列去保存,然后用变量size记录下队列的大小,接下来把这一层元素弹出来,对下一层进行处理,比如把第一层的根节点弹出来后,再把第二层的根节点的左右孩子加入队列,再用size记录第二层元素个数。当弹出第二层的一个节点后,再把弹出的这个节点对应的左右孩子加入队列里,此时队列既有第二层的元素,又有第三层的元素,如果对队列弹出的元素数量不加以控制的话,怎么知道队列里哪些元素是第二层的,哪些是第三层,所以这里用size记录。我们在遍历完第二层的时候,同时把第二层每个节点的左右孩子也加入队列里了。

   层序遍历代码:

 1 vector<vector<int>> levelOrder(TreeNode* root) {
 2         queue<TreeNode*> que;
 3         if (root != NULL) que.push(root);
 4         vector<vector<int>> result;
 5         while (!que.empty()) {
 6             int size = que.size();
 7             vector<int> vec;
 8             // 这里一定要使用固定大小size,不要使用que.size(),因为que.size是不断变化的
 9             for (int i = 0; i < size; i++) {
10                 TreeNode* node = que.front();
11                 que.pop();
12                 vec.push_back(node->val);
13                 if (node->left) que.push(node->left);
14                 if (node->right) que.push(node->right);
15             }
16             result.push_back(vec);
17         }
18         return result;

 

 226.翻转二叉树 (优先掌握递归) 

     卡哥建议:这道题目 一些做过的同学 理解的也不够深入,建议大家先看我的视频讲解,无论做过没做过,都会有很大收获。

    题目链接/文章讲解/视频讲解:https://programmercarl.com/0226.%E7%BF%BB%E8%BD%AC%E4%BA%8C%E5%8F%89%E6%A0%91.html

    做题思路:

 

      翻转画图理解的话,如上图,观察图发现,第一层的根节点没变,第二层的根节点的左右孩子互相交换了,同理,第三层的左右节点也交换了,翻转用c++的swap函数就行。注意理解的话,每个节点的左右孩子是不变的,不能变成其他节点的左右孩子,所以交换左右孩子的指针就能避免这点。

    这道题目使用前序遍历和后序遍历都可以,中序遍历不行,看卡哥视频讲解。递归思路看卡哥文章。

    本题前序遍历的递归法代码:

 

1 TreeNode* invertTree(TreeNode* root) {
2         if (root == NULL) return root;
3         swap(root->left, root->right);  // 中
4         invertTree(root->left);         // 左
5         invertTree(root->right);        // 右
6         return root;
7     }

 

 

101. 对称二叉树 (优先掌握递归)  

    卡哥建议:先看视频讲解,会更容易一些。 

   题目链接/文章讲解/视频讲解:https://programmercarl.com/0101.%E5%AF%B9%E7%A7%B0%E4%BA%8C%E5%8F%89%E6%A0%91.html

   做题思路:

   如果两个节点的元素值相同,那对称;如果4个节点的内侧节点的元素值相同,并且外侧节点的元素值相同,那对称。对于二叉树,可以理解为原来的树和翻转后的树对称,除了根节点为空对称外,就是看根节点的左右子树是否为相互翻转,看两个子树的里侧和外侧的元素是否相等。比较二叉树外侧是否对称:传入的是左节点的左孩子,右节点的右孩子。比较内侧是否对称,传入左节点的右孩子,右节点的左孩子。如果左右都对称就返回true ,有一侧不对称就返回false 。还要先排除不对称的情况,左节点为空,右节点不为空,不对称,return false;左不为空,右为空,不对称, return false;左右都不为空,比较节点数值,不相同就return false。还有一种情况一定对称,左右都为空,对称,返回true。

 

     本题遍历只能是“后序遍历”,因为我们要通过递归函数的返回值来判断两个子树的内侧节点和外侧节点是否相等,递归它是要通过比较底部左右孩子是否相等的信息返回给上一层。这一块看卡哥视频讲解更清楚。

    本题后序遍历的递归法代码:

 1 bool compare(TreeNode* left, TreeNode* right) {
 2         // 首先排除空节点的情况
 3         if (left == NULL && right != NULL) return false;
 4         else if (left != NULL && right == NULL) return false;
 5         else if (left == NULL && right == NULL) return true;
 6         // 排除了空节点,再排除数值不相同的情况
 7         else if (left->val != right->val) return false;
 8 
 9         // 此时就是:左右节点都不为空,且数值相同的情况
10         // 此时才做递归,做下一层的判断
11         bool outside = compare(left->left, right->right);   // 左子树:左、 右子树:右
12         bool inside = compare(left->right, right->left);    // 左子树:右、 右子树:左
13         bool isSame = outside && inside;                    // 左子树:中、 右子树:中 (逻辑处理)
14         return isSame;
15 
16     }
17     bool isSymmetric(TreeNode* root) {
18         if (root == NULL) return true;
19         return compare(root->left, root->right);
20     }

 

标签:遍历,return,root,随想录,right,二叉树,第十五天,节点,left
From: https://www.cnblogs.com/romantichuaner/p/17623720.html

相关文章

  • 二叉树的堂兄弟节点
    在二叉树中,根节点位于深度0处,每个深度为k的节点的子节点位于深度k+1处。如果二叉树的两个节点深度相同,但父节点不同,则它们是一对堂兄弟节点。我们给出了具有唯一值的二叉树的根节点root,以及树中两个不同节点的值x和y。只有与值x和y对应的节点是堂兄弟节点时,......
  • 二叉树和B树
    1、树(Tree)的基本概念 节点、根节点、父节点、子节点、兄弟节点一棵树可以没有任何节点,称为空树一棵树可以只有1个节点,也就是只有根节点子树、左子树、右子树节点的度(degree):子树的个数树的度:所有节点度中的最大值叶子节点(leaf):度为0的节点非叶子节点:度不为0的节点......
  • 代码随想录算法训练营第一天| 704. 二分查找、27. 移除元素
    704二分查找题目给定一个n个元素有序的(升序)整型数组nums和一个目标值target,写一个函数搜索nums中的target,如果目标值存在返回下标,否则返回-1。第一想法判断条件是value=target因为数组是升序,其实每种查找方法应该相差不大?不过题目都标了二分查找了emmm思......
  • 代码随想录算法训练营第十天|力扣232.用栈实现队列、力扣225.用队列实现栈
    栈与队列理论知识栈提供push和pop等等接口,所有元素必须符合先进后出规则,所以栈不提供走访功能,也不提供迭代器(iterator)。不像是set或者map提供迭代器iterator来遍历所有元素。栈是以底层容器完成其所有的工作,对外提供统一的接口,底层容器是可插拔的(也就是说我们可以控制......
  • 代码随想录算法训练营第十四天| 理论基础 递归遍历 迭代遍历
     理论基础    卡哥建议:需要了解 二叉树的种类,存储方式,遍历方式 以及二叉树的定义   文章讲解:https://programmercarl.com/%E4%BA%8C%E5%8F%89%E6%A0%91%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%80.html   补充的知识点:   名词的概念看卡哥文章。二叉树......
  • (未完全掌握)代码随想录算法训练营第八、九天|KMP算法;力扣28.实现strStr(),力扣459.重
    KMP算法(没掌握)主要功能:字符串匹配理论:检测文本串中是否出现过模式串前缀就是包含首字母不包含尾字母的所有子串后缀就是包含尾字母不包含首字母的所有子串最长相等前后缀:对子串分别分析,从左向右前缀表是用来回退的,它记录了模式串与主串(文本串)不匹配的时候,模式串应该从......
  • [代码随想录]Day13-二叉树part02
    题目:102.二叉树的层序遍历思路:先把根放进去,然后每次都是左右就可以了。记录一个深度,当len(res)==deepth的时候就说明这个深度还没有实例化,先搞一个再去收集。代码:/***Definitionforabinarytreenode.*typeTreeNodestruct{*Valint*Left*TreeN......
  • 二叉树后序遍历非递归遍历实现图解
    二叉树的后序遍历输入:{1,#,2,3}返回值:[3,2,1]输入:{1}返回值:[1]代码实现publicint[]postorderTraversal(TreeNoderoot){TreeNodecur=root;List<Integer>list=newArrayList<>();Deque<TreeNode>stack=newArrayDeq......
  • 144. 二叉树的前序遍历
    给你二叉树的根节点 root ,返回它节点值的 前序 遍历。示例1:输入:root=[1,null,2,3]输出:[1,2,3]示例2:输入:root=[]输出:[]示例3:输入:root=[1]输出:[1]示例4:输入:root=[1,2]输出:[1,2]classSolution:defpreorderTraversal(self,root:Optional[TreeNode])->Li......
  • 145. 二叉树的后序遍历
    给你一棵二叉树的根节点 root ,返回其节点值的 后序遍历 。示例1:输入:root=[1,null,2,3]输出:[3,2,1]示例2:输入:root=[]输出:[]classSolution:defpostorderTraversal(self,root:Optional[TreeNode])->List[int]:res=[]defdfs(node):......