zoukankan      html  css  js  c++  java
  • 数组中的逆序对(分治)

    题目描述:
    在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数。
    输入:
    每个测试案例包括两行:
    第一行包含一个整数n,表示数组中的元素个数。其中1 <= n <= 10^5。
    第二行包含n个整数,每个数组均为int类型。
    输出:
    对应每个测试案例,输出一个整数,表示数组中的逆序对的总数。
    样例输入:
    4
    7 5 6 4
    样例输出:
    5

    1.直接的做法是逐个统计,复杂度是N^2,

    2.可以利用归并排序的思想,在排序过程中统计逆序对的个数。时间复杂度依然是 N*Log(N)。 可以从代码中看到,只是比归并排序多了一句代码:cnt += (n1 - i);

    由于最终个数可能超过int,这里用long long

    
    
     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 using namespace std;
     5 
     6 long long mergeAndCount(int arr[], int l, int m, int r){
     7     long long cnt = 0;
     8     int n1 = m - l + 1;
     9     int n2 = r - m;
    10     int i, j, k;
    11     int L[n1], R[n2];
    12     for(i = 0; i < n1; i++){
    13         L[i] = arr[l + i];
    14     }
    15     for(i = 0; i < n2; i++){
    16         R[i] = arr[m + 1 + i];
    17     }
    18     i = 0; 
    19     j = 0;
    20     k = l;
    21     //从小到大排序 
    22     while(i < n1 && j < n2){
    23         if(L[i] <= R[j]){
    24             arr[k] = L[i];
    25             i++;
    26         } else{
    27             arr[k] = R[j];
    28             cnt += (n1 - i);
    29             j++;
    30         }
    31         k++;
    32     }
    33 
    34     while(i < n1){
    35         arr[k++] = L[i];
    36         i++;
    37     }
    38 
    39     while(j < n2){
    40         arr[k++] = R[j];
    41         j++;
    42     }
    43     
    44     return cnt;
    45 
    46 }
    47 
    48 long long MergeSortAndCount(int arr[], int l, int r){
    49     long long cnt = 0, cnt1, cnt2, cnt3;
    50     if(l >= r)
    51         return 0;
    52     else {
    53         int middle = l + (r - l) / 2;
    54         cnt1 = MergeSortAndCount(arr, l, middle);
    55         cnt2 = MergeSortAndCount(arr, middle + 1, r);
    56         cnt3 = mergeAndCount(arr, l, middle, r);
    57     }
    58     return cnt1 + cnt2 + cnt3;
    59 }
    60 
    61 int main(){
    62     int n;
    63     cin >> n;
    64     int *arr = new int [n];
    65     for(int i = 0; i < n; i++)
    66         cin >> arr[i];
    67     cout << MergeSortAndCount(arr, 0, n - 1) << endl;
    68     return 0;
    69 }
    
    
    
     
  • 相关阅读:
    通过HttpListener实现简单的Http服务
    WCF心跳判断服务端及客户端是否掉线并实现重连接
    NHibernate初学六之关联多对多关系
    NHibernate初学五之关联一对多关系
    EXTJS 4.2 资料 跨域的问题
    EXTJS 4.2 资料 控件之Grid 那些事
    EXTJS 3.0 资料 控件之 GridPanel属性与方法大全
    EXTJS 3.0 资料 控件之 Toolbar 两行的用法
    EXTJS 3.0 资料 控件之 combo 用法
    EXTJS 4.2 资料 控件之 Store 用法
  • 原文地址:https://www.cnblogs.com/qinduanyinghua/p/5793990.html
Copyright © 2011-2022 走看看