最大子数组问题


最大子数组问题

1.蛮力法求解

代码实现:

int baoli(int a[],int low, int high)
{
	int sum = 0;
	int max = 0;
	int max_i = 0;
	int max_j = 0;
	for (int i = 1; i <= high; i++)
	{
		max = 0;
		for (int j = i; j <= high; j++)
		{
			max = max + a[j];
			if (max > sum)
			{
				sum = max;
				max_i = i;
				max_j = j;
			}
		}
		
	}
	printf("low:%d,high:%d", max_i, max_j);
}

2.分治法求解

总体思路:

  分治法的精髓:
    1)分--将问题分解为规模更小的子问题;
    2)治--将这些规模更小的子问题逐个击破;
    3)合--将已解决的子问题合并,最终得出“母”问题的解;
  所以原数组的最大子数组求法:
    1)分--将原数组拆分成两部分,每个部分再拆分成新的两部分......直到数组被分得只剩下一个元素;
    2)治--每个小型的数组找最大子数组,只有一个元素的数组,解就是该元素;
    3)合--将两个小型数组合并为一个数组,其中解有三种可能:
      • 左边的返回值大,
      • 右边的返回值大,
      • 中间存在一个更大的子数组和;
int cir_mid(int a[], int l, int m, int r)
{
	int sum_left = 0;
	int sum_right = 0;
	int sum = 0;
	for (int i = m; i >= 1; i--)
	{
		sum = sum + a[i];
		if (sum_left < sum)
		{
			sum_left = sum;
		}
	}
	sum = 0;
	for (int i = m + 1; i <= r; i++)
	{
		sum = sum + a[i];
		if (sum_right < sum)
		{
			sum_right = sum;
		}
	}


	return (sum_left + sum_right);
}


int max_array(int *a,int l,int r)
{
	int max_left;
	int max_right;
	int max_mid;
	
	if (l == r)
		return a[1];
	else
	{
		int m = (l+r) / 2;
		if (m == 0)
		{
			m++;
		}
		max_left=max_array(a, l, m);                 //求出左边最大值
		max_right=max_array(a, m+1, r);             //求出右边最大值
		max_mid = cir_mid(a, l, m, r);             //求出中间最大值


		if (max_left > max_right&&max_left > max_mid)
		{
			return max_left;
		}
		else if (max_right > max_left&&max_right > max_mid)
		{
			return max_right;
		}
		else
		{
			return max_mid;
		}
	}		
}


int main()
{
	int a[18] = { 0, 13, -3, -25, 20, -3, -16, -23, 18, 20, -7, 12, -5, -22, 15, -4, 7 };
	int max=max_array(a, 1, 16);
	printf("%d", max);
	system("pause");
	return 0;
}


猜你喜欢

转载自blog.csdn.net/qq_33366098/article/details/79552511
今日推荐