Leetcode树刷题顺序

100. 相同的树

难度简单312
给定两个二叉树,编写一个函数来检验它们是否相同。
如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。
示例 1:

输入: 1         1
          / \       / \
         2   3     2   3
        [1,2,3],   [1,2,3]
输出: true

示例 2:

输入: 1       1
          /           \
         2             2
        [1,2],     [1,null,2]
输出: false

示例 3:

输入: 1         1
          / \       / \
         2   1     1   2
        [1,2,1],   [1,1,2]
输出: false

思路:基于递归思想,此题首先要知道

1.左右子树都为空的时候返回true;

2.左子树或者右子树为空的时候此时返回false;

3.左子树的值不等于右子树的值返回false;

4.然后递归判断其两个树的左右子树递归下去;

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */


bool isSameTree(struct TreeNode* p, struct TreeNode* q){
    if(p == NULL && q == NULL) return true;
    if(p == NULL || q == NULL ) return false;
    if( p->val - q->val) return false;
    return isSameTree(p->left, q->left) && isSameTree(p->right, q->right);//继续判断两个树
}
101. 对称二叉树

难度简单631

给定一个二叉树,检查它是否是镜像对称的。

例如,二叉树 [1,2,2,3,4,4,3] 是对称的。

    1
   / \
  2   2
 / \ / \
3  4 4  3

但是下面这个 [1,2,2,null,3,null,3] 则不是镜像对称的:

    1
   / \
  2   2
   \   \
   3    3

说明:

如果你可以运用递归和迭代两种方法解决这个问题,会很加分。

image.png

思路:当判断是否是对称二叉树时,我们应该把其左右子树进行比较是否对称;
1.把左右树传进去
2.分别递归两个树,如果全为空返回true,一方为空返回false,值相同时返回true;
3.然后递归判断一个树左子树是否与另一棵树的右子树相同并且一个树的右子树是否与另一棵树的左子树相同;

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */

bool ismirror(struct TreeNode *p, struct TreeNode *q) {
    if(p == NULL &&q == NULL) return true;
    if(p == NULL || q == NULL) return false;
    return  (p->val == q->val) &&ismirror(p->left, q->right) && ismirror(p->right, q->left);
}
bool isSymmetric(struct TreeNode* root){
    if(root == NULL) return true;
    return ismirror(root, root);
}
102. 二叉树的层次遍历

难度中等391

给定一个二叉树,返回其按层次遍历的节点值。 (即逐层地,从左到右访问所有节点)。

例如:
给定二叉树: [3,9,20,null,null,15,7],

    3
   / \
  9  20
    /  \
   15   7

返回其层次遍历结果:

[
  [3],
  [9,20],
  [15,7]
]
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */


/**
 * Return an array of arrays of size *returnSize.
 * The sizes of the arrays are returned as *returnColumnSizes array.
 * Note: Both returned array and *columnSizes array must be malloced, assume caller calls free().
 */

int getDepth(struct TreeNode *root) {//获取子树的最大深度
    if(root == NULL) return 0;
    int l = getDepth(root->left), r = getDepth(root->right);
    return (l > r ? l : r ) +  1;
}

void getCnt(struct TreeNode *root, int k, int *cnt) {//获取每一层有多少个结点
    if(root == NULL) return ;
    cnt[k] += 1;
    getCnt(root->left, k + 1, cnt);
    getCnt(root->right, k + 1, cnt);
    return;
}

void getResult(struct TreeNode *root, int k, int *cnt, int **ret) {//将每一层的结点
    if(root == NULL) return;
    ret[k][cnt[k]++] = root->val;//将每一层的节点对应不同的维度压进去
    getResult(root->left, k + 1, cnt, ret);//继续遍历左子树
    getResult(root->right, k + 1, cnt, ret);//继续遍历右子树
    return;
}


int** levelOrder(struct TreeNode* root, int* returnSize, int** returnColumnSizes){
    int depth = getDepth(root);//先获取树的最大深度
    int **ret = (int **)malloc(sizeof(int *) * depth);//定义一个二维数组,大小为深度
    int *cnt = (int *) calloc(depth, sizeof(int));//定义一个一维数组calloc进行清空大小为深度
    getCnt(root, 0, cnt);//将cnt传入获取对应的每一层有多少个结点
    //cnt[0] = 1, cnt[1] = 2, cnt[2] = 2;
    for(int i = 0; i < depth; i++) {//二维数组每一层存cnt[i]个数,一共有depth层
        ret[i] = (int *)malloc(sizeof(int ) * cnt[i]);
        cnt[i] = 0;//使用过的cnt清空,以便下面使用对应着哪一层
    }
    getResult(root, 0, cnt, ret);//将二维数组进行对应树赋值
    *returnSize = depth;
    *returnColumnSizes = cnt;
    return ret;
}
104. 二叉树的最大深度

