📌  相关文章
📜  具有所有唯一数字的数组的子数组计数

📅  最后修改于: 2021-05-17 04:48:13             🧑  作者: Mango

给定一个包含N个正整数的数组A ,任务是找到该数组的子数组数,以便在每个子数组中,没有数字重复两次,即子数组的所有数字必须唯一。
例子:

天真的方法:生成数组的所有子数组并遍历它们,以检查是否满足给定条件。在最后打印此子数组的计数。

下面是上述方法的实现:

C++
// C++ program to find the count
// of subarrays of an Array
// having all unique digits
 
#include 
using namespace std;
 
// Function to check whether
// the subarray has all unique digits
bool check(vector& v)
{
 
    // Storing all digits occurred
    set digits;
 
    // Traversing all the numbers of v
    for (int i = 0; i < v.size(); i++) {
        // Storing all digits of v[i]
        set d;
 
        while (v[i]) {
            d.insert(v[i] % 10);
            v[i] /= 10;
        }
 
        // Checking whether digits of v[i]
        // have already occurred
        for (auto it : d) {
            if (digits.count(it))
                return false;
        }
 
        // Inserting digits of v[i] in the set
        for (auto it : d)
            digits.insert(it);
    }
 
    return true;
}
 
// Function to count the number
// subarray with all digits unique
int numberOfSubarrays(int a[], int n)
{
 
    int answer = 0;
 
    // Traverse through all the subarrays
    for (int i = 1; i < (1 << n); i++) {
        // To store elements of this subarray
        vector temp;
 
        // Generate all subarray
        // and store it in vector
        for (int j = 0; j < n; j++) {
            if (i & (1 << j))
                temp.push_back(a[j]);
        }
 
        // Check whether this subarray
        // has all digits unique
        if (check(temp))
 
            // Increase the count
            answer++;
    }
 
    // Return the count
    return answer;
}
 
// Driver code
int main()
{
    int N = 4;
    int A[] = { 1, 12, 23, 34 };
 
    cout << numberOfSubarrays(A, N);
    return 0;
}


Java
// Java program to find the count
// of subarrays of an Array
// having all unique digits
  
 
import java.util.*;
 
class GFG{
  
// Function to check whether
// the subarray has all unique digits
static boolean check(Vector v)
{
  
    // Storing all digits occurred
    HashSet digits = new HashSet();
  
    // Traversing all the numbers of v
    for (int i = 0; i < v.size(); i++) {
        // Storing all digits of v[i]
        HashSet d = new HashSet();
  
        while (v.get(i)>0) {
            d.add(v.get(i) % 10);
            v.set(i, v.get(i)/10);
        }
  
        // Checking whether digits of v[i]
        // have already occurred
        for (int it : d) {
            if (digits.contains(it))
                return false;
        }
  
        // Inserting digits of v[i] in the set
        for (int it : d)
            digits.add(it);
    }
  
    return true;
}
  
// Function to count the number
// subarray with all digits unique
static int numberOfSubarrays(int a[], int n)
{
  
    int answer = 0;
  
    // Traverse through all the subarrays
    for (int i = 1; i < (1 << n); i++) {
        // To store elements of this subarray
        Vector temp = new Vector();
  
        // Generate all subarray
        // and store it in vector
        for (int j = 0; j < n; j++) {
            if ((i & (1 << j))>0)
                temp.add(a[j]);
        }
  
        // Check whether this subarray
        // has all digits unique
        if (check(temp))
  
            // Increase the count
            answer++;
    }
  
    // Return the count
    return answer;
}
  
// Driver code
public static void main(String[] args)
{
    int N = 4;
    int A[] = { 1, 12, 23, 34 };
  
    System.out.print(numberOfSubarrays(A, N));
}
}
 
// This code is contributed by 29AjayKumar


Python3
# Python3 program to find the count
# of subarrays of an Array
# having all unique digits
 
