二叉树路径和--只记录和&记录路径

一、问题描述

1、只记录和
给定一棵二叉树和一个和,确定树是否有从根到叶的路径,使得沿路径加起来的所有值等于给定的总和。
【示例】
给定下面的二叉树 以及待求和 sum = 22,
          5
        /   \
      4     8
     /     /  \
   11  13   4
   /  \     \
 7    2      1

返回 true, 因为存在一个从根到叶的路径:5->4->11->2 和为:22.

2、记录路径

给定一个二叉树和一个和,找到每个路径的总和等于给定总和的所有根到叶路径。

【举例】给定下面的二叉树,以及和 sum = 22,
            5
         /     \
       4       8
      /       /   \
   11     13    4
   /  \    /  \
 7    2  5   1
返回:
[
   [5,4,11,2],
   [5,8,4,5]

]

二、解题思路

1、只记录和
几个注意点:
    1)题目要求返回true/false,不需要记录路径
    2)给定结点没说是正整数,因此必须走到叶子结点才知道是否找到,没法剪枝,只能朴素深度搜索

    3)一旦找到sum结果,立即return

2、记录路径

dfs

三、解题算法

1、只记录和
/*********************************************
Author:tmw
date:2018-5-8
*********************************************/
#include <stdio.h>
#include <stdlib.h>

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

bool hasPathSum(TreeNode* root, int sum)
{
    if( !root ) return false;

    /**走到叶子结点,判断当前sum值与叶子结点值是否相等**/
    if( root->left == NULL && root->right == NULL )
        return root->val == sum;
    /**没走到叶子结点:左右孩子都可以走,更新sum**/
    return hasPathSum(root->left,sum-root->val) || hasPathSum(root->right,sum-root->val);
}
2、记录路径
/*******************************************
Author:tmw
date:2018-5-8
*******************************************/
#include <stdio.h>
#include <stdlib.h>

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

/**
 *returnSize  -- 返回的结果数组有多少组
 **columnSizes -- 返回的结果数组每一组有多少个元素
*/
#define MAX_SIZE 1000
/**
    *cur_array : 用于暂存中间值
    **result  : 最终满足和为sum的所有路径
    *colmn_size : 用于记录每条路径有多少元素
**/
int i=0;
int count = 0;
int colmn_size[MAX_SIZE];
void get_pathSum( TreeNode* root, int sum, int* cur_array, int** result )
{
    if( root==NULL ) return;

    cur_array[i++] = root->val;

    /**当遍历到叶子结点时,判断该路径下的和值是否满足sum,满足则记录到result数组中**/
    if( root->left == NULL && root->right == NULL )
    {
        /**满足则记录到result数组中**/
        if( root->val == sum )
        {
            int j;
            for( j=0; j<i; j++ )
                result[count][j] = cur_array[j];
            colmn_size[count] = i;
            count++;
        }
    }

    /**记录左子树路径**/
    get_pathSum( root->left, sum-root->val, cur_array, result);
    /**记录右子树路径**/
    get_pathSum( root->right, sum-root->val, cur_array, result);
}

int** pathSum(TreeNode* root, int sum, int** columnSizes, int* returnSize)
{
    if( root == NULL ) return NULL;

    /**自定义二维的结果数组,用来存储最终结果并返回**/
    int** result = (int**)malloc(MAX_SIZE*sizeof(int*));
    int ii;
    for( ii=0; ii<MAX_SIZE; ii++ )
        result[ii] = (int*)malloc(MAX_SIZE*sizeof(int));

    /**自定义临时一维数组用于暂存结果值**/
    int* temp_res = (int*)malloc(MAX_SIZE*sizeof(int));

    get_pathSum(root,sum,temp_res,result);

    /**赋值**/
    *returnSize = count;
    printf("%d",count);
    for( ii=0;ii<count;ii++ )
        (*columnSizes)[ii] = colmn_size[ii];

    return result;
}

梦想还是要有的,万一实现了呢~~~ヾ(◍°∇°◍)ノ゙~~~~


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值