如果串联的一对字符串至少由一次(0 – 9)的所有数字组成一次,则称其为“ Pandigital串联”。该任务是给定N个字符串,计算得出的对数。 “ Pandigital级联”。
例子:
Input : num[] = {"123567", "098234", "14765", "19804"}
Output : 3
The pairs, 1st and 2nd giving
(123567098234),1st and 4rd giving(12356719804) and
2nd and 3rd giving (09823414765),
on concatenation result in Pandigital Concatenations.
Input : num[] = {"56789", "098345", "1234"}
Output : 0
None of the pairs on concatenation result in Pandigital
Concatenations.
方法1(蛮力):一种可能的蛮力解决方案是通过在O(n 2)中形成所有对,并使用数字的频率数组(0 – 9)来形成所有可能的级联,我们检查每个数字是否至少存在一次在每对中形成的每个串联中。
C++
// C++ program to find all
// Pandigital concatenations
// of two strings.
#include
using namespace std;
// Checks if a given
// string is Pandigital
bool isPanDigital(string s)
{
bool digits[10] = {false};
for (int i = 0; i < s.length(); i++)
digits[s[i] - '0'] = true;
// digit i is not present
// thus not pandigital
for (int i = 0; i <= 9; i++)
if (digits[i] == false)
return false;
return true;
}
// Returns number of pairs
// of strings resulting in
// Pandigital Concatenations
int countPandigitalPairs(vector &v)
{
// iterate over all
// pair of strings
int pairs = 0;
for (int i = 0; i < v.size(); i++)
for (int j = i + 1; j < v.size(); j++)
if (isPanDigital(v[i] + v[j]))
pairs++;
return pairs;
}
// Driver code
int main()
{
vector v = {"123567", "098234",
"14765", "19804"};
cout << countPandigitalPairs(v) << endl;
return 0;
}
Java
// Java program to find all
// Pandigital concatenations
// of two strings.
import java.io.*;
import java.util.*;
class GFG
{
static ArrayList v =
new ArrayList();
// Checks if a given
// string is Pandigital
static int isPanDigital(String s)
{
int digits[] = new int[10];
for (int i = 0; i < s.length(); i++)
digits[s.charAt(i) -
(int)'0'] = 1;
// digit i is not present
// thus not pandigital
for (int i = 0; i <= 9; i++)
if (digits[i] == 0)
return 0;
return 1;
}
// Returns number of pairs
// of strings resulting in
// Pandigital Concatenations
static int countPandigitalPairs()
{
// iterate over all
// pair of strings
int pairs = 0;
for (int i = 0; i < v.size(); i++)
for (int j = i + 1;
j < v.size(); j++)
if (isPanDigital(v.get(i) +
v.get(j)) == 1)
pairs++;
return pairs;
}
// Driver code
public static void main(String args[])
{
v.add("123567");
v.add("098234");
v.add("14765");
v.add("19804");
System.out.print(countPandigitalPairs());
}
}
// This code is contributed
// by Manish Shaw(manishshaw1)
Python3
# Python3 program to find all
# Pandigital concatenations
# of two strings.
# Checks if a given
# is Pandigital
def isPanDigital(s) :
digits = [False] * 10;
for i in range(0, len(s)) :
digits[int(s[i]) -
int('0')] = True
# digit i is not present
# thus not pandigital
for i in range(0, 10) :
if (digits[i] == False) :
return False
return True
# Returns number of pairs
# of strings resulting in
# Pandigital Concatenations
def countPandigitalPairs(v) :
# iterate over all
# pair of strings
pairs = 0
for i in range(0, len(v)) :
for j in range (i + 1,
len(v)) :
if (isPanDigital(v[i] +
v[j])) :
pairs = pairs + 1
return pairs
# Driver code
v = ["123567", "098234",
"14765", "19804"]
print (countPandigitalPairs(v))
# This code is contributed by
# Manish Shaw(manishshaw1)
C#
// C# program to find all Pandigital
// concatenations of two strings.
using System;
using System.Collections.Generic;
class GFG
{
// Checks if a given
// string is Pandigital
static int isPanDigital(string s)
{
int []digits = new int[10];
Array.Clear(digits, 0, 10);
for (int i = 0; i < s.Length; i++)
digits[s[i] - (int)'0'] = 1;
// digit i is not present
// thus not pandigital
for (int i = 0; i <= 9; i++)
if (digits[i] == 0)
return 0;
return 1;
}
// Returns number of pairs
// of strings resulting in
// Pandigital Concatenations
static int countPandigitalPairs(ref List v)
{
// iterate over all
// pair of strings
int pairs = 0;
for (int i = 0; i < v.Count; i++)
for (int j = i + 1; j < v.Count; j++)
if (isPanDigital(v[i] + v[j]) == 1)
pairs++;
return pairs;
}
// Driver code
static void Main()
{
List v = new List{"123567", "098234",
"14765", "19804"};
Console.WriteLine(countPandigitalPairs(ref v));
}
}
// This code is contributed
// by Manish Shaw(manishshaw1)
PHP
C++
// C++ program to count PanDigital pairs
#include
using namespace std;
const int pandigitalMask = ((1 << 10) - 1);
void computeMaskFrequencies(vector v, map& freq)
{
for (int i = 0; i < v.size(); i++) {
int mask = 0;
// Stores digits present in string v[i]
// atleast once. We use a set as we only
// need digits which exist only once
// (irrespective of reputation)
unordered_set digits;
for (int j = 0; j < v[i].size(); j++)
digits.insert(v[i][j] - '0');
// Calculate the mask by considering all digits
// existing atleast once
for (auto it = digits.begin(); it != digits.end(); it++) {
int digit = (*it);
mask += (1 << digit);
}
// Increment the frequency of this mask
freq[mask]++;
}
}
// Returns number of pairs of strings resulting
// in Pandigital Concatenations
int pandigitalConcatenations(map freq)
{
int ans = 0;
// All possible strings lie between 1 and 1023
// so we iterate over every possible mask
for (int i = 1; i <= 1023; i++) {
for (int j = 1; j <= 1023; j++) {
// if the concatenation results in mask of
// Pandigital Concatenation, calculate all
// pairs formed with Masks i and j
if ((i | j) == pandigitalMask) {
if (i == j)
ans += (freq[i] * (freq[i] - 1));
else
ans += (freq[i] * freq[j]);
}
}
}
// since every pair is considers twice,
// we get rid of half of these
return ans/2;
}
int countPandigitalPairs(vector v)
{
// Find frequencies of all masks in
// given vector of strings
map freq;
computeMaskFrequencies(v, freq);
// Return all possiblg concatenations.
return pandigitalConcatenations(freq);
}
// Driver code
int main()
{
vector v = {"123567", "098234", "14765", "19804"};
cout << countPandigitalPairs(v) << endl;
return 0;
}
Java
// Java program to count PanDigital pairs
import java.util.*;
class GFG{
static int pandigitalMask = ((1 << 10) - 1);
static void computeMaskFrequencies(Vector v,
HashMap freq)
{
for(int i = 0; i < v.size(); i++)
{
int mask = 0;
// Stores digits present in String v[i]
// atleast once. We use a set as we only
// need digits which exist only once
// (irrespective of reputation)
HashSet digits = new HashSet<>();
for(int j = 0; j < v.get(i).length(); j++)
digits.add(v.get(i).charAt(j) - '0');
// Calculate the mask by considering
// all digits existing atleast once
for(int it :digits)
{
int digit = (it);
mask += (1 << digit);
}
// Increment the frequency of
// this mask
if (freq.containsKey(mask))
{
freq.put(mask, freq.get(mask) + 1);
}
else
{
freq.put(mask, 1);
}
}
}
// Returns number of pairs of Strings
// resulting in Pandigital Concatenations
static int pandigitalConcatenations(
HashMap freq)
{
int ans = 0;
// All possible Strings lie between
// 1 and 1023 so we iterate over every
// possible mask
for(int i = 1; i <= 1023; i++)
{
for(int j = 1; j <= 1023; j++)
{
// If the concatenation results in mask of
// Pandigital Concatenation, calculate all
// pairs formed with Masks i and j
if ((i | j) == pandigitalMask &&
freq.containsKey(j) &&
freq.containsKey(i))
{
if (i == j)
ans += (freq.get(i) *
(freq.get(i) - 1));
else
ans += (freq.get(i) *
freq.get(j));
}
}
}
// Since every pair is considers twice,
// we get rid of half of these
return ans / 2;
}
static int countPandigitalPairs(Vector v)
{
// Find frequencies of all masks in
// given vector of Strings
HashMap freq = new HashMap<>();
computeMaskFrequencies(v, freq);
// Return all possiblg concatenations.
return pandigitalConcatenations(freq);
}
// Driver code
public static void main(String[] args)
{
Vector v = new Vector<>();
v.add("123567");
v.add("098234");
v.add("14765");
v.add("19804");
System.out.print(countPandigitalPairs(v) + "\n");
}
}
// This code is contributed by Amit Katiyar
C#
// C# program to count
// PanDigital pairs
using System;
using System.Collections.Generic;
class GFG{
static int pandigitalMask =
((1 << 10) - 1);
static void computeMaskFrequencies(List v,
Dictionary freq)
{
for(int i = 0; i < v.Count; i++)
{
int mask = 0;
// Stores digits present in String v[i]
// atleast once. We use a set as we only
// need digits which exist only once
// (irrespective of reputation)
HashSet digits = new HashSet();
for(int j = 0; j < v[i].Length; j++)
digits.Add(v[i][j] - '0');
// Calculate the mask by considering
// all digits existing atleast once
foreach(int it in digits)
{
int digit = (it);
mask += (1 << digit);
}
// Increment the frequency of
// this mask
if (freq.ContainsKey(mask))
{
freq[mask]++;
}
else
{
freq.Add(mask, 1);
}
}
}
// Returns number of pairs of
// Strings resulting in Pandigital
// Concatenations
static int pandigitalConcatenations(Dictionary freq)
{
int ans = 0;
// All possible Strings lie between
// 1 and 1023 so we iterate over every
// possible mask
for(int i = 1; i <= 1023; i++)
{
for(int j = 1; j <= 1023; j++)
{
// If the concatenation results in
// mask of Pandigital Concatenation,
// calculate all pairs formed with
// Masks i and j
if ((i | j) == pandigitalMask &&
freq.ContainsKey(j) &&
freq.ContainsKey(i))
{
if (i == j)
ans += (freq[i] *
(freq[i] - 1));
else
ans += (freq[i] *
freq[j]);
}
}
}
// Since every pair is considers
// twice, we get rid of half of
// these
return ans / 2;
}
static int countPandigitalPairs(List v)
{
// Find frequencies of all masks in
// given vector of Strings
Dictionary freq = new Dictionary();
computeMaskFrequencies(v, freq);
// Return all possiblg concatenations.
return pandigitalConcatenations(freq);
}
// Driver code
public static void Main(String[] args)
{
List v = new List();
v.Add("123567");
v.Add("098234");
v.Add("14765");
v.Add("19804");
Console.Write(countPandigitalPairs(v) + "\n");
}
}
// This code is contributed by 29AjayKumar
输出:
3
方法2(高效):
现在,我们正在寻找比上面讨论的蛮力更好的东西。仔细的分析表明,对于出现的每个0到9的数字,我们都有一个掩码1111111111(即,所有0-9都存在于数字数组中)
Digits - 0 1 2 3 4 5 6 7 8 9
| | | | | | | | | |
Mask - 1 1 1 1 1 1 1 1 1 1
Here 1 denotes that the corresponding digits
exists at-least once thus for all such Pandigital
Concatenations, this relationship should hold.
So we can represent 11...11 as a valid mask for
pandigital concatenations.
所以,现在的做法是表示每一个字符串的地方,如果在字符串中存在第i位的第i位为10位掩码。
E.g., "11405" can be represented as
Digits - 0 1 2 3 4 5 6 7 8 9
| | | | | | | | | |
Mask for 11405 - 1 1 0 0 1 1 0 0 0 0
该方法虽然看起来很完整,但仍然无效,因为我们仍然必须遍历所有对,并检查这两个字符串的OR是否会导致有效的Pandigital级联的掩码。
如果我们分析所有可能的字符串的可能掩码,我们可以理解,每个单个字符串将仅由数字0 – 9组成,因此每个数字最多最多可以包含0到9的所有数字,因此该数字的掩码将是1111111111(十进制为1023)。因此,在十进制系统中,所有掩码都以(0 – 1023]的形式退出。
现在我们只需要维护一个频率数组来存储掩码在字符串数组中存在的次数。
Let two masks be i and j with frequencies freqi and freqj respectively,
If (i OR j) = Maskpandigital concatenation
Then,
Number of Pairs = freqi * freqj
C++
// C++ program to count PanDigital pairs
#include
using namespace std;
const int pandigitalMask = ((1 << 10) - 1);
void computeMaskFrequencies(vector v, map& freq)
{
for (int i = 0; i < v.size(); i++) {
int mask = 0;
// Stores digits present in string v[i]
// atleast once. We use a set as we only
// need digits which exist only once
// (irrespective of reputation)
unordered_set digits;
for (int j = 0; j < v[i].size(); j++)
digits.insert(v[i][j] - '0');
// Calculate the mask by considering all digits
// existing atleast once
for (auto it = digits.begin(); it != digits.end(); it++) {
int digit = (*it);
mask += (1 << digit);
}
// Increment the frequency of this mask
freq[mask]++;
}
}
// Returns number of pairs of strings resulting
// in Pandigital Concatenations
int pandigitalConcatenations(map freq)
{
int ans = 0;
// All possible strings lie between 1 and 1023
// so we iterate over every possible mask
for (int i = 1; i <= 1023; i++) {
for (int j = 1; j <= 1023; j++) {
// if the concatenation results in mask of
// Pandigital Concatenation, calculate all
// pairs formed with Masks i and j
if ((i | j) == pandigitalMask) {
if (i == j)
ans += (freq[i] * (freq[i] - 1));
else
ans += (freq[i] * freq[j]);
}
}
}
// since every pair is considers twice,
// we get rid of half of these
return ans/2;
}
int countPandigitalPairs(vector v)
{
// Find frequencies of all masks in
// given vector of strings
map freq;
computeMaskFrequencies(v, freq);
// Return all possiblg concatenations.
return pandigitalConcatenations(freq);
}
// Driver code
int main()
{
vector v = {"123567", "098234", "14765", "19804"};
cout << countPandigitalPairs(v) << endl;
return 0;
}
Java
// Java program to count PanDigital pairs
import java.util.*;
class GFG{
static int pandigitalMask = ((1 << 10) - 1);
static void computeMaskFrequencies(Vector v,
HashMap freq)
{
for(int i = 0; i < v.size(); i++)
{
int mask = 0;
// Stores digits present in String v[i]
// atleast once. We use a set as we only
// need digits which exist only once
// (irrespective of reputation)
HashSet digits = new HashSet<>();
for(int j = 0; j < v.get(i).length(); j++)
digits.add(v.get(i).charAt(j) - '0');
// Calculate the mask by considering
// all digits existing atleast once
for(int it :digits)
{
int digit = (it);
mask += (1 << digit);
}
// Increment the frequency of
// this mask
if (freq.containsKey(mask))
{
freq.put(mask, freq.get(mask) + 1);
}
else
{
freq.put(mask, 1);
}
}
}
// Returns number of pairs of Strings
// resulting in Pandigital Concatenations
static int pandigitalConcatenations(
HashMap freq)
{
int ans = 0;
// All possible Strings lie between
// 1 and 1023 so we iterate over every
// possible mask
for(int i = 1; i <= 1023; i++)
{
for(int j = 1; j <= 1023; j++)
{
// If the concatenation results in mask of
// Pandigital Concatenation, calculate all
// pairs formed with Masks i and j
if ((i | j) == pandigitalMask &&
freq.containsKey(j) &&
freq.containsKey(i))
{
if (i == j)
ans += (freq.get(i) *
(freq.get(i) - 1));
else
ans += (freq.get(i) *
freq.get(j));
}
}
}
// Since every pair is considers twice,
// we get rid of half of these
return ans / 2;
}
static int countPandigitalPairs(Vector v)
{
// Find frequencies of all masks in
// given vector of Strings
HashMap freq = new HashMap<>();
computeMaskFrequencies(v, freq);
// Return all possiblg concatenations.
return pandigitalConcatenations(freq);
}
// Driver code
public static void main(String[] args)
{
Vector v = new Vector<>();
v.add("123567");
v.add("098234");
v.add("14765");
v.add("19804");
System.out.print(countPandigitalPairs(v) + "\n");
}
}
// This code is contributed by Amit Katiyar
C#
// C# program to count
// PanDigital pairs
using System;
using System.Collections.Generic;
class GFG{
static int pandigitalMask =
((1 << 10) - 1);
static void computeMaskFrequencies(List v,
Dictionary freq)
{
for(int i = 0; i < v.Count; i++)
{
int mask = 0;
// Stores digits present in String v[i]
// atleast once. We use a set as we only
// need digits which exist only once
// (irrespective of reputation)
HashSet digits = new HashSet();
for(int j = 0; j < v[i].Length; j++)
digits.Add(v[i][j] - '0');
// Calculate the mask by considering
// all digits existing atleast once
foreach(int it in digits)
{
int digit = (it);
mask += (1 << digit);
}
// Increment the frequency of
// this mask
if (freq.ContainsKey(mask))
{
freq[mask]++;
}
else
{
freq.Add(mask, 1);
}
}
}
// Returns number of pairs of
// Strings resulting in Pandigital
// Concatenations
static int pandigitalConcatenations(Dictionary freq)
{
int ans = 0;
// All possible Strings lie between
// 1 and 1023 so we iterate over every
// possible mask
for(int i = 1; i <= 1023; i++)
{
for(int j = 1; j <= 1023; j++)
{
// If the concatenation results in
// mask of Pandigital Concatenation,
// calculate all pairs formed with
// Masks i and j
if ((i | j) == pandigitalMask &&
freq.ContainsKey(j) &&
freq.ContainsKey(i))
{
if (i == j)
ans += (freq[i] *
(freq[i] - 1));
else
ans += (freq[i] *
freq[j]);
}
}
}
// Since every pair is considers
// twice, we get rid of half of
// these
return ans / 2;
}
static int countPandigitalPairs(List v)
{
// Find frequencies of all masks in
// given vector of Strings
Dictionary freq = new Dictionary();
computeMaskFrequencies(v, freq);
// Return all possiblg concatenations.
return pandigitalConcatenations(freq);
}
// Driver code
public static void Main(String[] args)
{
List v = new List();
v.Add("123567");
v.Add("098234");
v.Add("14765");
v.Add("19804");
Console.Write(countPandigitalPairs(v) + "\n");
}
}
// This code is contributed by 29AjayKumar
输出:
3
复杂度: O(N * | s | + 1023 * 1023)其中| s |给出数组中字符串的长度