卡丹尔算法(max subarray problem)
来源:互联网 发布:禁止网游软件 编辑:程序博客网 时间:2024/06/07 08:57
问题介绍
Say you have an array for which the ith element is the price of a
given stock on day i. If you were only permitted to complete at most
one transaction (ie, buy one and sell one share of the stock), design
an algorithm to find the maximum profit.
抽象出来就是找到一个数组nums[0,n]
的子数组 nums[i, j] (0 <=i < j <= n)
使得 nums[j] - nums[i]
取得最大值。当然可以直接使用暴力解法,复杂度为O(n*n)
。但是有一个更为聪明的办法,可以将复杂度降解为O(n)
, 这就是非常有名的卡丹尔算法。求解思路很简洁,本质是动态规划的思想,只需要维护一个dp数组,记录子数组结束于当前位置i
时的最大值, 因为一定要包含位置i
, 故有dp[i] = dp[i - 1] + nums[i] - nums[i - 1]
。根据题意有dp[i]的最小值是0,因此 dp[i] = max(0, dp[i - 1] + nums[i] - nums[i - 1])
,遍历dp数组找到一个最大值即可。可以进一步进行优化,在扫描nums数组的时候使用max_ending_here
表示dp[i]
, 使用max_so_far
维护max_ending_here
所有出现的值中的最大值,从而将空间复杂度从O(n)
降解为O(1)
求解
#include <stdio.h>#include <stdlib.h>#include <assert.h>int * newIntRaw(int n){ return (int *)malloc(sizeof(int) * n);}int max(int a, int b){ return a > b ? a : b;}int maxProfit1(int *prices, int pricesSize){ int max_ending_here = 0, max_so_far = 0; int i; for (i = 1; i < pricesSize; ++i) { max_ending_here += prices[i] - prices[i - 1]; max_ending_here = max(0, max_ending_here); max_so_far = max(max_ending_here, max_so_far); } return max_so_far;}int maxProfit(int *prices, int pricesSize){ int *dp; int res = 0; int i; if (pricesSize <= 0) return 0; dp = newIntRaw(pricesSize); dp[0] = 0; for (i = 1; i < pricesSize; ++i) { dp[i] = max(0, dp[i - 1] + prices[i] - prices[i - 1]); res = max(res, dp[i]); } free(dp); return res;}int main(){ int i; int n; int *nums; scanf("%d", &n); nums = newIntRaw(n); for (i = 0; i < n; ++i) scanf("%d", &nums[i]); printf("%d\n", maxProfit(nums, n)); free(nums); return 0;}
类似问题
Maximum Subarray:
Find the contiguous subarray within an array (containing at least one number) which has the largest sum.
For example, given the array [-2,1,-3,4,-1,2,1,-5,4],
the contiguous subarray [4,-1,2,1] has the largest sum = 6.
求解思路与上一题一直,直接上代码:
#include <stdio.h>#include <stdlib.h>int * newIntRaw(int n){ return (int *)malloc(sizeof(int) * n);}int max(int a, int b){ return a > b ? a : b;}int maxSubArray(int *nums, int numsSize){ int maxEndingHere, maxCur; int i; if (numsSize <= 0) return 0; maxEndingHere = maxCur = nums[0]; for (i = 1; i < numsSize; ++i) { maxEndingHere = max(maxEndingHere + nums[i], nums[i]); maxCur = max(maxCur, maxEndingHere); } return maxCur;}int main(){ int n; int *nums; int i; scanf("%d", &n); nums = newIntRaw(n); for (i = 0; i < n; ++i) { scanf("%d", &nums[i]); } printf("%d\n", maxSubArray(nums, n)); free(nums); return 0;}/*9-2 1 -3 4 -1 2 1 -5 4*/
- 卡丹尔算法(max subarray problem)
- Max Subarray
- Max subarray
- 【算法导论学习-007】最大子数组和问题(Maximum subarray problem)
- Find Max Subarray
- Max-Sum Subarray
- Max product subarray
- 算法设计Week7 LeetCode Algorithms Problem #53 Maximum Subarray
- hdu2993 MAX Average Problem (斜率dp)
- max subarray with O(N)
- Maximum SubArray Problem
- The Maximum Subarray Problem
- The maximum-subarray problem
- Maximum subarray problem
- The Maximum-Subarray Problem
- 最大子串问题(The Maximum-subarray Problem)
- 最大子树问题(The maximum-subarray problem)
- 最大子数组(The maximum-subarray problem)
- Spark的Shuffle过程介绍
- AFNetworking的二次封装
- MySQL PT Error copying rows for 问题记录
- C++ Primer Plus 第三章课后编程练习
- 虚拟机使用桥接模式设置Linux静态IP
- 卡丹尔算法(max subarray problem)
- 通过反射了解集合泛型的本质
- python---python语句讲解for、while、布尔值
- 三角形最大和问题
- MacOS 开发
- [Unity 设计模式]桥接模式(BridgePattern)
- Lintcode最后一个单词的长度
- PAT [A1060]-Are They Equal
- 其他BlockingQueue实现类