最大子數組問題

尋找數組A[low...high]的和最大的非空連續子數組,

採用分治策略:找到子數組的中央位置,將A分爲A[low...mid]和A[mid+1...high],

A[low...high]的任何連續子數組必然是以下三種情況之一:

  • 處於子數組A[low...mid]中
  • 處於子數組A[mid+1...high]中
  • 跨越了中點,有一半在A[low...mid]中,有一半在A[mid+1...high]中,

前兩種情況是規模更小的子問題,第三種單獨處理,然後選三者和最大者。

以上摘自算法導論。。。。。。。。。。。。。。。。。。。。。。。。。。。

代碼實現如下

#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
#include<limits.h>
#include<tuple>
using namespace std;
tuple<int,int,int> find_max_crossing_subarray(int a[], int low, int mid, int high)
{
	int left_sum = INT64_MIN;
	int right_sum = INT64_MIN;
	int temp_left = 0;
	int temp_right = 0;
	int left_index = 0;
	int right_index = 0;
	for (int i = mid; i >= low; i--)
	{
		temp_left += a[i];
		if (temp_left > left_sum)
		{
			left_sum = temp_left;
			left_index = i;
		}
	}
	for (int i = mid + 1; i <= high; i++)
	{
		temp_right += a[i];
		if (temp_right > right_sum)
		{
			right_sum = temp_right;
			right_index = i;
		}
	}
	int sum = right_sum + left_sum;
	
	auto tp =  std::tie(sum, left_index, right_index);
	
	return tp;
}
tuple<int,int,int> find_max_subarray(int a[], int low, int high)
{
	if (a == nullptr || low > high)
		return make_tuple(0,0,0);
	if (low == high)
		return make_tuple(a[low],low,high);
	int mid = (low + high) / 2;
	int i = low;
	int j = high;
	tuple<int, int, int> tp[3];
	tp[0]= find_max_subarray(a, i, mid);
	tp[1]= find_max_subarray(a, mid + 1, j);
	tp[2]= find_max_crossing_subarray(a, i, mid, j);
	
	int tp_0[3] = { get<0>(tp[0]),get<0>(tp[1]), get<0>(tp[2]) };
	int *max = max_element(tp_0, tp_0 + 3);//最後一個元素不做比較,真的坑
	int index = max - tp_0;

	/*auto temp1 = find_max_subarray(a, low, mid);
	auto temp2 = find_max_subarray(a, mid + 1, high);
	auto temp3 = find_max_crossing_subarray(a, low, mid, high);*/
	
	return tp[index];
}
int main()
{
	int a[17] = { 0,13,-3,-25,20,-3,-16,-23,18,20,-7,12,-5,-22,15,-4,7 };
	auto result=find_max_subarray(a, 1, 16);
	auto result1 = find_max_crossing_subarray(a, 1, 8, 16);
	cout<<get<0>(result)<<" "<< get<1>(result)<<" "<< get<2>(result);
	return 0;

}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章