难度简单467

给定一个二叉树,找出其最大深度。

二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。

说明: 叶子节点是指没有子节点的节点。

示例:
给定二叉树 [3,9,20,null,null,15,7]

    3
   / \
  9  20
    /  \
   15   7

返回它的最大深度 3 。

**思路:**左子树有一个深度,右子树哟偶一个深度,左右子树的最大深度加上本层就是总的深度,递归处理

int maxDepth(struct TreeNode* root){
    if(root == NULL) return 0;
    int l = maxDepth(root->left), r= maxDepth(root->right);//左子树的深度和右子树的深度
    return (l > r ? l : r) + 1;//左右子树的最大的一个深度加上本层1就是此时结点树的最大深度
}
107. 二叉树的层次遍历 II

难度简单191收藏分享切换为英文关注反馈

给定一个二叉树,返回其节点值自底向上的层次遍历。 (即按从叶子节点所在层到根节点所在的层,逐层从左向右遍历)

例如:
给定二叉树 [3,9,20,null,null,15,7],

    3
   / \
  9  20
    /  \
   15   7

返回其自底向上的层次遍历为:

[
  [15,7],
  [9,20],
  [3]
]
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */


/**
 * Return an array of arrays of size *returnSize.
 * The sizes of the arrays are returned as *returnColumnSizes array.
 * Note: Both returned array and *columnSizes array must be malloced, assume caller calls free().
 */

int getDepth(struct TreeNode *root) {//获取树的最大深度
    if(root == NULL) return 0;
    int l = getDepth(root->left);
    int r = getDepth(root->right);
    return (l > r ? l : r) + 1;
}

void getCnt(struct TreeNode *root, int k , int *cnt) {//获取每一层有多少个结点
    if(root == NULL) return;
    cnt[k] += 1;
    getCnt(root->left, k - 1, cnt);
    getCnt(root->right, k - 1, cnt);
    return;
}

void getResult(struct TreeNode *root, int k, int *cnt, int **ret) {//从下往上进行存储每一层的数据
    if(root == NULL) return ;
    ret[k][cnt[k]++] = root->val;
    getResult(root->left, k - 1, cnt, ret);
    getResult(root->right, k - 1, cnt, ret);
    return ;
}
int** levelOrderBottom(struct TreeNode* root, int* returnSize, int** returnColumnSizes){
    int n = getDepth(root);
    int **ret = (int **) malloc(sizeof(int *) * n);
    int *cnt = (int *)calloc(n, sizeof(int));
    getCnt(root, n - 1, cnt);//树是从下往上
    for(int i = 0; i < n; i++) {
        ret[i] = (int *)malloc(sizeof(int) * cnt[i]);
        cnt[i] = 0;
    }
    getResult(root, n - 1, cnt, ret);
    *returnSize = n;
    *returnColumnSizes = cnt;
    return ret;
}
110. 平衡二叉树

难度简单244

给定一个二叉树,判断它是否是高度平衡的二叉树。

本题中,一棵高度平衡二叉树定义为:

一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过1。

示例 1:

给定二叉树 [3,9,20,null,null,15,7]

    3
   / \
  9  20
    /  \
   15   7

返回 true

示例 2:

给定二叉树 [1,2,2,3,3,null,null,4,4]

       1
      / \
     2   2
    / \
   3   3
  / \
 4   4

返回 false

**思路:**获取一个左右子树的深度,然后进行比较,然后递归左右子树,//不平衡的情况有3种:左树不平衡、右树不平衡、左树和右树差的绝对值大于1 ,//不满足上面3种情况,说明平衡了,树的深度为左右俩子树最大深度+1

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */

