題目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...