leecode 解题总结:257. Binary Tree Paths

本文介绍了一种算法,用于寻找二叉树中从根节点到叶节点的所有路径,并提供了详细的实现步骤与代码示例。
#include <iostream>
#include <stdio.h>
#include <vector>
#include <string>
#include <sstream>
using namespace std;
/*
问题:
Given a binary tree, return all root-to-leaf paths.

For example, given the following binary tree:

   1
 /   \
2     3
 \
  5
All root-to-leaf paths are:

["1->2->5", "1->3"]

分析:给定一颗二叉树,找出所有从根节点到叶节点的路径。
遍历当前结点,用栈存储当前结点,如果当前结点是叶节点,就将当前路径保存到结果集中;
并弹出当前叶子结点,
否则,左孩子不空,递归处理左孩子;
右孩子不空,递归处理右孩子。
这还是一个回溯问题,压入当前结点,递归处理左右孩子之后,还需要弹出当前结点
用vector就行了

			 1
		2			3
	4	   5	6		7
  8   9  10 11 12 13       15

输入:
5(二叉树结点个数)
1 2 3 N 5
1
1
2
1 2
15
1 2 3 4 5 6 7 8 9 10 11 12 13 N 15
输出:
1->2->5, 1->3
1
1->2
1->2->4->8, 1->2->4->9, 1->2->5->10, 1->2->5->11, 1->3->6->12, 1->3->6->13, 1->3->7->15

关键:
1 遍历当前结点,用栈存储当前结点,如果当前结点是叶节点,就将当前路径保存到结果集中;
并弹出当前叶子结点,
否则,左孩子不空,递归处理左孩子;
右孩子不空,递归处理右孩子。
这还是一个回溯问题,压入当前结点,递归处理左右孩子之后,还需要弹出当前结点
用vector就行了

2 把叶节点先压入,再弹出,否则漏掉最后叶子结点
result.push_back(root->val);
results.push_back(result);
result.pop_back()
*/

struct TreeNode {
    int val;
    TreeNode *left;
    TreeNode *right;
    TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};

class Solution {
public:
	void dfs(TreeNode* root , vector<int>& result , vector<vector<int>>& results)
	{
		if(!root)
		{
			return ;
		}
		//如果当前结点是叶子结点,直接拷贝结果
		if(NULL == root->left && NULL == root->right)
		{
			//把叶节点先压入,再弹出,否则漏掉最后叶子结点
			result.push_back(root->val);
			results.push_back(result);
			result.pop_back();
			return;
		}

		//其余情况就回溯处理
		result.push_back(root->val);
		if(root->left)
		{
			dfs(root->left , result , results);
		}
		if(root->right)
		{
			dfs(root->right , result , results);
		}
		result.pop_back();
	}

    vector<string> binaryTreePaths(TreeNode* root) {
		vector<string> realResults;
		if(!root)
		{
			return realResults;
		}
        vector<int> result;
		vector<vector<int> > results;
		dfs(root , result , results);
		//生成最终结果
		if(results.empty())
		{
			return realResults;
		}
		int size = results.size();
		int len;
		for(int i = 0 ; i < size ; i++)
		{
			stringstream stream;
			len = results.at(i).size();
			for(int j = 0 ; j < len ; j++)
			{
				if(j)
				{
					stream << "->" << results.at(i).at(j);
				}
				else
				{
					stream << results.at(i).at(j);
				}
			}
			realResults.push_back(stream.str());
		}
		return realResults;
    }
};

//构建二叉树,这里默认首个元素为二叉树根节点,然后接下来按照作为每个结点的左右孩子的顺序遍历
//这里的输入是每个结点值为字符串,如果字符串的值为NULL表示当前结点为空
TreeNode* buildBinaryTree(vector<string>& nums)
{
	if(nums.empty())
	{
		return NULL;
	}
	int size = nums.size();
	int j = 0;
	//结点i的孩子结点是2i,2i+1
	vector<TreeNode*> nodes;
	int value;
	for(int i = 0 ; i < size ; i++)
	{
		//如果当前结点为空结点,自然其没有左右孩子结点
		if("N" == nums.at(i))
		{
			nodes.push_back(NULL);
			continue;
		}
		value = atoi(nums.at(i).c_str());
		TreeNode* node = new TreeNode(value);
		nodes.push_back(node);
	}
	//设定孩子结点指向,各个结点都设置好了,如果但钱为空结点,就不进行指向
	for(int i = 1 ; i <= size ; i++)
	{
		if(NULL == nodes.at(i-1))
		{
			continue;
		}
		if(2 * i <= size)
		{
			nodes.at(i-1)->left = nodes.at(2*i - 1);
		}
		if(2*i + 1 <= size)
		{
			nodes.at(i-1)->right = nodes.at(2*i);
		}
	}
	//设定完了之后,返回根节点
	return nodes.at(0);
}

void deleteBinaryTree(TreeNode* root)
{
	if(!root)
	{
		return;
	}
	if(NULL == root->left && NULL == root->right)
	{
		delete root;
		root = NULL;
	}
	if(root)
	{
		deleteBinaryTree(root->left);
		deleteBinaryTree(root->right);
	}
}

void print(vector<string>& result)
{
	if(result.empty())
	{
		cout << "no result" << endl;
		return;
	}
	int size = result.size();
	for(int i = 0 ; i < size ; i++)
	{
		cout << result.at(i) << " " ;
	}
	cout << endl;
}

void process()
{
	 vector<string> nums;
	 string value;
	 int num;
	 Solution solution;
	 vector<string > result;
	 while(cin >> num )
	 {
		 nums.clear();
		 for(int i = 0 ; i < num ; i++)
		 {
			 cin >> value;
			 nums.push_back(value);
		 }
		 TreeNode* root = buildBinaryTree(nums);
		 result = solution.binaryTreePaths(root);
		 print(result);
		 deleteBinaryTree(root);
	 }
}

int main(int argc , char* argv[])
{
	process();
	getchar();
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值