111. 二叉树的最小深度

本文探讨了如何通过深度优先搜索(DFS)和广度优先搜索(BFS)算法求解LeetCode上最小二叉树深度问题。深度优先方法遇到递归宏定义导致超时,而广度优先采用队列实现逐层遍历,展示了自定义结构体队列的解决方案。

地址:

力扣https://leetcode-cn.com/problems/minimum-depth-of-binary-tree/

题目:

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

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

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

示例 1:

输入:root = [3,9,20,null,null,15,7]
输出:2


示例 2:

输入:root = [2,null,3,null,4,null,5,null,6]
输出:5
 

提示:

树中节点数的范围在 [0, 105] 内
-1000 <= Node.val <= 1000

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/minimum-depth-of-binary-tree
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路:

对于题目描述概念说明:

叶子节点的最小深度 = 1

父节点的最小深度依赖于其下的子节点,取其最小深度的最小值 ,再加 1

比如:

节点4,左子节点 = 1, 右子节点 = 1,所以节点 4 = 1+1

节点2,只有左子节点,那么节点 2 = 2+1

整个图示可以看出求根节点的最小深度就是遍历其子节点的最小深度

典型的递归

方法一、深度优先(DFS)

/**
 * 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;
		
	int min = INT_MAX;
	
	if(root->left)
	{
		min = fmin(min, minDepth(root->left));
	}
	
	if(root->right)
	{
		min = fmin(min, minDepth(root->right));
	}
	
	return min + 1;
}

需要注意一点:

最开始时使用了常用的 宏定义求最小值

结果再最后一组大数据时超时

// cause timeout
#define mymin(a,b) ( (a) < (b) ? (a) : (b) )

其原因在于:

宏定义只是简单的替换,如果参数是单纯的数,其实没问题

但是如果参数是需要一定计算的内容,像这里的还用的是递归函数

那么传入时计算一次,返回时又计算一次,这个量级就超级大了

方法二、广度优先(BFS)

不同于深度优先从叶子节点倒推,广度优先是从根节点开始遍历每一层,直到找到第一个叶子节点

根节点值等于 1

 

对于每一层的遍历,我们用 队列 来实现

1. 从根节点开始,入队

2. 循环操作:

        2.1 出队

        2.2 如果该节点是叶子节点,循环结束,返回深度

        2.3 如果有子节点,再入队子节点

这样的操作可以达到每一层的遍历,不过我们还面临一个问题

就是深度这个栏位没有,如果可以改变已有结构体,添加栏位最方便,像这样:

但是实际不会让你这么做,怎么处理呢?

我们只能做一个包裹,做一个自定义的结构体队列:

struct myTreeNode {
    struct TreeNode node;
    int dept;
};

 就能解决这个问题

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

struct myTreeNode {
    struct TreeNode node;
    int dept;
};



int enqueue(struct myTreeNode* queue, int len, int *rear, struct TreeNode* data, int dept)
{
	if(*rear == len) // fulll
		return -1;
	
	//printf("enqueue...rear=%d, val=%d, dept=%d\n", *rear, data->val, dept);
	queue[*rear].node = *data;
    queue[*rear].dept = dept;
	(*rear)++;

	return 0;
}

struct myTreeNode* dequeue(struct myTreeNode* queue, int len, int *front, int *rear)
{
	if(*front == *rear) // empty
		return NULL;
	
	int idx = *front;
	if(idx == len - 1)
	{
		*front = 0;
		*rear = 0;
	}
	else
		(*front)++;
		
	//printf("dequeue...front=%d, rear=%d, val=%d, dept=%d\n", *front, *rear, queue[idx].node.val, queue[idx].dept);

	return &queue[idx];
}

int isEmpty(int front, int rear)
{
	return front == rear ? 1:0;
}

int minDepth(struct TreeNode* root){
    if(root == NULL)
        return 0;

    struct myTreeNode queue[QUEUELEN];
    int front = 0;
    int rear = 0;

    struct myTreeNode* mynode;
    enqueue(queue, QUEUELEN, &rear, root, 1);

    while(! isEmpty(front, rear))
	{
        mynode = dequeue(queue, QUEUELEN, &front, &rear);
        if(mynode->node.left == NULL && mynode->node.right == NULL)
        {
            return mynode->dept;
        }
        
        if(mynode->node.left)
            enqueue(queue, QUEUELEN, &rear, mynode->node.left, mynode->dept + 1);
        
        if(mynode->node.right)
            enqueue(queue, QUEUELEN, &rear, mynode->node.right, mynode->dept + 1);
	}
	
	return 0; // never come here
}




查看更多刷题笔记

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值