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

📅  最后修改于: 2021-09-17 06:59:16             🧑  作者: Mango

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

例子:

方法 1:想法是使用位掩码模式来生成本文中讨论的所有组合。在考虑一个子集时,我们需要检查它是否包含相邻元素。如果在其位掩码中设置了两个或多个连续位,则子集将包含相邻元素。为了检查位掩码是否设置了连续位,我们可以将掩码右移一位并将其与掩码进行 AND 运算。如果 AND 运算的结果为 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


Javascript


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


Javascript


输出:
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

蟒蛇3

# 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

Javascript


输出:
5

方法三;如果我们仔细观察该模式,我们可以观察到,当N ≥ 1 时,计数实际上是第(N + 2)斐波那契数。

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

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程