1. 程式人生 > >利用分治策略來解決最大子陣列問題

利用分治策略來解決最大子陣列問題

#include<iostream>
#include<climits>
using namespace std;

//定義子陣列結構體,分別代表子陣列的下界和上界,以及和
struct sub_array {
	int max_left;
	int max_right;
	int max_sum;
};
//尋找跨越中點的最大子陣列的函式
sub_array Find_Max_Crossing_Subarray(int *A, int low, int mid, int high) {
	int left_sum = INT_MIN;
	int right_sum = INT_MIN;
	int sum = 0;
	sub_array cross_array;
	//計算中點左側的最大子陣列
	for (int i = mid; i >= 1; i--) {
		sum = sum + A[i];
		if (sum > left_sum) {
			left_sum = sum;
			cross_array.max_left = i;
		}
	}
	sum = 0;
	//計算中點右側的最大子陣列
	for (int j = mid + 1; j <= high; j++) {
		sum = sum + A[j];
		if (sum > right_sum) {
			right_sum = sum;
			cross_array.max_right = j;
		}
	}
	//將二者進行合併
	cross_array.max_sum = left_sum + right_sum;
	return cross_array;
}
//尋找最大子陣列的函式
sub_array Find_Maximun_Subarray(int *A, int low, int high) {
    int mid;
	if (high == low) {     //陣列中只有一個元素的情況
		sub_array temp;
		temp.max_left = low;
		temp.max_right = high;
		temp.max_sum = A[low];
		return temp;
	}
	else {
		mid = (low + high) / 2;
		sub_array cross_array;
		sub_array left_array;
		sub_array right_array;
		left_array = Find_Maximun_Subarray(A, low, mid);    //計算左子陣列
		right_array = Find_Maximun_Subarray(A, mid + 1, high);    //計算右子陣列
		cross_array = Find_Max_Crossing_Subarray(A, low, mid, high);    //計算橫跨中點的子陣列
		//尋找最大的情況
		if (left_array.max_sum >= right_array.max_sum && left_array.max_sum >= cross_array.max_sum) {
			return left_array;
		}
		else if (right_array.max_sum >= left_array.max_sum && right_array.max_sum >= cross_array.max_sum) {
			return right_array;
		}
		else {
			return cross_array;
		}
	}
}
int main() {
	int num;
	cin >> num;
	int *B = new int[num];
	int *A = new int[num];
	for (int i = 0; i < num; i++) {
		cin >> B[i];
	}
	for (int i = 1; i < num; i++) {
		A[i] = B[i] - B[i-1];
	}
	sub_array solution;
	solution = Find_Maximun_Subarray(A, 1, num-1);
	cout << solution.max_left<<" "<< solution.max_right<<" "<<solution.max_sum << endl;
	system("pause");
}