LeetCode53-最大连续子序列(有点意思的动态规划)

本文解析了一道经典的编程题目——最大子序列和问题。通过动态规划的方法,使用原数组来记录中间结果,实现了简洁高效的求解过程。文章详细解释了算法思路,并给出了示例代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这个题,第一眼不知道怎么做...

动态规划的话,好像也没什么状态转移。

卡了有一点久。

 

 

但是后来发现,可以用原来的数组,存放(在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个元素的时候,小问题的值  还是有点常见啊

 

转载于:https://www.cnblogs.com/weizhibin1996/p/9391800.html

LeetCode 题目 491 - 递增子序列 (Incremental Subsequence) 是一道关于算法设计的中等难度题目。这道题要求你在给定整数数组 nums 中找出所有长度大于等于 1 的递增子序列。递增子序列是指数组中的一串连续元素,它们按照顺序严格增大。 解决这个问题的一个常见策略是使用动态规划(Dynamic Programming),特别是哈希表或者单调栈(Monotonic Stack)。你可以维护一个栈,每当遍历到一个比栈顶元素大的数字时,就将它推入栈,并更新当前最长递增子序列的长度。同时,如果遇到一个不大于栈顶元素的数字,就从栈顶开始检查是否存在更长的递增子序列。 以下是 C++ 解决此问题的一种简单实现: ```cpp class Solution { public: vector<int> lengthOfLIS(vector<int>& nums) { int n = nums.size(); if (n == 0) return {}; // 使用单调栈存储当前已知的最大子序列 stack<pair<int, int>> stk; stk.push({nums[0], 1}); for (int i = 1; i < n; ++i) { while (!stk.empty() && nums[i] > stk.top().first) { // 如果新数大于栈顶元素,找到一个更长的递增子序列 int len = stk.top().second + 1; ans.push_back(len); stk.pop(); } // 如果新数不大于栈顶元素,尝试从当前位置开始寻找更长子序列 if (!stk.empty()) { stk.top().second = max(stk.top().second, 1); } else { stk.push({nums[i], 1}); } } return ans; } private: vector<int> ans; }; ``` 在这个解决方案中,`ans` 存储所有的递增子序列长度,最后返回这个结果向量即可。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值