2016-06-28 3 views
1

Задача состоит в том, что в очереди есть N номеров. И начальная последовательность от 1 до N. Операция «Переместить ab» означает перемещение всех чисел перед (включая a) , а затем вставить их перед b (без изменения порядка) и вывести весь очередь, когда появляется «Выход».Улучшение движения деления от O (n) до O (1)

Вот мой код, чтобы иметь дело с «Move»:

//I establish q & q1 deque 

while(cin>>commend){ 
    if(commend == "Move"){ 
     cin>>a>>b; 
     int checka,checkb = 0; 

      //search for a,b position 
      //it1,it2 are both iterators 

      for(int m = 0; m < num ; m++){ 
       if(q[m] == a){ 
        it1 = q.begin()+m; 
        checka = 1; 
       } 
       else if(q[m] == b){ 
        it2 = q.begin()+m; 
        con2 = m; //store m in con2 to use below 
        checkb = 1; 
       } 
       else if(checka == 1 && checkb == 1) 
        break; 
      } 

      //con is also a iterator 
      //q1 is a new deque to store the elements before (include)number"a" 
      //procedures below are moving the numbers before(include)"a" and push_front the elements between number "a" and number "b" 

      for(con = it1; con>= q.begin() ; con--) 
       q1.push_front(*con); 
      for(con = it2; con > it1+1; con--){ 
       q1.push_front(*con); 

      } 

      //copy the "swaped" elements from q1 to q 
      //and clear q1 

      for(int m = 0; m<con2-1; m++) 
       q[m] = q1[m]; 
      q1.clear(); 
    } 
} 

Но скорость O (N), и я не знаю, где я могу улучшить это, если это требуется для выполнения задачи с O (1).

Любое предложение, кроме построения связанного списка?

+0

Если вы знаете, где в списке находится ваша «точка разреза», то повторная организация очереди может быть O (1). но если вам нужно отсканировать этот список, чтобы найти свою точку пересечения, то не может быть O (1). –

+0

Я не вижу, как это можно сделать в 'O (1)'. Вы выполняете 'O (1)' операцию 'n' раз, что всегда приведет к' O (n) 'runtime –

+0

Это вопрос о конкуренции в программировании? Я уверен, что видел другие ответы на этот вопрос, но я не могу их найти, потому что забыл, что называется проблемой. Можете ли вы включить информацию о том, где проблема, так что этот вопрос может быть связан с другими? В частности, я уверен, что был хороший ответ на этот вопрос, который включал некоторый вариант списка пропусков. –

ответ

1

Вы можете сохранить связанный список ваших номеров в очереди плюс индекс (хеш, например std :: unordered_map) с каждым номером в качестве ключа, указывающего на номер в очереди. Чтобы изменить порядок, вы просто просматриваете a и b в индексе в O (1) раз, переходите к номерам в списке и свопите их указатели привязки, чтобы изменить их порядок, снова в O (1) раз.

+0

такой связанный список был бы лучшим способом работы с ним? –

+0

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

0

Вы не можете использовать функцию Move в O(1). Это связано с тем, что сложность определяется как операциями поиска, так и операций create. Ваша операция поиска принимает O(n), и вы не можете уменьшить ее до тех пор, пока вы не измените структуру данных (которую вы не захотите делать). Даже если вы, предположительно, ищете в O(1), вы сможете выполнить операцию копирования только в O(1), если данные хранятся в непрерывном блоке памяти, а затем вы можете использовать memcpy(). Тем не менее, ваша операция поиска никогда не будет находиться под O(n), и, следовательно, по моему мнению, нет возможности изменять асимптотические границы. Кроме того, ваша программа ничего не сделает, если a и b равны.

+0

Из-за предела операций, я ли это единственный способ изменить структуру данных для повышения эффективности? –

+0

@WayneWilliams Ну, я думаю, это возможно, только если вы хэш итераторы, например, какое число присутствует в каком положении. Хешируйте их, и вы получите позицию в 'O (1)'. Затем используйте deque, который хранит элементы в смежном блоке памяти, и используйте 'memcpy()'. Это было бы единственным решением, о котором я могу думать. –