Day3,Hot100(17/100)

普通数组

53. 最大子数组和

方法一:前缀和
(1) 维护当前前缀和pre
(2) 区间 [i, j]之和 = pre[j] - pre[i]
(3) 遍历数组,求以 j 结尾的最大和
(4) 要使j 结尾和最大,则需要pre[i]最小,于是维护 j 之前最小的前缀和使得 pre[j] - pre[i] 最大

class Solution:
    def maxSubArray(self, nums: List[int]) -> int:
        pre = 0
        min_pre = 0
        ans = -inf

        for v in nums:
            pre += v
            ans = max(pre - min_pre, ans)
            min_pre = min(min_pre, pre)
        return ans

方法二:DP
(1)状态表示:f[i] 为以 i 结尾的最大连续和
(2)状态计算:(根据前一个状态计算)i 结尾的最大值f[i],可由 f[i-1] 求得

class Solution:
    def maxSubArray(self, nums: List[int]) -> int:
        ans = -inf
        f = [0] * len(nums)

        for i in range(len(nums)):
            f[i] = max(nums[i], f[i-1]+nums[i])
            ans = max(ans, f[i])
        return ans

56. 合并区间

1、将数组按照左区间大小进行排序( sorted(array, key=lambda x: x[0]) )
2、维护结果数组ans,遍历intervals,判断ans[-1]与intervals[i]是否由交集

class Solution:
    def merge(self, intervals: List[List[int]]) -> List[List[int]]:
        n = sorted(intervals)
        ans = [n[0]]
        for i in range(1, len(n)):
            if ans[-1][1] >= n[i][0]:
                ans[-1][1] = max(ans[-1][1], n[i][1])
            else:
                ans.append(n[i])
        return ans

189. 轮转数组

不能用 nums = nums[::-1],这样不是原地修改nums,地址空间不一样

class Solution:
    def rotate(self, nums: List[int], k: int) -> None:
        """
        Do not return anything, modify nums in-place instead.
        """
        lens = len(nums)
        n = k % lens
        if n:  #  k % lens == 0,不需要操作
            nums.reverse()  # 原地翻转数组
            nums[:n] = nums[n - 1::-1]
            nums[n:] = nums[-1:n - 1:-1]

238. 除自身以外数组的乘积

1、除自身以外数组的乘积 = 左边乘积 × 右边乘积
2、参考前缀和的思想, 构建左前缀 与 右前缀积

class Solution:
    def productExceptSelf(self, nums: List[int]) -> List[int]:
        lens = len(nums)
        ans = [0] * lens
        
        left = [0] * lens
        left[0] = nums[0]
        right = [0] * lens
        right[-1] = nums[-1]

        for i in range(1, lens):
            left[i] = left[i-1] *  nums[i]
        for i in range(lens-2, -1, -1):
            right[i] = right[i+1] * nums[i]

        ans[0] = right[1]
        for i in range(1, lens - 1):
            ans[i] = left[i-1] * right[i+1]
        ans[-1] = left[-2]
        return ans

41. 缺失的第一个正数

直接法
(1)对数组排序;
(2)从正数开始,逐个比较当前元素与上一个元素tmp 是否是连在一起的。若不是,则最小正整数为tmp+1;
(3)如果最终tmp=0,说明数组全为负数,最小正整数为1。否则说明数组是连续的序列,最小正整数为 最大数+1。

class Solution:
    def firstMissingPositive(self, nums: List[int]) -> int:
        nums.sort()
        tmp = 0
        for i in range(len(nums)):
            if nums[i] <= 0:
                continue

            if tmp == 0:
                if nums[i] != 1:
                    return 1
                tmp = nums[i]
                continue

            if nums[i] - tmp <= 1:
                tmp = nums[i]
                continue
            else:
                return tmp+1

        if tmp == 0:
            return 1
        
        return nums[-1] + 1
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值