# Function to check whether
# the subarray has all unique digits
def check(v):
  
    # Storing all digits occurred
    digits = set()
  
    # Traversing all the numbers of v
    for i in range(len(v)):
         
        # Storing all digits of v[i]
        d = set()
  
        while (v[i] != 0):
            d.add(v[i] % 10)
            v[i] //= 10
  
        # Checking whether digits of v[i]
        # have already occurred
        for it in d:
            if it in digits:
                return False
         
        # Inserting digits of v[i] in the set
        for it in d:
            digits.add(it)
     
    return True
 
# Function to count the number
# subarray with all digits unique
def numberOfSubarrays(a, n):
  
    answer = 0
  
    # Traverse through all the subarrays
    for i in range(1, 1 << n):
     
        # To store elements of this subarray
        temp = []
  
        # Generate all subarray
        # and store it in vector
        for j in range(n):
            if (i & (1 << j)):
                temp.append(a[j])
         
        # Check whether this subarray
        # has all digits unique
        if (check(temp)):
  
            # Increase the count
            answer += 1
     
    # Return the count
    return answer
 
# Driver code
if __name__=="__main__":
     
    N = 4
    A = [ 1, 12, 23, 34 ]
  
    print(numberOfSubarrays(A, N))
 
# This code is contributed by rutvik_56


C#
// C# program to find the count
// of subarrays of an Array
// having all unique digits
using System;
using System.Collections.Generic;
 
class GFG{
 
// Function to check whether
// the subarray has all unique digits
static bool check(List v)
{
 
    // Storing all digits occurred
    HashSet digits = new HashSet();
 
    // Traversing all the numbers of v
    for(int i = 0; i < v.Count; i++)
    {
         
        // Storing all digits of v[i]
        HashSet d = new HashSet();
 
        while (v[i] > 0)
        {
            d.Add(v[i] % 10);
            v[i] = v[i] / 10;
        }
 
        // Checking whether digits of v[i]
        // have already occurred
        foreach(int it in d)
        {
            if (digits.Contains(it))
                return false;
        }
 
        // Inserting digits of v[i] in the set
        foreach(int it in d)
            digits.Add(it);
    }
    return true;
}
 
// Function to count the number
// subarray with all digits unique
static int numberOfSubarrays(int []a, int n)
{
    int answer = 0;
 
    // Traverse through all the subarrays
    for(int i = 1; i < (1 << n); i++)
    {
         
        // To store elements of this subarray
        List temp = new List();
 
        // Generate all subarray
        // and store it in vector
        for(int j = 0; j < n; j++)
        {
            if ((i & (1 << j)) > 0)
                temp.Add(a[j]);
        }
 
        // Check whether this subarray
        // has all digits unique
        if (check(temp))
 
            // Increase the count
            answer++;
    }
 
    // Return the count
    return answer;
}
 
// Driver code
public static void Main(String[] args)
{
    int N = 4;
    int []A = { 1, 12, 23, 34 };
 
    Console.Write(numberOfSubarrays(A, N));
}
}
 
// This code is contributed by sapnasingh4991


C++
// C++ program to find the count
// of subarrays of an Array
// having all unique digits
 
#include 
using namespace std;
 
// Dynamic programming table
int dp[5000][(1 << 10) + 5];
 
// Function to obtain
// the mask for any integer
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;
}
 
// Function to count the number of ways
int countWays(int pos, int mask,
              int a[], int n)
{
    // Subarray must not be empty
    if (pos == n)
        return (mask > 0 ? 1 : 0);
 
    // If subproblem has been solved
    if (dp[pos][mask] != -1)
        return dp[pos][mask];
 
    int count = 0;
 
    // Excluding this element in the subarray
    count = count
            + countWays(pos + 1, mask, a, n);
 
    // If there are no common digits
    // then only this element can be included
    if ((getmask(a[pos]) & mask) == 0) {
 
        // Calculate the new mask
        // if this element is included
        int new_mask
            = (mask | (getmask(a[pos])));
 
        count = count
                + countWays(pos + 1,
                            new_mask,
                            a, n);
    }
 
    // Store and return the answer
    return dp[pos][mask] = count;
}
 
// Function to find the count of
// subarray with all digits unique
int numberOfSubarrays(int a[], int n)
{
    // intializing dp
    memset(dp, -1, sizeof(dp));
 
    return countWays(0, 0, a, n);
}
 
