53-最大子序和-Java&python

本文深入探讨了求解最大子数组和的经典算法——逆向动态规划法。通过实例讲解了算法原理,提供了Java和Python两种语言的实现代码,并对比分析了算法的时间和空间复杂度。适合对算法设计和动态规划感兴趣的学习者。

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

1、题目

https://leetcode-cn.com/problems/maximum-subarray/submissions/

给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。

示例:

2、实现-逆向动态规划

分析:

设sum[i]为以第i个元素结尾且和最大的连续子数组。假设对于元素i,所有以它前面的元素结尾的子数组的长度都已经求得,那么以第i个元素结尾且和最大的连续子数组实际上,要么是以第i-1个元素结尾且和最大的连续子数组加上这个元素,要么是只包含第i个元素,即sum[i] 
= max(sum[i-1] + a[i], a[i])。可以通过判断sum[i-1] + a[i]是否大于a[i]来做选择,而这实际上等价于判断sum[i-1]是否大于0。由于每次运算只需要前一次的结果,因此并不需要像普通的动态规划那样保留之前所有的计算结果,只需要保留上一次的即可,因此算法的时间和空间复杂度都很小
-----------------
以上为转

java

class Solution {
    public int maxSubArray(int[] nums) {//动态规划
        int sumTemp=nums[0];//边界值
        int sum=nums[0];
        
        for(int i=1;i<nums.length;i++){
            if(sumTemp>0){ //如果前面的结果>0,+sum[i]才能更大
               sumTemp+=nums[i]; 
            }else{//如果前面的结果<=0,那么可以从sum[i]重新开始了
                sumTemp=nums[i];
            }
            sum=Math.max(sumTemp,sum);//本次sumTemp和上次保留的sum比较
        }
        return sum;
        
    }
}

 

python

class Solution:
    def maxSubArray(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        st=nums[0];
        s=nums[0];
        for i in range(1,len(nums)):
            if st>0:
                st=st+nums[i]
            else:
                st=nums[i]
            s=max(st,s)
        return s    
            

        

 


3、注意

python没有 for (;;) 要用 for range

python没有i++  要写成i=i+1

4、动态规划理解和应用 后续待补~~

### 字典最大列算法实现方法 #### 背景介绍 给定一个字符串 `s`,目标是从中提取字典最大列。此问题可以通过贪心策略解决,在遍历过程中动态维护当前可能构成的最大列。 --- #### 算法设计原理 为了找到字典最大列,可以从右向左扫描输入字符串,并记录遇到过的字符中的最大值。如果某个字符大于等于已知的最大值,则将其加入结果集合。最终将这些字符按逆排列即可得到答案[^1]。 以下是具体实现逻辑: - 使用变量存储当前发现的最大字母。 - 遍历整个字符串,从最后一个字符向前推进。 - 如果当前字符不小于之前保存的最大值,则更新最大值并将该字符纳入候选集。 - 完成遍历后反转收集到的结果列表以恢复原始顺。 这种方法的时间复杂度为 O(n),其中 n 是字符串长度,因为只需要一次线性扫描就能完成计算过程[^3]。 --- #### Python 实现代码 下面提供了一种基于上述思想编写的Python版本解决方案: ```python def largest_lex_subsequence(s): result = [] current_max = 'a' # Reverse iteration over the string to find lex-max subseq. for c in reversed(s): if c >= current_max: current_max = c result.append(c) # Since we collected characters backwards, reverse them back into correct order. return ''.join(reversed(result)) if __name__ == "__main__": test_string = input() print(largest_lex_subsequence(test_string)) ``` 这段程定义了一个函数来接收任意合法的小写英文字符串作为参数并返回其对应的字典最高列。 --- #### Java 实现代码 对于偏好Java语言的开发者来说,也可以参照以下示例编码方式: ```java import java.util.Scanner; public class LargestLexSubsequence { public static void main(String[] args){ Scanner scanner=new Scanner(System.in); String strInput=scanner.nextLine(); char maxChar='a'; StringBuilder builder=new StringBuilder(); // Iterate through each character from end towards start of array/string for(int index=strInput.length()-1 ;index>=0; --index ){ char chAtPos=strInput.charAt(index); if(chAtPos >=maxChar){ maxChar=chAtPos; builder.append(maxChar); } } // Print out final answer after reversing built sequence System.out.print(builder.reverse()); } } ``` 这里同样采用了类似的反向迭代机制以及条件判断语句构建起完整的解答流程。 --- #### 性能分析 由于只需单次循环访问数据结构内部的所有成员单元格,因此整体时间效率较高——达到最优级别O(N)[^2]。空间消耗方面也较为理想,仅需额外开辟少量辅助内存用于暂存中间状态信息。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值