广度优先搜索(层序遍历),深度优先搜索(前序、中序、后序,包含莫里斯遍历)递归和迭代(单栈、双栈),求解《1302. 层数最深叶子节点的和》

2022-08-17 22:43:42
广度优先搜索(层序遍历),深度优先搜索(前序、中序、后序,包含莫里斯遍历)递归和迭代(单栈、双栈),求解《1302. 层数最深叶子节点的和》

例题

给你一棵二叉树的根节点 root ,请你返回 层数最深的叶子节点的和 。
示例 1:
输入:root = [1,2,3,4,5,null,6,7,null,null,null,null,8]
输出:15
示例 2:

输入:root = [6,7,8,2,7,1,3,9,null,1,4,null,null,null,5]
输出:19
提示:
树中节点数目在范围 [1, 104] 之间。
1 <= Node.val <= 100

答案

广度优先搜索

var deepestLeavesSum = function(root) { // 队列 + shift + 实现
  const q = [root]
  let sum = 0
  while (q.length) {
    let l = q.length
    sum = 0
    while (l--) {
      const n = q.shift()
      sum += n.val
      if (n.left) q.push(n.left) 
      if (n.right) q.push(n.right)
    }
  }
  return sum
}; 
function deepestLeavesSum(root: TreeNode | null): number { // 队列 + 指针 + 实现
  const q = [root]
  let start = 0, end = 1, sum = 0
  while (start < end) {
    let l = end
    sum = 0
    while (start < l) {
      const n = q[start++]
      sum += n.val
      if (n.left) q[end++] = n.left
      if (n.right) q[end++] = n.right
    }
  }
  return sum
};
class Solution {
  function deepestLeavesSum($root) {
    $q = [$root];
    $sum = 0;
    while (count($q)) {
      $l = count($q);
      $sum = 0;
      while ($l--) {
        $n = array_shift($q);
        $sum += $n->val;
        if ($n->left) array_push($q, $n->left);
        if ($n->right) array_push($q, $n->right);
      }
    }
    return $sum;
  }
}
func deepestLeavesSum(root *TreeNode) int {
  q, sum := []*TreeNode{root}, 0
  for len(q) > 0 {
    l := len(q)
    sum = 0
    for l > 0 {
      l--
      n := q[0]
      sum += n.Val
      q = q[1:]
      if n.Left != nil {
        q = append(q, n.Left)
      }
      if n.Right != nil {
        q = append(q, n.Right)
      }
    }
  }
  return sum
}
class Solution {
  public int deepestLeavesSum(TreeNode root) {
    Deque<TreeNode> q = new ArrayDeque<TreeNode>();
    q.add(root);
    int sum = 0;
    while (q.isEmpty() == false) {
      int l = q.size();
      sum = 0;
      while (l-- > 0) {
        TreeNode n = q.pollFirst();
        sum += n.val;
        if (n.left != null) q.add(n.left);
        if (n.right != null) q.add(n.right);
      }
    }
    return sum;
  }
}
public class Solution {
  public int DeepestLeavesSum(TreeNode root) {
    Queue<TreeNode> q = new Queue<TreeNode>();
    q.Enqueue(root);
    int sum = 0;
    while (q.Count > 0) {
      int l = q.Count;
      sum = 0;
      while (l-- > 0) {
        TreeNode n = q.Dequeue();
        sum += n.val;
        if (n.left != null) q.Enqueue(n.left);
        if (n.right != null) q.Enqueue(n.right);
      }
    }
    return sum;
  }
}
int deepestLeavesSum(struct TreeNode* root){
  struct TreeNode** q = malloc(sizeof(struct TreeNode*) * 1e4);
  q[0] = root;
  int start = 0, end = 1, sum = 0;
  while (start < end) {
    int l = end;
    sum = 0;
    while (start < l) {
      struct TreeNode* n = q[start++];
      sum += n->val;
      if (n->left) q[end++] = n->left;
      if (n->right) q[end++] = n->right;
    }
  }
  return sum;
}
class Solution {
public:
  int deepestLeavesSum(TreeNode* root) {
    queue<TreeNode*> q;
    q.push(root);
    int sum = 0;
    while (q.size()) {
      int l = q.size();
      sum = 0;
      while (l--) {
        TreeNode* n = q.front();
        q.pop();
        sum += n->val;
        if (n->left) q.push(n->left);
        if (n->right) q.push(n->right);
      }
    }
    return sum;
  }
};
class Solution: # List 实现
  def deepestLeavesSum(self, root: Optional[TreeNode]) -> int:
    q, ans = [root], 0
    while len(q):
      l, ans = len(q), 0
      while l:
        l, n = l - 1, q.pop(0)
        ans += n.val
        if n.left: q.append(n.left)
        if n.right: q.append(n.right)
    return ans
