今天玩LeetCode的时候遇到了一道动态规划的题,题目是这样的:
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
.
因为刚研究算法没多长时间,所以不知道动态规划算法,对于这道题也无从下手,总是觉得要多次遍历数组,然后挨个累加,最后再比较大小,想想都麻烦,看了dp算法之后才发现自己的想法是dp算法的最原始框架
看了LeetCode的discuss的解法:
public static int maxSubArray(int[] nums) {
/*int maxSoFar=nums[0], maxEndingHere=nums[0];
for (int i=1;i<nums.length;++i){
maxEndingHere= Math.max(maxEndingHere+nums[i],nums[i]);
maxSoFar=Math.max(maxSoFar, maxEndingHere);
}
System.out.println(Arrays.toString(nums));
return maxSoFar;*/
int n = nums.length;
int[] dp = new int[n];//dp[i] means the maximum subarray ending with A[i];
dp[0] = nums[0];
int max = dp[0];
for(int i = 1; i < n; i++){
dp[i] = nums[i] + (dp[i - 1] > 0 ? dp[i - 1] : 0);
max = Math.max(max, dp[i]);
}
return max;
}
注释的也是一种解法,不过感觉虽然代码少,但是晦涩一些。
然后就开始研究DP算法:
对于概念,还是不多说了:就是在问题一堆解中求问题的最优解
然后是分类,copy网上的:
再回到LeetCode这道题目上,我遇到这种问题的时候,一般在想的是:穷举所有的情况,然后比较:
如果是这个想法:
第一次比较的所有数组是:【-2】,【-2,1】,【-2,1,-3】,【-2,1,-3,4】,【-2,1,-3,4,-1】,【-2,1,-3,4,-1,2】,【-2,1,-3,4,-1,2,1】,【-2,1,-3,4,-1,2,1,-5】,【-2,1,-3,4,-1,2,1,-5,4】然后在这里面找出最大的和,记录下来
第二次比较的所有数组是:【1】,【1,-3】,【1,-3,4】,【1,-3,4,-1】,【1,-3,4,-1,2】,【1,-3,4,-1,2,1】,【1,-3,4,-1,2,1,-5】,【1,-3,4,-1,2,1,-5,4】再找出最大的和,和第一次的比较,重置一下最大的和
。。。。。。。。依次类推,直到扫描到最后就剩下一个数组
这是常规想法,不过这样的时间复杂度是O(n²)