安全offer35を証明:配列に逆

1つのタイトル説明

  番号は図面の前後よりも大きい場合には、アレイ内の二つの数字は、2つの数字は逆対を形成します。配列を入力し、この配列P.逆ペアの総数を見出します P結果モジュロ十億七を出力します。すなわち、出力P%十億七

2つのアイデアや方法

  マージソートの使用を考え、サブアレイに分割最初の配列、内部逆サブアレイの数の最初のカウント、2つの隣接するサブアレイ間に逆の数の統計。あなたは2つのソートサブアレイをマージした後、配列を更新することがあります。O(n * log(n)の)。

 

3 C ++コアコード

1  クラスソリューション{
 2  公共3      int型 InversePairs(ベクトル< 整数 > データ){
 4          もし(data.size()<= 1 5              リターン 0 6          int型のカウント= 0 ;
7          ベクター< INT >コピー(データ)。// 初始化
8          InversePairsCore(データ、コピー、0、data.size() - 1 、カウント);
9          リターン数えます。
10      }
 11  
12      //マージ
13は     空隙 InversePairsCore(ベクトル< INT >&データ、ベクトル< INT >&コピー、int型スタート、int型エンド、INTCOUNT){
 14          IF(スタート> = 終了){
 15              リターン;
 16          }
 17。         INT MID =(スタート+エンド)/ 2 ;
 18である         InversePairsCore(データ、コピー、スタート、MID、COUNT);
 19          InversePairsCore(データ、コピー、MID + 。1 、エンド、COUNT)
 20は 
21である         INT copyIndex = END; // 裏から多数二次アレイにコピー
22は、         int型 I = MID;     // 標準の最初の半分の最後の要素
23は、         INT J = END;     // 添え字の下の最後の要素の半分
24          ながら(I> =スタート&& J> = MID + 1 ){
 25              IF(データ[J] <データ[I]){      // 
26は、                  COUNT = J + - MID;
 27                  COUNTの%= 十億七 ;     // モジュロ逆オーバーフローを防止する
28                  コピー[copyIndex--] = DATA [i-- ]。
 29              } {
 30                  コピー[copyIndex--] = DATA [J、]。
31              }
 32          }
 33  
34          ながら(iは> = スタート)
 35              コピー[copyIndex--] =データ[i-- ]。
36  
37          ながら(J> =ミッド+ 1 38              コピー[copyIndex--] =データ[j-- ]。
39  
40          のためにint型 kは=開始++; <=エンドk個K)
 41個の              データ[K] = [K]をコピーします。
42  
43      }
 44 }。
コードの表示

4 C ++完全なコード

1つの#include <iostreamの>
 2  使用して 名前空間STD;
 3  // 逆順に配列
。4  ロング ロング GetMergePairsBetween(INT * ARR、INT *コピー、int型開始を、int型 MID、INT エンド)
 5  {
 6は、     // 2つのサブアレイをマージ、および逆の順序の数を計算
7。     INT Final1 = MID; // 配列の最初の最後のビット
8。     INT Final2 =終了; // 二番目の配列の最後の
9      int型のインデックス= END; // 補助アレイ最後の
10      ロング ロング= COUNT 0 ;
 11      ながら(Final1> =スタート&& Final2> + = MID 。1// 二つの配列が処理されていない
12である     {
 13は、        IF(ARR [Final1]> ARR [Final2])
 14         {
 15             // 最初の場合二番目の配列の要素は、配列の要素のいずれよりも大きい、
 16             // 配列の最初の要素はFinal2前に、アレイのすべての要素よりも大きくなければならない
。17             COUNT + =(Final2 - MID);
 18である            // final1で配列要素をコピーするコピー
 19。            // インデックスと前進さfinal1 
20             コピー[インデックスザ] = ARR [final1-- ];
 21である        }
 22は、        
23         {
 24             // 素子アレイは、第二の配列の最初の要素よりも小さい
 25             // 配列の2番目の要素はコピーアレイにコピーされ、
 26             @ 前方指標とfinal2 
27             コピー[インデックスザ] = ARR 【final2-- ];
 28         }
 29      }
 30      ながら(Final1> =スタート)// 配列の要素が処理されない
31は、     {
 32         [インデックスザ] = ARR [final1--コピー;]
 33である     }
 34であり     、一方(Final2は> + = MID 。1// 配列の要素が処理されていない
35      {
 36         コピー[インデックスザ] = ARR [final2--];
37      }
 38      のためのint型 I =端と、I>索引; i-- 39の          ARRを[I] = [i]のコピー。
40      リターン数えます。
41  }
 42  長い 長い GetMergePairs(int型 *のARR、int型 *コピー、int型開始、int型エンド)
 43  {
 44      長い 長い RET = 0 45      場合(開始< エンド)
 46      {
 47         INTミッド= +((エンドを開始-開始)>> 1);
48         年+ = GetMergePairs(編曲、コピー、開始、ミッド)。
49         年+ = GetMergePairs(編曲、コピー、ミッド+ 1 ;エンド)。
50         年+ = GetMergePairsBetween(編曲、コピー、開始、途中、終わり)。
51      }
 52      リターンRET。
53  }
 54  ロング ロング GetTotalPairs(INT ARR []、int型N)
 55  {
 56      であれば(ARR == NULL || N < 2 57         リターン 0 58      のint *コピー= 新しい int型[N]。
59      ロング ロング和= GetMergePairs(ARR、コピー、0、N- 1 )。
60      削除[]コピーを。
61      リターン和;
62  }
 63  のint main()の
 64  {
 65      のint [] ARR = { 7564 }。
66      INT RET = GetTotalPairs(ARR、はsizeof(ARR)/ はsizeof(ARR [ 0 ]));
67      coutの<< RET << てendl;
68      システム("一時停止" );
 69      リターン 0 ;
 70 }
コードの表示

参考資料

https://blog.csdn.net/zjwreal/article/details/88769617

https://blog.csdn.net/DERRANTCM/article/details/46761051(図)

https://blog.csdn.net/peiyao456/article/details/54645952(完全なコード)

 

おすすめ

転載: www.cnblogs.com/wxwhnu/p/11421187.html