这个函数的Big O表示法是什么?

时间:2012-10-26 07:05:55

标签: algorithm big-o

我已经写了一个函数,我需要知道它的大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;
    }

2 个答案:

答案 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)。

可以通过将currentlongest的作业移至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)次。