leetcode
leetcode 3001 ~ 3050
二叉树灯饰

二叉树灯饰

难度:

标签:

题目描述

English description is not available for the problem. Please switch to Chinese.

代码结果

运行时间: 305 ms, 内存: 31.7 MB


import java.util.*;

// 题目思路:
// 使用Java Stream API处理树结构较为复杂,因此这里的实现与传统Java实现类似。
// Stream API更适合处理集合而非树结构。

class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;
    TreeNode(int x) { val = x; }
}

public class Solution {
    public int minFlips(TreeNode root) {
        return dfs(root);
    }
    
    private int dfs(TreeNode node) {
        if (node == null) return 0;
        int flips = 0;
        
        // 左右子树的翻转次数
        int leftFlips = dfs(node.left);
        int rightFlips = dfs(node.right);
        
        // 如果当前节点为1,则需要翻转
        if (node.val == 1) {
            flips += 1;
            // 切换以当前节点为根的子树所有节点
            toggleSubtree(node);
        }
        
        // 子节点的翻转次数加入总翻转次数
        flips += leftFlips + rightFlips;
        return flips;
    }
    
    private void toggleSubtree(TreeNode node) {
        if (node == null) return;
        node.val = 1 - node.val;
        toggleSubtree(node.left);
        toggleSubtree(node.right);
    }
}

解释

方法:

The solution employs a dynamic programming approach using depth-first search (DFS) to determine the minimum number of switch operations needed to turn off all the lights in a binary tree. At each node, four states are computed, representing the minimum operations required for different configurations: 1) all lights on, 2) all lights off, 3) only the current node light on, and 4) only the current node light off. These states are computed based on the node's current state (light on or off) and the minimal operations required for its children's states. The recursive DFS function calculates the optimal switch operations for each state by combining results from left and right children and considering all possible switch actions at the current node.

时间复杂度:

O(n)

空间复杂度:

O(h) where h is the height of the tree, worst-case O(n)

代码细节讲解

🦆
解题思路中提到的四种状态具体是如何定义的?能否详细解释每个状态的具体意义?
在这个题解中,每个节点都计算了四种不同的状态,这些状态反映了不同的灯光配置及其所需的最小操作次数。这四种状态分别为:1) 所有灯都亮着;2) 所有灯都熄灭;3) 仅当前节点的灯亮着,其他都熄灭;4) 当前节点的灯熄灭,其他都亮着。第一种状态用于计算将当前节点以及其所有子节点的灯全部点亮所需的最小操作数。第二种状态用于计算将所有灯熄灭的最小操作数。第三种状态专注于只有当前节点灯亮,其余节点灯都熄灭的情形,这在一些情况下可以最小化操作次数。第四种状态则是当前节点灯熄灭,其他节点灯亮的配置,这也是一种特殊的灯光状态。
🦆
在考虑转换状态时,为什么需要考虑`1 + l2 + r2`和`l1 + r1 + 1`这样的状态转换?这里的1代表什么操作?
在这个题解中,`1`代表进行一次开关操作,无论是将灯从开启状态切换到关闭状态,还是从关闭状态切换到开启状态。例如,在表达式`1 + l2 + r2`中,`1`表示对当前节点进行一次操作(如果当前灯是亮的,就关闭它;如果是灭的,就打开它),而`l2`和`r2`分别表示左、右子树已经全部熄灭的最小操作数。同理,`l1 + r1 + 1`中的`1`也表示对当前节点进行一次操作,`l1`和`r1`表示左右子树处于全亮状态的最小操作数。这些操作确保了在转换状态时,能够从一个状态准确地转换到另一个所需状态,同时保证操作次数最小。
🦆
解法中提到了利用深度优先搜索(DFS),请问这种方法在处理节点的子树状态时是如何确保所有情况都被考虑到的?
深度优先搜索(DFS)是一种递归遍历树的方法,它从根节点开始,递归地访问每个节点的左子树和右子树。在这个题解中,DFS被用来计算每个节点在四种不同状态下的最小操作数。通过递归调用,DFS确保了从每个叶子节点开始到根节点的每一步中,都将左子树和右子树的所有可能状态考虑在内。这样,每次递归返回时,都会结合当前节点的状态和其子节点的状态,计算出当前节点的最优状态。这种自底向上的计算方式确保了每个节点在计算时都有完整的子树信息,从而保证了所有可能的情况都被充分考虑。

相关问题