• 《Cracking the Coding Interview》——第4章:树和图——题目9


    2014-03-19 05:07

    题目:给定一棵二叉树T和一个值value,在T中找出所有加起来和等于value的路径。路径的起点和终点都可以是树的任意节点。

    解法:我偷了个懒,直接把这棵树看成一个无向图,用DFS来进行暴力搜索解决问题。因为没有什么数据顺序或是范围的限制,所以搜索剪枝好像也不太容易。

    代码:

      1 // 4.9 Find all paths in a binary tree, the path doesn't have to start or end at the root or a leaf node.
      2 #include <cstdio>
      3 #include <unordered_map>
      4 #include <unordered_set>
      5 using namespace std;
      6 
      7 struct TreeNode {
      8     int val;
      9     TreeNode *left;
     10     TreeNode *right;
     11     
     12     TreeNode(int _val = 0):val(_val), left(nullptr), right(nullptr) {};
     13 };
     14 
     15 void constructTree(TreeNode *&root)
     16 {
     17     int val;
     18     
     19     scanf("%d", &val);
     20     if (val == 0) {
     21         root = nullptr;
     22     } else {
     23         root = new TreeNode(val);
     24         constructTree(root->left);
     25         constructTree(root->right);
     26     }
     27 }
     28 
     29 void constructGraph(TreeNode *root, unordered_map<TreeNode *, unordered_set<TreeNode *> > &graph)
     30 {
     31     if (root->left != nullptr) {
     32         graph[root].insert(root->left);
     33         graph[root->left].insert(root);
     34         constructGraph(root->left, graph);
     35     }
     36     
     37     if (root->right != nullptr) {
     38         graph[root].insert(root->right);
     39         graph[root->right].insert(root);
     40         constructGraph(root->right, graph);
     41     }
     42 }
     43 
     44 void DFS(TreeNode *node, vector<TreeNode *> &path, int sum, const int target, 
     45          unordered_set<TreeNode *> &checked, 
     46          unordered_map<TreeNode *, unordered_set<TreeNode *> > &graph, vector<vector<TreeNode *> > &result)
     47 {
     48     path.push_back(node);
     49     checked.insert(node);
     50     
     51     if (sum == target) {
     52         result.push_back(path);
     53     }
     54     unordered_set<TreeNode *>::iterator it;
     55     for (it = graph[node].begin(); it != graph[node].end(); ++it) {
     56         if (checked.find(*it) == checked.end()) {
     57             DFS(*it, path, sum + (*it)->val, target, checked, graph, result);
     58         }
     59     }
     60     
     61     checked.erase(node);
     62     path.pop_back();
     63 }
     64 
     65 void doDFS(TreeNode *root, vector<TreeNode *> &path, const int target, 
     66          unordered_set<TreeNode *> &checked, 
     67          unordered_map<TreeNode *, unordered_set<TreeNode *> > &graph, vector<vector<TreeNode *> > &result)
     68 {
     69     path.clear();
     70     checked.clear();
     71     DFS(root, path, root->val, target, checked, graph, result);
     72     if (root->left != nullptr) {
     73         doDFS(root->left, path, target, checked, graph, result);
     74     }
     75     if (root->right != nullptr) {
     76         doDFS(root->right, path, target, checked, graph, result);
     77     }
     78 }
     79 
     80 void clearTree(TreeNode *&root)
     81 {
     82     if (root == nullptr) {
     83         return;
     84     }
     85     
     86     if (root->left != nullptr) {
     87         clearTree(root->left);
     88     }
     89     if (root->right != nullptr) {
     90         clearTree(root->right);
     91     }
     92     delete root;
     93     root = nullptr;
     94 }
     95 
     96 int main()
     97 {
     98     int i, j;
     99     int target;
    100     TreeNode *root;
    101     unordered_map<TreeNode *, unordered_set<TreeNode *> > graph;
    102     unordered_map<TreeNode *, unordered_set<TreeNode *> >::iterator it;
    103     unordered_set<TreeNode *> checked;
    104     vector<TreeNode *> path;
    105     vector<vector<TreeNode *> > result;
    106     
    107     while (true) {
    108         constructTree(root);
    109         if (root == nullptr) {
    110             break;
    111         }
    112         constructGraph(root, graph);
    113         while (scanf("%d", &target) == 1 && target) {
    114             doDFS(root, path, target, checked, graph, result);
    115             if (result.empty()) {
    116                 printf("No path is found.
    ");
    117             } else {
    118                 for (i = 0; i < (int)result.size(); ++i) {
    119                     printf("%d", result[i][0]->val);
    120                     for (j = 1; j < (int)result[i].size(); ++j) {
    121                         printf("->%d", result[i][j]->val);
    122                     }
    123                     result[i].clear();
    124                     printf("
    ");
    125                 }
    126                 result.clear();
    127             }
    128             path.clear();
    129             checked.clear();
    130         }
    131         for (it = graph.begin(); it != graph.end(); ++it) {
    132             (it->second).clear();
    133         }
    134         graph.clear();
    135         clearTree(root);
    136     }
    137     
    138     return 0;
    139 }
  • 相关阅读:
    初学 Delphi 嵌入汇编[13] 地址参数用 [] 取值
    初学 Delphi 嵌入汇编[17] 逻辑运算
    初学 Delphi 嵌入汇编[11] 用汇编重写一个 Delphi 函数
    初学 Delphi 嵌入汇编[12] 在汇编代码中可以直接使用 Result
    初学 Delphi 嵌入汇编[19] Delphi 的无符号整数类型
    分享:tcpproxy实现
    Socket编程之简单介绍 蓝天下的雨 博客园
    分享:libuv 中文编程指南
    分享:《编程之美》求二叉树中节点的最大距离
    CentOS6.0下编译最新版本boost库
  • 原文地址:https://www.cnblogs.com/zhuli19901106/p/3610481.html
Copyright © 2020-2023  润新知