leetcode 669.修剪二叉搜索树,释放内存的时候出现问题
![在这里插入图片描述](https://img-blog.csdnimg.cn/6264989425024eb89207d24bf3187728.png)
报错程序:
这种写法虽然逻辑正确,但是内存依然会报错
- 这里的delete结束之后直接return结束当前层的递归,所以是不会有内存问题的
- 走到root->left那一句的话,前面是并没有delete root的
class Solution {
public:
TreeNode* trimBST(TreeNode* root, int low, int high) {
if(root==nullptr){
return nullptr;
}
//如果root不满足条件,需要一直递归,直到找到满足条件的来继位为止
if(root->val<low){
TreeNode* right = trimBST(root->right, low, high);
delete root; // 删除节点
return right; // 返回修剪后的子树
}
if(root->val>high){
TreeNode* left = trimBST(root->left, low, high);
delete root; // 删除节点
return left; // 返回修剪后的子树
}
//如果root满足条件,那么继续向下遍历
root->left = trimBST(root->left,low,high);
root->right = trimBST(root->right,low,high);
return root;
}
};
但是,将报错用例在IDE里跑了一下,并没有内存问题。(报错用例就是力扣里面显示的最后执行的输入)
是力扣平台的问题,很坑,delete在IDE里面是正常的,并不会出现内存报错。
重新看了那个报错用例打了日志看也是也报错,应该判题程序会去调用原来的 root,但是程序把原来的 root 已经删了。这个问题就是平台的问题,但是我们要注意打日志debug的方法。
打日志debug示例
class Solution {
public:
TreeNode* trimBST(TreeNode* root, int low, int high) {
printf("又循环了一次");
if(root==nullptr){
return nullptr;
}
printf("一");
printf("%d",root->val);
if(root->val<low){
TreeNode* node = root->right;
printf("zheli");
printf("...................");
printf("%d",root->val);
delete root; // 删除节点
printf("nali");
return trimBST(node, low, high); // 返回修剪后的子树
}
printf("二");
printf("///");
printf("%d",root->val);
if(root->val>high){
TreeNode* node = root->left;
printf("++++++++++++++++++++++++");
printf("%d",root->val);
delete root; // 删除节点
return trimBST(node, low, high); // 返回修剪后的子树
}
printf("三");
//递归遍历与连接返回的子树
root->left = trimBST(root->left,low,high);
root->right = trimBST(root->right,low,high);
printf("四");
printf("***********************%d",root->val);
return root;
}
};
力扣平台delete问题的应对方案
一般不 delete 也是没问题的,但是就怕有些题数据量一大你不手动回收的话会内存泄露,毕竟我们用的是c++,不像 Java 那样可以自动 gc。
关于delete的问题,我的建议如果确定删是没问题的,可以删一下,这也是良好的编码习惯,实际开发不可能一直不回收。
这里主要是力扣自己的问题,遇到这道题可以长个心眼,之前还真没遇过。或者先写 delete 版本,出问题可以暂时把 delete 语句注释掉看看,反之也可以。