给定一个代表一个大数的字符串str ,任务是找到给定字符串可以被划分的最小段数,使得每个段都是1 到 10 6范围内的素数。
例子:
Input: str = “13499315”
Output: 3
Explanation:
The number can be segmented as [13499, 31, 5]
Input: str = “43”
Output: 1
Explanation:
The number can be segmented as [43]
朴素的方法:这个想法是考虑每个前缀最多 6 位(因为给定素数小于 10 6 )并检查它是否是素数。如果前缀是素数,则递归调用该函数以检查剩余的字符串。如果返回一个非负数,那么它被认为是一种可能的安排。如果所有可能的组合都没有返回正数,则打印 -1。
下面是上述方法的实现:
C++
// C++ implementation of the above approach
#include
#include
using namespace std;
// Function to check whether a string
// is a prime number or not
bool checkPrime(string number)
{
int num = stoi(number);
for (int i = 2; i * i <= num; i++)
if ((num % i) == 0)
return false;
return true;
}
// A recursive function to find the minimum
// number of segments the given string can
// be divided such that every segment is a prime
int splitIntoPrimes(string number)
{
// If the number is null
if (number.length() == 0)
return 0;
// checkPrime function is called to check if
// the number is a prime or not.
if (number.length() <= 6 and checkPrime(number))
return 1;
else {
int numLen = number.length();
// A very large number denoting maximum
int ans = 1000000;
// Consider a minimum of 6 and length
// since the primes are less than 10 ^ 6
for (int i = 1; i <= 6 && i <= numLen; i++) {
if (checkPrime(number.substr(0, i))) {
// Recursively call the function
// to check for the remaining string
int val = splitIntoPrimes(number.substr(i));
if (val != -1) {
// Evaluating minimum splits
// into Primes for the suffix
ans = min(ans, 1 + val);
}
}
}
// Checks if no combination found
if (ans == 1000000)
return -1;
return ans;
}
}
// Driver code
int main()
{
cout << splitIntoPrimes("13499315") << "\n";
cout << splitIntoPrimes("43") << "\n";
return 0;
}
Java
// Java implementation of the above approach
import java.util.*;
class GFG{
// Function to check whether a String
// is a prime number or not
static boolean checkPrime(String number)
{
int num = Integer.valueOf(number);
for (int i = 2; i * i <= num; i++)
if ((num % i) == 0)
return false;
return true;
}
// A recursive function to find the minimum
// number of segments the given String can
// be divided such that every segment is a prime
static int splitIntoPrimes(String number)
{
// If the number is null
if (number.length() == 0)
return 0;
// checkPrime function is called to check if
// the number is a prime or not.
if (number.length() <= 6 && checkPrime(number))
return 1;
else {
int numLen = number.length();
// A very large number denoting maximum
int ans = 1000000;
// Consider a minimum of 6 and length
// since the primes are less than 10 ^ 6
for (int i = 1; i <= 6 && i <= numLen; i++) {
if (checkPrime(number.substring(0, i))) {
// Recursively call the function
// to check for the remaining String
int val = splitIntoPrimes(number.substring(i));
if (val != -1) {
// Evaluating minimum splits
// into Primes for the suffix
ans = Math.min(ans, 1 + val);
}
}
}
// Checks if no combination found
if (ans == 1000000)
return -1;
return ans;
}
}
// Driver code
public static void main(String[] args)
{
System.out.print(splitIntoPrimes("13499315")+ "\n");
System.out.print(splitIntoPrimes("43")+ "\n");
}
}
// This code is contributed by Rajput-Ji
Python3
# Python3 implementation of the above approach
# Function to check whether a string
# is a prime number or not
def checkPrime(number) :
num = int(number)
for i in range(2, int(num**0.5)) :
if((num % i) == 0) :
return False
return True
# A recursive function to find the minimum
# number of segments the given string can
# be divided such that every segment is a prime
def splitIntoPrimes(number) :
# If the number is null
if( number == '' ) :
return 0
# checkPrime function is called to check if
# the number is a prime or not.
if( len(number)<= 6 and checkPrime(number) ) :
return 1
else :
numLen = len(number)
# A very large number denoting maximum
ans = 1000000
# Consider a minimum of 6 and length
# since the primes are less than 10 ^ 6
for i in range( 1, (min( 6, numLen ) + 1) ) :
if( checkPrime( number[:i] ) ) :
# Recursively call the function
# to check for the remaining string
val = splitIntoPrimes( number[i:] )
if(val != -1) :
# Evaluating minimum splits
# into Primes for the suffix
ans = min(ans, 1 + val)
# Checks if no combination found
if( ans == 1000000 ) :
return -1
return ans
# Driver code
print(splitIntoPrimes("13499315"))
print(splitIntoPrimes("43"))
C#
// C# implementation of the above approach
using System;
class GFG{
// Function to check whether a String
// is a prime number or not
static bool checkPrime(String number)
{
int num = Int32.Parse(number);
for (int i = 2; i * i <= num; i++)
if ((num % i) == 0)
return false;
return true;
}
// A recursive function to find the minimum
// number of segments the given String can
// be divided such that every segment is a prime
static int splitIntoPrimes(String number)
{
// If the number is null
if (number.Length == 0)
return 0;
// checkPrime function is called to check if
// the number is a prime or not.
if (number.Length <= 6 && checkPrime(number))
return 1;
else {
int numLen = number.Length;
// A very large number denoting maximum
int ans = 1000000;
// Consider a minimum of 6 and length
// since the primes are less than 10 ^ 6
for (int i = 1; i <= 6 && i <= numLen; i++) {
if (checkPrime(number.Substring(0, i))) {
// Recursively call the function
// to check for the remaining String
int val = splitIntoPrimes(number.Substring(i));
if (val != -1) {
// Evaluating minimum splits
// into Primes for the suffix
ans = Math.Min(ans, 1 + val);
}
}
}
// Checks if no combination found
if (ans == 1000000)
return -1;
return ans;
}
}
// Driver code
public static void Main(String[] args)
{
Console.Write(splitIntoPrimes("13499315")+ "\n");
Console.Write(splitIntoPrimes("43")+ "\n");
}
}
// This code is contributed by sapnasingh4991
Javascript
C++
// C++ implementation of the above approach
#include
using namespace std;
// Function to check whether a string
// is a prime number or not
bool checkPrime(string number)
{
int num = stoi(number);
for (int i = 2; i * i <= num; i++)
if ((num % i) == 0)
return false;
return true;
}
// A function to find the minimum
// number of segments the given string
// can be divided such that every
// segment is a prime
int splitIntoPrimes(string number)
{
int numLen = number.length();
// Declare a splitdp[] array
// and initialize to -1
int splitDP[numLen + 1];
memset(splitDP, -1, sizeof(splitDP));
// Build the DP table in
// a bottom-up manner
for (int i = 1; i <= numLen; i++) {
// Initially Check if the entire prefix is Prime
if (i <= 6 && checkPrime(number.substr(0, i)))
splitDP[i] = 1;
// If the Given Prefix can be split into Primes
// then for the remaining string from i to j
// Check if Prime. If yes calculate
// the minimum split till j
if (splitDP[i] != -1) {
for (int j = 1; j <= 6 && i + j <= numLen; j++) {
// To check if the substring from i to j
// is a prime number or not
if (checkPrime(number.substr(i, j))) {
// If it is a prime, then update the dp array
if (splitDP[i + j] == -1)
splitDP[i + j] = 1 + splitDP[i];
else
splitDP[i + j] = min(splitDP[i + j],
1 + splitDP[i]);
}
}
}
}
// Return the minimum number of splits
// for the entire string
return splitDP[numLen];
}
// Driver code
int main()
{
cout << splitIntoPrimes("13499315") << "\n";
cout << splitIntoPrimes("43") << "\n";
return 0;
}
Java
// Java implementation of the above approach
import java.util.*;
class GFG{
// Function to check whether a String
// is a prime number or not
static boolean checkPrime(String number)
{
if(number.length()==0)
return true;
int num = Integer.parseInt(number);
for (int i = 2; i * i <= num; i++)
if ((num % i) == 0)
return false;
return true;
}
// A function to find the minimum
// number of segments the given String
// can be divided such that every
// segment is a prime
static int splitIntoPrimes(String number)
{
int numLen = number.length();
// Declare a splitdp[] array
// and initialize to -1
int []splitDP = new int[numLen + 1];
Arrays.fill(splitDP, -1);
// Build the DP table in
// a bottom-up manner
for (int i = 1; i <= numLen; i++) {
// Initially Check if the entire prefix is Prime
if (i <= 6 && checkPrime(number.substring(0, i)))
splitDP[i] = 1;
// If the Given Prefix can be split into Primes
// then for the remaining String from i to j
// Check if Prime. If yes calculate
// the minimum split till j
if (splitDP[i] != -1) {
for (int j = 1; j <= 6 && i + j <= numLen; j++) {
// To check if the subString from i to j
// is a prime number or not
if (checkPrime(number.substring(i, i+j))) {
// If it is a prime, then update the dp array
if (splitDP[i + j] == -1)
splitDP[i + j] = 1 + splitDP[i];
else
splitDP[i + j] = Math.min(splitDP[i + j],
1 + splitDP[i]);
}
}
}
}
// Return the minimum number of splits
// for the entire String
return splitDP[numLen];
}
// Driver code
public static void main(String[] args)
{
System.out.print(splitIntoPrimes("13499315")+ "\n");
System.out.print(splitIntoPrimes("43")+ "\n");
}
}
// This code contributed by Princi Singh
Python3
# Python 3 implementation of the above approach
from math import sqrt
# Function to check whether a string
# is a prime number or not
def checkPrime(number):
if(len(number) == 0):
return True
num = int(number)
for i in range(2,int(sqrt(num)) + 1, 1):
if ((num % i) == 0):
return False
return True
# A function to find the minimum
# number of segments the given string
# can be divided such that every
# segment is a prime
def splitIntoPrimes(number):
numLen = len(number)
# Declare a splitdp[] array
# and initialize to -1
splitDP = [-1 for i in range(numLen + 1)]
# Build the DP table in
# a bottom-up manner
for i in range(1, numLen + 1, 1):
# Initially Check if the entire prefix is Prime
if (i <= 6 and checkPrime(number[0:i])):
splitDP[i] = 1
# If the Given Prefix can be split into Primes
# then for the remaining string from i to j
# Check if Prime. If yes calculate
# the minimum split till j
if (splitDP[i] != -1):
j = 1
while(j <= 6 and i + j <= numLen):
# To check if the substring from i to j
# is a prime number or not
if (checkPrime(number[i:i+j])):
# If it is a prime, then update the dp array
if (splitDP[i + j] == -1):
splitDP[i + j] = 1 + splitDP[i]
else:
splitDP[i + j] = min(splitDP[i + j], 1 + splitDP[i])
j += 1
# Return the minimum number of splits
# for the entire string
return splitDP[numLen]
# Driver code
if __name__ == '__main__':
print(splitIntoPrimes("13499315"))
print(splitIntoPrimes("43"))
# This code is contributed by Surendra_Gangwar
C#
// C# implementation of the above approach
using System;
class GFG{
// Function to check whether a String
// is a prime number or not
static bool checkPrime(String number)
{
if(number.Length==0)
return true;
int num = Int32.Parse(number);
for (int i = 2; i * i <= num; i++)
if ((num % i) == 0)
return false;
return true;
}
// A function to find the minimum
// number of segments the given String
// can be divided such that every
// segment is a prime
static int splitIntoPrimes(String number)
{
int numLen = number.Length;
// Declare a splitdp[] array
// and initialize to -1
int []splitDP = new int[numLen + 1];
for (int i = 0; i <= numLen; i++)
splitDP[i] = -1;
// Build the DP table in
// a bottom-up manner
for (int i = 1; i <= numLen; i++) {
// Initially Check if the entire prefix is Prime
if (i <= 6 && checkPrime(number.Substring(0, i)))
splitDP[i] = 1;
// If the Given Prefix can be split into Primes
// then for the remaining String from i to j
// Check if Prime. If yes calculate
// the minimum split till j
if (splitDP[i] != -1) {
for (int j = 1; j <= 6 && i + j <= numLen; j++) {
// To check if the subString from i to j
// is a prime number or not
if (checkPrime(number.Substring(i, j))) {
// If it is a prime, then update the dp array
if (splitDP[i + j] == -1)
splitDP[i + j] = 1 + splitDP[i];
else
splitDP[i + j] = Math.Min(splitDP[i + j],
1 + splitDP[i]);
}
}
}
}
// Return the minimum number of splits
// for the entire String
return splitDP[numLen];
}
// Driver code
public static void Main(String[] args)
{
Console.Write(splitIntoPrimes("13499315")+ "\n");
Console.Write(splitIntoPrimes("43")+ "\n");
}
}
// This code is contributed by Rajput-Ji
Javascript
C++
// C++ implementation of the above approach
#include
using namespace std;
// Function to precompute all the primes
// upto 1000000 and store it in a set
// using Sieve of Eratosthenes
void getPrimesFromSeive(set& primes)
{
bool prime[1000001];
memset(prime, true, sizeof(prime));
prime[0] = prime[1] = false;
for (int i = 2; i * i <= 1000000; i++) {
if (prime[i] == true) {
for (int j = i * i; j <= 1000000; j += i)
prime[j] = false;
}
}
// Here to_string() is used
// for converting int to string
for (int i = 2; i <= 1000000; i++) {
if (prime[i] == true)
primes.insert(to_string(i));
}
}
// A function to find the minimum
// number of segments the given string
// can be divided such that every
// segment is a prime
int splitIntoPrimes(string number)
{
int numLen = number.length();
// Declare a splitdp[] array
// and initialize to -1
int splitDP[numLen + 1];
memset(splitDP, -1, sizeof(splitDP));
// Call sieve function to store primes in
// primes array
set primes;
getPrimesFromSeive(primes);
// Build the DP table in a bottom-up manner
for (int i = 1; i <= numLen; i++) {
// If the prefix is prime then the prefix
// will be found in the prime set
if (i <= 6 && (primes.find(number.substr(0, i))
!= primes.end()))
splitDP[i] = 1;
// If the Given Prefix can be split into Primes
// then for the remaining string from i to j
// Check if Prime. If yes calculate
// the minimum split till j
if (splitDP[i] != -1) {
for (int j = 1; j <= 6 && i + j <= numLen; j++) {
// To check if the substring from i to j
// is a prime number or not
if (primes.find(number.substr(i, j))
!= primes.end()) {
// If it is a prime, then update the dp array
if (splitDP[i + j] == -1)
splitDP[i + j] = 1 + splitDP[i];
else
splitDP[i + j] = min(splitDP[i + j],
1 + splitDP[i]);
}
}
}
}
// Return the minimum number of splits
// for the entire string
return splitDP[numLen];
}
int main()
{
cout << splitIntoPrimes("13499315") << "\n";
cout << splitIntoPrimes("43") << "\n";
return 0;
}
Java
// Java implementation of the above approach
import java.util.*;
class GFG{
// Function to precompute all the primes
// upto 1000000 and store it in a set
// using Sieve of Eratosthenes
static void getPrimesFromSeive(HashSet primes)
{
boolean []prime = new boolean[1000001];
Arrays.fill(prime, true);
prime[0] = prime[1] = false;
for (int i = 2; i * i <= 1000000; i++) {
if (prime[i] == true) {
for (int j = i * i; j <= 1000000; j += i)
prime[j] = false;
}
}
// Here to_String() is used
// for converting int to String
for (int i = 2; i <= 1000000; i++) {
if (prime[i] == true)
primes.add(String.valueOf(i));
}
}
// A function to find the minimum
// number of segments the given String
// can be divided such that every
// segment is a prime
static int splitIntoPrimes(String number)
{
int numLen = number.length();
// Declare a splitdp[] array
// and initialize to -1
int []splitDP = new int[numLen + 1];
Arrays.fill(splitDP, -1);
// Call sieve function to store primes in
// primes array
HashSet primes = new HashSet();
getPrimesFromSeive(primes);
// Build the DP table in a bottom-up manner
for (int i = 1; i <= numLen; i++) {
// If the prefix is prime then the prefix
// will be found in the prime set
if (i <= 6 && (primes.contains(number.substring(0, i))))
splitDP[i] = 1;
// If the Given Prefix can be split into Primes
// then for the remaining String from i to j
// Check if Prime. If yes calculate
// the minimum split till j
if (splitDP[i] != -1) {
for (int j = 1; j <= 6 && i + j <= numLen; j++) {
// To check if the subString from i to j
// is a prime number or not
if (primes.contains(number.substring(i, i+j))) {
// If it is a prime, then update the dp array
if (splitDP[i + j] == -1)
splitDP[i + j] = 1 + splitDP[i];
else
splitDP[i + j] = Math.min(splitDP[i + j],
1 + splitDP[i]);
}
}
}
}
// Return the minimum number of splits
// for the entire String
return splitDP[numLen];
}
public static void main(String[] args)
{
System.out.print(splitIntoPrimes("13499315")+ "\n");
System.out.print(splitIntoPrimes("43")+ "\n");
}
}
// This code contributed by Princi Singh
Python3
# Python3 implementation of the above approach
# Function to precompute all the primes
# upto 1000000 and store it in a set
# using Sieve of Eratosthenes
def getPrimesFromSeive(primes):
prime = [True] * (1000001)
prime[0], prime[1] = False, False
i = 2
while (i * i <= 1000000):
if (prime[i] == True):
for j in range(i * i, 1000001, i):
prime[j] = False
i += 1
# Here str() is used for
# converting int to string
for i in range(2, 1000001):
if (prime[i] == True):
primes.append(str(i))
# A function to find the minimum
# number of segments the given string
# can be divided such that every
# segment is a prime
def splitIntoPrimes(number):
numLen = len(number)
# Declare a splitdp[] array
# and initialize to -1
splitDP = [-1] * (numLen + 1)
# Call sieve function to store
# primes in primes array
primes = []
getPrimesFromSeive(primes)
# Build the DP table in a bottom-up manner
for i in range(1, numLen + 1):
# If the prefix is prime then the prefix
# will be found in the prime set
if (i <= 6 and (number[0 : i] in primes)):
splitDP[i] = 1
# If the Given Prefix can be split into Primes
# then for the remaining string from i to j
# Check if Prime. If yes calculate
# the minimum split till j
if (splitDP[i] != -1):
j = 1
while (j <= 6 and (i + j <= numLen)):
# To check if the substring from i to j
# is a prime number or not
if (number[i : i + j] in primes):
# If it is a prime, then
# update the dp array
if (splitDP[i + j] == -1):
splitDP[i + j] = 1 + splitDP[i]
else:
splitDP[i + j] = min(splitDP[i + j],
1 + splitDP[i])
j += 1
# Return the minimum number of
# splits for the entire string
return splitDP[numLen]
# Driver code
print(splitIntoPrimes("13499315"))
print(splitIntoPrimes("43"))
# This code is contributed by chitranayal
C#
// C# implementation of the above approach
using System;
using System.Collections.Generic;
class GFG{
// Function to precompute all the primes
// upto 1000000 and store it in a set
// using Sieve of Eratosthenes
static void getPrimesFromSeive(HashSet primes)
{
bool []prime = new bool[1000001];
for(int i = 0; i < 1000001; i++)
prime[i] = true;
prime[0] = prime[1] = false;
for(int i = 2; i * i <= 1000000; i++)
{
if (prime[i] == true)
{
for(int j = i * i; j <= 1000000; j += i)
prime[j] = false;
}
}
// Converting int to String
for(int i = 2; i <= 1000000; i++)
{
if (prime[i] == true)
primes.Add(String.Join("", i));
}
}
// A function to find the minimum
// number of segments the given String
// can be divided such that every
// segment is a prime
static int splitIntoPrimes(String number)
{
int numLen = number.Length;
// Declare a splitdp[] array
// and initialize to -1
int []splitDP = new int[numLen + 1];
for(int i = 0; i < numLen + 1; i++)
splitDP[i] = -1;
// Call sieve function to store primes
// in primes array
HashSet primes = new HashSet();
getPrimesFromSeive(primes);
// Build the DP table in a bottom-up manner
for(int i = 1; i <= numLen; i++)
{
// If the prefix is prime then the prefix
// will be found in the prime set
if (i <= 6 && (primes.Contains
(number.Substring(0, i))))
splitDP[i] = 1;
// If the given prefix can be split into
// primes, then for the remaining String
// from i to j check if prime. If yes
// calculate the minimum split till j
if (splitDP[i] != -1)
{
for(int j = 1; j <= 6 && i + j <= numLen; j++)
{
// To check if the subString from
// i to j is a prime number or not
if (primes.Contains(number.Substring(i, j)))
{
// If it is a prime, then update
// the dp array
if (splitDP[i + j] == -1)
splitDP[i + j] = 1 + splitDP[i];
else
splitDP[i + j] = Math.Min(splitDP[i + j],
1 + splitDP[i]);
}
}
}
}
// Return the minimum number of
// splits for the entire String
return splitDP[numLen];
}
public static void Main(String[] args)
{
Console.Write(splitIntoPrimes("13499315") + "\n");
Console.Write(splitIntoPrimes("43") + "\n");
}
}
// This code is contributed by sapnasingh4991
Javascript
3
1
时间复杂度:
- 上述方法的时间复杂度为O(N 5/2 ) ,其中 N 是输入字符串的长度。
- 递归地找到所有可能的组合的复杂性是O(N 2 ) 。
- 对于每个组合,要检查数字是否为质数,需要使用额外的O(N 0.5 )时间。
- 这使得时间复杂度为O(N 5/2 ) 。
动态规划方法:可以看到给定的问题表现出重叠的子问题属性。因此,可以使用动态规划有效地解决这个问题。
定义并使用splitDP[]数组,其中 splitDP[i] 表示长度为 ‘i’ 的前缀字符串中将其分解为素数细分所需的最小拆分数。
splitDP[] 数组的填充方式如下:
- for 循环用于遍历给定字符串 的所有索引。
- 对于上述循环中的每个索引“i”,另一个循环从 1 到 6 进行迭代,以检查第 (i + j)个索引中的子字符串是否形成素数。
- 如果它形成一个质数,则 splitDP[] 处的值更新为:
splitDP[i + j] = min(splitDP[i + j], 1 + splitDP[i]);
- 更新完数组的所有值后,最后一个索引处的值是整个字符串的最小分割数。
下面是上述方法的实现:
C++
// C++ implementation of the above approach
#include
using namespace std;
// Function to check whether a string
// is a prime number or not
bool checkPrime(string number)
{
int num = stoi(number);
for (int i = 2; i * i <= num; i++)
if ((num % i) == 0)
return false;
return true;
}
// A function to find the minimum
// number of segments the given string
// can be divided such that every
// segment is a prime
int splitIntoPrimes(string number)
{
int numLen = number.length();
// Declare a splitdp[] array
// and initialize to -1
int splitDP[numLen + 1];
memset(splitDP, -1, sizeof(splitDP));
// Build the DP table in
// a bottom-up manner
for (int i = 1; i <= numLen; i++) {
// Initially Check if the entire prefix is Prime
if (i <= 6 && checkPrime(number.substr(0, i)))
splitDP[i] = 1;
// If the Given Prefix can be split into Primes
// then for the remaining string from i to j
// Check if Prime. If yes calculate
// the minimum split till j
if (splitDP[i] != -1) {
for (int j = 1; j <= 6 && i + j <= numLen; j++) {
// To check if the substring from i to j
// is a prime number or not
if (checkPrime(number.substr(i, j))) {
// If it is a prime, then update the dp array
if (splitDP[i + j] == -1)
splitDP[i + j] = 1 + splitDP[i];
else
splitDP[i + j] = min(splitDP[i + j],
1 + splitDP[i]);
}
}
}
}
// Return the minimum number of splits
// for the entire string
return splitDP[numLen];
}
// Driver code
int main()
{
cout << splitIntoPrimes("13499315") << "\n";
cout << splitIntoPrimes("43") << "\n";
return 0;
}
Java
// Java implementation of the above approach
import java.util.*;
class GFG{
// Function to check whether a String
// is a prime number or not
static boolean checkPrime(String number)
{
if(number.length()==0)
return true;
int num = Integer.parseInt(number);
for (int i = 2; i * i <= num; i++)
if ((num % i) == 0)
return false;
return true;
}
// A function to find the minimum
// number of segments the given String
// can be divided such that every
// segment is a prime
static int splitIntoPrimes(String number)
{
int numLen = number.length();
// Declare a splitdp[] array
// and initialize to -1
int []splitDP = new int[numLen + 1];
Arrays.fill(splitDP, -1);
// Build the DP table in
// a bottom-up manner
for (int i = 1; i <= numLen; i++) {
// Initially Check if the entire prefix is Prime
if (i <= 6 && checkPrime(number.substring(0, i)))
splitDP[i] = 1;
// If the Given Prefix can be split into Primes
// then for the remaining String from i to j
// Check if Prime. If yes calculate
// the minimum split till j
if (splitDP[i] != -1) {
for (int j = 1; j <= 6 && i + j <= numLen; j++) {
// To check if the subString from i to j
// is a prime number or not
if (checkPrime(number.substring(i, i+j))) {
// If it is a prime, then update the dp array
if (splitDP[i + j] == -1)
splitDP[i + j] = 1 + splitDP[i];
else
splitDP[i + j] = Math.min(splitDP[i + j],
1 + splitDP[i]);
}
}
}
}
// Return the minimum number of splits
// for the entire String
return splitDP[numLen];
}
// Driver code
public static void main(String[] args)
{
System.out.print(splitIntoPrimes("13499315")+ "\n");
System.out.print(splitIntoPrimes("43")+ "\n");
}
}
// This code contributed by Princi Singh
蟒蛇3
# Python 3 implementation of the above approach
from math import sqrt
# Function to check whether a string
# is a prime number or not
def checkPrime(number):
if(len(number) == 0):
return True
num = int(number)
for i in range(2,int(sqrt(num)) + 1, 1):
if ((num % i) == 0):
return False
return True
# A function to find the minimum
# number of segments the given string
# can be divided such that every
# segment is a prime
def splitIntoPrimes(number):
numLen = len(number)
# Declare a splitdp[] array
# and initialize to -1
splitDP = [-1 for i in range(numLen + 1)]
# Build the DP table in
# a bottom-up manner
for i in range(1, numLen + 1, 1):
# Initially Check if the entire prefix is Prime
if (i <= 6 and checkPrime(number[0:i])):
splitDP[i] = 1
# If the Given Prefix can be split into Primes
# then for the remaining string from i to j
# Check if Prime. If yes calculate
# the minimum split till j
if (splitDP[i] != -1):
j = 1
while(j <= 6 and i + j <= numLen):
# To check if the substring from i to j
# is a prime number or not
if (checkPrime(number[i:i+j])):
# If it is a prime, then update the dp array
if (splitDP[i + j] == -1):
splitDP[i + j] = 1 + splitDP[i]
else:
splitDP[i + j] = min(splitDP[i + j], 1 + splitDP[i])
j += 1
# Return the minimum number of splits
# for the entire string
return splitDP[numLen]
# Driver code
if __name__ == '__main__':
print(splitIntoPrimes("13499315"))
print(splitIntoPrimes("43"))
# This code is contributed by Surendra_Gangwar
C#
// C# implementation of the above approach
using System;
class GFG{
// Function to check whether a String
// is a prime number or not
static bool checkPrime(String number)
{
if(number.Length==0)
return true;
int num = Int32.Parse(number);
for (int i = 2; i * i <= num; i++)
if ((num % i) == 0)
return false;
return true;
}
// A function to find the minimum
// number of segments the given String
// can be divided such that every
// segment is a prime
static int splitIntoPrimes(String number)
{
int numLen = number.Length;
// Declare a splitdp[] array
// and initialize to -1
int []splitDP = new int[numLen + 1];
for (int i = 0; i <= numLen; i++)
splitDP[i] = -1;
// Build the DP table in
// a bottom-up manner
for (int i = 1; i <= numLen; i++) {
// Initially Check if the entire prefix is Prime
if (i <= 6 && checkPrime(number.Substring(0, i)))
splitDP[i] = 1;
// If the Given Prefix can be split into Primes
// then for the remaining String from i to j
// Check if Prime. If yes calculate
// the minimum split till j
if (splitDP[i] != -1) {
for (int j = 1; j <= 6 && i + j <= numLen; j++) {
// To check if the subString from i to j
// is a prime number or not
if (checkPrime(number.Substring(i, j))) {
// If it is a prime, then update the dp array
if (splitDP[i + j] == -1)
splitDP[i + j] = 1 + splitDP[i];
else
splitDP[i + j] = Math.Min(splitDP[i + j],
1 + splitDP[i]);
}
}
}
}
// Return the minimum number of splits
// for the entire String
return splitDP[numLen];
}
// Driver code
public static void Main(String[] args)
{
Console.Write(splitIntoPrimes("13499315")+ "\n");
Console.Write(splitIntoPrimes("43")+ "\n");
}
}
// This code is contributed by Rajput-Ji
Javascript
3
1
时间复杂度:
- 上述方法的时间复杂度为O(N 3/2 ) ,其中 N 是输入字符串的长度。
- 遍历所有索引的时间是O(N) 。
- 由于内部 for 循环对每个索引运行的次数都是恒定的,因此它的运行时间可以被认为是恒定的。
- 对于每个索引,检查数字是否为素数所花费的时间为O(N 0.5 ) 。
- 因此,总时间复杂度为O(N 3/2 ) 。
优化的动态规划方法:上述方法可以通过使用 Eratosthenes 筛的概念来进一步优化,以预先计算和存储一个数字是否为素数,并降低在每次迭代时检查数字的时间复杂度。
下面是上述方法的实现:
C++
// C++ implementation of the above approach
#include
using namespace std;
// Function to precompute all the primes
// upto 1000000 and store it in a set
// using Sieve of Eratosthenes
void getPrimesFromSeive(set& primes)
{
bool prime[1000001];
memset(prime, true, sizeof(prime));
prime[0] = prime[1] = false;
for (int i = 2; i * i <= 1000000; i++) {
if (prime[i] == true) {
for (int j = i * i; j <= 1000000; j += i)
prime[j] = false;
}
}
// Here to_string() is used
// for converting int to string
for (int i = 2; i <= 1000000; i++) {
if (prime[i] == true)
primes.insert(to_string(i));
}
}
// A function to find the minimum
// number of segments the given string
// can be divided such that every
// segment is a prime
int splitIntoPrimes(string number)
{
int numLen = number.length();
// Declare a splitdp[] array
// and initialize to -1
int splitDP[numLen + 1];
memset(splitDP, -1, sizeof(splitDP));
// Call sieve function to store primes in
// primes array
set primes;
getPrimesFromSeive(primes);
// Build the DP table in a bottom-up manner
for (int i = 1; i <= numLen; i++) {
// If the prefix is prime then the prefix
// will be found in the prime set
if (i <= 6 && (primes.find(number.substr(0, i))
!= primes.end()))
splitDP[i] = 1;
// If the Given Prefix can be split into Primes
// then for the remaining string from i to j
// Check if Prime. If yes calculate
// the minimum split till j
if (splitDP[i] != -1) {
for (int j = 1; j <= 6 && i + j <= numLen; j++) {
// To check if the substring from i to j
// is a prime number or not
if (primes.find(number.substr(i, j))
!= primes.end()) {
// If it is a prime, then update the dp array
if (splitDP[i + j] == -1)
splitDP[i + j] = 1 + splitDP[i];
else
splitDP[i + j] = min(splitDP[i + j],
1 + splitDP[i]);
}
}
}
}
// Return the minimum number of splits
// for the entire string
return splitDP[numLen];
}
int main()
{
cout << splitIntoPrimes("13499315") << "\n";
cout << splitIntoPrimes("43") << "\n";
return 0;
}
Java
// Java implementation of the above approach
import java.util.*;
class GFG{
// Function to precompute all the primes
// upto 1000000 and store it in a set
// using Sieve of Eratosthenes
static void getPrimesFromSeive(HashSet primes)
{
boolean []prime = new boolean[1000001];
Arrays.fill(prime, true);
prime[0] = prime[1] = false;
for (int i = 2; i * i <= 1000000; i++) {
if (prime[i] == true) {
for (int j = i * i; j <= 1000000; j += i)
prime[j] = false;
}
}
// Here to_String() is used
// for converting int to String
for (int i = 2; i <= 1000000; i++) {
if (prime[i] == true)
primes.add(String.valueOf(i));
}
}
// A function to find the minimum
// number of segments the given String
// can be divided such that every
// segment is a prime
static int splitIntoPrimes(String number)
{
int numLen = number.length();
// Declare a splitdp[] array
// and initialize to -1
int []splitDP = new int[numLen + 1];
Arrays.fill(splitDP, -1);
// Call sieve function to store primes in
// primes array
HashSet primes = new HashSet();
getPrimesFromSeive(primes);
// Build the DP table in a bottom-up manner
for (int i = 1; i <= numLen; i++) {
// If the prefix is prime then the prefix
// will be found in the prime set
if (i <= 6 && (primes.contains(number.substring(0, i))))
splitDP[i] = 1;
// If the Given Prefix can be split into Primes
// then for the remaining String from i to j
// Check if Prime. If yes calculate
// the minimum split till j
if (splitDP[i] != -1) {
for (int j = 1; j <= 6 && i + j <= numLen; j++) {
// To check if the subString from i to j
// is a prime number or not
if (primes.contains(number.substring(i, i+j))) {
// If it is a prime, then update the dp array
if (splitDP[i + j] == -1)
splitDP[i + j] = 1 + splitDP[i];
else
splitDP[i + j] = Math.min(splitDP[i + j],
1 + splitDP[i]);
}
}
}
}
// Return the minimum number of splits
// for the entire String
return splitDP[numLen];
}
public static void main(String[] args)
{
System.out.print(splitIntoPrimes("13499315")+ "\n");
System.out.print(splitIntoPrimes("43")+ "\n");
}
}
// This code contributed by Princi Singh
蟒蛇3
# Python3 implementation of the above approach
# Function to precompute all the primes
# upto 1000000 and store it in a set
# using Sieve of Eratosthenes
def getPrimesFromSeive(primes):
prime = [True] * (1000001)
prime[0], prime[1] = False, False
i = 2
while (i * i <= 1000000):
if (prime[i] == True):
for j in range(i * i, 1000001, i):
prime[j] = False
i += 1
# Here str() is used for
# converting int to string
for i in range(2, 1000001):
if (prime[i] == True):
primes.append(str(i))
# A function to find the minimum
# number of segments the given string
# can be divided such that every
# segment is a prime
def splitIntoPrimes(number):
numLen = len(number)
# Declare a splitdp[] array
# and initialize to -1
splitDP = [-1] * (numLen + 1)
# Call sieve function to store
# primes in primes array
primes = []
getPrimesFromSeive(primes)
# Build the DP table in a bottom-up manner
for i in range(1, numLen + 1):
# If the prefix is prime then the prefix
# will be found in the prime set
if (i <= 6 and (number[0 : i] in primes)):
splitDP[i] = 1
# If the Given Prefix can be split into Primes
# then for the remaining string from i to j
# Check if Prime. If yes calculate
# the minimum split till j
if (splitDP[i] != -1):
j = 1
while (j <= 6 and (i + j <= numLen)):
# To check if the substring from i to j
# is a prime number or not
if (number[i : i + j] in primes):
# If it is a prime, then
# update the dp array
if (splitDP[i + j] == -1):
splitDP[i + j] = 1 + splitDP[i]
else:
splitDP[i + j] = min(splitDP[i + j],
1 + splitDP[i])
j += 1
# Return the minimum number of
# splits for the entire string
return splitDP[numLen]
# Driver code
print(splitIntoPrimes("13499315"))
print(splitIntoPrimes("43"))
# This code is contributed by chitranayal
C#
// C# implementation of the above approach
using System;
using System.Collections.Generic;
class GFG{
// Function to precompute all the primes
// upto 1000000 and store it in a set
// using Sieve of Eratosthenes
static void getPrimesFromSeive(HashSet primes)
{
bool []prime = new bool[1000001];
for(int i = 0; i < 1000001; i++)
prime[i] = true;
prime[0] = prime[1] = false;
for(int i = 2; i * i <= 1000000; i++)
{
if (prime[i] == true)
{
for(int j = i * i; j <= 1000000; j += i)
prime[j] = false;
}
}
// Converting int to String
for(int i = 2; i <= 1000000; i++)
{
if (prime[i] == true)
primes.Add(String.Join("", i));
}
}
// A function to find the minimum
// number of segments the given String
// can be divided such that every
// segment is a prime
static int splitIntoPrimes(String number)
{
int numLen = number.Length;
// Declare a splitdp[] array
// and initialize to -1
int []splitDP = new int[numLen + 1];
for(int i = 0; i < numLen + 1; i++)
splitDP[i] = -1;
// Call sieve function to store primes
// in primes array
HashSet primes = new HashSet();
getPrimesFromSeive(primes);
// Build the DP table in a bottom-up manner
for(int i = 1; i <= numLen; i++)
{
// If the prefix is prime then the prefix
// will be found in the prime set
if (i <= 6 && (primes.Contains
(number.Substring(0, i))))
splitDP[i] = 1;
// If the given prefix can be split into
// primes, then for the remaining String
// from i to j check if prime. If yes
// calculate the minimum split till j
if (splitDP[i] != -1)
{
for(int j = 1; j <= 6 && i + j <= numLen; j++)
{
// To check if the subString from
// i to j is a prime number or not
if (primes.Contains(number.Substring(i, j)))
{
// If it is a prime, then update
// the dp array
if (splitDP[i + j] == -1)
splitDP[i + j] = 1 + splitDP[i];
else
splitDP[i + j] = Math.Min(splitDP[i + j],
1 + splitDP[i]);
}
}
}
}
// Return the minimum number of
// splits for the entire String
return splitDP[numLen];
}
public static void Main(String[] args)
{
Console.Write(splitIntoPrimes("13499315") + "\n");
Console.Write(splitIntoPrimes("43") + "\n");
}
}
// This code is contributed by sapnasingh4991
Javascript
3
1
时间复杂度:
- 这是最有效的方法,因为它以O(N)时间复杂度运行,其中 N 是输入字符串的长度。
- 由于 Eratosthenes 的筛子的运行时间为O(N*log(log(N)))并且质数列表高达 10 6 ,因此可以计算预计算复杂度。但是,由于这对任意数量的字符串只执行一次,因此在计算时间复杂度时不计算在内。
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。