我最近遇到了这个问题 - 给定一个二进制字符串,检查我们是否可以将字符串分割/拆分为0..n部分,使每个部分的幂为5.返回最小分割数,如果可以的话。
例子如下:
input = "101101" - returns 1, as the string can be split once to form "101" and "101",as 101= 5^1.
input = "1111101" - returns 0, as the string itself is 5^3.
input = "100"- returns -1, as it can't be split into power(s) of 5.
我提出了这种递归算法:
我在Java中实现了上述算法。我相信它可行,但它是一个简单的递归解决方案。这可以通过动态编程来解决,以改善运行时间吗?
代码如下:
public int partition(String inp){
if(inp==null || inp.length()==0)
return 0;
return partition(inp,inp.length(),0);
}
public int partition(String inp,int len,int index){
if(len==index)
return 0;
if(isPowerOfFive(inp,index))
return 0;
long sub=0;
int count = Integer.MAX_VALUE;
for(int i=index;i<len;++i){
sub = sub*2 +(inp.charAt(i)-'0');
if(isPowerOfFive(sub))
count = Math.min(count,1+partition(inp,len,i+1));
}
return count;
}
助手功能:
public boolean isPowerOfFive(String inp,int index){
long sub = 0;
for(int i=index;i<inp.length();++i){
sub = sub*2 +(inp.charAt(i)-'0');
}
return isPowerOfFive(sub);
}
public boolean isPowerOfFive(long val){
if(val==0)
return true;
if(val==1)
return false;
while(val>1){
if(val%5 != 0)
return false;
val = val/5;
}
return true;
}
答案 0 :(得分:1)
您只需在地图中保存给定字符串的值即可。例如,如果你有一个像这样结束的字符串:(每个字母可以是一个任意大小的字符串)
ABCD
您发现部分A mod 5
没问题,因此您再次尝试BCD
,但发现B mod 5
也正常,C
和{{1}也一样}以及D
在一起。现在您应该缓存以下结果:
CD
但是你还没有完成C -> 0
D -> 0
CD -> 0
BCD -> 1 # split B/CD is the best
- 你发现ABCD
没问题,所以你检查结果AB mod 5
- 它已经在缓存中而你不必从一开始就处理它。
实际上,您只需要缓存来自CD
的答案 - 无论是实际字符串还是partition()
元组。哪一个更好取决于你有多少重复序列,以及比较内容或只是索引更快。
答案 1 :(得分:0)
以下是C ++中的解决方案。使用动态编程我正在考虑所有可能的分裂并保存最佳结果。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int isPowerOfFive(ll n)
{
if(n == 0) return 0;
ll temp = (ll)(log(n)/log(5));
ll t = round(pow(5,temp));
if(t == n)
{
return 1;
}
else
{
return 0;
}
}
ll solve(string s)
{
vector<ll> dp(s.length()+1);
for(int i = 1; i <= s.length(); i++)
{
dp[i] = INT_MAX;
for(int j = 1; j <= i; j++)
{
if( s[j-1] == '0')
{
continue;
}
ll num = stoll(s.substr(j-1, i-j+1), nullptr, 2);
if(isPowerOfFive(num))
{
dp[i] = min(dp[i], dp[j-1]+1);
}
}
}
if(dp[s.length()] == INT_MAX)
{
return -1;
}
else
{
return dp[s.length()];
}
}
int main()
{
string s;
cin>>s;
cout<<solve(s);
}