刚刚完成最新的Codility,通过它,但没有得到100%
这是规范
字符串S的前缀是S的任何前导连续部分。例如,“c”和“cod”是字符串“codility”的前缀。为简单起见,我们要求前缀非空。 字符串S的前缀P的乘积是P的出现次数乘以P的长度。更确切地说,如果前缀P由K个字符组成并且P在S中恰好出现T次,那么乘积等于K * T. / p>
例如,S =“abababa”具有以下前缀:
"a", whose product equals 1 * 4 = 4,
"ab", whose product equals 2 * 3 = 6,
"aba", whose product equals 3 * 3 = 9,
"abab", whose product equals 4 * 2 = 8,
"ababa", whose product equals 5 * 2 = 10,
"ababab", whose product equals 6 * 1 = 6,
"abababa", whose product equals 7 * 1 = 7.
最长前缀与原始字符串相同。目标是选择这样的前缀以最大化产品的价值。在上面的例子中,最大乘积是10。 在这个问题中,我们只考虑由小写英文字母(a-z)组成的字符串。
基本上,这是一个字符串遍历问题。我能够通过所有验证部分,但我失去了时间。这是我写的
int Solution(string S)
{
int finalCount = 0;
for (int i = 0; i <= S.Length - 1; i++)
{
string prefix = S.Substring(0, i + 1);
int count = 0;
for (int j = 0; j <= S.Length - 1; j++)
{
if (prefix.Length + j <= S.Length)
{
string newStr = S.Substring(j, prefix.Length);
if (newStr == prefix)
{
count++;
}
}
if (j == S.Length - 1)
{
int product = count * prefix.Length;
if (product > finalCount)
{
finalCount = product;
}
}
}
}
return finalCount;
}
我知道嵌套循环正在杀死我,但我想不出一种方法来遍历字符串的“部分”而不添加其他循环。
任何帮助都将不胜感激。
答案 0 :(得分:4)
天真蛮力解决方案需要O(N ** 3)时间。选择从1到N的长度,获取其长度的前缀并通过强力搜索计算出现的次数。 ho长度需要O(N)时间,蛮力需要O(N ** 2)时间,总时间为O(N ** 3)。 如果你使用KMP或Z-algo,你可以在O(N)时间内找到出现,所以整个解决方案将是O(N ** 2)时间。
你可以预先发生,所以需要O(N)+ O(N)= O(N)时间解决方案。
vector<int> z_function(string &S); //z-function, z[0] = S.length()
vector<int> z = z_function(S);
//cnt[i] - count of i-length prefix occurrences of S
for (int i = 0; i < n; ++i)
++cnt[z[i]];
//if cnt[i] is in S, cnt[i - 1] will be in S
int previous = 0;
for (int i = n; i > 0; --i) {
cnt[i] += previous;
previous = cnt[i];
}
这是blog post,解释了所有O(N ** 3),O(N ** 2),O(N)解决方案。
答案 1 :(得分:1)
我的努力如下,试图消除不必要的字符串比较,我读了isaacs博客,但它在c如何转换为c#,我甚至到目前为止使用数组以避免字符串不变性因素但没有改进
int Rtn = 0;
int len = S.Length;
if (len > 1000000000)
return 1000000000;
for (int i = 1; i <= len; i++)
{
string tofind = S.Substring(0, i);
int tofindlen = tofind.Length;
int occurencies = 0;
for (int ii = 0; ii < len; ii++)
{
int found = FastIndexOf(S, tofind.ToCharArray(), ii);
if (found != -1)
{
if ((found == 0 && tofindlen != 1) || (found >= 0))
{
ii = found;
}
++occurencies ;
}
}
if (occurencies > 0)
{
int total = occurencies * tofindlen;
if (total > Rtn)
{
Rtn = total;
}
}
}
return Rtn;
}
static int FastIndexOf(string source, char[] pattern, int start)
{
if (pattern.Length == 0) return 0;
if (pattern.Length == 1) return source.IndexOf(pattern[0], start);
bool found;
int limit = source.Length - pattern.Length + 1 - start;
if (limit < 1) return -1;
char c0 = pattern[0];
char c1 = pattern[1];
// Find the first occurrence of the first character
int first = source.IndexOf(c0, start, limit);
while ((first != -1) && (first + pattern.Length <= source.Length))
{
if (source[first + 1] != c1)
{
first = source.IndexOf(c0, ++first);
continue;
}
found = true;
for (int j = 2; j < pattern.Length; j++)
if (source[first + j] != pattern[j])
{
found = false;
break;
}
if (found) return first;
first = source.IndexOf(c0, ++first);
}
return -1;
}
答案 2 :(得分:0)
我只有43 ...我喜欢我的代码! javascript中的相同脚本得到了56它的价值。
using System;
class Solution
{
public int solution(string S)
{
int highestCount = 0;
for (var i = S.Length; i > 0; i--)
{
int occurs = 0;
string prefix = S.Substring(0, i);
int tempIndex = S.IndexOf(prefix) + 1;
string tempString = S;
while (tempIndex > 0)
{
tempString = tempString.Substring(tempIndex);
tempIndex = tempString.IndexOf(prefix);
tempIndex++;
occurs++;
}
int product = occurs * prefix.Length;
if ((product) > highestCount)
{
if (highestCount > 1000000000)
return 1000000000;
highestCount = product;
}
}
return highestCount;
}
}
答案 3 :(得分:0)
效果更好
private int MaxiumValueOfProduct(string input)
{
var positions = new List<int>();
int max = 0;
for (int i = 1; i <= input.Length; i++)
{
var subString = input.Substring(0, i);
int position = 0;
while ((position < input.Length) &&
(position = input.IndexOf(subString, position, StringComparison.OrdinalIgnoreCase)) != -1)
{
positions.Add(position);
++position;
}
var currentMax = subString.Length * positions.Count;
if (currentMax > max) max = currentMax;
positions.Clear();
}
return max;
}