[B003]パスツリー和III(再帰|蓄積インターバル|とプレフィックス)

一つ、タイトル説明

You are given a binary tree in which each node contains an integer value.

Find the number of paths that sum to a given value.

The path does not need to start or end at the root or a leaf, 
but it must go downwards (traveling only from parent nodes to child nodes).

The tree has no more than 1,000 nodes and the values are in the range -1,000,000 to 1,000,000.

Example:
root = [10,5,-3,3,2,null,11,3,-2,null,1], sum = 8
      10
     /  \
    5   -3
   / \    \
  3   2   11
 / \   \
3  -2   1

Return 3. The paths that sum to 8 are:
1.  5 -> 3
2.  5 -> 2 -> 1
3. -3 -> 11

第二に、問題解決

方法の一つ:再帰

*私はほとんどが困惑しています。このタイトルは初めてです。

  • Q1:なぜ多層再帰を使用しています。
    A1は:後でパスの最初に発見されたルート・ノードではないかもしれない、リーフノードの終わりではないかもしれません。私たちが望むように、初めとして、各ノードは、列挙各ノードに行きます。

他とI、IIまたは変わりません。

int cnt;
public int pathSum(TreeNode root, int sum) {
  if (root == null)
      return 0;
  dfs(root, sum);
  pathSum(root.left, sum);
  pathSum(root.right, sum);
  return cnt;
}
void dfs(TreeNode root, int re) {
  if (root == null) {
      return;
  }
  if (re == root.val) {
      cnt++;
  }
  dfs(root.left, re-root.val);
  dfs(root.right, re-root.val);
}

複雑性分析

  • 時間計算: ザ・ n個 2 O(N ^ 2)
  • 宇宙の複雑さ: ザ・ n個 O(N)

方法2:蓄積部

パス内の各ノードのために、私たちは、パスの一致があるかどうかを確認するために戻っノード列挙からです。

  • Q1:私はパス、直接終端サイクルを見つけることができた後?
    A1:反例ルート= [0,1,1]、和=であり 1、 答えは4です。
  • Q2:なぜ反復が前方リストから?
    A2:この組み合わせは、前のノードとの接合部の終わりを保証することができますので。
    • たとえば、次の背面に少なくとも一つの前部が横断する場合はA1の反例は、1考え、[1,0]は、検討しました。
int cnt = 0;
int sum = 0;
List<Integer> path = null;
public int pathSum(TreeNode root, int target) {
  sum = target;
  path = new ArrayList<>();
  dfs(root);
  return cnt;
}
private void dfs(TreeNode root) {
  if (root == null) {
      return;
  }
  path.add(root.val);
  int t = 0;
  for (int i = path.size()-1; i >= 0; i++) {
      t += path.get(i);
      if (t == sum) {
          cnt++;
          //break; 不能提前break [1],[1,0]
      }
  }
  dfs(root.left);
  dfs(root.right);
  path.remove(path.size()-1);
}

複雑性分析

  • 時間計算: ザ・ n個 2 O(N ^ 2)
  • 宇宙の複雑さ: ザ・ n個 O(N)

方法2:接頭辞と

マップはCUR和があれば、我々はノードCUR和現在のノード・パスから来るようになったことを証明することは正当なパスです。例えば:私たちは、その合計=パス11を知っています。我々はリーフノード3を行って、経路21、21 --11 = 10の合計は、プレフィクス10及び地図があってもよいです。

ボトムライン:あなたは接頭辞を持っているとし、CUR場合 - (CUR - - 合計)パスの合計が、また、現在およびCURのために、差CURがなければなりません。

      10
     / 
    5
   /
  3  
 / 
3  
int cnt = 0;
int sum = 0;
int cur = 0;
Map<Integer, Integer> map = null;

public int pathSum(TreeNode root, int target) {
   map = new HashMap<>();
   map.put(0, 1);
   sum = target;
   dfs(root);
   return cnt;
}
private void dfs(TreeNode root) {
   if (root == null) {
       return;
   }
   cur += root.val;
   cnt += map.getOrDefault(cur - sum, 0);
   map.put(cur, map.getOrDefault(cur, 0) + 1);
   dfs(root.left);
   dfs(root.right);
   // 回溯
   cur -= root.val;
   map.put(cur, map.get(cur) - 1);
}

複雑性分析

  • 時間計算: ザ・ n個 O(N)
  • 宇宙の複雑さ: ザ・ n個 O(N)
公開された495元の記事 ウォンの賞賛105 ・は 30000 +を見て

おすすめ

転載: blog.csdn.net/qq_43539599/article/details/104828300