zoukankan      html  css  js  c++  java
  • 面试题34:二叉树中和为某一值的路径(C++)

    题目地址:https://leetcode-cn.com/problems/er-cha-shu-zhong-he-wei-mou-yi-zhi-de-lu-jing-lcof/

    题目描述

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

    题目示例

    示例:
    给定如下二叉树,以及目标和 sum = 22,

          5
          /     
        4        8
       /         /
      11      13  4
      /            /
     7   2        5  1
    返回:

    [
    [5,4,11,2],
    [5,8,4,5]
    ]

    解题思路

    思路1:首先分析题目,发现可以利用先序遍历实现,即“根元素->左子树->右子树”,在先序遍历实现时,我们使用path记录根节点到当前节点的路径,如果当前节点的路径中的各元素值恰好等于目标值sum时,则将此路径加入到结果集res中,递归左右子树,向上回溯。需要注意的是,如果要将此路径加入到结果集中的条件,即当前节点为叶子节点且路径各元素值恰好等于sum值。

    思路2:利用中序遍历以及栈的方法解决,思路先序遍历差不多,需要注意的是中序遍历顺序是“左子树 ->根节点 ->右子树”。

    程序源码

    先序遍历+回溯(递归)

    /**
     * Definition for a binary tree node.
     * struct TreeNode {
     *     int val;
     *     TreeNode *left;
     *     TreeNode *right;
     *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
     * };
     */
    class Solution {
        vector<vector<int>> res; //存储决策路径
        vector<int> path; //存储决策元素值
    public:
        vector<vector<int>> pathSum(TreeNode* root, int sum) {
            if(root == nullptr) return {};
            prior_sort(root, sum);
            return res;
        }
        void prior_sort(TreeNode* root, int sum)
        {
            if(root == nullptr) return;
            path.push_back(root->val); //1.加入决策路径path
            sum -= root->val; //更新sum值
            if(sum == 0 && root->left == nullptr && root->right == nullptr) //2.找到可行解,加入结果集中
            {
                res.push_back(path);
            }
            //3.进入下一次决策
            prior_sort(root->left, sum);
            prior_sort(root->right, sum);
            path.pop_back(); //4.移出决策路径,即向上回溯,将当前节点从路径path中移出
        }
    };

    中序遍历+非递归

    /**
     * Definition for a binary tree node.
     * struct TreeNode {
     *     int val;
     *     TreeNode *left;
     *     TreeNode *right;
     *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
     * };
     */
    class Solution {
    
    public:
        vector<vector<int>> pathSum(TreeNode* root, int sum) {
            if(root == nullptr) return {};
            stack<TreeNode*> sk;
            TreeNode* node = root, *prev_node = nullptr; //prev_node表示上一已被访问节点
            vector<vector<int>> res; //存储决策路径
            vector<int> path; //存储决策元素值
            int tmp_sum = 0;
            while(!sk.empty() || node != nullptr)
            {
                if(node != nullptr)
                {
                    tmp_sum += node->val;
                    path.push_back(node->val);
                    sk.push(node);
                    node = node->left; //一直往左遍历左子树
                }
                else
                {
                    node = sk.top(); //不能往左了,取得根节点
                    if(node->right == nullptr || node->right == prev_node)
                    {
                        if(node->left == nullptr && node->right == nullptr && tmp_sum == sum)
                        {
                            res.push_back(path);
                        }
                        path.pop_back();
                        tmp_sum -= node->val;
                        sk.pop();
                        prev_node = node; //标记已使用
                        node = nullptr; //回溯
                    }
                    else
                    {
                        node = node->right; //往右遍历右子树
                    }
                }
            }
        return res;
        }
    };
    ----------------------------------- 心之所向,素履所往;生如逆旅,一苇以航。 ------------------------------------------
  • 相关阅读:
    Spring 依赖注入:简单的HelloWorld例子
    浮动元素margin负值的应用
    小球拖动吸附
    三栏布局
    ES6学习之路1
    绝对定位模拟固定定位效果...
    jQuery中的一些小技巧
    探究css帧动画setps()用处
    你所不知道的cursor妙用
    正则表达式
  • 原文地址:https://www.cnblogs.com/wzw0625/p/12862741.html
Copyright © 2011-2022 走看看