简单的算法分析

时间:2012-05-17 02:09:44

标签: algorithm complexity-theory analysis

我试图将算法降低到至少O(n ^(3/2))的复杂度。这是算法:

function( string s, int n )
{
    bool result = false;
    int position = 0;
    for( int i = 0; i < n/2; i++ )
    {
        position = 0;
        for( int j = i+1; j < n; j++ )
        {
            if( s[j] != s[position] ) break;        
            if( j == n ) result = true;
            if( position == i ) position = 0;
            else position++;        
        }
        if(result) break;       
    }
    return result;
}

第一个for循环将迭代n / 2次,这是O(n)复杂度。我需要让内部for循环最多为O(sqrt(n)),从而使整个算法具有O(n ^(3/2))复杂度。我很难弄清楚嵌套for循环是否是我需要的正确复杂性。

注意:
n是字符串的大小。该函数基本上检查字符串s中是否出现重复模式。 s中唯一的字符是"0""1"。例如,如果字符串为"001001",则模式为"001"并出现两次。字符串也是均匀的。话虽这么说,语法和功能与这个问题无关。所有基本操作都被认为需要O(1)(常数)时间,这几乎是整个代码。

注2:
我这样做是为了完成家庭作业。但是功课问题只是为了让算法正常工作,我已经完成了。降低复杂性只是练习的额外工作。

任何帮助或指导都将不胜感激!

2 个答案:

答案 0 :(得分:2)

这很容易,只需检查长度是否除以总长度(如果L不分割总长度,则必须为,字符串不能是长度为L的重复模式)并且不运行如果没有内循环...除数的上限是2sqrt(n),所以这保证了O(Nsqrt(N))。

如果你想知道为什么,一个数字可以有的最大除数是每个数字直到sqrt(n),然后是每个数字x,N / x。所以在2sqrt(N)之下。

当然,实际上数字的除数要少得多,除了实际上全部有12的除数:1,2,3(每个数字直到sqrt),12 / 1,2 / 2,12 / 3(逆)。

有2个内环,但一个运行L次,另一个运行N / L次,因此内环为O(N)。

    static bool f(string s)
    {
        int n = s.Length;
        for (int l = n / 2; l >= 1; l--)
        {
            if (n % l != 0) continue;
            bool d = true;
            for (int o = 0; o < l; o++)
            {
                char f = s[o];
                for (int p = l; p < n; p += l)
                    if (s[p + o] != f) d = false;
            }
            if (d == true) return true;
        }
        return false;
    }

关键是:

if (n % l != 0) continue;

否则它将是O(N ^ 2)。

虽然外环看起来似乎是N / 2,但在数学上保证<&lt; 2sqrt(N)。你可以通过在几百万个字符的字符串上运行它来看到它 - 它会很快起作用。

答案 1 :(得分:0)

我认为你的内部循环不能降低到O(sqrt(n)),因为你必须比较从字符串的开头到特定索引i的所有字符,其值由外部循环控制。