class Solution: # deque 实现
  def deepestLeavesSum(self, root: Optional[TreeNode]) -> int:
    q = deque([root])
    while q:
      ans = 0
      for _ in range(len(q)):
        n = q.popleft()
        ans += n.val
        if n.left: q.append(n.left)
        if n.right: q.append(n.right)
    return ans

深度优先搜索 · 后序遍历 · 递归

var deepestLeavesSum = function(root) {
  let sum = [], maxDepth = -1
  ;(function d(n, depth) {
    if (n === null) return maxDepth = Math.max(maxDepth, depth - 1);
    d(n.left, depth + 1)
    d(n.right, depth + 1)
    if (maxDepth === depth) sum[depth] = (sum[depth] || 0) + n.val
  })(root, 0)
  return sum[sum.length - 1]
};
var deepestLeavesSum = function(root) {
  let sum = 0, maxDepth = -1, curMaxDepth = -1
  ;(function d(n, depth) {
    if (n === null) return maxDepth = Math.max(maxDepth, depth - 1);
    d(n.left, depth + 1)
    d(n.right, depth + 1)
    if (maxDepth === depth) {
      if (curMaxDepth === depth) sum += n.val
      else {
        curMaxDepth = depth
        sum = n.val
      }
    }
  })(root, 0)
  return sum
};

深度优先搜索 · 后序遍历 · 迭代 · 单栈

function deepestLeavesSum(root: TreeNode | null): number {
  const stack = []
  let p = root, prev = null, depths = new Map, maxDepth = -1, sum = 0
  depths.set(root, 0)
  while (stack.length || p) {
    while (p) {
      stack.push(p)
      updateDepth(depths, p.left, p)
      p = p.left
    }
    const n = stack.pop()
    if (n.right === null || n.right === prev) {
      const depth = depths.get(n)
      if (n.right === null && n.left === null) {
        if (depth === maxDepth) sum += n.val
        else if (depth > maxDepth) {
          sum = n.val
          maxDepth = depth
        }
      }
      prev = n
    } else {
      stack.push(n)
      updateDepth(depths, n.right, n)
      p = n.right
    }
  }
  return sum
};
function updateDepth(depths, n, prev) {
  if (depths.has(n) === false) depths.set(n, depths.get(prev) + 1)
}
class Solution {
  public int deepestLeavesSum(TreeNode root) {
    Deque<TreeNode> stack = new ArrayDeque<TreeNode>();
    Map<TreeNode, Integer> depths = new HashMap<TreeNode, Integer>();
    TreeNode p = root, prev = null;
    depths.put(root, 0);
    int maxDepth = -1, sum = 0;
    while (stack.size() > 0 || p != null) {
      while (p != null) {
        stack.push(p);
        update(depths, p.left, p);
        p = p.left;
      }
      TreeNode n = stack.pop();
      if (n.right == null || n.right == prev) {
        if (n.right == null && n.left == null) {
          int depth = depths.get(n);
          if (maxDepth < depth) {
            maxDepth = depth;
            sum = n.val;
          } else if (maxDepth == depth) {
            sum += n.val;
          }
        }
        prev = n;
      } else {
        stack.push(n);
        update(depths, n.right, n);
        p = n.right;
      }
    }
    return sum;
  }
  public void update(Map<TreeNode, Integer> depths, TreeNode n, TreeNode prev) {
    if (depths.containsKey(n) == false) depths.put(n, depths.get(prev) + 1);
  }
}

深度优先搜索 · 后序遍历 · 迭代 · 双栈

class Solution {
  function deepestLeavesSum($root) {
    $stack = [$root];
    $root->depth = 0;
    $outStack = [];
    while (count($stack)) {
      $n = array_pop($stack);
      $outStack []= $n;
      if ($n->left) {
        $stack []= $n->left;
        $n->left->depth = $n->depth + 1;
      }
      if ($n->right) {
        $stack []= $n->right;
        $n->right->depth = $n->depth + 1;
      }
    }
    $maxDepth = -1;
    $sum = 0;
    while (count($outStack)) {
      $n = array_pop($outStack);
      if ($n->left == null && $n->right == null) {
        if ($maxDepth < $n->depth) {
          $maxDepth = $n->depth;
          $sum = $n->val;
        } else if ($maxDepth === $n->depth) {
          $sum += $n->val;
        }
      }
    }
    return $sum;
  }
}

深度优先搜索 · 前序遍历 · 迭代

func deepestLeavesSum(root *TreeNode) int {
  stack, depths, maxDepth, sum := []*TreeNode{root}, map[*TreeNode]int{}, -1, 0
  depths[root] = 0
  for len(stack) > 0 {
    n := stack[len(stack) - 1]
    stack = stack[:len(stack) - 1]
    depth := depths[n]
    if n.Right == nil && n.Left == nil {
      if maxDepth < depth {
        maxDepth = depth
        sum = n.Val
      } else if maxDepth == depth {
        sum += n.Val
      }
    }
    if n.Right != nil {
      stack = append(stack, n.Right)
      depths[n.Right] = depths[n] + 1
    }
    if n.Left != nil {
      stack = append(stack, n.Left)
      depths[n.Left] = depths[n] + 1
    }
  }
  return sum
}

