# Definition for a binary tree node.
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
class Solution:
def sumEvenGrandparent(self, root: TreeNode) -> int:
def dfs(node, parent, grandparent):
if not node:
return 0
total = 0
if grandparent and grandparent.val % 2 == 0:
total += node.val
total += dfs(node.left, node, parent)
total += dfs(node.right, node, parent)
return total
return dfs(root, None, None)
// 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:
int sumEvenGrandparent(TreeNode* root) {
return dfs(root, nullptr, nullptr);
}
int dfs(TreeNode* node, TreeNode* parent, TreeNode* grandparent) {
if (!node) return 0;
int total = 0;
if (grandparent && grandparent->val % 2 == 0) {
total += node->val;
}
total += dfs(node->left, node, parent);
total += dfs(node->right, node, parent);
return total;
}
};
// Definition for a binary tree node.
class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) { val = x; }
}
class Solution {
public int sumEvenGrandparent(TreeNode root) {
return dfs(root, null, null);
}
private int dfs(TreeNode node, TreeNode parent, TreeNode grandparent) {
if (node == null) return 0;
int total = 0;
if (grandparent != null && grandparent.val % 2 == 0) {
total += node.val;
}
total += dfs(node.left, node, parent);
total += dfs(node.right, node, parent);
return total;
}
}
/**
* Definition for a binary tree node.
* function TreeNode(val, left, right) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
*/
/**
* @param {TreeNode} root
* @return {number}
*/
var sumEvenGrandparent = function(root) {
function dfs(node, parent, grandparent) {
if (!node) return 0;
let total = 0;
if (grandparent && grandparent.val % 2 === 0) {
total += node.val;
}
total += dfs(node.left, node, parent);
total += dfs(node.right, node, parent);
return total;
}
return dfs(root, null, null);
};
You are given the root
of a binary tree. Your task is to calculate the sum of all nodes whose grandparent node has an even value. A grandparent of a node is defined as the parent of its parent, if it exists.
TreeNode
definition.The key challenge is to efficiently traverse the tree and, for each node, determine if its grandparent exists and has an even value. The sum of all such nodes' values should be returned.
At first glance, this problem seems to require checking every node's ancestry to determine if it has a grandparent with an even value. A brute-force approach might involve, for each node, traversing up to its parent and grandparent, checking the values, and then summing as needed.
However, this can be inefficient, especially for large trees, as it leads to repeated work. Instead, it's more efficient to traverse the tree in a way that, at each node, you already know the values of its parent and grandparent. This can be accomplished by passing information down the recursion as you traverse the tree.
The conceptual shift is from "for each node, look up" to "as you go down, carry information about ancestors." This avoids repeated traversals and makes the solution much cleaner and faster.
This approach ensures that each node is visited only once, and the necessary ancestor information is always available without extra lookups. It's efficient and easy to implement in a recursive manner.
Let's consider the following binary tree:
6 / \ 7 8 / \ / \ 2 7 1 3 / / \ 9 1 4
We need to sum all nodes whose grandparent has an even value.
The sum is 2 + 7 + 1 + 3 = 13.
The algorithm traverses the tree recursively, always knowing the parent and grandparent at each step, and accumulates the sum as described.
This problem is elegantly solved by a recursive traversal that carries parent and grandparent information at each step. By doing this, we avoid redundant ancestor lookups and ensure each node is processed efficiently. The approach leverages the natural structure of recursion in trees and demonstrates the power of passing context through recursive calls. The result is a clean, O(n) solution that is easy to reason about and implement.