📌  相关文章
📜  不包含相邻元素的子集计数

📅  最后修改于: 2021-04-23 18:07:05             🧑  作者: Mango

给定N个整数的数组arr [] ,任务是查找不包含给定数组中的相邻元素的所有子集的计数。

例子:

方法1:想法是使用位掩码模式来生成本文所讨论的所有组合。在考虑子集时,我们需要检查它是否包含相邻元素。如果子集的位掩码中设置了两个或更多连续位,则子集将包含相邻元素。为了检查位掩码是否设置了连续的位,我们可以将掩码右移一位,然后将其与掩码进行“与”运算。如果“与”运算的结果为0,则掩码没有设置连续的位,因此,对应的子集将不具有数组中的相邻元素。

下面是上述方法的实现:

C++
// C++ implementation of the approach
#include 
#include 
using namespace std;
  
// Function to return the count
// of possible subsets
int cntSubsets(int* arr, int n)
{
  
    // Total possible subsets of n
    // sized array is (2^n - 1)
    unsigned int max = pow(2, n);
  
    // To store the required
    // count of subsets
    int result = 0;
  
    // Run from i 000..0 to 111..1
    for (int i = 0; i < max; i++) {
        int counter = i;
  
        // If current subset has consecutive
        // elements from the array
        if (counter & (counter >> 1))
            continue;
        result++;
    }
    return result;
}
  
// Driver code
int main()
{
    int arr[] = { 3, 5, 7 };
    int n = sizeof(arr) / sizeof(arr[0]);
  
    cout << cntSubsets(arr, n);
  
    return 0;
}


Java
// Java implementation of the approach
import java.util.*;
      
class GFG
{
  
// Function to return the count
// of possible subsets
static int cntSubsets(int[] arr, int n)
{
  
    // Total possible subsets of n
    // sized array is (2^n - 1)
    int max = (int) Math.pow(2, n);
  
    // To store the required
    // count of subsets
    int result = 0;
  
    // Run from i 000..0 to 111..1
    for (int i = 0; i < max; i++) 
    {
        int counter = i;
  
        // If current subset has consecutive
        if ((counter & (counter >> 1)) > 0)
            continue;
        result++;
    }
    return result;
}
  
// Driver code
static public void main (String []arg)
{
    int arr[] = { 3, 5, 7 };
    int n = arr.length;
  
    System.out.println(cntSubsets(arr, n));
}
}
  
// This code is contributed by Rajput-Ji


Python3
# Python3 implementation of the approach
  
# Function to return the count
# of possible subsets
def cntSubsets(arr, n):
  
    # Total possible subsets of n
    # sized array is (2^n - 1)
    max = pow(2, n)
  
    # To store the required
    # count of subsets
    result = 0
  
    # Run from i 000..0 to 111..1
    for i in range(max):
        counter = i
  
        # If current subset has consecutive
        # elements from the array
        if (counter & (counter >> 1)):
            continue
        result += 1
  
    return result
  
# Driver code
arr = [3, 5, 7]
n = len(arr)
  
print(cntSubsets(arr, n))
  
# This code is contributed by Mohit Kumar


C#
// C# implementation of the approach
using System;
  
class GFG
{
      
// Function to return the count
// of possible subsets
static int cntSubsets(int[] arr, int n)
{
  
    // Total possible subsets of n
    // sized array is (2^n - 1)
    int max = (int) Math.Pow(2, n);
  
    // To store the required
    // count of subsets
    int result = 0;
  
    // Run from i 000..0 to 111..1
    for (int i = 0; i < max; i++) 
    {
        int counter = i;
  
        // If current subset has consecutive
        if ((counter & (counter >> 1)) > 0)
            continue;
        result++;
    }
    return result;
}
  
// Driver code
static public void Main (String []arg)
{
    int []arr = { 3, 5, 7 };
    int n = arr.Length;
  
    Console.WriteLine(cntSubsets(arr, n));
}
}
      
// This code is contributed by Rajput-Ji


C++
// C++ implementation of the approach
#include 
using namespace std;
  
// Function to return the count
// of possible subsets
int cntSubsets(int* arr, int n)
{
    int a[n], b[n];
  
    a[0] = b[0] = 1;
  
    for (int i = 1; i < n; i++) {
  
        // If previous element was 0 then 0
        // as well as 1 can be appended
        a[i] = a[i - 1] + b[i - 1];
  
        // If previous element was 1 then
        // only 0 can be appended
        b[i] = a[i - 1];
    }
  
    // Store the count of all possible subsets
    int result = a[n - 1] + b[n - 1];
  
    return result;
}
  
// Driver code
int main()
{
    int arr[] = { 3, 5, 7 };
    int n = sizeof(arr) / sizeof(arr[0]);
  
    cout << cntSubsets(arr, n);
  
    return 0;
}


Java
// Java implementation of the approach
import java.util.*;
  
class GFG 
{
  
// Function to return the count
// of possible subsets
static int cntSubsets(int []arr, int n)
{
    int []a = new int[n];
    int []b = new int[n];
  
    a[0] = b[0] = 1;
  
    for (int i = 1; i < n; i++) 
    {
  
        // If previous element was 0 then 0
        // as well as 1 can be appended
        a[i] = a[i - 1] + b[i - 1];
  
        // If previous element was 1 then
        // only 0 can be appended
        b[i] = a[i - 1];
    }
  
    // Store the count of all possible subsets
    int result = a[n - 1] + b[n - 1];
  
    return result;
}
  
// Driver code
public static void main(String[] args)
{
    int arr[] = { 3, 5, 7 };
    int n = arr.length;
  
    System.out.println(cntSubsets(arr, n));
}
}
  
// This code is contributed by Princi Singh


Python3
# Python3 implementation of the approach 
  
