두 개의 대기열을 사용하여 목록 반전


12

이 질문은 스택 작업 당 상각 된 O ( 1 ) 시간 에 두 개의 대기열을 사용하여 스택을 시뮬레이션 할 수 있는지 여부 에 대한 기존 질문에서 영감을 얻었습니다 . 답을 알 수없는 것 같습니다. 다음은 모든 PUSH 작업이 먼저 수행되고 모든 POP 작업이 수행되는 특수한 경우에 해당하는보다 구체적인 질문입니다. 처음에 비어있는 두 개의 대기열을 사용하여 N 요소 목록을 얼마나 효율적 으로 되돌릴 수 있습니까? 법적 운영은 다음과 같습니다.O(1)N

  1. 입력 목록에서 다음 요소를 큐에 넣습니다.
  2. 각 대기열의 헤드에서 요소를 대기열에서 빼고 다시 대기열에 넣습니다 (각 대기열의 꼬리 부분까지).
  3. 큐의 헤드에서 요소를 큐에서 빼고 출력 목록에 추가하십시오.

입력리스트의 요소로 구성되어있는 경우 , 반전 된 출력 목록 [ N , N - 1 , 을 생성하는 데 필요한 최소 작업 수는 어떻게됩니까 ? . . , 2 , 1 ] 동작? 그것이 O ( N ) 보다 빠르게 성장한다는 증거는 특히 부정적인 것의 원래 질문을 해결할 것이기 때문에 흥미로울 것입니다.[1,2,...,N1,N][N,N1,...,2,1]O(N)


업데이트 (2011 년 1 월 15 일) : 제출 된 답변과 의견에 표시된대로 문제를 해결할 수 있습니다 . Ω ( N ) 의 하한 은 사소하다. 이 범위 중 하나를 향상시킬 수 있습니까?O(NlogN)Ω(N)


명확히하기 위해 : "각 대기열의 마지막 요소"를 통해 대기열 헤드의 요소를 참조하고 있습니까?
피터 테일러

@ 피터 : 예, 설명 주셔서 감사합니다. 질문을 편집했습니다.
mjqxxxx

입력 및 출력 목록이 모두 스택됩니까? 그렇다면 n 개의 op1 (동일한 대기열로)과 n 개의 op3이 그 반대입니다. 중요한 것을 놓치고 있어야한다고 생각합니다.
jbapple

@jbapple : 아니요. 스택이 아닙니다. 입력 목록에서 읽은 것과 반대 순서로 출력 목록에 요소를 써야합니다.
mjqxxxx

답변:


11

N이 2의 거듭 제곱이면 모든 항목이 대기열 중 하나에서 시작하고 대기열 중 하나에서 역순으로 끝나야하는 다소 제한된 문제인 경우에도 O (N log N) 연산으로 충분하다고 생각합니다. 입력 및 출력 목록).

O (N) 단계에서는 한 큐의 모든 요소로 시작하여 "나를 위해 하나만"재생하여 다른 큐의 대체 서브 세트로 분할 한 다음 다시 한 큐로 연결하는 것이 가능합니다. 아이템의 위치의 이진 표현의 관점에서, 이것은 회전 연산을 구현합니다.

O (N) 단계에서는 하나의 큐에서 요소 쌍을 가져 와서 교체 한 다음 다시 배치하여 모든 쌍을 되돌릴 수도 있습니다. 아이템의 위치에 대한 이진 표현의 관점에서, 이것은 위치의 하위 비트를 보완한다.

O (log N) 시간에 셔플 해제와 페어 와이즈 스왑을 반복함으로써 위치의 이진 표현의 모든 비트를 보완 할 수 있습니다. 이는 목록을 뒤집는 것과 같습니다.


그런 다음 목록을 이진 표현으로 분류하고 O (n lg n) 알고리즘에 대해 조각별로 반전 할 수 있다고 생각합니다.
jbapple

바이너리 대신 2-3 트리를 사용하여 모든 N으로 확장 할 수 있다고 생각했지만 아이디어가 더 간단합니다. 그러나 O (n log n) 총 단계에서 각 O (log n) 조각을 어떻게 뒤집습니까?
David Eppstein

시간은 0에서 [lg n]까지의 i에 대한 O (sum (2 ^ i) lg (2 ^ i))입니다. Wolfram alpha는 O (n lg n)이라고 말합니다. wolframalpha.com/input/?i=sum+ (2 ^ k) + log2 + (2 ^ k) + from + 0 + to + log2 + n
jbapple

물론, 각 조각의 길이와 로그의 시간에 비례하여 각 조각을 뒤집을 수 있다면 끝났습니다. 그러나 조각을 뒤집 으면 어딘가에 놓아야하므로 나머지 조각을 뒤집는 것이 더 어려울 수 있습니다.
David Eppstein

문제는 "출력 목록"을 나타냅니다. 그것들을 거기에 넣을 수 있습니까?
jbapple

1

i=0N/21(N2i2)

사용 가능한 두 개의 대기열을 왼쪽과 오른쪽으로 지정할 수 있습니다. 다음은 N이 짝수라는 가정하에이 알고리즘의 기본 개념입니다.

  1. 초기 요소 목록에서 값을 읽고 모든 홀수를 왼쪽 큐로, 짝수를 오른쪽 큐로 푸시
  2. 최대 값을 출력하는 가장 빠른 방법 중 하나는 N / 2-1 요소를 오른쪽 큐에서 왼쪽으로 전송하고 오른쪽 큐에서 최상위 값을 출력 목록으로 팝하는 것입니다.
  3. 이제 우리는 다른 대기열에 대해서도 동일한 작업을 수행해야합니다-왼쪽 대기열에서 오른쪽 대기열로 N / 2-1 요소를 전송하고 왼쪽 대기열에서 상단 요소를 출력 목록으로 팝하십시오.
  4. N = N-2에 대해 대기열 교체 및 2 단계와 3 단계 반복

홀수 N에 대해 알고리즘이 어떻게 작동하는지 쉽게 알 수 있습니다.


$ ... $ 를 사용 하여 LaTeX-ish 코드 (\ 빼기)를 삽입 할 수 있습니다 .
Mark Reitblatt
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.