说明:本人是一个菜鸟,接触到动态规划,有点想法。所以分享一下,有不严谨的地方望大佬指正。
我将从力扣的一道题目来说明我对想法:
题目:
做题前的思考:要找和最大的连续子数组,那么我们就是要找到所有的子数组,然后比较他们的大小,但是如果是想先找含有1个大小的数组,再找含有2个大小的数组...的话,那就需要计算n*(n+1)/2个数组的大小,不仅多,而且实现起来也比较麻烦。
想法一:在之前的思考上,这时候再往下思索就可以想到一个方便实现的想法,该方法就是把包含第一个元素的1个大小数组,2个大小数组...9的大小数组进行计算比较,找到最大的数并存入新数组arr中,然后再对第二个元素进行相同操作,一直到最后一个元素。虽然他也需要计算n*(n+1)/2个数组,但是该想法容易实现。
代码如下:
int maxSubArray(int *nums, int numsSize)//nums是传入数组,numSize是数组大小 { int arr[numsSize];//新数组 for (int i = 0; i < numsSize; i++)//9次循环,从-2,1,-3,4,-1,2,1,-5,4 { int max = nums[i];//定义最大值 for (int j = i; j < numsSize; j++)//每个数都有numsSize-i个组合 { //该循环得到一组最大值 int sum = 0; for (int a = i; a <= j; a++) { sum += nums[a]; } if (max < sum) { max = sum; } } arr[i] = max;//得到numsSize-i个组合中的最大值 } int m = arr[0]; for (int p = 0; p < numsSize; p++) { //在新建数组中查找最大数 if (arr[p] > m) { m = arr[p]; } } return m; }
力扣提交结果:
说明:该算法的时间复杂度为O(n^3),对于他提示中的三个样例是能很快执行的,但是当测试数组的大小达到上万个元素,他的执行速度很慢。可以试试哟,他会给出一个超级大的测试数组😕
想法二(动态规划DP):我理解的DP有2个特点,①将一个大问题化成多个小问题,②将小问题的结果比较(根据题目要求比较)、存储
这个题目的理解:
①将一个大问题化成多个小问题
大问题:求这个数组的最大和的连续数组,
小问题:我们可以考虑求[-2] 的最大和的连续数组,然后求[-2, 1] 的最大和的连续数组...
最后求[-2,1,-3,4,-1,2,1,-5,4]的最大和的连续数组
②将小问题的结果比较(根据题目要求比较)、存储
比较:是比较前面一个数组的最大和与该位置数组大小,取最大的存储。
注意:如果上一个的连续数组最大和小于该位置数组,则表示上一个数组与当前位置的数组断开,当前位置的数组元素可能与下一个元素相连。
代码如下:
int maxSubArray(int *nums, int numsSize) { int arr[numsSize];//定义新数组 arr[0] = nums[0]; int Maximum = arr[0]; for (int i = 1; i < numsSize; i++) { arr[i] = max(nums[i] + arr[i - 1], nums[i]);//动态规划转移方程 Maximum = max(Maximum, arr[i]);//寻找最大值 } return Maximum; } int max(int a, int b) { return ((a > b) ? a : b); }
力扣提交结果:
说明:该算法的时间复杂度为O(n),动态规划最重要的就是将一个大问题化成什么样的多个小问题,以及如何设计动态规划转移方程。
如果大家有好的理解,欢迎讨论