LeetCode53-最大连续子序列(有点意思的动态规划)
这个题,第一眼不知道怎么做...
动态规划的话,好像也没什么状态转移。
卡了有一点久。
但是后来发现,可以用原来的数组,存放(在i位置的时候,连续子序列的值)。
比如例题的[-2,1,-3,4,-1,2,1,-5,4]
第一个肯定是-2,就是当前最大子序列的值是-2
第二个的时候,-2+1 就是 -1了,还没有1大,所以选1做新的开头,当前最大值子序列是1
第三个的时候,当前最大值子序列是1,但是如果一定要带上-3的话,子序列是1,-3,这样虽然不是最大值,但是可以期待后面是最大值
第四个 ,因为是要连续的,直接开头,前面都丢掉
第五个 4,-1
第六个,因为前一个的子序列最值的3,所以可以加上,当前最大值的最长4 -1 2,前面之所以加上-1,就是为了以后可能的正数!
第七个 4 -1 2 1
第八个,4 -1 2 1 -5 ===》-1
第九个 ,因为前面是-1,所以直接4开头
整个序列就是 -2 1 -2 4 3 5 6 -1 4
能看到里面最大就是6了
初步写出来的代码,其实可以发现无论当前是正数还是负数,操作都是一样的
前面和是负数的序列,丢掉,不要给自己加包袱
前面和是正数的序列,加上自己
代码懒得改了,不太优雅
public static int maxSubArray(int[] nums) { int max = nums[0]; for(int i=1,len=nums.length;i<len;i++){ int last = nums[i-1]; int current = nums[i]; //如果当前是正数,肯定加上去会使子序列变大啊! if(current>=0){ //如果前面小于0,那就是给自己拖后腿的,还不如以自己开头 if(last<0){ }else{ //如果前面大于0,毫无疑问要加上自己 nums[i] = last+current; } //判断此时的自己是不是当前最大 if(nums[i]>max) max = nums[i]; }else{ //如果小于0,无论如何,都会减少当前序列的最大值了,但是可能后头有更大的值 //如果前面小于0,那就是给自己拖后腿的,还不如以自己开头 if(last<0){ }else{ //如果前面大于0,毫无疑问要加上自己 nums[i] = last+current; } //负数其实也要判断,因为有可能一直都是负数,那么最大的那个负数就是最大值了 if(nums[i]>max) max = nums[i]; } } //其实可以看到无论当前大于0还是小于0,都是一样的操作,懒得改了 return max; }
这种利用原数组,存放 在第i个元素的时候,小问题的值 还是有点常见啊