Input: s ="1011"Output: 2Explanation: We can paritition the given string into ["101","1"].- The string "101" does not contain leading zeros and is the binary representation of integer 51=5.- The string "1" does not contain leading zeros and is the binary representation of integer 50=1.It can be shown that 2is the minimum number of beautiful substrings that s can be partitioned into.
Input: s ="111"Output: 3Explanation: We can paritition the given string into ["1","1","1"].- The string "1" does not contain leading zeros and is the binary representation of integer 50=1.It can be shown that 3is the minimum number of beautiful substrings that s can be partitioned into.
The key idea is to partition the string such that every substring is a binary representation of a power of 5 and does not have leading zeros. Since the string is short (length ≤ 15), we can use dynamic programming to try all possible partitions efficiently. We precompute all possible binary strings representing powers of 5 up to the maximum possible value for the given length.
classSolution {
public:int minimumBeautifulSubstrings(string s) {
unordered_set<string> pow5;
for (int i =0; i <15; ++i) {
int val = pow(5, i);
string bin = bitset<15>(val).to_string();
bin = bin.substr(bin.find('1'));
pow5.insert(bin);
}
int n = s.size();
vector<int> dp(n +1, 20);
dp[0] =0;
for (int i =1; i <= n; ++i) {
for (int j =0; j < i; ++j) {
string sub = s.substr(j, i - j);
if (pow5.count(sub)) {
dp[i] = min(dp[i], dp[j] +1);
}
}
}
return dp[n] > n ?-1: dp[n];
}
};
classSolution {
funminimumBeautifulSubstrings(s: String): Int {
val pow5 = mutableSetOf<String>()
for (i in0 until 15) {
val bin = Integer.toBinaryString(Math.pow(5.0, i.toDouble()).toInt())
pow5.add(bin)
}
val n = s.length
val dp = IntArray(n + 1) { 20 }
dp[0] = 0for (i in1..n) {
for (j in0 until i) {
if (pow5.contains(s.substring(j, i))) {
dp[i] = minOf(dp[i], dp[j] + 1)
}
}
}
returnif (dp[n] > n) -1else dp[n]
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
classSolution:
defminimumBeautifulSubstrings(self, s: str) -> int:
pow5: set[str] = set()
for i in range(15):
val =5** i
bin_str = bin(val)[2:]
pow5.add(bin_str)
n = len(s)
dp: list[int] = [20] * (n +1)
dp[0] =0for i in range(1, n +1):
for j in range(i):
if s[j:i] in pow5:
dp[i] = min(dp[i], dp[j] +1)
return-1if dp[n] > n else dp[n]
impl Solution {
pubfnminimum_beautiful_substrings(s: String) -> i32 {
letmut pow5 = std::collections::HashSet::new();
for i in0..15 {
let val =5_i32.pow(i);
let bin =format!("{:b}", val);
pow5.insert(bin);
}
let n = s.len();
letmut dp =vec![20; n +1];
dp[0] =0;
let s_bytes = s.as_bytes();
for i in1..=n {
for j in0..i {
if pow5.contains(std::str::from_utf8(&s_bytes[j..i]).unwrap()) {
dp[i] = dp[i].min(dp[j] +1);
}
}
}
if dp[n] > n asi32 { -1 } else { dp[n] }
}
}
⏰ Time complexity: O(n^2 * L), where n is the length of s (≤ 15), and L is the maximum length of a substring (≤ 15). For each position, we check all previous positions and substring lookup is O(L).
🧺 Space complexity: O(2^L), for storing all possible binary strings of powers of 5 up to length L, and O(n) for the dp array.