日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

两种方法求解逆序对

發布時間:2025/3/11 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 两种方法求解逆序对 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

逆序對定義:對于一個包含N個非負整數的數組A[1..n],如果有i < j,且A[ i ]>A[ j ],則稱(A[ i] ,A[ j] )為數組A中的一個逆序對。


常見的兩種方法求解逆序對:1.窮舉法(暴力求解),時間復雜度O(n^2)。2.歸并法, 時間復雜度O(nlogn)。




窮舉法:對于一個給定的序列,依次從左往右取每一個元素,從該元素右邊第一個元素開始向右掃描,遇到比它小的元素,則計數+1,直到處理完整個序列。


  • #include <iostream>
  • #include <cstdlib>
  • #include <cstdio>
  • using namespace std;
  • #define MAXN 1000
  • int num[MAXN];
  • int sum = 0;
  • void solve(int n)
  • {
  • for(int i = 0; i < n; i++)
  • for(int j = i+1; j < n; j++)
  • {
  • if(num[i] > num[j])
  • sum++;
  • }
  • }
  • int main(int argc, char const *argv[])
  • {
  • int n;
  • scanf("%d", &n);
  • for(int i = 0; i < n; i++)
  • scanf("%d", &num[i]);
  • solve(n);
  • printf("%d\n", sum);
  • return 0;
  • }


  • 歸并法:將序列A[l..r]分成兩半A[l..mid]和A[mid+1..r]分別進行歸并排序,然后再將這兩半合并起來。

    在合并的過程中(設l<=i<=mid,mid+1<=j<=r),當A[i]<=A[j]時,不產生逆序數;當A[i]>A[j]時,在

    前半部分中比A[i]大的數都比A[j]大,所以,將A[j]放在A[i]前面的話,逆序數要加上mid+1-i。因此,可以在歸并排序中的合并過程中計算逆序數。



  • #include <iostream>
  • #include <cstdlib>
  • #include <cstdio>
  • using namespace std;
  • #define MAXN 1000
  • int num[MAXN], temp[MAXN];
  • int sum = 0;
  • void Merge(int l, int mid, int r)
  • {
  • int i = l, j = mid+1, k = l;
  • while(i <= mid && j <= r)
  • {
  • if(num[i] > num[j])
  • {
  • temp[k++] = num[j++];
  • sum += mid-i+1;//產生逆序對
  • }
  • else
  • temp[k++] = num[i++];
  • }
  • while(i <= mid)
  • temp[k++] = num[i++];
  • while(j <= r)
  • temp[k++] = num[j++];
  • for(int i = l; i <= r; i++)
  • num[i] = temp[i];
  • }
  • void Merge_sort(int l, int r)
  • {
  • if(l < r)
  • {
  • int mid = l + (r-l)/2;//可防止加法溢出
  • Merge_sort(l, mid);//左邊
  • Merge_sort(mid+1, r);//右邊
  • Merge(l, mid, r);//合并
  • }
  • }
  • int main(int argc, char const *argv[])
  • {
  • int n;
  • scanf("%d", &n);
  • for(int i = 0; i < n; i++)
  • scanf("%d", &num[i]);
  • Merge_sort(0, n-1);
  • printf("%d\n", sum);
  • return 0;
  • }





  • 附上POJ逆序對的一道測試題:http://poj.org/problem?id=1804




    總結

    以上是生活随笔為你收集整理的两种方法求解逆序对的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。