《算法导论》第四章-第1节_练习(参考答案)
来源:互联网 发布:excel函数重复数据 编辑:程序博客网 时间:2024/05/18 02:47
算法导论(第三版)参考答案:练习4.1-1,练习4.1-2,练习4.1-3,练习4.1-4,练习4.1-5
Exercise 4.1-1
What does FIND-MAXIMUM-SUBARRAY return when all elements of
A are negative?
返回
Exercise 4.1-2
Write pseudocode for the brute-force method of solving the maximum-subarray problem. Your procedure should run in
Θ(n2) time.
FIND-MAX-SUBARRAY(A, low, high) left = 0 right = 0 sum = -∞ for i = low to high current-sum = 0 for j = i to high current-sum += A[j] if sum < current-sum sum = current-sum left = i right = j return (left, right, sum)
Exercise 4.1-3
Implement both the brute-force and recursive algorithms for the maximum-subarray problem on your own computer. What problem size
n0 gives the crossover point at which the recursive algorithm beats the brute-force algorithm? Then, change the base case of the recursive algorithm to use the brute-force algorithm whenever the problem size is less thann0 . Does that change the crossover point?
C code
#include <limits.h>#define CROSSOVER_POINT 37// A struct to represent the tupletypedef struct { unsigned left; unsigned right; int sum;} max_subarray;// The brute force approachmax_subarray find_maximum_subarray_brute(int A[], unsigned low, unsigned high) { max_subarray result = {0, 0, INT_MIN}; for (int i = low; i < high; i++) { int current_sum = 0; for (int j = i; j < high; j++) { current_sum += A[j]; if (result.sum < current_sum) { result.left = i; result.right = j + 1; result.sum = current_sum; } } } return result;}// The divide-and-conquer solutionmax_subarray find_max_crossing_subarray(int A[], unsigned low, unsigned mid, unsigned high) { max_subarray result = {-1, -1, 0}; int sum = 0, left_sum = INT_MIN, right_sum = INT_MIN; for (int i = mid - 1; i >= (int) low; i--) { sum += A[i]; if (sum > left_sum) { left_sum = sum; result.left = i; } } sum = 0; for (int j = mid; j < high; j++) { sum += A[j]; if (sum > right_sum) { right_sum = sum; result.right = j + 1; } } result.sum = left_sum + right_sum; return result;}max_subarray find_maximum_subarray(int A[], unsigned low, unsigned high) { if (high == low + 1) { max_subarray result = {low, high, A[low]}; return result; } else { unsigned mid = (low + high) / 2; max_subarray left = find_maximum_subarray(A, low, mid); max_subarray right = find_maximum_subarray(A, mid, high); max_subarray cross = find_max_crossing_subarray(A, low, mid, high); if (left.sum >= right.sum && left.sum >= cross.sum) { return left; } else if (right.sum >= left.sum && right.sum >= cross.sum) { return right; } else { return cross; } }}// The mixed algorithmmax_subarray find_maximum_subarray_mixed(int A[], unsigned low, unsigned high) { if (high - low < CROSSOVER_POINT) { return find_maximum_subarray_brute(A, low, high); } else { unsigned mid = (low + high) / 2; max_subarray left = find_maximum_subarray_mixed(A, low, mid); max_subarray right = find_maximum_subarray_mixed(A, mid, high); max_subarray cross = find_max_crossing_subarray(A, low, mid, high); if (left.sum >= right.sum && left.sum >= cross.sum) { return left; } else if (right.sum >= left.sum && right.sum >= cross.sum) { return right; } else { return cross; } }}
Exercise 4.1-4
Suppose we change the definition of the maximum-subarray problem to allow the result to be an empty subarray, where the sum of the values of an empty subarray is
0 . How would you change any of the algorithms that do not allow empty subarrays to permit an empty subarray to be the result?
原代码中加入,最大子数组为负数情况的判断。
C code
#include <limits.h>typedef struct { unsigned left; unsigned right; int sum;} max_subarray;max_subarray find_max_crossing_subarray(int A[], unsigned low, unsigned mid, unsigned high) { max_subarray result = {mid + 1, mid, 0}; int sum = 0, left_sum = INT_MIN, right_sum = INT_MIN; for (int i = mid - 1; i >= (int) low; i--) { sum += A[i]; if (sum > left_sum) { left_sum = sum; result.left = i; } } sum = 0; for (int j = mid; j < high; j++) { sum += A[j]; if (sum > right_sum) { right_sum = sum; result.right = j + 1; } } if (left_sum + right_sum < 0) { max_subarray empty = { mid, mid, 0 }; return empty; } else { result.sum = left_sum + right_sum; return result; }}max_subarray find_maximum_subarray(int A[], unsigned low, unsigned high) { if (high == low + 1) { if (A[low] < 0) { max_subarray empty = {low, low, 0}; return empty; } else { max_subarray result = {low, high, A[low]}; return result; } } else { unsigned mid = (low + high) / 2; max_subarray left = find_maximum_subarray(A, low, mid); max_subarray right = find_maximum_subarray(A, mid, high); max_subarray cross = find_max_crossing_subarray(A, low, mid, high); if (left.sum >= right.sum && left.sum >= cross.sum) { return left; } else if (right.sum >= left.sum && right.sum >= cross.sum) { return right; } else { return cross; } }}
Exercise 4.1-5
使用如下思想为最大子数组问题设计一个非递归的、线性时间的算法。从数组的左边界开始,由左至右处理,记录到目前为止已经处理过的最大子数组。若已知
A[1..j] 的最大子数组,基于如下性质将解扩展为A[1..j+1] 的最大子数组:A[1..j+1] 的最大子数组要么是A[1..j] 的最大子数组,要么是某个子数组A[i..j+1](1≤i≤j+1) 。在已知A[1..j] 的最大子数组的情况下,可以在线性时间内找出形如A[i..j+1] 的最大子数组。
(挺有意思的)
思想:
函数find_maximum_subarray02,可以很好的说明这一切。current结构体中保存着最大的
C code
typedef struct { unsigned left; unsigned right; int sum;} max_subarray;max_subarray find_maximum_subarray(int A[], unsigned low, unsigned high) { max_subarray suffixes[high - low]; suffixes[0].left = low; suffixes[0].right = low + 1; suffixes[0].sum = A[low]; for (int i = low + 1; i < high; i++) { if (suffixes[i - 1].sum < 0) { suffixes[i].left = i; suffixes[i].right = i + 1; suffixes[i].sum = A[i]; } else { max_subarray *previous = &suffixes[i - 1]; suffixes[i].left = previous->left; suffixes[i].right = i + 1; suffixes[i].sum = previous->sum + A[i]; } } max_subarray *max = &suffixes[0]; for (int i = low + 1; i < high; i++) { if (max->sum < suffixes[i].sum) { max = &suffixes[i]; } } return *max;}max_subarray find_maximum_subarray02(int A[], unsigned low, unsigned high) { max_subarray result = {0, 0, INT_MIN}; max_subarray current = {low, low + 1, A[p]}; for (int i = low + 1; i < high; i++) { if (current.sum <= 0) { current.sum = A[i]; current.left = i; current.right = i + 1; } else { current.sum += A[i]; current.right = i + 1; } if (current.sum > result.sum) { result.sum = current.sum; result.left = current.left; result.right = result.right; } return result;}
- 《算法导论》第四章-第1节_练习(参考答案)
- 《算法导论》第四章-第2节_练习(参考答案)
- 《算法导论》第四章-第3节_练习(参考答案)
- 《算法导论》第四章-第4节_练习(参考答案)
- 《算法导论》第四章-第5节_练习(参考答案)
- 《算法导论》第四章-第6节_练习(参考答案)
- 《算法导论》第一章-第1节_练习(参考答案)
- 《算法导论》第二章-第1节_练习(参考答案)
- 《算法导论》第三章-第1节_练习(参考答案)
- 《算法导论》第五章-第1节_练习(参考答案)
- 《算法导论》第一章-第2节_练习(参考答案)
- 《算法导论》第二章-第2节_练习(参考答案)
- 《算法导论》第二章-第3节_练习(参考答案)
- 《算法导论》第三章-第2节_练习(参考答案)
- 《算法导论》第五章-第2节_练习(参考答案)
- 《算法导论》第五章-第3节_练习(参考答案)
- 《算法导论》第五章-第4节_练习(参考答案)
- 《算法导论》第四章-思考题(参考答案)
- PHPStorm 使用正则批量查询替换并自动转换大小写的方法
- 【杂记】万丈红尘一杯酒,千秋大业一壶茶
- vue 组件(Component)
- SpringMVC4.3x教程之一基本使用详解
- 3 如何修改文字颜色
- 《算法导论》第四章-第1节_练习(参考答案)
- Mahout 聚类算法学习之Canopy(一)
- Redis4.0.1 安装、设置密码、开启远程访问
- 深度理解链式前向星
- Codeforces Round #426 (Div. 2) C
- A. Knight Tournament----并查集
- OAuth的三种认证方式
- 外国商标中国注册的规定有哪些
- day18之用shell脚本实现一个希尔排序