给定一个由数字组成的字符串str ,任务是查找可能的4个数字子序列的数量,这些子序列的形式为(x,x,x + 1,x + 1) ,其中x可以在[0, 8] 。
例子:
Input: str = “1122”
Output: 1
Only one sub-sequence is valid, i.e the entire string itself.
Input: str = “13134422”
Output: 2
Two Valid sub-sequences are present “1122” and “3344”.
方法:
- 我们将找出从0到8的每个可能x的可能子序列的总数。
- 对于每个x,请从字符串中删除所有其他数字,但x和x + 1除外,因为它们不会影响答案。
- 维护前缀Sum数组以计算x + 1位数,直到在字符串中的第i个索引为止。
- 现在,对于每个大小为K的数字俱乐部(即x),我们都可以用KC2的方式选择两个数字。最后两个数字可以是所有数字(x + 1)中的任意两个数字,其后跟数字俱乐部(使用前缀和数组确定数字)的大小L,因此有LC2种选择方式。总路数= KC2 * LC2。
- 直到现在,我们可以认为x来自同一个俱乐部,但也可以来自多个俱乐部。因此,我们必须考虑所有可能的球杆对,并将它们的大小相乘,以获得选择前两个数字的方式。对于最后两个数字,方式将保持不变。
- 为了防止在步骤5中出现计数过多的问题,将只选择可能的方法,其中包括正在考虑的当前球杆,因为在计算先前球杆时已经考虑了其他方法。
- 为x的所有值添加所有可能的方法,并取Modulo。
下面是上述方法的实现:
C++
// C++ implementation of the approach
#include
#define ll long long int
#define MOD 1000000007
using namespace std;
// Function to return the total
// requried sub-sequences
int solve(string test)
{
int size = test.size();
int total = 0;
// Find ways for all values of x
for (int i = 0; i <= 8; i++) {
int x = i;
// x+1
int y = i + 1;
string newtest;
// Removing all unnecessary digits
for (int j = 0; j < size; j++) {
if (test[j] == x + 48 || test[j] == y + 48) {
newtest += test[j];
}
}
if (newtest.size() > 0) {
int size1 = newtest.size();
// Prefix Sum Array for X+1 digit
int prefix[size1] = { 0 };
for (int j = 0; j < size1; j++) {
if (newtest[j] == y + 48) {
prefix[j]++;
}
}
for (int j = 1; j < size1; j++) {
prefix[j] += prefix[j - 1];
}
int count = 0;
int firstcount = 0;
// Sum of squares
int ss = 0;
// Previous sum of all possible pairs
int prev = 0;
for (int j = 0; j < size1; j++) {
if (newtest[j] == x + 48) {
count++;
firstcount++;
}
else {
ss += count * count;
// To find sum of multiplication of all
// possible pairs
int pairsum = (firstcount * firstcount - ss) / 2;
int temp = pairsum;
// To prevent overcounting
pairsum -= prev;
prev = temp;
int secondway = prefix[size1 - 1];
if (j != 0)
secondway -= prefix[j - 1];
int answer = count * (count - 1)
* secondway * (secondway - 1);
answer /= 4;
answer += (pairsum * secondway
* (secondway - 1)) / 2;
// Adding ways for all possible x
total += answer;
count = 0;
}
}
}
}
return total;
}
// Driver code
int main()
{
string test = "13134422";
cout << solve(test) << endl;
return 0;
}
Java
// Java Implementation of above approach
import java.io.*;
class GFG
{
// Function to return the total
// requried sub-sequences
static int solve(String test, int MOD)
{
int size = test.length();
int total = 0;
// Find ways for all values of x
for (int i = 0; i <= 8; i++)
{
int x = i;
// x+1
int y = i + 1;
String newtest = "";
// Removing all unnecessary digits
for (int j = 0; j < size; j++)
{
if (test.charAt(j) == x + 48 || test.charAt(j) == y + 48)
{
newtest += test.charAt(j);
}
}
if (newtest.length() > 0) {
int size1 = newtest.length();
// Prefix Sum Array for X+1 digit
int []prefix = new int[size1];
for (int j = 0; j < size1; j++)
{
prefix[j] = 0;
if (newtest.charAt(j) == y + 48)
{
prefix[j]++;
}
}
for (int j = 1; j < size1; j++)
{
prefix[j] += prefix[j - 1];
}
int count = 0;
int firstcount = 0;
// Sum of squares
int ss = 0;
// Previous sum of all possible pairs
int prev = 0;
for (int j = 0; j < size1; j++)
{
if (newtest.charAt(j) == x + 48)
{
count++;
firstcount++;
}
else
{
ss += count * count;
// To find sum of multiplication of all
// possible pairs
int pairsum = (firstcount * firstcount - ss) / 2;
int temp = pairsum;
// To prevent overcounting
pairsum -= prev;
prev = temp;
int secondway = prefix[size1 - 1];
if (j != 0)
secondway -= prefix[j - 1];
int answer = count * (count - 1)
* secondway * (secondway - 1);
answer /= 4;
answer += (pairsum * secondway
* (secondway - 1)) / 2;
// Adding ways for all possible x
total += answer;
count = 0;
}
}
}
}
return total;
}
// Driver code
public static void main (String[] args)
{
String test = "13134422";
int MOD = 1000000007;
System.out.println(solve(test,MOD));
}
}
// This code is contributed by krikti..
Python3
# Python3 implementation of the approach
MOD= 1000000007
# Function to return the total
# requried sub-sequences
def solve(test):
size = len(test)
total = 0
# Find ways for all values of x
for i in range(9):
x = i
# x+1
y = i + 1
newtest=""
# Removing all unnecessary digits
for j in range(size):
if (ord(test[j]) == x + 48 or ord(test[j]) == y + 48):
newtest += test[j]
if (len(newtest) > 0):
size1 = len(newtest)
# Prefix Sum Array for X+1 digit
prefix=[0 for i in range(size1)]
for j in range(size1):
if (ord(newtest[j]) == y + 48):
prefix[j]+=1
for j in range(1,size1):
prefix[j] += prefix[j - 1]
count = 0
firstcount = 0
# Sum of squares
ss = 0
# Previous sum of all possible pairs
prev = 0
for j in range(size1):
if (ord(newtest[j]) == x + 48):
count+=1
firstcount+=1
else:
ss += count * count
# To find sum of multiplication of all
# possible pairs
pairsum = (firstcount * firstcount - ss) // 2
temp = pairsum
# To prevent overcounting
pairsum -= prev
prev = temp
secondway = prefix[size1 - 1]
if (j != 0):
secondway -= prefix[j - 1]
answer = count * (count - 1)* secondway * (secondway - 1)
answer //= 4
answer += (pairsum * secondway * (secondway - 1)) // 2
# Adding ways for all possible x
total += answer
count = 0
return total
# Driver code
test = "13134422"
print(solve(test))
# This code is contributed by mohit kumar 29
C#
// C# Implementation of above approach
using System;
class GFG
{
// Function to return the total
// requried sub-sequences
static int solve(string test, int MOD)
{
int size = test.Length;
int total = 0;
// Find ways for all values of x
for (int i = 0; i <= 8; i++)
{
int x = i;
// x+1
int y = i + 1;
string newtest = "";
// Removing all unnecessary digits
for (int j = 0; j < size; j++)
{
if (test[j] == x + 48 || test[j] == y + 48)
{
newtest += test[j];
}
}
if (newtest.Length > 0) {
int size1 = newtest.Length;
// Prefix Sum Array for X+1 digit
int []prefix = new int[size1];
for (int j = 0; j < size1; j++)
{
prefix[j] = 0;
if (newtest[j] == y + 48)
{
prefix[j]++;
}
}
for (int j = 1; j < size1; j++)
{
prefix[j] += prefix[j - 1];
}
int count = 0;
int firstcount = 0;
// Sum of squares
int ss = 0;
// Previous sum of all possible pairs
int prev = 0;
for (int j = 0; j < size1; j++)
{
if (newtest[j] == x + 48)
{
count++;
firstcount++;
}
else
{
ss += count * count;
// To find sum of multiplication of all
// possible pairs
int pairsum = (firstcount * firstcount - ss) / 2;
int temp = pairsum;
// To prevent overcounting
pairsum -= prev;
prev = temp;
int secondway = prefix[size1 - 1];
if (j != 0)
secondway -= prefix[j - 1];
int answer = count * (count - 1)
* secondway * (secondway - 1);
answer /= 4;
answer += (pairsum * secondway
* (secondway - 1)) / 2;
// Adding ways for all possible x
total += answer;
count = 0;
}
}
}
}
return total;
}
// Driver code
public static void Main ()
{
string test = "13134422";
int MOD = 1000000007;
Console.WriteLine(solve(test,MOD));
}
}
// This code is contributed by AnkitRai01
输出:
2