Search code examples
c++recursionbacktrackingrecursive-backtracking

Different behaviors with same time complexity


I am solving the following question on LeetCode:

Write a function that takes an integer n and return all possible combinations of its factors. For e.g., 12 should return:
[
   [2, 6],
   [2, 2, 3],
   [3, 4]
]

I came up with the following approach (in C++):

class Solution {
public:
    vector<vector<int>> getFactors(int n) {
        if(n==0 || n==1) return vector<vector<int>>();

        vector<vector<int>> result;
        vector<int> factors;
        getFactorsUtil(result, factors, n, 2);

        return result;
    }

    void getFactorsUtil(vector<vector<int>>& result, vector<int>& factors, int n, int start) {
        long int each=1;
        for(int i=0; i<factors.size(); i++)
            each = each*factors[i];
        if(each==n) result.push_back(factors);
        if(each>n) return;

        for(int i=start; i<=n; i++) {
            if(n%i==0) {        //perfectly divisible
                factors.push_back(i);
                getFactorsUtil(result, factors, n, i);
                factors.pop_back();
            }
        }
    }
};

This works as expected, but times out on the last test case: 23848713.

One of the accepted and upvoted solutions (in Java) is as follows:

public List<List<Integer>> getFactors(int n) {
    List<List<Integer>> result = new ArrayList<List<Integer>>();
    helper(result, new ArrayList<Integer>(), n, 2);
    return result;
}

public void helper(List<List<Integer>> result, List<Integer> item, int n, int start){
    if (n <= 1) {
        if (item.size() > 1) {
            result.add(new ArrayList<Integer>(item));
        }
        return;
    }

    for (int i = start; i <= n; ++i) {
        if (n % i == 0) {
            item.add(i);
            helper(result, item, n/i, i);
            item.remove(item.size()-1);
        }
    }
}

The time complexities of both the codes are same (in my opinion). Why then does my code fail and the other code run successfully on 23848713? I mean, is there some apparent bug in my code, or is it some problem with the online judge?

I appreciate your help.

Edit: There was no <=n in my for loop condition in the code earlier (just because the other code has it - it is not actually needed as per the question). I included it later. But anyway, it still times out.

Edit2: In big-O notation, we skip the co-efficients of n. I think that is the reason it breaks here. My code has large values of these constants. I can come up with no other explanation.


Solution

  • Because of the first loop (in which I calculate the product of all the numbers in factors into each), my code was higher than a magnitude of O(n). Due to this, it failed.

    However, when I called it with the value n/i (and not n), I could completely get rid of the O(n) factor by elimination the entire loop. This is so because I no longer had to check if the product was equal to n.

    Thus, the code finally got accepted because of this change. Thanks.

    (Posting as it might be helpful to someone). Also, thanks to @user4581301 for the hint which eventually led me to it.