Count of subsequence of an Array having all unique digits
Given an array A containing N positive integers, the task is to find the number of subsequences of this array such that in each subsequence , no digit is repeated twice, i.e. all the digits of the subsequences must be unique.
Examples:
Input: A = [1, 12, 23, 34]
Output: 7
The subsequences are: {1}, {12}, {23}, {34}, {1, 23}, {1, 34}, {12, 34}
Therefore the count of such subsequences = 7
Input: A = [5, 12, 2, 1, 165, 2323, 7]
Output: 33
Naive approach: Generate all subsequences of the array and traverse through them to check whether the given condition is satisfied or not. Print the count of such subsequences at the end.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
bool check(vector< int >& v)
{
set< int > digits;
for ( int i = 0; i < v.size(); i++) {
set< int > d;
while (v[i]) {
d.insert(v[i] % 10);
v[i] /= 10;
}
for ( auto it : d) {
if (digits.count(it))
return false ;
}
for ( auto it : d)
digits.insert(it);
}
return true ;
}
int numberOfSubarrays( int a[], int n)
{
int answer = 0;
for ( int i = 1; i < (1 << n); i++) {
vector< int > temp;
for ( int j = 0; j < n; j++) {
if (i & (1 << j))
temp.push_back(a[j]);
}
if (check(temp))
answer++;
}
return answer;
}
int main()
{
int N = 4;
int A[] = { 1, 12, 23, 34 };
cout << numberOfSubarrays(A, N);
return 0;
}
|
Java
import java.util.*;
class GFG{
static boolean check(Vector<Integer> v)
{
HashSet<Integer> digits = new HashSet<Integer>();
for ( int i = 0 ; i < v.size(); i++) {
HashSet<Integer> d = new HashSet<Integer>();
while (v.get(i)> 0 ) {
d.add(v.get(i) % 10 );
v.set(i, v.get(i)/ 10 );
}
for ( int it : d) {
if (digits.contains(it))
return false ;
}
for ( int it : d)
digits.add(it);
}
return true ;
}
static int numberOfSubarrays( int a[], int n)
{
int answer = 0 ;
for ( int i = 1 ; i < ( 1 << n); i++) {
Vector<Integer> temp = new Vector<Integer>();
for ( int j = 0 ; j < n; j++) {
if ((i & ( 1 << j))> 0 )
temp.add(a[j]);
}
if (check(temp))
answer++;
}
return answer;
}
public static void main(String[] args)
{
int N = 4 ;
int A[] = { 1 , 12 , 23 , 34 };
System.out.print(numberOfSubarrays(A, N));
}
}
|
Python3
def check(v):
digits = set ()
for i in range ( len (v)):
d = set ()
while (v[i] ! = 0 ):
d.add(v[i] % 10 )
v[i] / / = 10
for it in d:
if it in digits:
return False
for it in d:
digits.add(it)
return True
def numberOfSubarrays(a, n):
answer = 0
for i in range ( 1 , 1 << n):
temp = []
for j in range (n):
if (i & ( 1 << j)):
temp.append(a[j])
if (check(temp)):
answer + = 1
return answer
if __name__ = = "__main__" :
N = 4
A = [ 1 , 12 , 23 , 34 ]
print (numberOfSubarrays(A, N))
|
C#
using System;
using System.Collections.Generic;
class GFG{
static bool check(List< int > v)
{
HashSet< int > digits = new HashSet< int >();
for ( int i = 0; i < v.Count; i++)
{
HashSet< int > d = new HashSet< int >();
while (v[i] > 0)
{
d.Add(v[i] % 10);
v[i] = v[i] / 10;
}
foreach ( int it in d)
{
if (digits.Contains(it))
return false ;
}
foreach ( int it in d)
digits.Add(it);
}
return true ;
}
static int numberOfSubarrays( int []a, int n)
{
int answer = 0;
for ( int i = 1; i < (1 << n); i++)
{
List< int > temp = new List< int >();
for ( int j = 0; j < n; j++)
{
if ((i & (1 << j)) > 0)
temp.Add(a[j]);
}
if (check(temp))
answer++;
}
return answer;
}
public static void Main(String[] args)
{
int N = 4;
int []A = { 1, 12, 23, 34 };
Console.Write(numberOfSubarrays(A, N));
}
}
|
Javascript
<script>
function check(v) {
let digits = new Set();
for (let i = 0; i < v.length; i++) {
let d = new Set();
while (v[i]) {
d.add(v[i] % 10);
v[i] = Math.floor(v[i] / 10);
}
for (let it of d) {
if (digits.has(it))
return false ;
}
for (let it of d)
digits.add(it);
}
return true ;
}
function numberOfSubarrays(a, n) {
let answer = 0;
for (let i = 1; i < (1 << n); i++) {
let temp = new Array();
for (let j = 0; j < n; j++) {
if (i & (1 << j))
temp.push(a[j]);
}
if (check(temp))
answer++;
}
return answer;
}
let N = 4;
let A = [1, 12, 23, 34];
document.write(numberOfSubarrays(A, N));
</script>
|
Time Complexity: O(N * 2N)
Efficient Approach: This approach depends upon the fact that there exist only 10 unique digits in the Decimal number system. Therefore the longest subsequence will have only 10 digits in it, to meet the required condition.
- We will use Bitmasking and Dynamic Programming to solve the problem.
- Since there are only 10 digits, consider a 10-bit representation of every number where each bit is 1 if digit corresponding to that bit is present in that number.
- Let, i be the current array element (elements from 1 to i-1 are already processed). An integer variable ‘mask‘ indicates the digits which have already occurred in the subsequence. If i’th bit is set in the mask, then i’th digit has occurred, else not.
- At each step of recurrence relation, the element can either be included in the subsequence or not. If the element is not included in the subarray, then simply move to the next index. If it is included, change the mask by setting all the bits corresponding to the current element’s digit, ON in the mask.
Note: The current element can only be included if all of its digits have not occurred previously.
- This condition will be satisfied only if the bits corresponding to the current element’s digits in the mask are OFF.
- If we draw the complete recursion tree, we can observe that many subproblems are being solved again and again. So we use Dynamic Programming. A table dp[][] is used such that for every index dp[i][j], i is the position of the element in the array and j is the mask.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int dp[5000][(1 << 10) + 5];
int getmask( int val)
{
int mask = 0;
if (val == 0)
return 1;
while (val) {
int d = val % 10;
mask |= (1 << d);
val /= 10;
}
return mask;
}
int countWays( int pos, int mask,
int a[], int n)
{
if (pos == n)
return (mask > 0 ? 1 : 0);
if (dp[pos][mask] != -1)
return dp[pos][mask];
int count = 0;
count = count
+ countWays(pos + 1, mask, a, n);
if ((getmask(a[pos]) & mask) == 0) {
int new_mask
= (mask | (getmask(a[pos])));
count = count
+ countWays(pos + 1,
new_mask,
a, n);
}
return dp[pos][mask] = count;
}
int numberOfSubarrays( int a[], int n)
{
memset (dp, -1, sizeof (dp));
return countWays(0, 0, a, n);
}
int main()
{
int N = 4;
int A[] = { 1, 12, 23, 34 };
cout << numberOfSubarrays(A, N);
return 0;
}
|
Java
import java.util.*;
class GFG{
static int [][]dp = new int [ 5000 ][( 1 << 10 ) + 5 ];
static int getmask( int val)
{
int mask = 0 ;
if (val == 0 )
return 1 ;
while (val > 0 ) {
int d = val % 10 ;
mask |= ( 1 << d);
val /= 10 ;
}
return mask;
}
static int countWays( int pos, int mask,
int a[], int n)
{
if (pos == n)
return (mask > 0 ? 1 : 0 );
if (dp[pos][mask] != - 1 )
return dp[pos][mask];
int count = 0 ;
count = count
+ countWays(pos + 1 , mask, a, n);
if ((getmask(a[pos]) & mask) == 0 ) {
int new_mask
= (mask | (getmask(a[pos])));
count = count
+ countWays(pos + 1 ,
new_mask,
a, n);
}
return dp[pos][mask] = count;
}
static int numberOfSubarrays( int a[], int n)
{
for ( int i = 0 ;i< 5000 ;i++)
{
for ( int j = 0 ; j < ( 1 << 10 ) + 5 ; j++) {
dp[i][j] = - 1 ;
}
}
return countWays( 0 , 0 , a, n);
}
public static void main(String[] args)
{
int N = 4 ;
int A[] = { 1 , 12 , 23 , 34 };
System.out.print(numberOfSubarrays(A, N));
}
}
|
Python3
def getmask(val):
mask = 0
if val = = 0 :
return 1
while (val):
d = val % 10 ;
mask | = ( 1 << d)
val = val / / 10
return mask
def countWays(pos, mask, a, n):
if pos = = n :
if mask > 0 :
return 1
else :
return 0
if dp[pos][mask] ! = - 1 :
return dp[pos][mask]
count = 0
count = (count +
countWays(pos + 1 , mask, a, n))
if (getmask(a[pos]) & mask) = = 0 :
new_mask = (mask | (getmask(a[pos])))
count = (count +
countWays(pos + 1 ,
new_mask,
a, n))
dp[pos][mask] = count
return count
def numberOfSubarrays(a, n):
return countWays( 0 , 0 , a, n)
N = 4
A = [ 1 , 12 , 23 , 34 ]
rows = 5000
cols = 1100
dp = [ [ - 1 for i in range (cols) ]
for j in range (rows) ]
print ( numberOfSubarrays(A, N))
|
C#
using System;
public class GFG{
static int [,]dp = new int [5000, (1 << 10) + 5];
static int getmask( int val)
{
int mask = 0;
if (val == 0)
return 1;
while (val > 0) {
int d = val % 10;
mask |= (1 << d);
val /= 10;
}
return mask;
}
static int countWays( int pos, int mask,
int []a, int n)
{
if (pos == n)
return (mask > 0 ? 1 : 0);
if (dp[pos, mask] != -1)
return dp[pos, mask];
int count = 0;
count = count
+ countWays(pos + 1, mask, a, n);
if ((getmask(a[pos]) & mask) == 0) {
int new_mask
= (mask | (getmask(a[pos])));
count = count
+ countWays(pos + 1,
new_mask, a, n);
}
return dp[pos, mask] = count;
}
static int numberOfSubarrays( int []a, int n)
{
for ( int i = 0; i < 5000; i++)
{
for ( int j = 0; j < (1 << 10) + 5; j++) {
dp[i,j] = -1;
}
}
return countWays(0, 0, a, n);
}
public static void Main(String[] args)
{
int N = 4;
int []A = { 1, 12, 23, 34 };
Console.Write(numberOfSubarrays(A, N));
}
}
|
Javascript
<script>
var dp = Array.from(Array(5000), ()=>Array((1 << 10) + 5).fill(-1));
function getmask(val)
{
var mask = 0;
if (val == 0)
return 1;
while (val) {
var d = val % 10;
mask |= (1 << d);
val = parseInt(val/10);
}
return mask;
}
function countWays(pos, mask, a, n)
{
if (pos == n)
return (mask > 0 ? 1 : 0);
if (dp[pos][mask] != -1)
return dp[pos][mask];
var count = 0;
count = count
+ countWays(pos + 1, mask, a, n);
if ((getmask(a[pos]) & mask) == 0) {
var new_mask
= (mask | (getmask(a[pos])));
count = count
+ countWays(pos + 1,
new_mask,
a, n);
}
return dp[pos][mask] = count;
}
function numberOfSubarrays(a, n)
{
dp = Array.from(Array(5000), ()=>Array((1 << 10) + 5).fill(-1));
return countWays(0, 0, a, n);
}
var N = 4;
var A = [1, 12, 23, 34];
document.write( numberOfSubarrays(A, N));
</script>
|
Time Complexity: O(N * 210)
Last Updated :
30 Nov, 2021
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...