给定由0和1组成的字符串S。找到最小拆分,以使子字符串是4或6的幂的二进制表示,且没有前导零。如果无法进行此类分区,请打印-1。
例子:
Input: 100110110
Output: 3
The string can be split into a minimum of
three substrings 100(power of 4), 110
(power of 6) and 110(power of 6).
Input : 00000
Output : -1
0 is not a power of 4 or 6.
推荐:在继续解决方案之前,请先在“实践”上解决它。
一个简单的解决方案是在不同的索引处递归拆分字符串,并检查每个拆分是否为4或6的幂。从索引0开始,然后从其他字符串拆分str [0]。如果它是4或6的幂,则递归调用索引1并执行相同的操作。拆分整个字符串,请检查到目前为止分区的总数是否最小。然后拆分str [0..1],检查它是4还是6的幂,然后递归调用rest 字符串。到目前为止,在字符串遍历结束时比较分区与最小分区。这种方法在时间上将是指数式的。
一个有效的解决方案是使用动态编程。将创建一个一维dp表,其中dp [i]存储将字符串str [i..n-1]拆分为4或6的幂的子字符串所需的最小分区数。假设我们位于索引i和str [i..j]是4或6的幂,则最小分区数将是从中拆分str [j + 1..n-1]的最小分区数加上一个从中拆分str [i..j]的分区字符串,即dp [j + 1] +1。因此(j!=(n-1))和(dp [j + 1]!=-1)的递归关系将是:
dp[i] = min(dp[i], dp[j + 1] + 1)
执行:
C++
// CPP program for Minimum splits in a
//string such that substring is a power of 4 or 6.
#include
using namespace std;
// Function to find if given number
// is power of another number or not.
bool isPowerOf(long val, int base)
{
// Divide given number repeatedly
// by base value.
while (val > 1) {
if (val % base != 0)
return false; // not a power
val /= base;
}
return true;
}
// Function to find minimum number of
// partitions of given binary string
// so that each partition is power of 4 or 6.
int numberOfPartitions(string binaryNo)
{
int i, j, n = binaryNo.length();
// Variable to store integer value of
// given binary string partition.
long val;
// DP table to store results of
// partitioning done at differentindices.
int dp[n];
// If the last digit is 1, hence 4^0=1 and 6^0=1
dp[n - 1] = ((binaryNo[n - 1] - '0') == 0) ? -1 : 1;
// Fix starting position for partition
for (i = n - 2; i >= 0; i--) {
val = 0;
// Binary representation
// with leading zeroes is not allowed.
if ((binaryNo[i] - '0') == 0) {
dp[i] = -1;
continue;
}
dp[i] = INT_MAX;
// Iterate for all different partitions starting from i
for (j = i; j < n; j++) {
// Find integer value of current
// binary partition.
val = (val * 2) + (long)(binaryNo[j] - '0');
// Check if the value is a power of 4 or 6 or not
// apply recurrence relation
if (isPowerOf(val, 4) || isPowerOf(val, 6)) {
if (j == n - 1) {
dp[i] = 1;
}
else {
if (dp[j + 1] != -1)
dp[i] = min(dp[i], dp[j + 1] + 1);
}
}
}
// If no partitions are possible, then
// make dp[i] = -1 to represent this.
if (dp[i] == INT_MAX)
dp[i] = -1;
}
return dp[0];
}
// Driver code
int main()
{
string binaryNo = "100110110";
cout << numberOfPartitions(binaryNo);
return 0;
}
Java
// Java program for Minimum splits
// in a string such that substring
// is a power of 4 or 6.
import java.io.*;
class GFG
{
static boolean isPowerOf(long val,
int base)
{
// Divide given number
// repeatedly by base value.
while (val > 1)
{
if (val % base != 0)
return false; // not a power
val /= base;
}
return true;
}
// Function to find minimum
// number of partitions of
// given binary string so that
// each partition is power
// of 4 or 6.
static int numberOfPartitions(String binaryNo)
{
int i, j, n = binaryNo.length();
// Variable to store integer
// value of given binary
// string partition.
long val;
// DP table to store results
// of partitioning done at
// differentindices.
int dp[] = new int[n];
// If the last digit is 1,
// hence 4^0=1 and 6^0=1
dp[n - 1] = (((binaryNo.charAt(n - 1) -
'0') == 0) ?
-1 : 1);
// Fix starting position
// for partition
for (i = n - 2; i >= 0; i--)
{
val = 0;
// Binary representation
// with leading zeroes
// is not allowed.
if ((binaryNo.charAt(i) - '0') == 0)
{
dp[i] = -1;
continue;
}
dp[i] = Integer.MAX_VALUE;
// Iterate for all different
// partitions starting from i
for (j = i; j < n; j++)
{
// Find integer value of
// current binary partition.
val = (val * 2) +
(long)(binaryNo.charAt(j) - '0');
// Check if the value is a
// power of 4 or 6 or not
// apply recurrence relation
if (isPowerOf(val, 4) ||
isPowerOf(val, 6))
{
if (j == n - 1)
{
dp[i] = 1;
}
else
{
if (dp[j + 1] != -1)
dp[i] = Math.min(dp[i],
dp[j + 1] + 1);
}
}
}
// If no partitions are possible,
// then make dp[i] = -1 to
// represent this.
if (dp[i] == Integer.MAX_VALUE)
dp[i] = -1;
}
return dp[0];
}
// Driver code
public static void main (String[] args)
{
String binaryNo = "100110110";
System.out.println(numberOfPartitions(binaryNo));
}
}
// This code is contributed
// by shiv_bhakt.
Python 3
# Python 3 program for Minimum
# splits in a string such that
# substring is a power of 4 or 6.
import sys
# Function to find if given number
# is power of another number or not.
def isPowerOf(val, base):
# Divide given number repeatedly
# by base value.
while (val > 1):
if (val % base != 0):
return False # not a power
val //= base
return True
# Function to find minimum number of
# partitions of given binary string
# so that each partition is power of 4 or 6.
def numberOfPartitions(binaryNo):
n = len(binaryNo)
# DP table to store results of
# partitioning done at differentindices.
dp = [0] * n
# If the last digit is 1, hence 4^0=1 and 6^0=1
if ((ord(binaryNo[n - 1]) - ord('0')) == 0) :
dp[n - 1] = -1
else:
dp[n - 1] = 1
# Fix starting position for partition
for i in range( n - 2, -1, -1):
val = 0
# Binary representation
# with leading zeroes is not allowed.
if ((ord(binaryNo[i]) - ord('0')) == 0):
dp[i] = -1
continue
dp[i] = sys.maxsize
# Iterate for all different partitions starting from i
for j in range(i, n):
# Find integer value of current
# binary partition.
val = (val * 2) + (ord(binaryNo[j]) - ord('0'))
# Check if the value is a power of 4 or 6 or not
# apply recurrence relation
if (isPowerOf(val, 4) or isPowerOf(val, 6)):
if (j == n - 1):
dp[i] = 1
else :
if (dp[j + 1] != -1):
dp[i] = min(dp[i], dp[j + 1] + 1)
# If no partitions are possible, then
# make dp[i] = -1 to represent this.
if (dp[i] == sys.maxsize):
dp[i] = -1
return dp[0]
# Driver code
if __name__ == "__main__":
binaryNo = "100110110"
print(numberOfPartitions(binaryNo))
# This code is contributed by Ita_c.
C#
// C# program for Minimum splits
// in a string such that substring
// is a power of 4 or 6.
using System;
class GFG
{
static bool isPowerOf(long val, int b)
{
// Divide given number
// repeatedly by base value.
while (val > 1)
{
if (val % b != 0)
return false; // not a power
val /= b;
}
return true;
}
// Function to find minimum
// number of partitions of
// given binary string so that
// each partition is power
// of 4 or 6.
static int numberOfPartitions(string binaryNo)
{
int i, j, n = binaryNo.Length;
// Variable to store integer
// value of given binary
// string partition.
long val;
// DP table to store results
// of partitioning done at
// differentindices.
int[] dp = new int[n];
// If the last digit is 1,
// hence 4^0=1 and 6^0=1
dp[n - 1] = (((binaryNo[n - 1] -
'0') == 0) ?
-1 : 1);
// Fix starting position
// for partition
for (i = n - 2; i >= 0; i--)
{
val = 0;
// Binary representation
// with leading zeroes
// is not allowed.
if ((binaryNo[i] - '0') == 0)
{
dp[i] = -1;
continue;
}
dp[i] = int.MaxValue;
// Iterate for all different
// partitions starting from i
for (j = i; j < n; j++)
{
// Find integer value of
// current binary partition.
val = (val * 2) +
(long)(binaryNo[j] - '0');
// Check if the value is a
// power of 4 or 6 or not
// apply recurrence relation
if (isPowerOf(val, 4) ||
isPowerOf(val, 6))
{
if (j == n - 1)
{
dp[i] = 1;
}
else
{
if (dp[j + 1] != -1)
dp[i] = Math.Min(dp[i],
dp[j + 1] + 1);
}
}
}
// If no partitions are possible,
// then make dp[i] = -1 to
// represent this.
if (dp[i] == int.MaxValue)
dp[i] = -1;
}
return dp[0];
}
// Driver code
public static void Main ()
{
string binaryNo = "100110110";
Console.Write(numberOfPartitions(binaryNo));
}
}
输出:
3
时间复杂度: O(n ^ 2 * log(x)),x =可从输入字符串获得4或6的最大幂。
辅助空间: O(n)