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个元素的时候,小问题的值  还是有点常见啊

 

posted @ 2018-07-30 17:37  朋友圈  阅读(155)  评论(0编辑  收藏  举报