// Driver code
int main()
{
    int N = 4;
    int A[] = { 1, 12, 23, 34 };
 
    cout << numberOfSubarrays(A, N);
    return 0;
}


Java
// Java program to find the count
// of subarrays of an Array
// having all unique digits
import java.util.*;
 
class GFG{
  
// Dynamic programming table
static int [][]dp = new int[5000][(1 << 10) + 5];
  
// Function to obtain
// the mask for any integer
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;
}
  
// Function to count the number of ways
static int countWays(int pos, int mask,
              int a[], int n)
{
    // Subarray must not be empty
    if (pos == n)
        return (mask > 0 ? 1 : 0);
  
    // If subproblem has been solved
    if (dp[pos][mask] != -1)
        return dp[pos][mask];
  
    int count = 0;
  
    // Excluding this element in the subarray
    count = count
            + countWays(pos + 1, mask, a, n);
  
    // If there are no common digits
    // then only this element can be included
    if ((getmask(a[pos]) & mask) == 0) {
  
        // Calculate the new mask
        // if this element is included
        int new_mask
            = (mask | (getmask(a[pos])));
  
        count = count
                + countWays(pos + 1,
                            new_mask,
                            a, n);
    }
  
    // Store and return the answer
    return dp[pos][mask] = count;
}
  
// Function to find the count of
// subarray with all digits unique
static int numberOfSubarrays(int a[], int n)
{
    // intializing dp
    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);
}
  
// Driver code
public static void main(String[] args)
{
    int N = 4;
    int A[] = { 1, 12, 23, 34 };
  
    System.out.print(numberOfSubarrays(A, N));
}
}
 
// This code is contributed by Princi Singh


Python3
# Python3 program to find the count
# of subarrays of an Array having all
# unique digits
 
# Function to obtain
# the mask for any integer
def getmask(val):
     
    mask = 0
     
    if val == 0:
        return 1
 
    while (val):
        d = val % 10;
        mask |= (1 << d)
        val = val // 10
 
    return mask
 
# Function to count the number of ways
def countWays(pos, mask, a, n):
 
    # Subarray must not be empty
    if pos == n :
        if mask > 0:
            return 1
        else:
            return 0
 
    # If subproblem has been solved
    if dp[pos][mask] != -1:
        return dp[pos][mask]
 
    count = 0
 
    # Excluding this element in the subarray
    count = (count +
             countWays(pos + 1, mask, a, n))
 
    # If there are no common digits
    # then only this element can be included
    if (getmask(a[pos]) & mask) == 0:
 
        # Calculate the new mask
        # if this element is included
        new_mask = (mask | (getmask(a[pos])))
 
        count = (count +
                 countWays(pos + 1,
                           new_mask,
                           a, n))
 
    # Store and return the answer
    dp[pos][mask] = count
    return count
 
# Function to find the count of
# subarray with all digits unique
def numberOfSubarrays(a, n):
     
    return countWays(0, 0, a, n)
 
# Driver Code
N = 4
A = [ 1, 12, 23, 34 ]
 
rows = 5000
cols = 1100
 
# Initializing dp
dp = [ [ -1 for i in range(cols) ]
            for j in range(rows) ]
             
print( numberOfSubarrays(A, N))
 
# This code is contributed by sarthak_eddy.


C#
// C# program to find the count
// of subarrays of an Array
// having all unique digits
using System;
 
public class GFG{
 
// Dynamic programming table
static int [,]dp = new int[5000, (1 << 10) + 5];
 
// Function to obtain
// the mask for any integer
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;
}
 
// Function to count the number of ways
static int countWays(int pos, int mask,
            int []a, int n)
{
    // Subarray must not be empty
    if (pos == n)
        return (mask > 0 ? 1 : 0);
 
    // If subproblem has been solved
    if (dp[pos, mask] != -1)
        return dp[pos, mask];
 
    int count = 0;
 
    // Excluding this element in the subarray
    count = count
        + countWays(pos + 1, mask, a, n);
 
    // If there are no common digits
    // then only this element can be included
    if ((getmask(a[pos]) & mask) == 0) {
 
        // Calculate the new mask
        // if this element is included
        int new_mask
            = (mask | (getmask(a[pos])));
 
        count = count
            + countWays(pos + 1,
            new_mask, a, n);
    }
 
    // Store and return the answer
    return dp[pos, mask] = count;
}
 
