📌  相关文章
📜  查找设置了n位的k位数字的所有组合,其中1 <= n <= k按排序顺序

📅  最后修改于: 2021-04-24 05:21:24             🧑  作者: Mango

给定数字k,找到设置n位为1 <= n <= k的k位数字的所有可能组合。解决方案应首先打印所有带有一个置位的数字,然后再打印带有两个置位的数字,直到所有其k位都已设置的数字。如果两个数字具有相同的置位位数,则应首先使用较小的数字。

例子:

Input: K = 3
Output:  
001 010 100 
011 101 110 
111 

Input: K = 4
Output:  
0001 0010 0100 1000 
0011 0101 0110 1001 1010 1100 
0111 1011 1101 1110 
1111 

Input: K = 5
Output:  
00001 00010 00100 01000 10000 
00011 00101 00110 01001 01010 01100 10001 10010 10100 11000 
00111 01011 01101 01110 10011 10101 10110 11001 11010 11100 
01111 10111 11011 11101 11110 
11111 

我们需要找到k位数字与n个设置位的所有可能组合,其中1 <= n <= k。如果我们仔细分析,我们会发现问题可以进一步分为子问题。通过将长度k-1和n-1的所有组合都前缀0,并将长度k-1和n-1的所有组合都加上1,可以找到长度为k和n的所有组合。我们可以使用动态编程来保存子问题的解决方案。

以下是上述想法的C++实现–

// C++ program find all the possible combinations of 
// k-bit numbers with n-bits set where 1 <= n <= k
#include 
#include 
using namespace std;
// maximum allowed value of K
#define K 16
  
// DP lookup table
vector DP[K][K];
  
// Function to find all combinations k-bit numbers with 
// n-bits set where 1 <= n <= k
void findBitCombinations(int k)
{
    string str = "";
      
    // DP[k][0] will store all k-bit numbers  
    // with 0 bits set (All bits are 0's)
    for (int len = 0; len <= k; len++) 
    {
        DP[len][0].push_back(str);
        str = str + "0";
    }
      
    // fill DP lookup table in bottom-up manner
    // DP[k][n] will store all k-bit numbers  
    // with n-bits set
    for (int len = 1; len <= k; len++)
    {
        for (int n = 1; n <= len; n++)
        {
            // prefix 0 to all combinations of length len-1 
            // with n ones
            for (string str : DP[len - 1][n])
                DP[len][n].push_back("0" + str);
  
            // prefix 1 to all combinations of length len-1 
            // with n-1 ones
            for (string str : DP[len - 1][n - 1])
                DP[len][n].push_back("1" + str);
        }
    }
      
    // print all k-bit binary strings with
    // n-bit set
    for (int n = 1; n <= k; n++) 
    {
        for (string str : DP[k][n])
            cout << str << " ";
  
        cout << endl;
    }
}
  
// Driver code
int main()
{
    int k = 5;
    findBitCombinations(k);
  
    return 0;
}

输出:

00000 
00001 00010 00100 01000 10000 
00011 00101 00110 01001 01010 01100 10001 10010 10100 11000 
00111 01011 01101 01110 10011 10101 10110 11001 11010 11100 
01111 10111 11011 11101 11110 
11111