时间和空间复杂性(针对特定算法)

时间:2015-09-13 12:26:23

标签: time-complexity space-complexity

尽管最后30分钟我花了更多时间来尝试理解时间和空间的复杂性,但仍然无法自信地确定以下算法的那些:

bool checkSubstr(std::string sub)
{
    //6 OR(||) connected if statement(checks whether the parameter
    //is among the items in the list)
}

void checkWords(int start,int end)
{
    int wordList[2] ={0};
    int j = 0;

    if (start < 0)
    {
        start = 0;
    }
    if (end>cAmount)
    {
        end = cAmount -1;
    }
    if (end-start < 2)
    {
        return;
    }
    for (int i = start; i <= end-2; i++)
    {
        if (crystals[i] == 'I' || crystals[i] == 'A')
        {
            continue;
        }
        if (checkSubstr(crystals.substr(i,3)))
        {
            wordList[j] = i;
            j++;
        }
    }
    if (j==1)
    {
        crystals.erase(wordList[0],3);
        cAmount -= 3;
        checkWords(wordList[0]-2,wordList[0]+1);
    }
    else if (j==2)
    {
        crystals.erase(wordList[0],(wordList[1]-wordList[0]+3));
        cAmount -= wordList[1]-wordList[0]+3;
        checkWords(wordList[0]-2,wordList[0]+1);
    }

}

该函数基本上检查整个字符串的子字符串是否有预定的(3个字母,例如“SAN”)字母组合。子串长度可以是4-6没有真正的方法来确定,取决于输入(非常确定它不相关,虽然不是100%)。

我的推理:

如果字符串中有n个字母,最糟糕的情况是,我们必须检查每个字母。同样取决于输入,这可以通过3种方式完成。

  1. 所有6个长度子字符串:如果是这种情况,该函数运行n / 6次,每个运行8(或10?)个进程,(我认为)意味着它的时间复杂度为O(n)。 / LI>
  2. 所有4个长度子字符串:与上面几乎相同的原因,O(n)。
  3. 4和6长度子串混合:看不出为什么这会比以前的2. O(n)
  4. 至于空间复杂性,我完全迷失了。但是,我有一个想法: 如果函数在最长时间内重复出现,则需要: n / 4 x一次运行中使用的金额 这让我觉得它应该是O(n)。虽然,我不相信这是正确的。我想也许在这个例子中看到别人的思考过程会帮助我理解如何更好地计算时间和空间的复杂性。 谢谢你的时间。

    编辑:让我提供更清晰的信息。我们将6个不同的字母组合成一个字符串,这可以是(几乎)任何长度的任意组合。 'crystals'是字符串,我们在该字母列表中寻找6种不同的3个字母组合。有点像宝石匹配游戏。现在,起始列表不包含任何匹配(首先存在6个预定组合中的任何一个)。因此,从那时起匹配的唯一方法是交换或匹配消失。一旦顶级代码处理交换,就会调用该函数来检查匹配,如果找到匹配,则在删除字符串的“匹配”部分后,该函数会再次出现。

    现在让我们看看代码是如何寻找匹配的。为了证明2个字母的交换:

    ABA B-R ZIB(实际字符串中没有空格或' - ',用于更好的演示),

    正在交换B和R.此交换仅影响从第2个字母开始到第7个字母结束的6个字母。换句话说,在交换之前和之后,第一个A和最后一个B可以形成匹配的字母是相同的,因此没有点检查包括那些字的匹配。所以发送到检查算法的6个字母的子串。类似地,如果形成的匹配消失(从字符串中删除),受影响的字母的范围是4.所以当我想到最坏的情况时,我想象1交换创建整个连锁反应并且一直匹配直到有没有足够的信件来形成匹配,或者每次匹配都会发生交换。同样,我并不是说这是我们在计算时间和空间复杂度时应该如何思考,但这就是代码的工作方式。希望这很清楚,如果不让我知道,我可以提供更多细节。同样重要的是要注意交换金额和地点是我们阅读的输入的一部分。

    编辑:以下是第一次在顶级调用该函数的方法: checkWords(swaps[i]-2,swaps[i]+3);

1 个答案:

答案 0 :(得分:0)

  

子串长度可以4-6没有真正的方法来确定,取决于   输入(非常确定它不相关,尽管不是100%)。

这不是代码所显示的内容;行if (checkSubstr(crystals.substr(i,3)))表示子串总是有3个字符。如果子字符串长度不同,则它是相关的,因为在一般情况下,您的幼稚子字符串匹配将降级为O(N*M),其中Nstart-end+1(输入字符串的大小)和{ {1}}是要搜索的子字符串的大小。这是因为在最坏的情况下,您将比较源字符串的每个M字符的M个字符。

本答案的其余部分假设子串的大小为3,因为这就是代码所显示的内容。

如果子串长度总是3个字符,则它会有所不同:您基本上可以假设NcheckSubstr(),因为您总是会比较最多3个字符。大部分工作发生在for循环中,即O(1),其中O(N)N

在循环之后,在最坏的情况下(当输入end-1-start之一时),您将从if中删除一堆字符。假设这是由内存中的数组支持的字符串,这是crystal操作,因为必须移位O(cAmount)之后的所有元素。递归调用总是在4的范围内传递;它不会随着输入的大小而增长或缩小,所以你也可以说有wordList[0]个递归调用。

因此,时间复杂度为O(1)(其中O(N+cAmount)N),空间复杂度为end-1-start