程序员面试金典: 9.4树与图 4.9在二叉树中,打印结点数值总和等于给定值的所有路径
来源:互联网 发布:课程与教学论 知乎 编辑:程序博客网 时间:2024/06/05 02:56
#include <iostream>#include <stdio.h>#include <vector>#include <string>using namespace std;/*问题:给定一颗二叉树,其中每个结点都含有一个数值。设计一个算法,打印结点数值总和等于某个给定值的所有路径。 注意,路径不一定非得从二叉树的根节点或叶节点开始或结束。分析:如果采用暴力破解,对每个结点都去计算路径,判断路径结点值是否等于给定值,则时间复杂度至少为O(N!),这肯定 不行,想到用栈来做,但是对于是否需要设置访问标记无法确定。书上的解法:向上检查是否得到总和。关注“这个结点是否为总和为给定值的某条路径的末端”注意:当找到总和,需要继续访问路径,因为可能存在其他数值总和为0的结点序列输入:7(第一棵树的结点个数n) 12(给定总和)6 3 9 1 4 2 5(第一棵树的所有结点的值,接下来共有n行,每一行表示当前第i个结点对应孩子结点的下标)d(表示有两个孩子结点,后面跟两个孩子结点的下标) 2 3d 4 5 z(无孩子结点)r(只有右孩子结点,后跟右孩子结点下标) 6r 7zz输出:6 3 1 2,3 4 5关键:1 向上检查是否得到总和。关注“这个结点是否为总和为给定值的某条路径的末端”注意:当找到总和,需要继续访问路径,因为可能存在其他数值总和为0的结点序列时间复杂度为O( N log(N) ),n个结点,每个结点平均需要向上计算高度为log(N),//从当前结点开始向上遍历寻找路径,并对其左右孩子递归处理void findSum(TreeNode* head , int sum , vector<int>& vecPath , int level){if(NULL == head){return;}//将当前结点值插入路径vecPath.push_back(head->_value);//最经典的部分,向上遍历int total = 0;for(int i = level ; i >= 0 ; i--){total += vecPath.at(i);//注意,即使找到,仍然要继续查找,易错if(total == sum){printPath(vecPath , i , level);}}//递归对孩子结点处理findSum(head->_pLeft , sum , vecPath , level+1);findSum(head->_pRight , sum , vecPath , level+1);//处理完成后,需要将当前结点移除,因为如果是从其他分支结点进入,则当前结点是不需要的,易错vecPath.pop_back();}*/const int MAXSIZE = 10000;typedef struct TreeNode{int _value;TreeNode* _pLeft;TreeNode* _pRight;TreeNode* _pParent;}TreeNode;TreeNode g_treeNodeArray[MAXSIZE];int g_index;TreeNode* createTreeNode(){++g_index;g_treeNodeArray[g_index]._pLeft = g_treeNodeArray[g_index]._pRight = g_treeNodeArray[g_index]._pParent = NULL;return &g_treeNodeArray[g_index];}void buildTree(vector<int>& vecData){if(vecData.empty()){return;}int value ;string childFlag;int leftIndex ;int rightIndex;int size = vecData.size();for(int index = 1 ; index <= size; index++){cin >> childFlag;g_treeNodeArray[index]._value = vecData.at(index-1);if("d" == childFlag){cin >> leftIndex >> rightIndex;g_treeNodeArray[index]._pLeft = &g_treeNodeArray[leftIndex];g_treeNodeArray[leftIndex]._pParent = &g_treeNodeArray[index];g_treeNodeArray[index]._pRight = &g_treeNodeArray[rightIndex];g_treeNodeArray[rightIndex]._pParent = &g_treeNodeArray[index];}else if("l" == childFlag){cin >> leftIndex;g_treeNodeArray[index]._pLeft = &g_treeNodeArray[leftIndex];g_treeNodeArray[leftIndex]._pParent = &g_treeNodeArray[index];}else if("r" == childFlag){cin >> rightIndex;g_treeNodeArray[index]._pRight = &g_treeNodeArray[rightIndex];g_treeNodeArray[rightIndex]._pParent = &g_treeNodeArray[index];}}}int max(int a, int b){return a > b ? a : b;}int getDepth(TreeNode* head){if(NULL == head){return 0;}return max( getDepth(head->_pLeft) , getDepth(head->_pRight) ) + 1;}void printPath(vector<int>& vecPath , int begin , int end){for(int i = begin ; i <= end; i++){cout << vecPath.at(i) << " ";}cout << ",";}//从当前结点开始向上遍历寻找路径,并对其左右孩子递归处理void findSum(TreeNode* head , int sum , vector<int>& vecPath , int level){if(NULL == head){return;}//将当前结点值插入路径vecPath.push_back(head->_value);//最经典的部分,向上遍历int total = 0;for(int i = level ; i >= 0 ; i--){total += vecPath.at(i);//注意,即使找到,仍然要继续查找,易错if(total == sum){printPath(vecPath , i , level);}}//递归对孩子结点处理findSum(head->_pLeft , sum , vecPath , level+1);findSum(head->_pRight , sum , vecPath , level+1);//处理完成后,需要将当前结点移除,因为如果是从其他分支结点进入,则当前结点是不需要的,易错vecPath.pop_back();}TreeNode* findRoot(TreeNode* node){if(NULL == node){return NULL;}if(node->_pParent == NULL){return node;}else{return findRoot(node->_pParent);}}void process(){int nodeNum;int sum;vector<int> vecData;int value;while(cin >> nodeNum >> sum){vecData.clear();g_index = 0;for(int i = 0 ; i < nodeNum ; i++){cin >> value;vecData.push_back(value);}buildTree(vecData);TreeNode* root = findRoot(&g_treeNodeArray[1]);int depth = getDepth(root);//寻找路径vector<int> vecPath;findSum(root , sum , vecPath , 0);cout << endl;}}int main(int argc, char* argv[]){process();getchar();return 0;}
0 0
- 程序员面试金典: 9.4树与图 4.9在二叉树中,打印结点数值总和等于给定值的所有路径
- 节点数值总和等于某个给定值的所有路径
- 给定一棵二叉树,和一个数值。求二叉树的路径和等于给定值的所有路径
- 【31】给定一个二叉树打印出所有从根结点到叶子结点路径和为 k 的路径
- 【31】给定一个二叉树打印出所有从根结点到叶子结点路径和为 k 的路径
- 求tree中节点之间路径总和等于给定数值的算法
- 打印出二叉树中结点值的和为输入整数的所有路径
- 打印结点和等于某个值的所有路径
- 程序员面试金典: 9.4树与图 4.6找出二叉查找树指定结点的下一个结点
- 二叉树的路径和为给定数值的所有路径
- 《剑指Offer》面试题:打印出二叉树中结点值的和为输入整数的所有路径
- 【算法-java】打印出二叉树中结点值的和为输入整数的所有路径
- 剑指offer_输入一颗二叉树和一个整数,打印出二叉树中结点值的和为输入整数的所有路径
- 输入一颗二叉树和一个整数,打印出二叉树中结点值的和为输入整数的所有路径(剑指offer)
- java实现输入一颗二叉树和一个整数,打印出二叉树中结点值的和为输入整数的所有路径
- 打印二叉树根结点到所有叶子结点的路径
- 面试100题:4.在二叉树中找出和为某一值的所有路径
- 4.在二元树中找出和为某一值的所有路径 题目:输入一个整数和一棵二元树。 从树的根结点开始往下访问一直到叶结点所经过的所有结点形成一条路径。 打印出和与输入整数相等的所有路径。
- 80C51 K1控制D1发光
- Color Map Optimization for 3D Reconstruction with Consumer Depth Cameras
- 模拟Json加载数据(淘宝购物车效果1)
- 决策树、ID3、C4.5以及CART算法小结
- 直接拿来用!最火的Android开源项目(一)
- 程序员面试金典: 9.4树与图 4.9在二叉树中,打印结点数值总和等于给定值的所有路径
- 学OpenGL 遇到的坑
- 自己写bootloader------汇编---第1阶段(学习笔记)
- 使用dockerfile来创建环境镜像images
- java实验六 接口与实现
- KVM虚拟化技术
- java list判空
- Android Framework学习起步
- 17 - 01 - 20 计算机网络(10)(IP地址分配)