2015-11-10 4 views
4

я наткнулся на этот вопрос на InterviewBit:Какое худшее время для этого кода O (R * C)?

int memo[101][101]; 
int findMinPath(vector<vector<int> > V, int r, int c) { 
    int R = V.size(); 
    int C = V[0].size(); 
    if (r >= R || c >= C) return 100000000; // Infinity 
    if (r == R - 1 && c == C - 1) return 0; 
    if (memo[r][c] != -1) return memo[r][c]; 
    memo[r][c] = V[r][c] + min(findMinPath(V, r + 1, c), findMinPath(V, r, c + 1)); 
    return memo[r][c]; 
} 

Callsite : 
memset(memo, -1, sizeof(memo)); 
findMinPath(V, 0, 0); 

Предположим R = V.size() и C = V[0].size() и V имеет положительные элементы

Не будет ли код создания бинарного дерева рода вызов функции, которая принимает O (2 (m + n)), так как каждый вызов функции вызывает два других вызова функций?

+0

Да, но для каждого r + 1 вы также получаете c и c + 1. –

+1

Не ответ, но следите за тем, что происходит! Это может показаться правдоподобным, но если вы попытаетесь инициализировать «памятку» примерно на все, кроме 0 или -1, то это будет ужасно неправильно. – user2357112

+0

@ user2357112: И даже '-1' не будет работать на своих системах дополнений, если вы когда-нибудь столкнетесь с одним (у меня никогда не было сомнений, что я когда-либо буду, но хорошо придерживаться определенных стандартами поведения). – ShadowRanger

ответ

3

Этот алгоритм использует метод, известный как dynamic programming. Суть этого заключается в том, чтобы запомнить промежуточные результаты в таблице поиска и найти общее решение в виде комбинации частичных решений.

В этом конкретном случае вы можете видеть, что каждый вызов findMinPath будет либо листовым вызовом (не рекурсивом) с постоянной сложностью, либо сделать хотя бы одну запись в memo неотрицательной. Легко видеть, что если все записи в memo неотрицательны, функция никогда не будет рекурсивно. Поскольку существует только R × C элементов в memo, это верхняя граница общей сложности.

Тем не менее, реализация довольно неуклюжая. Зачем использовать глобальную переменную для memo и полагаться на ее инициализацию вызывающим абонентом -1? Кроме того, использование memset для записи массива целых чисел работает только для некоторых целых чисел со всеми одинаковыми байтами, что делает неперспективные предположения для целочисленного макета. И, наконец, есть уязвимость переполнения буфера, если R или C превышает магическое значение 101. Поэтому, если вы хотите быть педантичным, фактическая сложность постоянна.

+0

Можете ли вы более подробно объяснить вопрос более подробно. на самом деле это вопрос в интервью. есть два вопроса подобного типа. Я не понял никого из них. Можете ли вы объяснить разницу между [this] (https://www.interviewbit.com/problems/rec_cmpl2/) и [это] (https://www.interviewbit.com/problems/rec_cmpl3/)? – Krishna

+0

@Krishna Это немного для объяснения в комментарии. Вы можете задать новый вопрос, но, пожалуйста, убедитесь, что он по теме (https://stackoverflow.com/help/on-topic). Тем не менее, я сейчас очень занят и, вероятно, не смогу ответить. Кто-то другой. – 5gon12eder

Смежные вопросы