深度优先搜索 · 前序遍历 · 递归

void d(struct TreeNode* n, int depth, int* maxDepth, int* sum) {
  if (n->left == NULL && n->right == NULL) {
    if (*maxDepth < depth) {
      *maxDepth = depth;
      *sum = n->val;
    } else if (*maxDepth == depth) {
      *sum += n->val;
    }
  }
  if (n->left) d(n->left, depth + 1, maxDepth, sum);
  if (n->right) d(n->right, depth + 1, maxDepth, sum);
}

int deepestLeavesSum(struct TreeNode* root){
  int sum = 0;
  int maxDepth = -1;
  d(root, 0, &maxDepth, &sum);
  return sum;
}

深度优先搜索 · 中序遍历 · 迭代 · 单栈

public class Solution {
  private Dictionary<TreeNode, int> depths;
  public int DeepestLeavesSum(TreeNode root) {
    Stack<TreeNode> st = new Stack<TreeNode>();
    depths = new Dictionary<TreeNode, int>();
    TreeNode p = root;
    depths.Add(p, 0);
    int sum = 0, maxDepth = -1;
    while (st.Count > 0 || p != null) {
      while (p != null) {
        st.Push(p);
        Update(p.left, p);
        p = p.left;
      }
      TreeNode n = st.Pop();
      if (n.right == null && n.left == null) {
        int depth = depths[n];
        if (maxDepth < depth) {
          maxDepth = depth;
          sum = n.val;
        } else if (maxDepth == depth) {
          sum += n.val;
        }
      }
      Update(n.right, n);
      p = n.right;
    }
    return sum;
  }
  private void Update(TreeNode n, TreeNode prev) {
    if (n != null && depths.ContainsKey(n) == false) depths.Add(n, depths[prev] + 1);
  } 
}

深度优先搜索 · 中序遍历 · 迭代 · 莫里斯

class Solution {
public:
  int deepestLeavesSum(TreeNode* root) {
    unordered_map<TreeNode*, int> depths;
    depths.emplace(root, 0);
    int maxDepth = 0, sum = root->val;
    while (root) {
      int depth = depths[root];
      if (root->left) {
        TreeNode* p = root->left;
        while (p->right != nullptr && p->right != root) p = p->right;
        if (p->right == nullptr ) {
          p->right = root;
          root = root->left;
        } else {
          p->right = nullptr;
          root = root->right;
        }
      } else {
        root = root->right;
      }
      if (root && depths.find(root) == depths.end()) {
        depths.emplace(root, depth + 1); 
        if (maxDepth < depths[root]) {
          maxDepth = depths[root];
          sum = root->val;
        } else if (maxDepth == depths[root]) {
          sum += root->val;
        }
      }
    }
    return sum;
  }
};

深度优先搜索· 中序遍历 · 递归

class Solution:
  def d(self, n: Optional[TreeNode], depth: int):
    if n.left: self.d(n.left, depth + 1)
    if n.left == None and n.right == None:
      if self.maxDepth < depth:
        self.maxDepth = depth
        self.sum = n.val
      elif self.maxDepth == depth: self.sum += n.val
    if n.right: self.d(n.right, depth + 1)

  def deepestLeavesSum(self, root: Optional[TreeNode]) -> int:
    self.maxDepth, self.sum = -1, 0
    self.d(root, 0)
    return self.sum
递归,迭代右子节点(新建递归函数 / 使用原函数),3 解法,求解《998. 最大二叉树 II》
递归,迭代右子节点(新建递归函数 / 使用原函数),3 解法,求解《998. 最大二叉树 II》
广度优先搜索,深度优先搜索(前序遍历、中序遍历、后序遍历),递归、迭代(单栈、双栈和莫里斯),用减去每行起始序号技巧缩小数据范围,求解《662. 二叉树最大宽度》
广度优先搜索(队列 / 列表 + 层序遍历),深度优先搜索(前序遍历、中序遍历(包含莫里斯)、后序遍历),递归、迭代(单栈),用减去每行起始序号技巧缩小数据范围,求解《662. 二叉树最大宽度》
广度优先搜索,深度优先搜索(前序 / 中序(含莫里斯) / 后序 遍历,递归和迭代(单栈 / 双栈)),数字转为字符串,求解《655. 输出二叉树》
广度优先搜索,深度优先搜索(前序 / 中序(含莫里斯) / 后序 遍历,递归和迭代(单栈 / 双栈)),''+ int / strconv.Itoa / Integer.toString / int.ToString / sprintf(char*, "%d", int) / to_string / str 将数字转为字符串,求解《655. 输出二叉树》