剑指offer 打卡计划 | 每日进步一点点 | 第10天

97 阅读2分钟

图片.png

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

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第12天,点击查看活动详情思路

(二叉树,递归) O(n)

观察样例,我们可以发现镜像后的树就是将原树的所有节点的左右儿子互换,因此递归遍历原树的所有节点,将每个节点的左右儿子互换即可。

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

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 NULL;  //如果节点为空,则返回NULL
         swap(root->left, root->right); //互换左右节点儿子
         mirrorTree(root->left); //递归左子树
         mirrorTree(root->right); //递归右子树
         return root;
     }
 };

剑指 Offer 28. 对称的二叉树

思路

(二叉树,递归) O(n)

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

  1. 两个子树的根节点值相等。
  2. 第一棵子树的左子树和第二棵子树的右子树互为镜像,且第一棵子树的右子树和第二棵子树的左子树互为镜像。

递归边界:

  1. 两个子树的当前节点都为空,判断成功,返回true
  2. 只有一个为空,判断失败,返回false
  3. 都不为空,但是值不相等,同样判断失败,返回false
  4. 递归左右子树继续判断

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

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

剑指 Offer 29. 顺时针打印矩阵

思路

(模拟) O(nm)

我们顺时针定义四个方向:上右下左。

从左上角开始遍历,先往右走,走到不能走为止,然后更改到下个方向,再走到不能走为止,依次类推,遍历 n*m 个格子后停止。

图片.png 时间复杂度分析: 矩阵中每个格子遍历一次,所以总时间复杂度是 O(nm)。

c++代码

 class Solution {
 public:
     int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1};
     vector<int> spiralOrder(vector<vector<int>>& matrix) {
         vector<int> res;
         if(matrix.empty()) return res; 
         int n = matrix.size(), m = matrix[0].size();
         vector<vector<bool>> st(n, vector<bool>(m)); //标记数组
         int x = 0, y = 0, d = 1;  //当前所在位置
         for(int i = 1; i <= n * m; i++){
             res.push_back(matrix[x][y]);
             st[x][y] = true; //将当前位置标记为走过
             int a = x + dx[d], b = y + dy[d]; //下一个位置
             if(a < 0 || a >= n || b < 0 || b >= m || st[a][b]){
                 d = (d + 1) % 4;
                 a = x + dx[d], b = y + dy[d];
             }
             x = a, y = b;
         }
         return res;
     }
 };