Leetcode刷题(18) 最大自序和, 最长递增子序列,最大....

Leetcode刷题(18) 最大自序和, 最长递增子序列,最大....

这两道题较为类似,dp数组的定义比较特别,转移方程也很相似。

方法参考labuladong的动态规划设计:最大子数组动态规划设计:最长递增子序列

53. 最大子序和

class Solution(object):
    def maxSubArray(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        n = len(nums)
        res = -float('Inf')
        if n < 0:
            return 0
        # dp数组含义: 以 nums[i] 为结尾的「最大子数组和」为 dp[i]
        dp = [0] * n
        dp[0] = nums[0]
        # 循环(状态)
        for i in range(1, n):
            # 接着上一个dp[i-1], 还是自立门户(做选择)
            dp[i] = max(dp[i-1] + nums[i], nums[i])

        # 得到以那个i结尾的最大子数组和大
        for i in range(n):
            res = max(res, dp[i])
        return res
# ===============================================================
# 空间压缩
class Solution(object):
    def maxSubArray(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        n = len(nums)
        
        if n < 0:
            return 0
        dp_0 = nums[0]
        res = dp_0
        dp_1 = 0
        # 循环(状态)
        for i in range(1, n):
            # 接着上一个dp[i-1], 还是自立门户(做选择)
            dp_1 = max(dp_0 + nums[i], nums[i])
            res = max(dp_1, res)
            dp_0 = dp_1
        return res

128. 最长连续序列

哈希辅助

class Solution:
    def longestConsecutive(self, nums):
        longest_streak = 0
        # hash辅助
        num_set = set(nums)
        for num in num_set:
            if num - 1 not in num_set:
                # num-1不在的话就可以以num为起点开始记录连续值
                cur_num = num
                # 开始匹配以当前值为起点的连续值
                l = 0
                while cur_num in num_set:
                    l += 1
                    cur_num += 1
                # 更新最大值
                longest_streak = max(l, longest_streak) 
        return longest_streak

快慢指针迭代法

class Solution(object):
    def longestConsecutive(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        nums = sorted(list(set(nums)))
        if len(nums) == 0:
            return 0
        
        start = 0
        pre_end = 0
        end = 1
        l = 1  # 无论什么情况,只要list不是空的,都至少有1的连续
        while end < len(nums):
            # 发生断裂, start跳到当前的end
            if nums[end] - nums[pre_end] > 1: 
                # 在当前位置重置
                start = end 
                pre_end = end
            else:
                # 连续, 更新l
                l = max(l, end - start + 1)
                pre_end += 1
            end += 1
        return l

718. 最长重复子数组

动态规划

class Solution(object):
    def findLength(self, A, B):
        """
        :type A: List[int]
        :type B: List[int]
        :rtype: int
        """
        na = len(A)
        nb = len(B)
        # 用一个变量跟踪记录全局的最大值
        res = 0
        dp = [[0] * (nb + 1) for _ in range(na + 1)]
        for i in range(1, na + 1):
            for j in range(1, nb + 1):
                # 连续相同 +1
                if A[i-1] == B[j-1]:
                    dp[i][j] = dp[i-1][j-1] + 1
                    res = max(dp[i][j], res)
                # 阶段 重置为0
                else: 
                    dp[i][j] = 0
        return res

128. 最长连续序列

迭代法

class Solution(object):
    def longestConsecutive(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        nums = sorted(list(set(nums)))
        if len(nums) == 0:
            return 0
        n = len(nums)
        start = 0
        # end的前驱
        pre = 0
    
        l = 1  # 无论什么情况,只要list不是空的,都至少有1的连续
        for end in range(1, n):
            # 断裂
            if nums[end] - nums[pre] > 1:
                # start跳到end上
                start = end
                pre = end
            # 接上了
            else:
                l = max(l, end - start + 1)
                pre = end
        return l

哈希辅助法

class Solution:
    def longestConsecutive(self, nums):
        if len(nums) == 0:
            return 0
        num_set = set(nums)
        # 在前进(+1)的路上已经遇到过的数就不要计算了
        visited = [] 
        l_max = 1
        for num in num_set:
            # num-1在的话就没有必要处理num, 遍历到num-1的时候处理num-1就行啦
            if num - 1 not in num_set and num not in visited:
                cur_num = num
                l = 1
                while cur_num + 1 in num_set:
                    cur_num = cur_num + 1
                    l += 1
                l_max = max(l, l_max)
        return l_max

 

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值