/*
int Depth(struct TreeNode *root) {//获取最大的深度
    if(root == NULL) return 0;
    int l = Depth(root->left), r = Depth(root->right);
    return (l > r ? l : r) + 1;
}

bool isBalanced(struct TreeNode* root){
    if(root == NULL) return true;
    int l = Depth(root->left);//获取左右孩子的深度;
    int r = Depth(root->right);
    if(abs(l - r) > 1) return false;//进行比较差值
    return isBalanced(root->left) && isBalanced(root->right);//继续递归比较左右孩子的深度;
}
*/
int Balanced(struct TreeNode *root) {
    if(root == NULL) return 0;
    //不平衡的情况有3种:左树不平衡、右树不平衡、左树和右树差的绝对值大于1
    int left = Balanced(root->left);
    if(left == -1) return -1;
    int right = Balanced(root->right);
    if(right == -1) return -1;
    if(abs(left - right) > 1) return -1;
    //不满足上面3种情况,说明平衡了,树的深度为左右俩子树最大深度+1
    return (left > right ? left : right) + 1;

}
bool isBalanced(struct TreeNode* root){
    return Balanced(root) != -1;
}


/*
int Depth(struct TreeNode *root) {
    if(root == NULL) return 0;
    int l = Depth(root->left), r = Depth(root->right);
    if(l == -2 || r == -2 || abs(l - r) > 1) return -2;
    return (l > r ? l : r) + 1;
}

bool isBalanced(struct TreeNode* root){
    return Depth(root) >= 0;
}
*/
111. 二叉树的最小深度

难度简单216

给定一个二叉树,找出其最小深度。

最小深度是从根节点到最近叶子节点的最短路径上的节点数量。

说明: 叶子节点是指没有子节点的节点。

示例:

给定二叉树 [3,9,20,null,null,15,7],

    3
   / \
  9  20
    /  \
   15   7

返回它的最小深度 2.

**思路:**如果此时左孩子为空,右孩子不为空,返回右边孩子最小深度加上本层(+1),如果左孩子不为空,右孩子为空,返回左孩子加上本层(+1),其他的话(其左右孩子全为空,全为不空时),那就返回走右子树最小的加上本层;

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */
/*
int minDepth(struct TreeNode* root){
    if(root == NULL) return 0;
    if(root->left == NULL && root->right == NULL) return 1;
    if(root->left == NULL ||root->right == NULL) {
        return minDepth(root->left ? root->left : root->right)  + 1;
    }
    return fmin(minDepth(root->left), minDepth(root->right)) + 1;
}
*/
int minDepth(struct TreeNode* root){
    if(root == NULL) return 0;
    if(root->left == NULL && root->right != NULL) {//左孩子为空,右孩子不为空
        return 1 + minDepth(root->right);//右边孩子最小深度+1
    }
    if(root->right == NULL && root->left != NULL) {//左孩子不为空,右孩子为空
        return 1 + minDepth(root->left);//返回左边孩子的最小深度+1
    }
    return fmin(minDepth(root->left), minDepth(root->right)) + 1;//返回左右孩子最小的那个+1
}

112. 路径总和

难度简单245

给定一个二叉树和一个目标和,判断该树中是否存在根节点到叶子节点的路径,这条路径上所有节点值相加等于目标和。

说明: 叶子节点是指没有子节点的节点。

示例:
给定如下二叉树,以及目标和 sum = 22

              5
             / \
           4    8
          /     /  \
        11  13   4
       /  \             \
     7    2             1

返回 true, 因为存在目标和为 22 的根节点到叶子节点的路径 5->4->11->2

**思路:**DFS,记录每一层的值,递归出口:左右孩子为空,此时sum 减去本层为0,就可以判定是否存在路径,因为可能有多条路径,所以要用“||”进行对左孩子右孩子进行递归然后减去本层的值,如果搜到则返回1,直至到递归出口

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */
bool hasPathSum(struct TreeNode* root, int sum){
    if(root == NULL) return false;
    if(root->left == NULL && root->right == NULL) {
        return sum - root->val == 0;
    }
    return (hasPathSum(root->left, sum - root->val) || hasPathSum(root->right, sum -root->val));
}
226. 翻转二叉树

难度简单373

翻转一棵二叉树。

示例:

输入:

     4
   /   \
  2     7
 / \   / \
1   3 6   9

输出:

     4
   /   \
  7     2
 / \   / \
9   6 3   1

思路:如何翻转一个二叉树,只有左右对应的孩子进行交换才能进行反转,所以得设置一个中间变量进行反转二叉树,然后进行递归左右孩子

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */
struct TreeNode* invertTree(struct TreeNode* root){
    if(root == NULL)return NULL;
        struct TreeNode *s;
        s = root->left;
        root->left = root ->right;
        root->right = s;
        invertTree(root->left);
        invertTree(root->right);
    return root;
}
235. 二叉搜索树的最近公共祖先

