zoukankan      html  css  js  c++  java
  • JZ-C-36

    剑指offer第三十六题:数组中的逆序对

      1 //============================================================================
      2 // Name        : JZ-C-36.cpp
      3 // Author      : Laughing_Lz
      4 // Version     :
      5 // Copyright   : All Right Reserved
      6 // Description : 数组中的逆序对
      7 //============================================================================
      8 
      9 #include <iostream>
     10 #include <stdio.h>
     11 using namespace std;
     12 
     13 int InversePairsCore(int* data, int* copy, int start, int end);
     14 
     15 /**
     16  *统计逆序对的过程:先把数组分隔成子数组,1:先统计出子数组内部的逆序对的数目,
     17  *2:然后再统计出两个相邻子数组之间的逆序对数目。★在统计逆序对的过程中,还需要对数组进行排序(归并排序)
     18  */
     19 int InversePairs(int* data, int length) {
     20     if (data == NULL || length < 0)
     21         return 0;
     22 
     23     int* copy = new int[length];
     24     for (int i = 0; i < length; ++i)
     25         copy[i] = data[i];
     26 
     27     int count = InversePairsCore(data, copy, 0, length - 1);
     28     delete[] copy;
     29 
     30     return count;
     31 }
     32 /**
     33  *类似归并排序,每次递归拆分为两个子数组,缩小为两个单元素时候比较大小获得count逆序对数,最后再缩小为同一个元素时候返回。
     34  */
     35 int InversePairsCore(int* data, int* copy, int start, int end) {
     36     if (start == end) {
     37         copy[start] = data[start];
     38         return 0; //最后缩小为同一个元素,直接返回
     39     }
     40 
     41     int length = (end - start) / 2;
     42 
     43     int left = InversePairsCore(copy, data, start, start + length); //注意此处参数:copy,data,交换的原因在于需要对子数组进行排序(归并)。
     44     int right = InversePairsCore(copy, data, start + length + 1, end);
     45 
     46     // i初始化为前半段最后一个数字的下标
     47     int i = start + length;
     48     // j初始化为后半段最后一个数字的下标
     49     int j = end;
     50     int indexCopy = end;
     51     int count = 0; //count为被拆两个子数组相比较得出的逆序对数
     52     while (i >= start && j >= start + length + 1) {
     53         if (data[i] > data[j]) {
     54             copy[indexCopy--] = data[i--];
     55             count += j - start - length;
     56         } else {
     57             copy[indexCopy--] = data[j--];
     58         }
     59     }
     60 
     61     for (; i >= start; --i)
     62         copy[indexCopy--] = data[i];
     63 
     64     for (; j >= start + length + 1; --j)
     65         copy[indexCopy--] = data[j];
     66 
     67     return left + right + count;
     68 }
     69 
     70 // ====================测试代码====================
     71 void Test(char* testName, int* data, int length, int expected) {
     72     if (testName != NULL)
     73         printf("%s begins: ", testName);
     74 
     75     if (InversePairs(data, length) == expected)
     76         printf("Passed.
    ");
     77     else
     78         printf("Failed.
    ");
     79 }
     80 
     81 void Test1() {
     82     int data[] = { 1, 2, 3, 4, 7, 6, 5 };
     83     int expected = 3;
     84 
     85     Test("Test1", data, sizeof(data) / sizeof(int), expected);
     86 }
     87 
     88 // 递减排序数组
     89 void Test2() {
     90     int data[] = { 6, 5, 4, 3, 2, 1 };
     91     int expected = 15;
     92 
     93     Test("Test2", data, sizeof(data) / sizeof(int), expected);
     94 }
     95 
     96 // 递增排序数组
     97 void Test3() {
     98     int data[] = { 1, 2, 3, 4, 5, 6 };
     99     int expected = 0;
    100 
    101     Test("Test3", data, sizeof(data) / sizeof(int), expected);
    102 }
    103 
    104 // 数组中只有一个数字
    105 void Test4() {
    106     int data[] = { 1 };
    107     int expected = 0;
    108 
    109     Test("Test4", data, sizeof(data) / sizeof(int), expected);
    110 }
    111 
    112 // 数组中只有两个数字,递增排序
    113 void Test5() {
    114     int data[] = { 1, 2 };
    115     int expected = 0;
    116 
    117     Test("Test5", data, sizeof(data) / sizeof(int), expected);
    118 }
    119 
    120 // 数组中只有两个数字,递减排序
    121 void Test6() {
    122     int data[] = { 2, 1 };
    123     int expected = 1;
    124 
    125     Test("Test6", data, sizeof(data) / sizeof(int), expected);
    126 }
    127 
    128 // 数组中有相等的数字
    129 void Test7() {
    130     int data[] = { 1, 2, 1, 2, 1 };
    131     int expected = 3;
    132 
    133     Test("Test7", data, sizeof(data) / sizeof(int), expected);
    134 }
    135 
    136 void Test8() {
    137     int expected = 0;
    138 
    139     Test("Test8", NULL, 0, expected);
    140 }
    141 
    142 int main(int argc, char** argv) {
    143     Test1();
    144     Test2();
    145     Test3();
    146     Test4();
    147     Test5();
    148     Test6();
    149     Test7();
    150     Test8();
    151 
    152     return 0;
    153 }
  • 相关阅读:
    PHP面试总结
    yii2-dingtalk 钉钉群机器人
    分布式锁机制原理及实现方式
    strtotime的一个使用问题
    JavaScript的程序构成
    libsvm源码凝视+算法描写叙述:svm_train
    android事件分发(二)
    Windows 上通过本地搭建 Jekyll环境
    重点:用户画像
    easyui英文提示变中文
  • 原文地址:https://www.cnblogs.com/Laughing-Lz/p/5608536.html
Copyright © 2011-2022 走看看