# Function to return the count 
# of possible subsets 
def cntSubsets(arr, n) : 
  
    a = [0] * n
    b = [0] * n; 
  
    a[0] = b[0] = 1; 
  
    for i in range(1, n) :
          
        # If previous element was 0 then 0 
        # as well as 1 can be appended 
        a[i] = a[i - 1] + b[i - 1]; 
  
        # If previous element was 1 then 
        # only 0 can be appended 
        b[i] = a[i - 1]; 
  
    # Store the count of all possible subsets 
    result = a[n - 1] + b[n - 1]; 
  
    return result; 
  
# Driver code 
if __name__ == "__main__" : 
  
    arr = [ 3, 5, 7 ]; 
    n = len(arr); 
  
    print(cntSubsets(arr, n)); 
  
# This code is contributed by AnkitRai01


C#
// C# implementation of the approach
using System;
      
class GFG 
{
  
// Function to return the count
// of possible subsets
static int cntSubsets(int []arr, int n)
{
    int []a = new int[n];
    int []b = new int[n];
  
    a[0] = b[0] = 1;
  
    for (int i = 1; i < n; i++) 
    {
  
        // If previous element was 0 then 0
        // as well as 1 can be appended
        a[i] = a[i - 1] + b[i - 1];
  
        // If previous element was 1 then
        // only 0 can be appended
        b[i] = a[i - 1];
    }
  
    // Store the count of all possible subsets
    int result = a[n - 1] + b[n - 1];
  
    return result;
}
  
// Driver code
public static void Main(String[] args)
{
    int []arr = { 3, 5, 7 };
    int n = arr.Length;
  
    Console.WriteLine(cntSubsets(arr, n));
}
}
  
// This code is contributed by 29AjayKumar


输出:
5

方法2:上述方法需要花费指数时间。在上面的代码中,需要不带连续1的位掩码的数量。如本文所述,可以使用动态编程在线性时间内获得此计数。

下面是上述方法的实现:

C++

// C++ implementation of the approach
#include 
using namespace std;
  
// Function to return the count
// of possible subsets
int cntSubsets(int* arr, int n)
{
    int a[n], b[n];
  
    a[0] = b[0] = 1;
  
    for (int i = 1; i < n; i++) {
  
        // If previous element was 0 then 0
        // as well as 1 can be appended
        a[i] = a[i - 1] + b[i - 1];
  
        // If previous element was 1 then
        // only 0 can be appended
        b[i] = a[i - 1];
    }
  
    // Store the count of all possible subsets
    int result = a[n - 1] + b[n - 1];
  
    return result;
}
  
// Driver code
int main()
{
    int arr[] = { 3, 5, 7 };
    int n = sizeof(arr) / sizeof(arr[0]);
  
    cout << cntSubsets(arr, n);
  
    return 0;
}

Java

// Java implementation of the approach
import java.util.*;
  
class GFG 
{
  
// Function to return the count
// of possible subsets
static int cntSubsets(int []arr, int n)
{
    int []a = new int[n];
    int []b = new int[n];
  
    a[0] = b[0] = 1;
  
    for (int i = 1; i < n; i++) 
    {
  
        // If previous element was 0 then 0
        // as well as 1 can be appended
        a[i] = a[i - 1] + b[i - 1];
  
        // If previous element was 1 then
        // only 0 can be appended
        b[i] = a[i - 1];
    }
  
    // Store the count of all possible subsets
    int result = a[n - 1] + b[n - 1];
  
    return result;
}
  
// Driver code
public static void main(String[] args)
{
    int arr[] = { 3, 5, 7 };
    int n = arr.length;
  
    System.out.println(cntSubsets(arr, n));
}
}
  
// This code is contributed by Princi Singh

Python3

# Python3 implementation of the approach 
  
# Function to return the count 
# of possible subsets 
def cntSubsets(arr, n) : 
  
    a = [0] * n
    b = [0] * n; 
  
    a[0] = b[0] = 1; 
  
    for i in range(1, n) :
          
        # If previous element was 0 then 0 
        # as well as 1 can be appended 
        a[i] = a[i - 1] + b[i - 1]; 
  
        # If previous element was 1 then 
        # only 0 can be appended 
        b[i] = a[i - 1]; 
  
    # Store the count of all possible subsets 
    result = a[n - 1] + b[n - 1]; 
  
    return result; 
  
# Driver code 
if __name__ == "__main__" : 
  
    arr = [ 3, 5, 7 ]; 
    n = len(arr); 
  
    print(cntSubsets(arr, n)); 
  
# This code is contributed by AnkitRai01

C#

// C# implementation of the approach
using System;
      
class GFG 
{
  
// Function to return the count
// of possible subsets
static int cntSubsets(int []arr, int n)
{
    int []a = new int[n];
    int []b = new int[n];
  
    a[0] = b[0] = 1;
  
    for (int i = 1; i < n; i++) 
    {
  
        // If previous element was 0 then 0
        // as well as 1 can be appended
        a[i] = a[i - 1] + b[i - 1];
  
        // If previous element was 1 then
        // only 0 can be appended
        b[i] = a[i - 1];
    }
  
    // Store the count of all possible subsets
    int result = a[n - 1] + b[n - 1];
  
    return result;
}
  
// Driver code
public static void Main(String[] args)
{
    int []arr = { 3, 5, 7 };
    int n = arr.Length;
  
    Console.WriteLine(cntSubsets(arr, n));
}
}
  
// This code is contributed by 29AjayKumar
输出:
5

方法3;如果我们仔细研究一下模式,我们可以观察到,对于N≥1而言,该计数实际上是第(斐波那契数)(N + 2)

因此,可以使用本文的方法5以O(log n)时间对子集进行计数。