难度简单240

给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。

百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”

例如,给定如下二叉搜索树: root = [6,2,8,0,4,7,9,null,null,3,5]

img

示例 1:

输入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 8
输出: 6 
解释: 节点 2 和节点 8 的最近公共祖先是 6。

示例 2:

输入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 4
输出: 2
解释: 节点 2 和节点 4 的最近公共祖先是 2, 因为根据定义最近公共祖先节点可以为节点本身。

说明:

  • 所有节点的值都是唯一的。
  • p、q 为不同节点且均存在于给定的二叉搜索树中。

**思路:**如何判断其最近的公共祖先,可以分为三种情况
1.如果此时值小于p->val,q->val,那么肯定就得往右找合适的祖先
2.如果此时值大于p->val,q->val, 那么肯定就得往左找合适的祖先
3.如果找到的值在他们两个之间,那么肯定就是所要找的公共祖先

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */
struct TreeNode* lowestCommonAncestor(struct TreeNode* root, struct TreeNode* p, struct TreeNode* q) {
    if(root == NULL) return root;
    if(root ->val  < p->val && root ->val < q->val) {
        return lowestCommonAncestor(root->right, p, q);
    }else if(root ->val  > p->val && root ->val > q->val) {
        return lowestCommonAncestor(root->left, p, q);
    } else {
        return root;
    }
}

257. 二叉树的所有路径

难度简单213

给定一个二叉树,返回所有从根节点到叶子节点的路径。

说明: 叶子节点是指没有子节点的节点。

示例:

输入:

   1
 /   \
2     3
 \
  5

输出: ["1->2->5", "1->3"]

解释: 所有根节点到叶子节点的路径为: 1->2->5, 1->3

**思路:**二叉树有多条路径,我们可以把他的多条路径存在一个二维数组里,获取二叉树有路径个数,然后将他们分别存在相互对应的路径里,

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */
/*
void dfs(struct TreeNode *root, char **bin_tree_paths, int *path, int *return Size, int depth) {
    int i = 0;
    path[depth++] = root->val;
    if(root->left == NULL && root->right == NULL) {
        bin_tree_path[*returnSize] = (char *)malloc(sizeof(char) * 100);
        bin_tree_path[*returnSize][0] = 0;
        for(i = 0; i < depth - 1; i ++) {
            sprintf(bin_tree_paths[*returnSize], "%s%d", bin_tree_paths[*returnSize], path[i]);
        }
    }
}*/

/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
/*
char ** binaryTreePaths(struct TreeNode* root, int* returnSize){
    int path[100] = {0}, depth = 0;
    char ** bin_tree_path = (char **)malloc(sizeof(char *) * 100);
    if(root == NULL) return root;
    *returnSize = 0;
    dfs(root, bin_tree_path, path, returnSize, depth);
    return bin_tree_paths;
}*/
int getPathCnt(struct TreeNode *root) {//获取路径个数
    if(root == NULL) return 0;
    if(root ->left == NULL && root->right == NULL) return 1;
    return getPathCnt(root->left) + getPathCnt(root->right);
}

int getResult(struct TreeNode *root, int len, int k, char **ret, char *buff) {//len是每条路径元素个数,k表示第几条路
    if(root == NULL) return 0;
    len += sprintf(buff + len, "%d", root->val);//当加入数时表示此时路径中元素个数len+"",buff存储此时路径
    buff[len] = 0;//将buff置为零
    if(root->left == NULL && root->right == NULL) {
        ret[k] = strdup(buff);//如果走到叶子节点时,那么将buff存储的路径给二维数组的第k层
        return 1;
    }
    len += sprintf(buff + len, "->");//将箭头加入buff;
    int cnt  = getResult(root->left, len, k, ret, buff);//往左搜
    cnt += getResult(root->right, len,k+cnt,ret,buff );//往右子树搜
    return cnt;
}

char ** binaryTreePaths(struct TreeNode* root, int* returnSize){
    int pathCnt = getPathCnt(root);//获取路径的个数
    char **ret = (char **)malloc(sizeof(char *) * pathCnt);//开辟一个字符型的二维数组;
    int max_len = 1024;
    char *buff = (char * )malloc(sizeof(char) * max_len);//存储每个路径里的所有元素
    getResult(root, 0, 0, ret, buff);
    *returnSize = pathCnt;
    return ret;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值
>