Sign up ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free.

This is a very classic problem and most of the solutions I found use the recursion approach like this. Since there are Cn,k combinations, I was wondering if there exists an algorithm that can print all the combinations in O(n*Cn,k) time. I think the answer given in the link takes more time than this. Also, is there an algorithm that can print the results without using additional space(I mean, without additional space that is dependent on n and k. O(1) is surely OK)?

Thanks.

share|improve this question
    
The question you linked provides the answer you are looking for. Why do you think it is inefficient? It does not perform any unnecessary recursions. – user1990169 Jul 31 '14 at 7:39
    
possible duplicate of Find all subsets of length k in an array – user1990169 Jul 31 '14 at 7:40
    
@user1990169: That algorithm will return the combinations when (current.size() < k) and (idx == superSet.size()), which are unnecessary, I think. – eaglesky Jul 31 '14 at 7:47

2 Answers 2

The algorithm linked is giving you all of the permutations as quickly as possible -- O(n!/k!) -- which is slow, because there are exponentially many permutations.

To get all of the combinations in O(Cn,k) time, you can use one of the algorithms in answers to this other question: Algorithm to return all combinations of k elements from n.

share|improve this answer
    
@didierc Why the wikipedia link? Sorry, I'm confused. – Patrick Collins Jul 31 '14 at 10:15
    
No, it's fine, I just wanted to make srue that I hadn't messed up the definition of a combination or something like that. – Patrick Collins Jul 31 '14 at 13:30

Just a simple javascript code to test from windows command line (cscript test.js).

This is nothing more than a sum with carry where the "digits" are the position of the element in the set.

No recursion and only needs to store the set elements and the array to hold the current subset.

// define the initial set
var set = 'abcdefg'.split('');
var setLength = set.length;

// define the subset length and initialize the first subset
var subsetLength = 5;
var aSubset = new Array(subsetLength+1);

var i;
    for( i = 0 ; i < subsetLength ; i++ ) aSubset[i]=i;

// place a guard at the end
    aSubset[subsetLength] = setLength;

// generate each of the posible subsets 
// This is just a sum with carry where the value of each of the "digits" 
// is in the range [i..subset[i+1])
var r = 0, start = 0;
    do {
        // print the subset
        for( i = 0 ; i < subsetLength ; i++ ) {
            WScript.StdOut.Write( set[aSubset[i]] );
        };
        WScript.StdOut.WriteLine('');

        // calculate the next subset
        for( i = start, r = 1 ; i < subsetLength ; i++ ) {
            aSubset[i]++;
            if (aSubset[i] < aSubset[i+1]) { 
                start = ( i==0 ? 0 : i-1 ); 
                r = 0; 
                break; 
            } else { 
                aSubset[i] = i 
            };
        };
    } while (r == 0);
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.