力扣hot100_普通数组_python版本

一、53. 最大子数组和

  • 思路1:前缀和。
  • 代码
python 复制代码
class Solution:
    def maxSubArray(self, nums: List[int]) -> int:
        if len(nums) == 1:
            return nums[0]
        preSum = [0] * (len(nums)+1)
        for idx, n in enumerate(nums):
            preSum[idx+1] = preSum[idx] + n
            
        res = -inf
        for idx, p in enumerate(preSum):
            for i in range(idx):
                res = max(res, p-preSum[i])
        return res
# 前缀和比较好写,但是上面复杂度太高,没法AK
# 其实每次我们只需要减去最小的前缀和,维护一个最小的前缀和,就不需要多一层循环。优化如下
class Solution:
    def maxSubArray(self, nums):
        if len(nums) == 1:
            return nums[0]
        res = -inf
        preSum = 0
        minPreSum = 0
        for n in nums:
            preSum += n
            res = max(res, preSum - minPreSum)
            minPreSum = min(minPreSum, preSum)
        return res
  • 思路2:dp

    • 定义dpi,表示以numsij结尾的最大子数组和。当来到第i个位置,有两种可能
    1. 以dpi = numsi,单独成一个子数组
    2. dpi = dpi-1 + numsi,这种情况需要dpi-1 >=0
  • 代码

python 复制代码
class Solution:
    def maxSubArray(self, nums):
        dp =[0] * len(nums)
        dp[0] = nums[0]
        for i in range(1, len(nums)):
            dp[i] = max(dp[i-1], 0) + nums[i]
        return max(dp)

二、56. 合并区间

  • 思路:先将intervals中的区间按起始排序。这样每个新来的区间就不用和已经确定好没要交集的区间比较了。
  • 代码
python 复制代码
class Solution:
    def merge(self, intervals: List[List[int]]) -> List[List[int]]:
        intervals.sort(key=lambda p:p[0])  
        res = []
        for p in intervals:
            if res and p[0] <= res[-1][1]:
                res[-1][1] = max(ans[-1][1], p[1])
            else: # 这是第一个区间 或者 新来的区间和之前的区间没有交集
                res.append(p)
        return res

三、189. 轮转数组

  • 思路:这道题可以推公式出来,如果不想推的话直接根据结果反转。注意不要使用切片或者列表的insert语法。这都会产生额外的空间
  • 代码1:
python 复制代码
class Solution:
    def rotate(self, nums: List[int], k: int) -> None:
        def reverse(i, j):
            while i < j:
                nums[i], nums[j] = nums[j], nums[i]
                i += 1
                j -= 1
        n = len(nums)
        k %= n           # 防止k比数组大
        reverse(0, n-1)
        reverse(0, k-1)
        reverse(k, n-1)
  • 代码2:使用python自带的reverse语法
python 复制代码
    def rotate2(self, nums: List[int], k: int) -> None:
    	# python也有自带的reverse语法
    	n = len(nums)
    	k %= n
    	nums.reverse()
    	nums[:k] = reversed(nums[:k])
    	nums[k:] = reversed(nums[k:])

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

  • 思路:前后缀分解。维护一个prei:表示0到i-1的乘积,sufi表示i+1到n-1的乘积。
  • 代码
python 复制代码
class Solution:
    def productExceptSelf(self, nums: List[int]) -> List[int]:
        n = len(nums)
        pre = [1]*n
        for i in range(1, n):
            pre[i] = pre[i-1] * nums[i-1]

        suf = [1]*n
        for i in range(n-2, -1, -1):
            suf[i] = suf[i+1] * nums[i+1]
            
        return [p * s for p, s in zip(pre, suf)]

五、41. 缺失的第一个正数

  • 思路:将每个数字放到自己值对应的索引上
  • 代码:
python 复制代码
class Solution:
    def firstMissingPositive(self, nums: List[int]) -> int:
        n = len(nums)
        for i in range(n):
        	# 当前数字大小在列表范围内且没有放到对应的索引位置上。
            while 1 <= nums[i] <= n and nums[nums[i] - 1] != nums[i]:
                nums[nums[i] - 1], nums[i] = nums[i], nums[nums[i] - 1]
        for i in range(n):
            if nums[i] != i + 1:
                return i + 1
        # 如果都对上了
        return n + 1
相关推荐
熊猫钓鱼>_>35 分钟前
普通用户视角的端侧智能体验手记【鸿蒙心迹】
开发语言·人工智能·华为·智能手机·性能优化·ai编程·harmonyos
瑞雪兆丰年兮36 分钟前
JavaWeb-day13-SpringBootWeb事务管理&AOP
java·开发语言·springboot·javaweb·事务·web·aop
lsc_blog2 小时前
听到优化风声,先准备能由自己掌控的事
数据库·分布式·中间件·职场和发展·重构
用户019027581612 小时前
Dify / Coze 低代码 Agent 怎么接 A 股行情?
python
布莱克6052 小时前
Swift 常量详解:从 let 到编译期优化
服务器·开发语言·ssh·swift·常量·let
Dumbness2 小时前
不传 day 参数,座位图显示全空:用 Python 标准库手写 Web 框架,请求到业务代码前的 5 个细节
后端·python
布莱克6053 小时前
Swift 可选类型(Optionals)详解:从原理到实战
开发语言·安全·ssh·swift·optional·可选类型
通信小呆呆3 小时前
电子战抗干扰技术:当“不被干扰”成为一种系统
算法·通信·mimo·isac
笑容掩饰我的失落3 小时前
区块链从小白到精通(八):从零实现一个标准 ERC-20 代币(完整可运行代码)
算法·区块链·php·智能合约·哈希算法
databook3 小时前
收上来一堆 Excel,怎么保证没改错
python·数据分析