POJ 1804 逆序数 解题(归并排序)
生活随笔
收集整理的這篇文章主要介紹了
POJ 1804 逆序数 解题(归并排序)
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
文章目錄
- 解法1:直接雙重循環(huán)求解,n*n復(fù)雜度
- 解法2:采用歸并排序求解,復(fù)雜度nlgn
題目鏈接 http://poj.org/problem?id=1804
題目大意:
讓一串無(wú)序數(shù),在只能相鄰數(shù)字交換的前提下,最短的次數(shù)變成有序,求該最短次數(shù)。
該最短次數(shù)=該序列的逆序數(shù)
解法1:直接雙重循環(huán)求解,n*n復(fù)雜度
#include<iostream> #include<cstring> using namespace std; int main() {const int N = 1001;int cyctime,len,len1,sum=0;int arr[N];int i=0,j=0,k=0,temp;memset(arr,0,sizeof(int)*N);cin >> cyctime;for(i = 0; i < cyctime; ++i){//cin.clear();cin >> len;len1=len;j=0;while(len1--) //先輸入數(shù)組{cin >> temp;arr[j++] = temp;}for(j = 0; j < len; ++j) //從前往后依次比較{for(k = j+1; k < len; ++k){if(arr[j]>arr[k]){sum++;}}}cout << "Scenario #" << i+1 << ":" << endl;cout << sum << endl << endl;sum = 0;}return 0; }解法2:采用歸并排序求解,復(fù)雜度nlgn
#include<iostream> #include<cstring> using namespace std; int sum=0; void merge(int *arr,size_t left,size_t mid,size_t right) {int len = right - left + 1;int *temp = new int [len]; //數(shù)組較長(zhǎng)時(shí)請(qǐng)用new,不然棧空間容易溢出size_t index = 0;size_t i = left, j = mid + 1;while(i <= mid && j <= right){if(arr[i]<=arr[j]){temp[index++] = arr[i++];}else{temp[index++] = arr[j++];sum += mid - i + 1; //左邊數(shù)比右邊大,那么左邊剩余的也比其大!!!!!!!!!!}//對(duì)兩邊的數(shù)組從小到大放入臨時(shí)空間}while(i <= mid) //比較完后,左半邊有沒放進(jìn)去的,直接寫入{temp[index++]= arr[i++];}while(j <= right) //比較完后,右半邊有沒有放進(jìn)去的,直接寫入{temp[index++]= arr[j++];}for(int k = 0;k< len;++k){arr[left++ ]= temp[k]; //把有序的臨時(shí)數(shù)組寫入原來(lái)數(shù)組的起始位置}delete [] temp; //釋放空間temp = NULL; //指針置空 } void divide(int *arr,size_t left,size_t right) {if(left == right){ return;}size_t mid = (left+right)/2; //找出區(qū)間中部的數(shù),將數(shù)組分段divide(arr,left,mid); //遞歸調(diào)用,對(duì)左邊繼續(xù)分段;divide(arr,mid+1,right); //遞歸調(diào)用,對(duì)右邊繼續(xù)分段;merge(arr,left,mid,right); //對(duì)左右兩半進(jìn)行排序合并成一小段有序的數(shù)組 } void mergesort(size_t dsize, int *arr) {if(dsize <= 1) //預(yù)防特殊情況下后面代碼失效{return;}size_t left = 0, right = dsize-1;divide(arr,left,right); }int main() {const int N = 1001;int cyctime,len,len1;int arr[N];int i=0,j=0,temp;memset(arr,0,sizeof(int)*N);cin >> cyctime;for(i = 0; i < cyctime; ++i){//cin.clear();cin >> len;len1=len;j=0;while(len1--) //先輸入數(shù)組{cin >> temp;arr[j++] = temp;}mergesort(len,arr);cout << "Scenario #" << i+1 << ":" << endl;cout << sum << endl << endl;sum = 0;}return 0; }由上可看出歸并排序求解時(shí)間效率更高。
總結(jié)
以上是生活随笔為你收集整理的POJ 1804 逆序数 解题(归并排序)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: mysql中数据定义语言_SQL数据定义
- 下一篇: LeetCode 45. 跳跃游戏 II