как бы я нашел временную и пространственную сложность этого кода?

#algorithm #time-complexity #palindrome #space-complexity

#алгоритм #временная сложность #палиндром #пространственная сложность

Вопрос:

У меня возникли трудности с поиском пространственной и временной сложности для этого кода, который я написал, чтобы найти количество палиндромов в строке.

 /**
 This program finds palindromes in a string.
*/

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int checkPalin(char *str, int len)
{
    int result = 0, loop;

    for ( loop = 0; loop < len/2; loop  )
    {

        if ( *(str loop) == *(str ((len - 1) - loop)) )
            result = 1;
        else {
            result = 0;
            break;
        }
    }

    return resu<
}

int main()
{
    char *string = "baaab4";
    char *a, *palin;

    int len = strlen(string), index = 0, fwd=0, count=0, LEN;
    LEN = len;

    while(fwd < (LEN-1))
    {
        a = string fwd;
        palin = (char*)malloc((len 1)*sizeof(char));    

        while(index<len)
        {
            sprintf(palin index, "%c",*a);
            index  ;
            a  ;

            if ( index > 1 ) {
                *(palin index) = '';
                count =checkPalin(palin, index);
            }
        }

        free(palin);
        index = 0;
        fwd  ;
        len--;
    }

    printf("Palindromes: %dn", count);
    return 0;
}
  

Я попробовал и вот что я думаю:

в main у нас есть два цикла while. Внешний выполняется по всей длине строки-1. Теперь вот в чем путаница, сначала выполняется внутренний цикл while по всей длине, затем n-1, затем n-2 и т.д. Для каждой итерации внешнего цикла while. значит ли это, что наша временная сложность будет O(n(n-1)) = O(n^2-n) = O(n^2) ?
И для пространственной сложности изначально я назначаю пробел для длины строки 1, затем (длина 1) -1, (длина 1) -2 и т.д. итак, как мы можем определить пространственную сложность из этого?
Для функции checkPalin это O(n/2) .
я готовлюсь к собеседованиям и хотел бы понять эту концепцию.
Спасибо

Ответ №1:

Не забывайте, что каждый вызов checkPalin (который вы выполняете каждый раз через внутренний цикл main) index / 2 раз выполняет цикл внутри checkPalin. Ваши вычисления временной сложности алгоритма верны, за исключением этого. Поскольку index становится таким большим, как n , это добавляет еще один коэффициент n к временной сложности, давая O (n3).

Что касается сложности пространства, вы выделяете каждый раз через внешний цикл, но затем освобождаете его. Итак, пространственная сложность равна O (n). (Обратите внимание, что O (n) == O (n / 2). Важен только показатель степени и форма функции.)

Комментарии:

1. ах, я это пропустил. Поправьте меня, если я ошибаюсь, поэтому временную сложность следовало записать следующим образом: O (n (n-1 (n / 2))) = O (1/2 (n ^ 3-n ^ 2)) = O (n ^ 3). Это довольно плохо!!!

2. @rashid — Я думаю, что ваш пересмотренный анализ верен. Довольно ли это плохо или нет, я не знаю. Это сложная задача для эффективного решения. Возможно, вы смогли бы уменьшить пространственную сложность до O (1), не замедляя работу алгоритма; Я не понимаю, почему вы не можете (с немного большей бухгалтерией) просто проверить на месте, не копируя подстроку в область нуля.

Ответ №2:

Что касается временной сложности, то ваш анализ верен. Это O (n ^ 2) из-за n (n-1) (n-2) … 1 шагов. Для пространственной сложности обычно учитывается только пространство, необходимое в любой момент времени. В вашем случае самая большая дополнительная память, которая вам когда-либо требовалась, — это O (n) при первом прохождении цикла, поэтому пространственная сложность линейна.

Тем не менее, это не особенно хороший код для проверки палиндрома. Вы могли бы сделать это за O (n) времени и O (1) пространства и фактически получить более чистый и понятный код для загрузки.

Черт: недостаточно внимательно прочитал. Правильный ответ дан в другом месте.

Комментарии:

1. этот код проверяет наличие нескольких палиндромов в строке, а не только одного. итак, у нас могло бы быть n палиндромов в строке. По сути, я создаю подстроки из заданной строки, а затем проверяю в O (n / 2) (выполняется функцией checkPalin), является ли это палиндромом.

2. Я не понимаю, как это можно сделать за O (n) раз. Строка из n идентичных символов имеет O (n ^ 2) палиндромов (каждый символ сам по себе; каждая последовательная пара; каждая последовательная строка из 3; и т.д.). Я не знаю, как (в общем случае) вы могли бы сосчитать их все во времени быстрее, чем их количество.

3. Тед прав, в принципе, мы должны составлять пары (ну, по крайней мере, так я думал об этом), и нам нужно как минимум два символа в строках, чтобы проверить наличие палиндрома. 🙂

4. Извините. Я просмотрел код и не заметил проверок на подпалиндромы. Моя ошибка.