逆序對定義:對於乙個包含n個非負整數的陣列a[1..n],如果有i < j,且a[ i ]>a[ j ],則稱(a[ i] ,a[ j] )為陣列a中的乙個逆序對。
常見的兩種方法求解逆序對:1.窮舉法(暴力求解),時間複雜度o(n^2)。2.歸併法, 時間複雜度o(nlogn)。
窮舉法:對於乙個給定的序列,依次從左往右取每乙個元素,從該元素右邊第乙個元素開始向右掃瞄,遇到比它小的元素,則計數+1,直到處理完整個序列。
#include
#include
#include
using
namespace
std;
#define maxn 1000
int num[maxn];
int sum =
0;void
solve
(int n)
}
intmain
(int argc, char
const *ar**)
歸併法:將序列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
#include
#include
using
namespace
std;
#define maxn 1000
int num[maxn], temp[maxn];
int sum =
0;void
merge
(int l, int mid, int r)
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)
}int
main
(int argc, char
const *ar**)
附上poj逆序對的一道測試題:
N!的位數兩種方法求解
第一種方法 將n 表示成10的次冪,即n 10 m 則不小於m的最小整數就是 n 的位數,對該式兩邊取對數,有 m log10 n 即 m log10 1 log10 2 log10 3.log10 n 迴圈求和,就能算得m值,該m是n 的精確位數 include include include i...
兩種方法求解 約瑟夫環
題目描述 已知n個人 以編號1,2,3.n分別表示 圍坐在一張圓桌周圍。從編號為0的人開始報數,數到2的那個人出列 他的下乙個人又從0開始報數,數到2的那個人又出列 依此規律重複下去,直到圓桌周圍的人全部出列。解法一 基於陣列實現 public void solution int totalnum,...
單鏈表反轉 逆序的兩種方法
摘自 延伸閱讀 此文章所在專題列表如下 第01話 線性表的概念與定義 第02話 線性表的抽象資料型別adt定義 第03話 線性表的順序儲存結構 第04話 線性表的初始化 第05話 線性表的遍歷 插入操作 第06話 判斷線性表是否為空與置空操作 第07話 線性表的查詢操作 第08話 線性表刪除某個元素...