演算法概論 分治演算法 計算陣列中的逆序對

2021-09-12 13:07:52 字數 3034 閱讀 9878

題目1:

在陣列中的兩個數字如果前面乙個數字大於後面的數字,則這兩個數字組成乙個逆序對。輸入乙個陣列,求出這個陣列中的逆序對的總數。

例如在陣列中,共存在5組逆序對。

最直觀的方法就是直接求解了,依次掃瞄陣列中的各個數字,並將其與其後的數字作比較。

還有一種方法就是,利用分治的思想:

比如陣列data = ;我們可以將data分解,一直分解到每個子陣列只有乙個元素,然後,一邊比較一邊歸併,如下圖所示:

1、先來複習一下歸併排序:

#include using namespace std;

void mergesort(int data, int head, int tail);

void merge(int data, int head, int mid, int tail);

int main()

; int len = 4;

mergesort(data, 0, len - 1);

for (int i = 0; i < 4; ++i)

cout << endl;

return 0;

}void mergesort(int data, int head, int tail)

return;

}void merge(int data, int head, int mid, int tail)

for (int j = 0, n = mid + 1; j < len2; ++j, ++n)

//比較大小,從小到大排列

int i = 0, j = 0, k = head;

for ( ; i < len1 && j < len2; ++k) //i和j分別指向陣列l和r的下標,k為指向陣列data的下標

else if (l[i] < r[j])

else

}//將剩下的元素存入data中

if (i == len1) }

if (j == len2) }

delete l; //new的空間最後記得delete掉!

delete r;

return;

}

2、在其基礎上補充計算逆序對的**:

data下標從小到大填充:

#include using namespace std;

void mergesort(int data, int head, int tail);

void merge(int data, int head, int mid, int tail);

int cnt = 0; //用來記錄逆序對的個數

int main()

; int len = 4;

mergesort(data, 0, len - 1);

for (int i = 0; i < 4; ++i)

cout << endl;

cout << cnt << endl;

return 0;

}void mergesort(int data, int head, int tail)

return;

}void merge(int data, int head, int mid, int tail)

for (int j = 0, n = mid + 1; j < len2; ++j, ++n)

//比較大小,從小到大排列

int i = 0, j = 0, k = head;

for (; i < len1 && j < len2; ++k) //i和j分別指向陣列l和r的下標,k為指向陣列data的下標

else if (l[i] < r[j])

else

}//將剩下的元素存入data中

if (i == len1) }

if (j == len2) }

delete l; //new的空間最後記得delete掉!

delete r;

return;

}

data下標是從大到小填充(和上面data下標從小到大填充相比,可能會有點繞?):

#include using namespace std;

void mergesort(int data, int head, int tail);

void merge(int data, int head, int mid, int tail);

int cnt = 0; //記錄逆序對的個數

int main()

; int len = 4;

mergesort(data, 0, len - 1);

for (int i = 0; i < 4; ++i)

cout << endl;

cout << cnt << endl;

return 0;

}void mergesort(int data, int head, int tail)

return;

}void merge(int data, int head, int mid, int tail)

for (int j = 0, n = mid + 1; j < len2; ++j, ++n)

//比較大小,從小到大排列

int i = len1-1, j = len2-1, k = tail;

for ( ; i >= 0 && j >= 0; --k) //i和j分別指向陣列l和r的下標,k為指向陣列data的下標

else if (l[i] < r[j])

else

}//將剩下的元素存入data中

if (i < 0) }

if (j < 0) }

delete l; //new的空間最後記得delete掉!

delete r;

return;

}

演算法32 計算陣列中的逆序對

設 a 1.n 是乙個陣列,如果對於 i j 有 a i a j 則 a i 和 a j 構成一對逆序。給定乙個陣列,計算陣列中逆序對的個數。例如陣列 a 則 是逆序對,返回 3。兩個 for 迴圈列舉所有的數對,如果是逆序對,則 count 最終返回 count 即可。時間複雜度 o n 2 如下...

最大子陣列的分治演算法

讀演算法導論當中的最大子陣列當中的分治演算法,涉及到的問題是怎麼從find max subarray 函式當中返回三個引數,所以用了vector來返回,總感覺不是太好,太浪費空間了,但也沒想到其他辦法。int max left,max right,sum int find max crossing ...

乙個計算數字陣列概覽的演算法2

在先前的博文中提到了如何自己寫乙個演算法來實現該功能。雖然演算法很簡單,但畢竟需要自己實現。如果用objc的話,其foundation中自帶了nsindexset和nsmutableindexset類,可以很方便的為我們解決這個問題 nsmutableindexset set nsmutablein...