leecode 解题总结:129. Sum Root to Leaf Numbers

#include <iostream>
#include <stdio.h>
#include <vector>
#include <string>
#include <sstream>
using namespace std;
/*
问题:
Given a binary tree containing digits from 0-9 only, each root-to-leaf path could represent a number.

An example is the root-to-leaf path 1->2->3 which represents the number 123.

Find the total sum of all root-to-leaf numbers.

For example,

    1
   / \
  2   3
The root-to-leaf path 1->2 represents the number 12.
The root-to-leaf path 1->3 represents the number 13.

Return the sum = 12 + 13 = 25.

分析:此题实际上就是要求出从根节点到叶子结点的所有路径,将各个路径上代表的数字求和。
从根节点遍历到叶子结点,可以用递归。
如果当前结点为空,直接返回;
如果当前结点为叶子结点,说明已经到达末尾,将叶子结点的值压入结果,将结果存入到结果集;
其余情况表明结点是非叶子节点,需要递归遍历左子树,设返回的结果leftStrs(应该是一个集合),
递归遍历右子树,返回的结果为rightStrs,
则当前结点返回: 将sCur 与 sLeft集合中的每个字符串 组成新的字符串集合lefts,
将sCur 与 rightStrs中每个字符串组成的新的字符串集合rights
将lefts和rights合并成新的结果集results返回
遍历results中每个元素求和
    1
   / \
  2   3
4  5 6  7

输入:
3(二叉树结点个数)
1 2 3(每个结点的值)
5
1 2 3 4 5 N N
1
1
2
1 2
输出:
25
262
1
12

关键:
1 一种更简单的方法,高位在顶部:可以采用 10 * n + val的形式
将左右子树的和累加并返回。由于高位已经传入,每次是高位 * 10然后加上当前位,保证了正确性
2 方法2:如果当前是非叶子节点,需要递归遍历左子树,设返回的结果leftStrs(应该是一个集合),
递归遍历右子树,返回的结果为rightStrs,
则当前结点返回: 将sCur 与 sLeft集合中的每个字符串 组成新的字符串集合lefts,
将sCur 与 rightStrs中每个字符串组成的新的字符串集合rights
*/

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

	//value是高位的值
	int sum(TreeNode* root , int value)
	{
		if(!root)
		{
			return 0;
		}
		int curValue = value * 10 + root->val;
		if(NULL == root->left && NULL == root->right)
		{
			return curValue;
		}
		int leftSum = sum(root->left , curValue);
		int rightSum = sum(root->right , curValue);
		return (leftSum + rightSum);
	}

    int sumNumbers(TreeNode* root) {
		//初始的时候,高位为0
        int result = sum(root , 0);
		return result;
	}

	vector<string> dfs(TreeNode* root)
	{
		vector<string> results;
		if(!root)
		{
			return results;
		}
		stringstream stream;
		stream << root->val;
		string num = stream.str();
		//如果是叶子结点,直接返回该叶子结点的值
		if(NULL == root->left && NULL == root->right)
		{
			results.push_back(num);
			return results;
		}
		vector<string> leftResults = dfs(root->left);
		vector<string> rightResults = dfs(root->right);
		//拼接当前结点的值
		if(!leftResults.empty())
		{
			int leftSize = leftResults.size();
			for(int i = 0 ; i < leftSize ; i++)
			{
				results.push_back(num + leftResults.at(i));
			}
		}
		if(!rightResults.empty())
		{
			int rightSize = rightResults.size();
			for(int i = 0 ; i < rightSize ; i++)
			{
				results.push_back(num + rightResults.at(i));
			}
		}
		return results;
	}

    int sumNumbers2(TreeNode* root) {
        vector<string> results = dfs(root);
		if(results.empty())
		{
			return 0;
		}
		int size = results.size();
		int sum = 0;
		for(int i = 0 ; i < size ; i++)
		{
			sum += atoi(results.at(i).c_str());
		}
		return sum;
    }
};

//构建二叉树,这里默认首个元素为二叉树根节点,然后接下来按照作为每个结点的左右孩子的顺序遍历
//这里的输入是每个结点值为字符串,如果字符串的值为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 process()
{
	 vector<string> nums;
	 string value;
	 int num;
	 Solution solution;
	 vector<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);
		 int maxSum = solution.sumNumbers(root);
		 cout << maxSum << endl;
		 deleteBinaryTree(root);
	 }
}

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


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。
经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值