【LeetCode每日一题】——257.二叉树的所有路径

一【题目类别】

二【题目难度】

  • 简单

三【题目编号】

  • 257.二叉树的所有路径

四【题目描述】

给定一个二叉树,返回所有从根节点到叶子节点的路径。
说明: 叶子节点是指没有子节点的节点。

五【题目示例】

  • 示例:
    输入:

          1
        /     \
      2       3
        \
         5

输出: [“1->2->5”, “1->3”]
解释: 所有根节点到叶子节点的路径为: 1->2->5, 1->3

六【解题思路】

  • 使用递归,保存每一个节点的状态(就是当前节点值),如果是非叶子节点,继续向左或向右递归,并且将本节点的状态(当前节点值)传入到下一个递归,方便下一个节点计算到下一个节点的值,这里计算每次将传入的值10+当前节点值就是当前结点的状态值,如果遇到叶子节点,找到了一条路径,把之前路径的状态值10+当前节点值就是这条路径的值,以此类推递归即可

七【时间频度】

  • 时间复杂度:因为需要遍历每个结点,所以时间复杂度为 O ( N ) O(N) O(N)

八【代码实现】

  1. Java语言版
package Tree;

import java.util.ArrayList;
import java.util.List;

public class p257_BinaryTreePaths {

    p257_BinaryTreePaths left;
    p257_BinaryTreePaths right;
    int val;

    p257_BinaryTreePaths() {

    }

    p257_BinaryTreePaths(int val) {
        this.val = val;
    }

    public static void main(String[] args) {
        p257_BinaryTreePaths root = new p257_BinaryTreePaths(1);
        p257_BinaryTreePaths left1 = new p257_BinaryTreePaths(2);
        p257_BinaryTreePaths left2 = new p257_BinaryTreePaths(5);
        p257_BinaryTreePaths right = new p257_BinaryTreePaths(3);
        root.left = left1;
        left1.right = left2;
        root.right = right;
        p257_BinaryTreePaths p257_binaryTreePaths = new p257_BinaryTreePaths();
        List<String> res = p257_binaryTreePaths.binaryTreePaths(root);
        System.out.println("res = " + res);
    }

    public List<String> binaryTreePaths(p257_BinaryTreePaths root) {
        List<String> list = new ArrayList<String>();
        // 如果root节点为null,直接返回list
        if (root == null) {
            return list;
        }
        // 如果是叶子节点,说明一条路径已经找到就把当前结点的值加入到list中,并返回
        if (root.left == null && root.right == null) {
            list.add(Integer.toString(root.val));
            return list;
        }
        // 首先新建左子树的路径集合,这里因为是递归,每一次返回一条路径
        List<String> leftPath = new ArrayList<String>();
        // 然后使用这个list接收返回的一条路径,使用增强for循环遍历
        leftPath = binaryTreePaths(root.left);
        for (String left : leftPath) {
            // 使用StringBufferi字符串缓冲提供对每一个节点值的存储
            // 首先我们需要把头结点root加入进来
            // 因为root.val是数字,最后要求字符串存储,所以需要转换一下
            StringBuffer sb = new StringBuffer(Integer.toString(root.val));
            // 因为题目要求以->分割,所以加入->
            sb.append("->");
            // 加入当前遍历到的节点值
            sb.append(left);
            // 加入最终结果集
            list.add(sb.toString());
        }
        // 右子树同理,不再赘述
        List<String> rightPath = new ArrayList<String>();
        rightPath = binaryTreePaths(root.right);
        for (String right : rightPath) {
            StringBuffer sb = new StringBuffer(Integer.toString(root.val));
            sb.append("->");
            sb.append(right);
            list.add(sb.toString());
        }
        return list;
    }

}
  1. C语言版
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

struct TreeNode
{
	int val;
	struct TreeNode *left;
	struct TreeNode *right;
};

void p257_BinaryTreePaths_getRes(struct TreeNode* root, char** res, int* returnSize, int* path, int pathIndex)
{
	/*空结点返回NULL*/
	if (root == NULL)
	{
		return NULL;
	}
	/*遇到叶子结点把这条路径放到结果数组中*/
	if (root->left == NULL && root->right == NULL)
	{
		char* temp = (char*)malloc(sizeof(char*) * 1001);
		int len = 0;
		for (int i = 0; i < pathIndex; i++)
		{
			len += sprintf(temp + len, "%d->", path[i]);
		}
		sprintf(temp + len, "%d", root->val);
		res[(*returnSize)++] = temp;
	}
	/*如果不是叶子节点加入到路经数组中*/
	else
	{
		path[pathIndex++] = root->val;
	}
	/*向左子树递归*/
	p257_BinaryTreePaths_getRes(root->left, res, returnSize, path, pathIndex);
	/*向右子树递归*/
	p257_BinaryTreePaths_getRes(root->right, res, returnSize, path, pathIndex);
}

char ** binaryTreePaths(struct TreeNode* root, int* returnSize)
{
	/*结果数组*/
	char** res = (char**)malloc(sizeof(char*) * 1001);
	/*结果数组指针,也是返回的结果数组长度*/
	*returnSize = 0;
	/*存放路径数组*/
	int path[1001];
	/*路经数组指针*/
	int pathIndex = 0;
	/*开始递归*/
	p257_BinaryTreePaths_getRes(root, res, returnSize, path, pathIndex);
	/*返回结果*/
	return res;
}

/*主函数省略*/

九【提交结果】

  1. Java语言版
    在这里插入图片描述

  2. C语言版
    在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

IronmanJay

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值