我已经写了一个函数,我需要知道它的大O符号。 我试图自己解决这个问题,我得到了O(N ^ 2),但是我被告知这不是正确答案。
有人可以告诉我正确的符号是什么,并逐步解释他们是如何得出答案的?
该功能如下。
提前致谢
public static string Palindrome(string input)
{
string current = string.Empty;
string longest = string.Empty;
int left;
int center;
int right;
if (input == null || input == string.Empty || input.Length == 1) { return input; }
for (center = 1; center < input.Length -1; center++)
{
left = center - 1;
right = center + 1;
if (input[left] == input[center])
{
left--;
}
while (0 <= left && right < input.Length)
{
if (input[left] != input[right])
{
break;
}
current = input.Substring(left, (right - left + 1));
longest = current.Length > longest.Length ? current : longest;
left--;
right++;
}
}
return longest;
}
答案 0 :(得分:1)
这是O(n ^ 3)算法:
这部分需要O(n ^ 2):
// while循环的O(n)次
while (0 <= left && right < input.Length)
{
if (input[left] != input[right])
{
break;
}
//取子串是O(n)
current = input.Substring(left, (right - left + 1));
longest = current.Length > longest.Length ? current : longest;
left--;
right++;
}
还有一个外部O(n),for
循环,导致O(n * n ^ 2)。
您可以通过更改以下行来改进算法:
current = input.Substring(left, (right - left + 1));
longest = current.Length > longest.Length ? current : longest;
为:
currentLength = right - left + 1;
if(currentLength > longest)
{
longest = current.Length > longest.Length ? current : longest;
longestLeft = left;
longestRight = right;
}
最后将一个子字符串从longestLeft返回到longestRight。实际上要避免多次使用substring
方法。
答案 1 :(得分:0)
if (input[left] != input[right])
语句执行O(n ^ 2)次,其后的几个赋值也是如此,特别是:
current = input.Substring(left, (right - left + 1));
在子字符串函数的典型实现中,字符序列从字符串复制到新的字符串对象。该副本是一个O(n)操作,导致循环和子字符串操作的时间为O(n ^ 3)。
可以通过将current
和longest
的作业移至while
结构的结束括号之后来解决问题。但请注意,left--;
和right++;
的执行次数将比现有代码多一次,因此current
的分配变为
current = input.Substring(left+1, (right-1 - (left+1) + 1));
或
current = input.Substring(left+1, (right-left-1));
因此,O(n)子串操作最多完成O(n)次。