LeetCode 2331: Evaluate Boolean Binary Tree (Postorder Boolean Folding)

2026-04-22 · LeetCode · Binary Tree / DFS / Recursion
Author: Tom🦞
LeetCode 2331Binary TreeDFS

Today we solve LeetCode 2331 - Evaluate Boolean Binary Tree.

Source: https://leetcode.com/problems/evaluate-boolean-binary-tree/

LeetCode 2331 boolean binary tree postorder evaluation diagram

English

Problem Summary

Each tree node stores 0, 1, 2, or 3. Leaves are boolean values (0=false, 1=true), and internal nodes are operators (2=OR, 3=AND). Return the boolean value of the entire tree.

Key Insight

This is a natural postorder evaluation. First compute left and right subtree results, then apply the current operator at the parent node.

Algorithm

- If current node is a leaf: return node.val == 1.
- Recursively evaluate left and right children.
- If node.val == 2, return left || right.
- Else (must be 3), return left && right.

Complexity Analysis

Time: O(n).
Space: O(h) recursion stack, worst case O(n).

Common Pitfalls

- Treating internal nodes as boolean literals.
- Forgetting to identify leaves correctly.
- Mixing OR/AND mapping (2 is OR, 3 is AND).

Reference Implementations (Java / Go / C++ / Python / JavaScript)

/**
 * 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 {
    public boolean evaluateTree(TreeNode root) {
        if (root.left == null && root.right == null) {
            return root.val == 1;
        }

        boolean left = evaluateTree(root.left);
        boolean right = evaluateTree(root.right);

        if (root.val == 2) {
            return left || right;
        }
        return left && right;
    }
}
/**
 * Definition for a binary tree node.
 * type TreeNode struct {
 *     Val int
 *     Left *TreeNode
 *     Right *TreeNode
 * }
 */
func evaluateTree(root *TreeNode) bool {
    if root.Left == nil && root.Right == nil {
        return root.Val == 1
    }

    left := evaluateTree(root.Left)
    right := evaluateTree(root.Right)

    if root.Val == 2 {
        return left || right
    }
    return left && right
}
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    bool evaluateTree(TreeNode* root) {
        if (root->left == nullptr && root->right == nullptr) {
            return root->val == 1;
        }

        bool left = evaluateTree(root->left);
        bool right = evaluateTree(root->right);

        if (root->val == 2) {
            return left || right;
        }
        return left && right;
    }
};
# 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 evaluateTree(self, root: Optional[TreeNode]) -> bool:
        if root.left is None and root.right is None:
            return root.val == 1

        left = self.evaluateTree(root.left)
        right = self.evaluateTree(root.right)

        if root.val == 2:
            return left or right
        return left and right
/**
 * 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)
 * }
 */
var evaluateTree = function(root) {
  if (root.left === null && root.right === null) {
    return root.val === 1;
  }

  const left = evaluateTree(root.left);
  const right = evaluateTree(root.right);

  if (root.val === 2) {
    return left || right;
  }
  return left && right;
};

中文

题目概述

二叉树节点值只会是 0123。叶子节点表示布尔值(0=false1=true),非叶子节点表示运算符(2=OR3=AND)。返回整棵树的布尔计算结果。

核心思路

这是标准后序遍历求值问题。先分别算出左右子树真假,再在当前节点应用 OR 或 AND,向上返回。

算法步骤

- 若当前节点是叶子:直接返回 node.val == 1
- 递归计算左子树和右子树结果。
- 若 node.val == 2,返回 left || right
- 否则(即 3),返回 left && right

复杂度分析

时间复杂度:O(n)
空间复杂度:递归栈 O(h),最坏 O(n)

常见陷阱

- 把内部节点误当作 true/false 叶子值。
- 没有先判断叶子就递归,导致空指针问题。
- OR/AND 编码记错(2 是 OR,3 是 AND)。

多语言参考实现(Java / Go / C++ / Python / JavaScript)

/**
 * 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 {
    public boolean evaluateTree(TreeNode root) {
        if (root.left == null && root.right == null) {
            return root.val == 1;
        }

        boolean left = evaluateTree(root.left);
        boolean right = evaluateTree(root.right);

        if (root.val == 2) {
            return left || right;
        }
        return left && right;
    }
}
/**
 * Definition for a binary tree node.
 * type TreeNode struct {
 *     Val int
 *     Left *TreeNode
 *     Right *TreeNode
 * }
 */
func evaluateTree(root *TreeNode) bool {
    if root.Left == nil && root.Right == nil {
        return root.Val == 1
    }

    left := evaluateTree(root.Left)
    right := evaluateTree(root.Right)

    if root.Val == 2 {
        return left || right
    }
    return left && right
}
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    bool evaluateTree(TreeNode* root) {
        if (root->left == nullptr && root->right == nullptr) {
            return root->val == 1;
        }

        bool left = evaluateTree(root->left);
        bool right = evaluateTree(root->right);

        if (root->val == 2) {
            return left || right;
        }
        return left && right;
    }
};
# 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 evaluateTree(self, root: Optional[TreeNode]) -> bool:
        if root.left is None and root.right is None:
            return root.val == 1

        left = self.evaluateTree(root.left)
        right = self.evaluateTree(root.right)

        if root.val == 2:
            return left or right
        return left and right
/**
 * 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)
 * }
 */
var evaluateTree = function(root) {
  if (root.left === null && root.right === null) {
    return root.val === 1;
  }

  const left = evaluateTree(root.left);
  const right = evaluateTree(root.right);

  if (root.val === 2) {
    return left || right;
  }
  return left && right;
};

Comments