给定N个整数的数组arr [] ,任务是查找不包含给定数组中的相邻元素的所有子集的计数。
例子:
Input: arr[] = {2, 7}
Output: 3
All possible subsets are {}, {2} and {7}.
Input: arr[] = {3, 5, 7}
Output: 5
方法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) 。
n = 1, count = 2 = fib(3)
n = 2, count = 3 = fib(4)
n = 3, count = 5 = fib(5)
n = 4, count = 8 = fib(6)
n = 5, count = 13 = fib(7)
…………….
因此,可以使用本文的方法5以O(log n)时间对子集进行计数。