• 剑指offer-二叉树中和为某一值的路径


    描述

    输入一颗二叉树的根节点和一个整数,按字典序打印出二叉树中结点值的和为输入整数的所有路径。路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。

    解决思路:

    1. 注意这里的路径是根节点到叶子节点的遍历顺序,所以难度并不是很大(思路类似于dfs,单写起来比dfs更简单)
    2. 其实遍历目标路径很简单,主要就路径记录的问题(dfs方便记录路径),我这里就用个成员变量记录了,有点小作弊的感觉。
     1 class Solution {
     2 private:
     3     vector<vector<int>> res;
     4 public:
     5     vector<vector<int> > FindPath(TreeNode* root,int expectNumber) {
     6         // dfs吧 9         // 首先,怎么记录路径呢?11         // 用类成员变量?带检验路径需要逐层记录,所以需要另写递归函数
    12         if(root==nullptr){
    13             return res;
    14         }
    15         vector<int> cp;
    16         CalPath(root,expectNumber,cp);
    17         return res;    // 感觉有点像作弊
    18     }
    19     
    20     // 尽量用dfs,不然路径不好记录
    21     // 遍历到某节点时,如果总和大于aim,那么就返回空向量
    22     // 如果等于aim,就返回该向量
    23     // 如果小于aim,就继续遍历,并记录目前的路径
    24     void CalPath(TreeNode* root,int aim,vector<int> cp){
    25         cp.push_back(root->val);
    26         // 叶子节点作为递归出口
    27        if(root->left==nullptr && root->right==nullptr){ 
    28             if(root->val==aim){
    29                 res.push_back(cp);
    30             }
    31             return;
    32         }
    33          // 非叶子节点
    34         if(root->val>=aim){   // 这里最好释放一下cp向量的栈空间
    35             return;
    36         }else{
    37             if(root->left!=nullptr) CalPath(root->left, aim-root->val, cp);
    38             if(root->right!=nullptr) CalPath(root->right, aim-root->val, cp);
    39         }
    40     }
    41 };

    如果是根节点到任意节点的路径,可采用如下代码(核心算法是正确的,但边界问题我没处理了)

     1 /*
     2 struct TreeNode {
     3     int val;
     4     struct TreeNode *left;
     5     struct TreeNode *right;
     6     TreeNode(int x) :
     7             val(x), left(NULL), right(NULL) {
     8     }
     9 };*/
    10 class Solution {
    11 private:
    12     vector<vector<int>> res;
    13 public:
    14     vector<vector<int> > FindPath(TreeNode* root,int expectNumber) {
    15         // dfs吧17         // 这里根节点是固定,就不用考虑子树根节点了
    18         // 首先,怎么记录路径呢?
    19         // 遍历到下一层时,有的路径是正确,有些是不正确的
    20         // 用类成员变量?带检验路径需要逐层记录,所以需要另写递归函数
    21         vector<int> cp;
    22         CalPath(root,expectNumber,cp);
    23         return res;    // 感觉有点像作弊
    24     }
    25     
    26     // 尽量用dfs,不然路径不好记录
    27     // 遍历到某节点时,如果总和大于aim,那么就返回空向量
    28     // 如果等于aim,就返回该向量
    29     // 如果小于aim,就继续遍历,并记录目前的路径
    30     void CalPath(TreeNode* root,int aim,vector<int> cp){
    31         if(root==nullptr){
    32             return;
    33         }
    34         cp.push_back(root->val);
    35         if(root->val==aim){
    36             res.push_back(cp);
    37             return;
    38         }else if(root->val>aim){
    39             return;
    40         }else{
    41             CalPath(root->left, aim-root->val, cp);
    42             CalPath(root->right, aim-root->val, cp);
    43         }
    44     }
    45     
    46 };
    心之所愿,永不相忘
  • 相关阅读:
    SQL SERVER 2005中同义词实例
    内聚性是模块之所以成为模块的原因--一个中心、单一职责
    软件开发的方法论
    系统集成与软件开发
    编程的本质是构建---建构你想要表达的世界
    编程思想与以人为本-编程的本质
    软件开发之道-软件开发背后的哲学
    swift 协议(结合扩展)的特点
    swift的特性:扩展、协议、泛型
    从数据流角度管窥 Moya 的实现(一):构建请求
  • 原文地址:https://www.cnblogs.com/zgll/p/15072464.html
Copyright © 2020-2023  润新知