常见数据结构面试题目(四)
2015-04-01 22:30
302 查看
题目:
输入一个整数和一棵二元树。从树的根结点开始往下访问一直到叶结点所经过的所有结点形成一条路径。打印出和与输入整数相等的所有路径。
例如输入整数 22 ,如下图二元树:
10
/ \
5 12
/ \
4 7
则打印出两条路径:10, 12和10, 5, 7。
思路:
有三种方法:
(1)找出并记录下从根节点到叶子节点的所有路径,对每条路径进行尝试,找到路径上节点和为输入整数的路径。
(2)改造普通二元树为双向二元树,通过指针便可查找相邻的上下级节点。遍历二元树,可找到树上的叶子节点。满足条件路径是叶子到根节点路径的子集。由叶子节点向上查找,当路径上节点和为输入整数,并且到达跟节点时,此路径满足条件。
(3)此方法参考/article/7799387.html。算法中涉及递归和回溯。由根节点向叶子节点遍历,记录下遍历路径。当到达叶子节点,并且路径和为输入整数,则此路径满足条件;否则该路径自动废弃。
方法一与方法二思路基本一致,遍历二元树找出所有全通路径,针对每一条计算经过节点的和,找到符合条件的路径。代码实现如下:
输入一个整数和一棵二元树。从树的根结点开始往下访问一直到叶结点所经过的所有结点形成一条路径。打印出和与输入整数相等的所有路径。
例如输入整数 22 ,如下图二元树:
10
/ \
5 12
/ \
4 7
则打印出两条路径:10, 12和10, 5, 7。
思路:
有三种方法:
(1)找出并记录下从根节点到叶子节点的所有路径,对每条路径进行尝试,找到路径上节点和为输入整数的路径。
(2)改造普通二元树为双向二元树,通过指针便可查找相邻的上下级节点。遍历二元树,可找到树上的叶子节点。满足条件路径是叶子到根节点路径的子集。由叶子节点向上查找,当路径上节点和为输入整数,并且到达跟节点时,此路径满足条件。
(3)此方法参考/article/7799387.html。算法中涉及递归和回溯。由根节点向叶子节点遍历,记录下遍历路径。当到达叶子节点,并且路径和为输入整数,则此路径满足条件;否则该路径自动废弃。
方法一与方法二思路基本一致,遍历二元树找出所有全通路径,针对每一条计算经过节点的和,找到符合条件的路径。代码实现如下:
//记录所有从根节点到叶子节点的路径 private static List<List<Node>> paths=new ArrayList<List<Node>>(); //获得所有到子节点的路线,记录到path中 private static void getAllPaths(List<Node> path , Node node){ path.add(node); if(node.getLeft() == null && node.getRight()==null){//node为叶子节点 paths.add(path); return; } Node left = node.getLeft(); if(left != null){ List<Node> leftPath = new ArrayList<Node>(); leftPath.addAll(path); getAllPaths(leftPath, left); } Node right = node.getRight(); if(right !=null){ List<Node> rightPath = new ArrayList<Node>(); rightPath.addAll(path); getAllPaths(rightPath, right); } } //寻找路径上节点和为sum的路径 private static void getCorrectPath(int sum){ List<List<Node>> corPath = new ArrayList<List<Node>>(); for(List<Node> path : paths){ int total = 0; for(Node node : path){ total += node.getValue(); } if(total == sum){ corPath.add(path); } } for(List<Node> path : paths){ for(Node node :path){ System.out.print(node.getValue() + " "); } System.out.println(); } }方法三核心代码如下:
//sum表示整数值,top为经过路径的节点个数,path用来存放路径节点。 //符合条件的路径满足两个条件:1)sum逐一减去经过节点值后为0。2)节点节点时叶子节点 void findPath(BiTreeNode *root, int sum,int top,int path[]) { path[top++] = root->data; //所经过节点存入数据路径中 sum -= root->data; if (root->left == NULL && root->right==NULL) { if (sum == 0) { printPath(path, top); //满足条件节点,输出路径 } } else { if (root->left != NULL) findPath(root->left, sum, top,path); if (root->right!=NULL) findPath(root->right, sum, top,path); } top --; //回溯,当返回后,路径长度减一 sum += root->data; //sum值回溯 }方法三成功利用递归函数返回特性,程序走完一条路径后,会自动返回分歧节点,沿另一条路径继续执行,由此可遍历完成所有根节点到叶子节点的路径。当回到分歧节点后,重点是恢复状态值,即sum与path值。此方法通过path记录所经过路径,且对于公共路径进行了重复利用。
相关文章推荐
- 常见数据结构面试题目(二)
- 常见数据结构面试题目(一)
- 常见数据结构面试题目(三)
- C++面试常见题目问与答(汇总一)
- Java常见笔试面试题目解析(十):Java中检查的异常与未检查的异常
- 我思故我在系列—数据结构面试NO.24(题目搜集整理者JULY,非常感谢!!)
- 我思故我在系列—数据结构面试NO.30题(题目搜集整理者JULY,非常感谢!!)
- 数据结构常见面试(1)
- Oracle常见面试题目
- 数据结构面试之八——图的常见操作2之最短路径
- 最全常见算法工程师面试题目整理
- 面试10大算法汇总以及常见题目解答
- Java面试常见题目汇总(主要是概念)
- 常见的abap面试题目,请大家对照学习
- 面试中常见递归题目 Java版
- PHP常见面试题目深入解答分析(二)
- Android面试题目之常见的填空题和简答题
- 常见面试笔试编程题目
- Linux 笔试面试常见题目
- 大数据常见面试题目