LeetCode 热题 HOT 100 打卡计划 | 第十四天 | 每日进步一点点

83 阅读4分钟

图片.png

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第15天,点击查看活动详情

101. 对称二叉树

思路

(递归) O(n)

给定我们一个二叉树的根节点root,检查这颗二叉树是否轴对称。

样例:

图片.png

如样例所示,root = [1,2,2,3,4,4,3],是一颗轴对称二叉树,因此我们返回true。判断一棵二叉树是否轴对称,其实就是判断这颗二叉树的左右两个子树是否互为镜像

两个子树互为镜像当且仅当:

  1. 两个子树的根节点值相等;
  2. 第一棵子树的左子树和第二棵子树的右子树对称,且第一棵子树的右子树和第二棵子树的左子树对称;

图片.png

具体实现过程如下:

  • 1、我们定义两个指针pq ,让pq指针一开始分别指向左子树和右子树。
  • 2、同步移动这两个指针来遍历这棵树,每次检查当前 pq 节点的值是否相等,如果相等再判断左右子树是否对称。

判断两颗树对称的递归边界:

  • pq节点都为空时,左右子树都为空,返回true
  • pq节点只有一个为空时,左右子树不对称,返回false
  • pq节点值不相等,左右子树不对称,返回false

时间复杂度分析: 从上到下每个节点仅被遍历一遍,所以时间复杂度是 O(n)。

c++代码

 /**
  * Definition for a binary tree node.
  * struct TreeNode {
  *     int val;
  *     TreeNode *left;
  *     TreeNode *right;
  *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
  *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
  *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
  * };
  */
 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 true;
         if(!p || !q) return false;
         if(p->val != q->val) return false;
         return dfs(p->left, q->right) && dfs(p->right, q->left);
     }
 };

102. 二叉树的层序遍历

思路

(BFS) O(n) 我们从根节点开始按宽度优先的顺序遍历整棵树,每次先扩展左儿子,再扩展右儿子。

这样我们会:

  1. 先扩展根节点;
  2. 再依次扩展根节点的左右儿子,也就是从左到右扩展第二层节点;
  3. 再依次从左到右扩展第三层节点;
  4. 依次类推

然后在遍历过程中我们给每一层加一个结尾标记NULL,当我们访问到一层的结尾时,由于BFS的特点,我们刚好把下一层都加到了队列中。这个时候就可以给这层加上结尾标记NULL了,每次遍历到一层的结尾NULL时,就将这一层添加到结果中。

时间复杂度分析: 每个节点仅会被遍历一次,因此时间复杂度为O(n)。

c++代码

 /**
  * Definition for a binary tree node.
  * struct TreeNode {
  *     int val;
  *     TreeNode *left;
  *     TreeNode *right;
  *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
  *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
  *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
  * };
  */
 class Solution {
 public:
     vector<vector<int>> levelOrder(TreeNode* root) {
         vector<vector<int>> res;
         vector<int> path;
         queue<TreeNode*> q;
         q.push(root);
         q.push(nullptr);
         while(q.size()){
             TreeNode* t = q.front();
             q.pop();
             if(!t){
                 if(path.empty())  break;  //如果当前层没有元素,直接结束(防止进入死循环)
                 res.push_back(path);
                 path.clear();
                 q.push(nullptr); //每一层的结尾加一个null标记结束
             }else{
                 path.push_back(t->val);
                 if(t->left)  q.push(t->left);
                 if(t->right) q.push(t->right);
             }
         }
         return res;
     }
 };

104. 二叉树的最大深度

思路

(递归) O(n) 当前树的最大深度等于左右子树的最大深度加1,也就是说如果我们知道了左子树和右子树的最大深度 lhrh,那么该二叉树的最大深度即为 max(lh,rh) + 1

图示:

图片.png

递归设计:

  • 1、递归边界:当前节点为空时,树的深度为0
  • 2、递归返回值:返回当前子树的深度,即max(lh,rh) + 1

时间复杂度分析: 树中每个节点只被遍历一次,所以时间复杂度是 O(n)。

c++代码

 /**
  * Definition for a binary tree node.
  * struct TreeNode {
  *     int val;
  *     TreeNode *left;
  *     TreeNode *right;
  *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
  *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
  *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
  * };
  */
 class Solution {
 public:
     int maxDepth(TreeNode* root) {
         if(!root) return 0;
         int lh = maxDepth(root->left), rh = maxDepth(root->right);
         return max(lh, rh) + 1;
     }
 };