// Function to find the count of
// subarray with all digits unique
static int numberOfSubarrays(int []a, int n)
{
    // intializing dp
    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);
}
 
// Driver code
public static void Main(String[] args)
{
    int N = 4;
    int []A = { 1, 12, 23, 34 };
 
    Console.Write(numberOfSubarrays(A, N));
}
}
// This code contributed by sapnasingh4991


输出:
7


时间复杂度: O(N * 2 N )

有效方法:该方法取决于以下事实:十进制数系统中仅存在10个唯一数字。因此,最长的子数组中只有10位数字才能满足要求的条件。

  • 我们将使用位屏蔽和动态编程来解决该问题。
  • 由于只有10位数字,请考虑每个数字的10位表示形式,如果该数字中存在与该位对应的数字,则每个位为1。
  • 令i为当前数组元素(从1到i-1的元素已被处理)。整数变量“ mask ”表示子数组中已经出现的数字。如果在掩码中设置了第i个位,则表示第i个数字,否则没有。
  • 递归关系的每个步骤中,元素可以包含在子数组中,也可以不包含在子数组中。如果该元素未包含在子数组中,则只需移至下一个索引。如果包含它,则通过将与当前元素数字相对应的所有位设置为“ ON”来更改掩码。
    注意:仅当先前所有元素均未出现时,才可以包括当前元素。
  • 仅当掩码中与当前元素的数字相对应的位为OFF时,才能满足此条件。
  • 如果我们绘制完整的递归树,则可以观察到许多子问题一次又一次地得到解决。因此,我们使用动态编程。使用表dp [] [] ,以便对于每个索引dp [i] [j],i是元素在数组中的位置,而j是掩码。

下面是上述方法的实现:

C++

// C++ program to find the count
// of subarrays of an Array
// having all unique digits
 
#include 
using namespace std;
 
// Dynamic programming table
int dp[5000][(1 << 10) + 5];
 
// Function to obtain
// the mask for any integer
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;
}
 
// Function to count the number of ways
int countWays(int pos, int mask,
              int a[], int n)
{
    // Subarray must not be empty
    if (pos == n)
        return (mask > 0 ? 1 : 0);
 
    // If subproblem has been solved
    if (dp[pos][mask] != -1)
        return dp[pos][mask];
 
    int count = 0;
 
    // Excluding this element in the subarray
    count = count
            + countWays(pos + 1, mask, a, n);
 
    // If there are no common digits
    // then only this element can be included
    if ((getmask(a[pos]) & mask) == 0) {
 
        // Calculate the new mask
        // if this element is included
        int new_mask
            = (mask | (getmask(a[pos])));
 
        count = count
                + countWays(pos + 1,
                            new_mask,
                            a, n);
    }
 
    // Store and return the answer
    return dp[pos][mask] = count;
}
 
// Function to find the count of
// subarray with all digits unique
int numberOfSubarrays(int a[], int n)
{
    // intializing dp
    memset(dp, -1, sizeof(dp));
 
    return countWays(0, 0, a, n);
}
 
// Driver code
int main()
{
    int N = 4;
    int A[] = { 1, 12, 23, 34 };
 
    cout << numberOfSubarrays(A, N);
    return 0;
}

Java

// Java program to find the count
// of subarrays of an Array
// having all unique digits
import java.util.*;
 
class GFG{
  
// Dynamic programming table
static int [][]dp = new int[5000][(1 << 10) + 5];
  
// Function to obtain
// the mask for any integer
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;
}
  
