257.给定一个二叉树,返回所有从根节点到叶子节点的路径。
说明: 叶子节点是指没有子节点的节点。
- 该题虽然说是简单题,但做起来却不那么简单,依旧是可以利用递归或者迭代法来解,但是在编写递归函数就犯了难。如何才能一个路径不漏地利用递归解出这个题呢?通过看题解有了一下代码:通过前序遍历递归地求解每个路径;其中用一个path数组来存储每条路径中非叶结点的值,当递归到叶子结点的时候,将path数组中的值一个一个取出来利用sprintf函数拼接成一个字符串,在接上当前结点的值,形成一条路径存储到结果数组中。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
void getPath(struct TreeNode* cur, char** res, int* returnSize, int* path, int i) {
if (cur != NULL) { //当前结点不为空才进行处理
//当前结点为叶节点,开始将path数组中存的数取出来进行拼接路径
if (cur->left == NULL && cur->right == NULL) {
//用于存储拼接的字符串
char *temp = malloc(sizeof(char) * 1000);
//用于辅助将path数组中的字符存入temp中
int len = 0;
for (int j = 0; j < i; j++) {
//sprintf函数能够将格式化字符串输出到指定地址处,返回写入的字符数
len += sprintf(temp + len, "%d->", path[j]);
}
//将当前的结点加到temp后面
sprintf(temp + len, "%d", cur->val);
res[(*returnSize)++] = temp;
} else { //当前结点不是叶节点,将当前结点的值存入path数组中然后开始递归
path[i++] = cur->val;
getPath(cur->left, res, returnSize, path, i);
getPath(cur->right, res, returnSize, path, i);
}
}
}
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
char ** binaryTreePaths(struct TreeNode* root, int* returnSize){
//结果数组
char **res = (char **)malloc(sizeof(char *) * 2000);
//路径条数
*returnSize = 0;
//用于暂存路径
int* path = malloc(sizeof(int) * 2000);
//用于指向path数组中的某一个元素
int i = 0;
getPath(root, res, returnSize, path, i);
return res;
}
注意在设计递归函数时,传入一个变量i用于指向path数组,这个变量很关键,在获得路径之后,可能会连续引起多个递归函数的结束,变量i的值对应的也会产生变化,这称为回溯,相当于将path数组中后面几个结点删除,回到二叉树的某个分叉路口,走向另外一条路径。
- 该题还能用迭代法解,有空再说吧。