最大子数组问题
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; }