// Function to count the number of ways
static int countWays(int pos, int mask,
              int a[], int n)
{
    // Subarray must not be empty
    if (pos == n)
        return (mask > 0 ? 1 : 0);
  
    // If subproblem has been solved
    if (dp[pos][mask] != -1)
        return dp[pos][mask];
  
    int count = 0;
  
    // Excluding this element in the subarray
    count = count
            + countWays(pos + 1, mask, a, n);
  
    // If there are no common digits
    // then only this element can be included
    if ((getmask(a[pos]) & mask) == 0) {
  
        // Calculate the new mask
        // if this element is included
        int new_mask
            = (mask | (getmask(a[pos])));
  
        count = count
                + countWays(pos + 1,
                            new_mask,
                            a, n);
    }
  
    // Store and return the answer
    return dp[pos][mask] = count;
}
  
// Function to find the count of
// subarray with all digits unique
static int numberOfSubarrays(int a[], int n)
{
    // intializing dp
    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);
}
  
// Driver code
public static void main(String[] args)
{
    int N = 4;
    int A[] = { 1, 12, 23, 34 };
  
    System.out.print(numberOfSubarrays(A, N));
}
}
 
// This code is contributed by Princi Singh

Python3

# Python3 program to find the count
# of subarrays of an Array having all
# unique digits
 
# Function to obtain
# the mask for any integer
def getmask(val):
     
    mask = 0
     
    if val == 0:
        return 1
 
    while (val):
        d = val % 10;
        mask |= (1 << d)
        val = val // 10
 
    return mask
 
# Function to count the number of ways
def countWays(pos, mask, a, n):
 
    # Subarray must not be empty
    if pos == n :
        if mask > 0:
            return 1
        else:
            return 0
 
    # If subproblem has been solved
    if dp[pos][mask] != -1:
        return dp[pos][mask]
 
    count = 0
 
    # Excluding this element in the subarray
    count = (count +
             countWays(pos + 1, mask, a, n))
 
    # If there are no common digits
    # then only this element can be included
    if (getmask(a[pos]) & mask) == 0:
 
        # Calculate the new mask
        # if this element is included
        new_mask = (mask | (getmask(a[pos])))
 
        count = (count +
                 countWays(pos + 1,
                           new_mask,
                           a, n))
 
    # Store and return the answer
    dp[pos][mask] = count
    return count
 
# Function to find the count of
# subarray with all digits unique
def numberOfSubarrays(a, n):
     
    return countWays(0, 0, a, n)
 
# Driver Code
N = 4
A = [ 1, 12, 23, 34 ]
 
rows = 5000
cols = 1100
 
# Initializing dp
dp = [ [ -1 for i in range(cols) ]
            for j in range(rows) ]
             
print( numberOfSubarrays(A, N))
 
# This code is contributed by sarthak_eddy.

C#

// C# program to find the count
// of subarrays of an Array
// having all unique digits
using System;
 
public class GFG{
 
// Dynamic programming table
static int [,]dp = new int[5000, (1 << 10) + 5];
 
// Function to obtain
// the mask for any integer
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;
}
 
// Function to count the number of ways
static int countWays(int pos, int mask,
            int []a, int n)
{
    // Subarray must not be empty
    if (pos == n)
        return (mask > 0 ? 1 : 0);
 
    // If subproblem has been solved
    if (dp[pos, mask] != -1)
        return dp[pos, mask];
 
    int count = 0;
 
    // Excluding this element in the subarray
    count = count
        + countWays(pos + 1, mask, a, n);
 
    // If there are no common digits
    // then only this element can be included
    if ((getmask(a[pos]) & mask) == 0) {
 
        // Calculate the new mask
        // if this element is included
        int new_mask
            = (mask | (getmask(a[pos])));
 
        count = count
            + countWays(pos + 1,
            new_mask, a, n);
    }
 
    // Store and return the answer
    return dp[pos, mask] = count;
}
 
// Function to find the count of
// subarray with all digits unique
static int numberOfSubarrays(int []a, int n)
{
    // intializing dp
    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);
}
 
// Driver code
public static void Main(String[] args)
{
    int N = 4;
    int []A = { 1, 12, 23, 34 };
 
    Console.Write(numberOfSubarrays(A, N));
}
}
// This code contributed by sapnasingh4991
输出:
7


时间复杂度: O(N * 2 10 )