Search code examples
javastaticnon-static

static and non-static difference in Kth Smallest Element in a BST


In this problem, if I make the count variable in the second line static, as shown, the kthSmallest() method computes the wrong answer. If the variable is instead made non-static then the correct answer is computed. Non-static methods can use static variables, so why is there a difference?

class Solution {
    public static int count = 0;
    public int res = 0;

    public int kthSmallest(TreeNode root, int k) {
        inorder(root,k);
        return res;
    }

    public void inorder(TreeNode root, int k) {
        if (root == null) return;
        inorder(root.left,k);
        count++;
        if (count == k) {
            res = root.val;
            return;
        }
        inorder(root.right,k);
    }
}

Solution

  • I see no reason why the result of a single run of your kthSmallest() method would be affected by whether count is static, but if you perform multiple runs, whether sequentially or in parallel, you will certainly have a problem. count being static means every instance of class Solution shares that variable, which you initialize once to zero, and then only increment. A second run of the method, whether on the same or a different instance of Solution, will continue with the value of count left by the previous run.

    Making count non-static partially addresses that issue, by ensuring that every instance of Solution has its own count variable. You still have a problem with performing multiple kthSmallest() computations using the same instance, but you can perform one correct run per instance. If you're testing this via some automated judge then it's plausible that it indeed does create a separate instance for each test case.

    But even that is not a complete solution. You still get at most one run per instance, and you're not even sure to get that if an attempt is made to perform two concurrent runs using the same instance. The fundamental problem here is that you are using instance (or class) variables to hold state specific to a single run of the kthSmallest() method.

    You ought instead to use local variables of that method, communicated to other methods, if needed, via method arguments and / or return values. For example:

    class Solution {
        // no class or instance variables at all
    
        public int kthSmallest(TreeNode root, int k) {
            // int[1] is the simplest mutable container for an int
            int[] result = new int[1];
            inorder(root, k, result);
            return result[0]; 
        }
    
        // does not need to be public:
        // returns the number of nodes traversed (not necessarily the whole subtree)
        int inorder(TreeNode root, int k, int[] result) {
            if (root == null) {
                return 0;
            } else {
                // nodes traversed in the subtree, plus one for the present node
                int count = inorder(root.left, k, result) + 1;
    
                if (count == k) {
                    result[0] = root.val;
                } else {
                    count += inorder(root.right, k, result);
                }
    
                return count;
            }
        }
    }