求解最大子数组问题
来源:互联网 发布:没钱能拍网络剧吗 编辑:程序博客网 时间:2024/05/30 13:41
明日复明日,明日何其多。我生待明日,万事成蹉跎。
求解最大子数组的问题一般会有类似这样的描述:给定一个数组,求出数组中一个连续的子数组,该子数组中元素的和为所有连续子数组中的最大值。
这样的问题是典型分治思想,适合使用递归处理。我们可以考虑将给定的数组分成两部分,那么最大子数组必定存在于左侧部分,或者右侧部分,或者是跨越了分界线的部分。那么,只要分别求出这三种情况下的最大子数组,再进行比较,就能得出最后的结果。从这里的分析可以看出,我们采用了分解数组(分治思想),继而对每次的分解结果进行同样的处理(递归),最后求解(合并)。
C++实现示例:
int main(){ int A[] = {13, -3, -25, 20, -3, -16, -23, 18, 20, -7, 12, -5, -22, 15, -4, 7}; int low = 0; int high = 0; int sum = 0; find_max_subarray(A, 0, 15, low, high, sum); cout << "{"; for (int i = low; i <= high; i++) { cout << A[i] << ", "; } cout << "(sum = " << sum << ")" << "}" << endl; system("pause"); return 0;}void find_max_subarray(int* arr, int low, int high, int& result_low, int& result_high, int& result_sum){ if (low == high) { result_low = low; result_high = high; result_sum = arr[low]; return; } int mid = (low + high) / 2; int left_low = 0; int left_high = 0; int left_sum = 0; find_max_subarray(arr, low, mid, left_low, left_high, left_sum); int right_low = 0; int right_high = 0; int right_sum = 0; find_max_subarray(arr, mid + 1, high, right_low, right_high, right_sum); int cross_low = 0; int cross_high = 0; int cross_sum = 0; find_max_crossing_subarray(arr, low, mid, high, cross_low, cross_high, cross_sum); if (left_sum >= right_sum && left_sum >= cross_sum) { result_low = left_low; result_high = left_high; result_sum = left_sum; } else if (right_sum >= left_sum && right_sum >= cross_sum) { result_low = right_low; result_high = right_high; result_sum = right_sum; } else { result_low = cross_low; result_high = cross_high; result_sum = cross_sum; }}void find_max_crossing_subarray(int* arr, int low, int mid, int high, int& cross_low, int& cross_high, int& cross_sum){ int sum = 0; int left_sum = arr[mid] - 1; for (int i = mid; i >= low; i--) { sum += arr[i]; if (sum >= left_sum) { left_sum = sum; cross_low = i; } } sum = 0; int right_sum = arr[mid + 1] - 1; for (int i = mid + 1; i <= high; i++) { sum += arr[i]; if (sum >= right_sum) { right_sum = sum; cross_high = i; } } cross_sum = left_sum + right_sum;}
Java实现示例:
public static void main(String[] args) { int A[] = { 13, -3, -25, 20, -3, -16, -23, 18, 20, -7, 12, -5, -22, 15, -4, 7 }; int[] result = new int[3]; findMaxSubarray(A, 0, 15, result); // output for (int i = result[0]; i <= result[1]; i++) { System.out.print(A[i]); System.out.print(", "); } System.out.println("Sum = " + result[2]);}public static void findMaxSubarray(int[] arr, int low, int high, int[] result) { if (low == high) { result[0] = low; // the left index of the array result[1] = high; // the right index of the array result[2] = arr[low]; // the sum result of the sub-array return; } int mid = (low + high) / 2; // index 0 - low index of the sub-array // index 1 - high index of the sub-array // index 2 - sum of the sub-array int[] leftResult = new int[3]; findMaxSubarray(arr, low, mid, leftResult); int[] rightResult = new int[3]; findMaxSubarray(arr, mid + 1, high, rightResult); int[] crossResult = new int[3]; findMaxCrossingSubarray(arr, low, mid, high, crossResult); if (leftResult[2] >= rightResult[2] && leftResult[2] >= crossResult[2]) { System.arraycopy(leftResult, 0, result, 0, 3); } else if (rightResult[2] >= leftResult[2] && rightResult[2] >= crossResult[2]) { System.arraycopy(rightResult, 0, result, 0, 3); } else { System.arraycopy(crossResult, 0, result, 0, 3); }}public static void findMaxCrossingSubarray(int[] arr, int low, int mid, int high, int[] result) { int sum = 0; int left_sum = arr[mid] - 1; for (int i = mid; i >= low; i--) { sum += arr[i]; if (sum > left_sum) { left_sum = sum; result[0] = i; // low index of the sub-array } } sum = 0; int right_sum = arr[mid + 1] - 1; for (int i = mid + 1; i <= high; i++) { sum += arr[i]; if (sum > right_sum) { right_sum = sum; result[1] = i; // high index of the sub-array } } result[2] = left_sum + right_sum;}
0 0
- 求解最大子数组问题
- 求解最大子数组问题
- Python实现求解最大子数组问题
- 分治法求解最大子数组问题
- 分治策略求解最大子数组问题
- 分治法求解最大子数组问题
- 求解最大连续子数组问题
- 求解最大子数组
- 求解最大子数组
- 求解最大子数组问题的三种方法
- 【算法学习】最大子数组问题的分治法求解
- 最大子数组求解问题(算法导论)
- 最大子数组问题的分治求解算法
- 算法导论--分治策略求解最大子数组问题
- 最大子数组问题-暴力求解-c++代码实现
- 最大子序列问题求解
- 子数组最大和 动态规划求解
- 求解最大连续子数组的算法
- [BZOJ1207][HNOI2004]打鼹鼠
- 简单html5小活动开发——CSS基础之margin
- 流枫诗阁
- [最大流法二分匹配]uva753
- Android App 性能评测与调优
- 求解最大子数组问题
- Android代码优化小技巧
- MIPI(CSI-2)之从bit流中获取图像数据
- JSP网页编码
- HTML中的一些元素属性
- c#编码规范
- Best Compression Algorithms(网易游戏2015笔试题)
- PS AD 命令之禁用AD账户!
- 【学习日记】javaIO流的知识点总结(2)