剑指offer(二十四):二叉树中和为某一值的路径

题目描述

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

思路:中序递归遍历或者先序递归遍历,栈中所存结点为当前结点的所有祖先结点,因此设置一个vector用来存储当前栈中的结点值,当走到叶子结点时,判断当前的结点和是否为给定值,弹出结点,每一轮递归返回到父结点时,需要将最后一个结点删除

class Solution {
    vector<vector<int> > result;
    vector<int> tmp;
public:
    vector<vector<int> > FindPath(TreeNode* root,int expectNumber) {
        
        if(root){
            tmp.push_back(root->val);
            if(!root->left && !root->right){
                if(sum(tmp) == expectNumber)
                    result.push_back(tmp);
            }
            FindPath(root->left,expectNumber);
            FindPath(root->right,expectNumber);
            tmp.pop_back();
        }
        return result;
    }
    int sum(vector<int> v){
        int sum = 0;
        for(int i=0;i<v.size();i++){
            sum+=v[i];
        }
        return sum;
    }
};

优化:

class Solution {
    vector<vector<int> > result;
    vector<int> tmp;
public:
    vector<vector<int> > FindPath(TreeNode* root,int expectNumber) {
        
        if(root){
            tmp.push_back(root->val);
            if(!root->left && !root->right && root->val == expectNumber)
                    result.push_back(tmp);
            FindPath(root->left,expectNumber-root->val);
            FindPath(root->right,expectNumber-root->val);
            tmp.pop_back();
        }
        return result;
    }
    
};

评论区有人说要求:在返回值的list中,数组长度大的数组靠前,那就排一下序吧

class Solution {
    vector<vector<int> > result;
    vector<int> tmp;
public:
    static bool cmp(vector<int> a,vector<int>b){
        return a.size()>b.size();
    }
    vector<vector<int> > FindPath(TreeNode* root,int expectNumber) {
        
        if(root){
            tmp.push_back(root->val);
            if(!root->left && !root->right && root->val == expectNumber)
                result.push_back(tmp);
            FindPath(root->left,expectNumber-root->val);
            FindPath(root->right,expectNumber-root->val);
            tmp.pop_back();
        }
        if(result.size()>0){
            sort(result.begin(),result.end(),cmp);
        }
        return result;
    }
    
};

注意cmp函数要加static,否则会报reference to non-static member function must be called!这个错误,原因是由于参数不匹配的问题,我们普通的成员函数都有一个隐含的this指针,即cmp函数看上去只有两个参数,但实际有三个参数,即bool cmp(Solution* this,vector<int> a,vector<int>b),而我们调用sort排序函数的时候指传入了两个参数,所以就出现了形参和实参不匹配的现象,

解决办法就是将cmp函数定义为static成员函数,静态成员函数没有this指针;或者将cmp函数放在类外,变为普通函数

 使用java实现:

import java.util.Collections;
import java.util.Comparator;
public class Solution {
    ArrayList<ArrayList<Integer>> result = new ArrayList<ArrayList<Integer>>();
    ArrayList<Integer> tmp = new ArrayList<Integer>();
    public ArrayList<ArrayList<Integer>> FindPath(TreeNode root,int target) {
        
        FindPath(root, target,result,tmp);
        //排序
        Collections.sort(result,new Comparator<ArrayList<Integer>>(){
            public int compare(ArrayList<Integer> o1,ArrayList<Integer> o2){
                return o2.size()-o1.size();
            }
        });
        return result;
    }
    //为避免每次递归都要进行排序,因此把主要函数写在了外面
    public void FindPath(TreeNode root,int target,ArrayList<ArrayList<Integer>> result, ArrayList<Integer> tmp){
        if(root != null){
            tmp.add(root.val);
            if(root.left == null && root.right == null && root.val == target)
                result.add(new ArrayList<>(tmp));
            FindPath(root.left,target-root.val);
            FindPath(root.right,target-root.val);
            tmp.remove(tmp.size()-1);
        }
    }
}

红色部分要注意ArrayList的浅拷贝问题,此时要新建一个ArrayList对象。

原文地址:https://www.cnblogs.com/ttzz/p/13514627.html