You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++中static关键字的正确用法及BST求和问题解析

C++ static关键字正确用法解析(附BST求和问题修复)

问题场景

你用局部static变量实现二叉搜索树(BST)范围内节点值求和时,第一个测试用例(root = [10,5,15,3,7,null,18], low=7, high=15)得到正确结果32,但第二个测试用例(root = [10,5,15,3,7,13,18,1,null,6], low=6, high=10)预期23却得到55,换成类成员变量后结果正常。

错误原因

你代码里的局部static变量sum,只会在第一次进入函数时初始化一次,之后所有函数调用(包括不同测试用例)都会保留之前的数值。第一个测试用例结束后sum是32,第二个测试用例运行时,sum从32开始累加,最终32+23=55,这就是错误的根源。

C++ static关键字的不同场景用法

1. 函数内的局部静态变量

  • 生命周期:从第一次初始化开始,直到程序结束
  • 作用域:仅限当前函数内部
  • 特性:值会在多次函数调用之间保留,适合需要跨调用维持状态的场景(比如统计函数被调用的次数)
  • 坑点:不能用于每次调用都需要重置状态的场景,比如你的BST求和,每个测试用例都需要全新的累加起点。

2. 类成员静态变量

  • 归属:属于整个类,而非某个对象,所有类实例共享同一个变量
  • 初始化:必须在类外部单独初始化(const static整型除外)
  • 特性:适合存储类级别的共享数据(比如统计类的实例数量)
  • 你的正确代码里,每次测试用例会创建新的Solution对象,成员变量sum会重新初始化,所以不会有状态残留问题。

修复方案

方案1:无状态递归实现(推荐)

不需要依赖任何外部状态,直接通过递归返回值累加,代码更简洁健壮:

class Solution {
public:
    int rangeSumBST(TreeNode* root, int low, int high) {
        if (!root) return 0;
        // 当前节点符合条件就加值,否则加0
        int current = (root->val >= low && root->val <= high) ? root->val : 0;
        // 递归累加左右子树的结果
        return current + rangeSumBST(root->left, low, high) + rangeSumBST(root->right, low, high);
    }
};

方案2:保留类成员变量的实现

你的原有正确代码可以继续使用,但要注意这种方式依赖对象状态,不如无状态递归灵活:

class Solution {
public:
    int sum = 0;
    int rangeSumBST(TreeNode* root, int low, int high) {
        if (!root) return sum;
        if (root->val >= low && root->val <= high) sum += root->val;
        if (root->left) rangeSumBST(root->left, low, high);
        if (root->right) rangeSumBST(root->right, low, high);
        return sum;
    }
};

方案3:强制重置static变量(不推荐)

如果一定要用static,需要在每次新的测试用例调用时重置sum,但这种方式存在线程安全问题,代码也不优雅:

class Solution {
public:
    int rangeSumBST(TreeNode* root, int low, int high) {
        static int sum = 0;
        // 仅在递归入口(根节点)时重置sum
        if (root && !root->left && !root->right) { // 这里的判断逻辑仅作示例,实际需根据场景调整
            sum = 0;
        }
        if (!root) return sum;
        if (root->val >= low && root->val <= high) sum += root->val;
        if (root->left) rangeSumBST(root->left, low, high);
        if (root->right) rangeSumBST(root->right, low, high);
        return sum;
    }
};

总结

  • 局部static变量适合跨函数调用保留状态的场景,绝对不能用于每次调用都需要干净初始值的场景。
  • 优先选择无状态的递归实现,避免状态残留带来的隐蔽bug。

内容的提问来源于stack exchange,提问作者Syed Abdulla

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 05:40:41