leetcode 437. 路径总和 III / 剑指 Offer II 050. 向下的路径节点之和 -前缀和

地址 https://leetcode-cn.com/problems/6eUYwP/

一道树的遍历,求树中一个子树,其权值为指定值。

暴力做法

对树进行遍历,计算所有子树的求和。每遍历一个节点,计算所有 以 该节点和其父节点组成的子树的权值,并进行比较这里通过一个数组去保存所有的权值。然后去遍历其孩子。

遇到的坑

  1. ArrayList对元素的修改
    当数组中元素是对象时,存储的是句柄,可以直接对值进行修改。但当元素是Integer 或int时,get得到元素后,再修改是无效的。这里用到arrayist.set(index,value)的api实现修改。
  2. 数组为空
    日常忘记判断,传入的对象需要先判断null
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {

    int count = 0;
    int targe ;
    public int pathSum(TreeNode root, int targetSum) {
        targe = targetSum;
        f(root,new ArrayList());
        return count;
    }

    public void f(TreeNode root ,ArrayList<Integer> list){
        if(root == null)
            return;
        Integer val = root.val;
        list.add(0);
        for(int i=0;i<list.size();i++){
            list.set(i, list.get(i)+ val);
            if(list.get(i) == targe){
                count ++;
            }
        }
        if(root.left != null){
            f(root.left,list);
        }
        if(root.right != null){
            f(root.right,list);
        }
        list.remove(val);
        for(int i=0;i<list.size();i++){
            list.set(i, list.get(i)- val);
        }
    }
}

前缀和

和暴力做法有点相似。暴力中用数组记录了每条路径的权重,需要动态增加和删除。这里通过前缀和来记录。

为了描述方便,将树退化为数组,也可以认为是考虑树中某一条路径。
5-4-3 ,5是root,3是叶子。

      5-4-3  从root 到叶子
     0-5-9-12  # 前缀和

当目标是7时,对应的子树是4-3,那么这条路径的补就是5。 当遍历到“3”时,前缀和是12,如果在路径中存在一段路径权重为5,那么必然存在一段路径,且以3结尾,权重为7。我们要去找的就是当前路径的补。

class Solution {
    HashMap<Integer,Integer> map = new HashMap();
    int count = 0;
    public int pathSum(TreeNode root, int targetSum) {
        int cur =0;
        map.put(0,1);// baozheng root 
        f(root,cur,targetSum);
        return count;
    }

    public void f(TreeNode root ,int cur,int targetSum){
        if(root == null)
           return;

        cur += root.val;
        count += map.getOrDefault(cur-targetSum,0);// !!!
        
        map.put(cur,map.getOrDefault(cur,0)+1);// !!!
        
        f(root.left,cur,targetSum);
        f(root.right,cur,targetSum);
        map.put(cur,map.getOrDefault(cur,0)-1);

    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值