2

私は、順列番号のソートされていないリストの反転の数をカウントするために、以下の疑似コードに従うコードを考え出すのに数日間苦労してきました。O(nlogn) 時間で実行するアルゴリズムが必要ですが、O(n^2logn) 時間でしか解決策を思いつきません。

より具体的には、ネストされた for ループを使用せずに 2 番目のステップを高速化する方法を知りたいです。動作する他の効率的なアルゴリズム (つまり、マージソート) があることは知っていますが、疑似コードの手順に従う必要があります。

Instance: An array A[1] . . . A[n], a permutation of n numbers 1, . . . , n
Question: Calculate vector B[j] = |{A[i] : j > i and A[i] > A[j]}| (the same as 
          B[j] = |{i : j > i and A[i] > A[j]}|) B[j] is the number of element 
          larger than A[j] to the left of A[j] in t the array A. In other words, 
          the sum of the elements in B is equal to the number of inversions in 
          the permutation A[1] . . . A[n].
(1) Initialize B[i] to 0.
(2) For each even A[j] find elements with indices smaller than j that are by one larger
than A[j]: increase B[j] by the number of such elements;
(3) Divide each A[i] by 2 (in the integer sense);
(4) Stop when all A[i] are 0.

これまでに思いついたコードは次のとおりです。

long long numInversions = 0;     
// number of elements that are zero in the array
unsigned int zeros = 0;

do {

   // solution will need to replace this nested
   // for loop so it is O(n) not O(n^2)
   for (int i = 0; i < permNumber; i++){

           // checks if element is even
           if(array[i] % 2 == 0){
                  for (int j = i; j >= 0; j--){
                         if (array[j] == array[i] + 1){
                                numInversions++;
                         }
                 }
           }

      }

     // resets value of zeros for each pass
     zeros = 0;

     for (int k = 0; k < permNumber; k++){
             array[k] = array[k] / 2;
             if (array[k] == 0)
                  zeros++;


      }

} while(zeros != permNumber);

注: アルゴリズムは、リスト内の反転の数をスカラーで返す必要があります。疑似コードは配列を要求しますが、最終的に配列の要素を合計して反転カウントを計算します。

Example: Consider a permutation (2, 3, 6, 1, 3, 5) with six inversions. The 
above algorithm works as follows:
2 4 6 1 3 5        (no pairs)                                  ÷2
1 2 3 0 1 2 1 =    0: one '1' to left, 2: one 3 to left        ÷2
0 1 1 0 0 1 1 =    0: two '1's to left, 0: two '1's to left    ÷2
0 0 0 0 0 0        total: 6 pairs 
4

2 に答える 2