數組的小和&逆序對—歸併排序(c++)

數組的小和—歸併排序

數組小和

數組小和的定義如下:
例如,數組s = [1, 3, 5, 2, 4, 6],在s[0]的左邊小於或等於s[0]的數的和爲0;在s[1]的左邊小於或等於s[1]的數的和爲1;在s[2]的左邊小於或等於s[2]的數的和爲1+3=4;在s[3]的左邊小於或等於s[3]的數的和爲1;
在s[4]的左邊小於或等於s[4]的數的和爲1+3+2=6;在s[5]的左邊小於或等於s[5]的數的和爲1+3+5+2+4=15。所以s的小和爲0+1+4+1+6+15=27
給定一個數組s,實現函數返回s的小和
[要求]
時間複雜度爲O(nlogn)O(nlog_n),空間複雜度爲O(n)O(n)

#include <iostream>
#include <vector>
using namespace std;
long mergesort(vector<int>& a, int L, int q, int R)
{
	int n = R - L + 1;
	vector<int> b(n, 0);
	int z = 0;
	int left = L;
	int right = q + 1;
	long sum = 0;
	while (left <= q && right <= R)
	{
		sum += (a[left] <= a[right]) ? (R - right + 1)*a[left] : 0;
		b[z++] = (a[left] <= a[right]) ? a[left++] : a[right++];
	}
	while (left <= q)
		b[z++] = a[left++];
	while (right <= R)
		b[z++] = a[right++];
	for (int m = 0; m < n; m++)
		a[L + m] = b[m];
	return sum;
}

long sort(vector<int>& a, int L, int R)
{
	if (L == R)
		return 0;
	int q = L + ((R - L) >> 1);
	return sort(a, L, q) + sort(a, q + 1, R) + mergesort(a, L, q, R);
}
int main()
{
	int N;
	cin >> N;
	vector<int> arr(N, 0);
	for (int i = 0; i < N; i++)
		cin >> arr[i];
	cout << sort(arr, 0, arr.size() - 1);
	system("pause");
	return 0;
}

運行結果
在這裏插入圖片描述

逆序對

題目描述
有一組數,對於其中任意兩個數組,若前面一個大於後面一個數字,則這兩個數字組成一個逆序對。請設計一個高效的算法,計算給定數組中的逆序對個數。

給定一個int數組A和它的大小n,請返回A中的逆序對個數。保證n小於等於5000。

測試樣例:
[1,2,3,4,5,6,7,0],8
返回:7

暴力解法

class AntiOrder {
public:
    int count(vector<int> A, int n) {
        // write code here
        int count = 0;
        for (int i = 0; i< n-1;i++)
            for (int j =i+1;j<n;j++)
                if (A[i]>A[j])
                    count++;
        return count;      
    }
};

歸併解法

#include <iostream>
#include <vector>
using namespace std;
long mergesort(vector<int>& a, int L, int q, int R)
{
	int n = R - L + 1;
	vector<int> b(n, 0);
	int z = 0;
	int left = L;
	int right = q + 1;
	long sum = 0;
	while (left <= q && right <= R)
	{
		sum += (a[left] > a[right]) ? (q - L + 1) : 0;
		b[z++] = (a[left] <= a[right]) ? a[left++] : a[right++];
	}
	while (left <= q)
		b[z++] = a[left++];
	while (right <= R)
		b[z++] = a[right++];
	for (int m = 0; m < n; m++)
		a[L + m] = b[m];
	return sum;
}

long sort(vector<int>& a, int L, int R)
{
	if (L == R)
		return 0;
	int q = L + ((R - L) >> 1);
	return sort(a, L, q) + sort(a, q + 1, R) + mergesort(a, L, q, R);
}
int main()
{
	int N;
	cin >> N;
	vector<int> arr(N, 0);
	for (int i = 0; i < N; i++)
		cin >> arr[i];
	cout << sort(arr, 0, arr.size() - 1);
	system("pause");
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章