2014-01-23 6 views
0

Я пытаюсь выяснить время выполнения следующего алгоритма. Я утверждаю, что это O (n), потому что внутренний цикл не зависит от внешнего цикла. Таким образом, мы могли бы иметь O (n) + O (n) = O (2n), который равен O (n) Правильно ли это? Я не уверен, что моя логика правильная, и я не могу понять, как правильно анализировать.Время выполнения алгоритма

Алгоритм находит наибольшие элементы слева от списка элементов. Спасибо!

public static void main(String[] args){ 
    int[] a = {4,3,2,10,4,8,9,1}; 
    int[] p = new int[a.length]; 
    ArrayDeque<Integer> previousIndex = new ArrayDeque<Integer>(); 
    for(int i = 0; i < a.length ; i++){ 
     while (!previousIndex.isEmpty() && a[previousIndex.peek()] <= a[i]){ 
      previousIndex.pop(); 
     } 
     if (previousIndex.isEmpty()) { 
      p[i] = 0; 
     } else { 
      p[i] = previousIndex.peek(); 
     } 
     previousIndex.push(i); 
    } 
    for(int i = 0; i < p.length ; i++){ 
     System.out.println(p[i]); 
    } 
    } 
} 
+1

Да O (n) + O (n) совпадает с O (n), однако в цикле 'for' имеется цикл' while'. Сколько раз этот цикл может работать? Это может повлиять на ответ. – Matt

+0

Это не полная функция, поэтому на вопрос невозможно ответить. Что должен делать алгоритм? – Gene

+0

@Matt Точно, он может работать n-1 раз – ola

ответ

0

Чтобы определить порядок, вы действительно смотрите на наихудший случай. Вы правы, что вложенная петля является причиной для беспокойства здесь:

for(int i = 0; i < a.length ; i++){ 

Это сразу же заказать N

while (!previousIndex.isEmpty() && a[previousIndex.peek()] <= a[i]){ 

Это потенциально может также пойти почти N раз.

Таким образом, окончательный порядок N*N или N^2

Вы должны иметь в виду обычное дело, хотя. Если вполне вероятно, что цикл while фактически выйдет после всего лишь нескольких итераций, вы можете вернуться к O(N).

+0

Это еще не o (n), как вы описали ранее, вы, вероятно, хотели написать знак омеги .... – steve

+0

@steve. Если внутренний цикл while всегда возвращается на 1 или 2 шага, общий алгоритм равен «O (N)». Если число шагов, которые он возвращает, увеличивается с увеличением N, тогда он начинает двигаться от «O (N)» до «O (N^2)» –

0

На самом деле, вы в порядке и имеете алгоритм O (N), но это сложнее доказать, чем большинство. Это предполагает, однако, что .isEmpty(), .peek() и т. Д. На ArrayDeque - все операции с постоянным временем. Проконсультируйтесь с документацией.

Ключ в том, что ваша обработка deque во внутреннем цикле разрушительно:

while (!previousIndex.isEmpty() && a[previousIndex.peek()] <= a[i]){ 
    previousIndex.pop(); 
} 

Это удаляет элемент из previousIndex каждый раз, и может работать только тогда, когда есть один, чтобы удалить. Таким образом, всего количество циклов while может работать по всем индексам, это количество раз, которое что-то .push ed в deque. И так как это происходит только в одной точке - в конце первого цикла for - мы можем видеть, что количество нажатых элементов - O (N).

+0

Это был мой мыслительный процесс ... но в конце цикла for, скажем, что массив a = [5, 4, 3, 2, 1, 7] не будет, когда в 7. стек будет выглядеть 5 4 3 2 1 с 1, являющимся последним элементом в стеке. Мы будем проходить стек до тех пор, пока он не станет пустым, что будет n-1 раз .... – ola

+0

Каждый раз, когда «через стек» считается постоянным («.isEmpty()» и «.peek() 'проверки); и если эти значения присутствуют в стеке, которые должны быть удалены сейчас, они не должны быть удалены ранее. На этих других итерациях мы бы посмотрели на стек один раз, обнаружили, что 'a [previousIndex.peek()]> a [i]', и перешли. Мы заботимся о * количестве * томов, всплывающих окон и т. Д. На всем протяжении процесса. –

+0

Тем не менее, было бы гораздо проще * просто сохранить единственное значение, представляющее наибольшее значение, увиденное до сих пор. :) –

1

Это O (N) для хотя у вас есть цикл внутри цикла, общее число раз, когда внутренний цикл будет выполняться никогда не может быть больше, чем общее число раз, когда

previousIndex.push(i); 

является (или N)

+0

Для очень похожего алгоритма с O (n) сложностью, даже если у вас есть вложенные петли, см. Knuth-Morris-Pratt. Как и @waTeim, число исполнений внутреннего цикла ограничено N (в худшем случае это точно N в последней итерации внешнего цикла, но 0 на всех других внешних итерациях). Другой способ понять это: среднее число поп, которое вы можете выполнить, составляет <= 1 (так как «среднее» количество push-es равно 1, и вы никогда не «поп» больше, чем вы «нажимаете») –

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