在牛客网在线编程时,后台会有几组测试数据。当第一组测试数据运行时,如果某个全局静态变量发生了改变,在第二组数据测试的时候,该静态变量会保持改变后的值,这样可能会带来错误结果或异常。
如下:
public class Solution {
static int i = 0;
static TreeNode[] nodes;
public TreeNode Convert(TreeNode pRootOfTree) {
if(pRootOfTree==null) return null;
traversal(true,pRootOfTree);
nodes = new TreeNode[i];
i = 0;
traversal(false,pRootOfTree);
if(i==1){
return pRootOfTree;
}
for(int i = 0; i<nodes.length;i++){
if(i==0){
nodes[i].left = null;
nodes[i].right = nodes[i+1];
} else if(i==nodes.length-1) {
nodes[i].left = nodes[i-1];
nodes[i].right = null;
} else {
nodes[i].left = nodes[i-1];
nodes[i].right = nodes[i+1];
}
}
i = 0; //注意这里!
return nodes[0];
}
public void traversal(boolean isCount, TreeNode node) {
if(node.left!=null){
traversal(isCount, node.left);
}
if(isCount) {
i++;
} else {
nodes[i++] = node;
}
if(node.right!=null) {
traversal(isCount, node.right);
}
}
}
上面代码是将二叉搜索树转化为有序双向链表的一个拙劣实现(。。。)。静态变量 static int i 在每次测试中初始值都应该为0,但是每次测试后,其值都会改变,如果不在程序最后将i归零的话,就会对后续测试造成影响。我一开始的程序就报NullPointerException。
我的个人猜想是,后台回调我的Convert函数。是在一个进程中创建一个Solution对象后,连续调用Convert函数,或者是创多个对象,每个执行Convert函数。
为了证实哪个猜想是对的,我又把int i 改为非静态变量,这样每次创建新对象的时候i都会为0,然后我把程序末尾的i = 0;注释掉。这样如果程序每次测试都创建新对象,i就会自动归零。跑的结果显示成功了。说明后台调用的机制是每组数据测试时会创建一个新对象。
结论:后台会开启一个进程测试我们的数据,且每次测试都会创建一个新的对象,并调用一次算法的函数。
建议:不要用静态变量。首先静态变量不符合算法要求的低耦合和良好的封装性,其次静态变量会出错。