Leetcode刷题第四天

Leetcode刷题第四天


刷完题就赶紧去看论文了,不然周报没东西写,一周又过完了,这周主要是一场接一场的面试,没有看论文了,罪恶啊。

一、今天刷了两题
**1.**难度级别——中等
在这里插入图片描述
题目中要求不能使用除法
①第一种解法

from functools import reduce
class Solution:
    def productExceptSelf(self, nums: List[int]) -> List[int]:
        b=list(range(len(nums)))
        for i in range(len(nums)):
            c=nums[i]
            nums[i]=1
            b[i]=reduce(lambda x,y:x * y,nums)
            nums[i]=c
        return b

运行结果
提交时显示超出时间限制,但是是可以运行成功的

想法
利用reduce函数来计算列表中的元素之积,计算[i]处的值就让nums[i]=1,但是在跳出这次循环之前要将它恢复到原来的值,所以又引入了一个c,用于暂时存储nums[i]的值,并且也不能直接在nums里操作,将nums[i]换成除了此位元素,其余元素的乘积之和。

reduce函数实例如下,reduce(function,可迭代对象)

#!/usr/bin/python
from functools import reduce

def add(x, y) :            # 两数相加
    return x + y
sum1 = reduce(add, [1,2,3,4,5])   # 计算列表和:1+2+3+4+5
sum2 = reduce(lambda x, y: x+y, [1,2,3,4,5])  # 使用 lambda 匿名函数

②第二种解法
引入了前缀之积和后缀之积两种概念
代码如下

class Solution:
    def productExceptSelf(self, nums: List[int]) -> List[int]:
        L=list(range(len(nums)))
        R=list(range(len(nums)))
        L[0]=1
        R[len(nums)-1]=1
        for i in range(1,len(nums)):
            L[i]=L[i-1]*nums[i-1]
        for i in range(len(nums)-2,-1,-1):
            R[i]=R[i+1]*nums[i+1]
        for i in range(len(nums)):
            nums[i]=L[i]*R[i]
        return nums

运行结果
在这里插入图片描述
想法
三次循环,时间复杂度是O(N)
构造了L,R两个数组,空间复杂度也是O(N)
对于数组[4,5,1,8,2]
前缀之积
4没有前缀元素,令前缀之积为1,最终结果为前缀之积乘后缀之积
5的前缀之积是4*4的前缀之积
在这里插入图片描述
后缀之积
此时倒着看,这也用到了for i in range(len(nums)-2,-1,-1),仍然和顺着一样取不到[-1]处的值,其实实际上[-1]处的值就是末尾处的值,[-2]就是倒数第二个,我们的目的就是取到[0]处的值。
2没有后缀元素,所以让它的后缀之积为1,8的后缀之积=8后面的一位数字(2)*2的后缀之积
在这里插入图片描述
优化空间复杂度,优化第二种解法

class Solution:
    def productExceptSelf(self, nums: List[int]) -> List[int]:
        ans=list(range(1,len(nums)+1))
        R=1
        for i in range(1,len(nums)):
            ans[i]=ans[i-1]*nums[i-1]
        for i in range(len(nums)-1,-1,-1):
            ans[i]=ans[i]*R
            R=R*nums[i]
        return ans

实验结果
在这里插入图片描述
这里的想法是白嫖ans空间,此时空间复杂度是O(1)

2.
难度级别:简单
在这里插入图片描述
想法
如果题目改成,让你求由三个数组成的最大的和,那就很简单直接找出数组里面最大的三个数,此时它们的和一定最大
如何找出数组里面最大的三个数
①利用np.sort()
https://numpy.org/doc/stable/reference/generated/numpy.sort.html
②利用“打擂台”的方法

class Solution:
    def maximumProduct(self, nums: List[int]) -> int:
        a = b = c = float('-inf')
        d = e = float('inf')
        for i, num in enumerate(nums):
            # 更新最大三个数
            if num > a:
                a, b, c = num, a, b
            elif num > b:
                b, c = num, b
            elif num > c:
                c = num
            # 更新最小两个数
            if num < d:
                d, e = num, d
            elif num < e:
                e = num

        return max(d * e * a, a * b * c)
作者:yim-6
链接:https://leetcode-cn.com/problems/maximum-product-of-three-numbers/solution/python3-liang-chong-fang-fa-ji-suan-san-nae0f/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

学习一下,求三个最大的数a,b,c,遍历这个数组,若遇到了这个数字大于a,则该数字赋值给a,a赋值给b,b赋值给c
(赋值是同时的,没有先后顺序)

但是此时是求由三个数组成的最大的乘积
有几种情况
(1)三个数全为正数
那我们直接np.sort排好序之后,这是按从小到大的顺序,求最后三位[-1] [-2] [-3]的乘积
(2)三个数全为负数,这样最后的结果也是为负数,和上述情况一样
(3)两个正数,一个负数,这种情况只在"数组中只有三个数的情况下才成立",因为如果有四个数,无论这是正数,还是负数,都不可能是两个正数和一个负数组合在一起得到最大的值
(4)两个负数,一个正数,这是有可能的,因此在np.sort之后,去找最大的正数[-1],以及最小的两位负数,[0][1]

现在是(1)(2)(4)三种情况,(1)(2)在代码中是一样的,(4)是单独一种,分别求出来值之后,再用max(a,b)

代码

class Solution:
    def maximumProduct(self, nums: List[int]) -> int:
        nums.sort()#引入numpy库之后,用np.sort(nums)也行,二者不同是前者直接改变了nums,而后者是返回一个新的array
        return max(nums[-1]*nums[-2]*nums[-3],nums[0]*nums[1]*nums[-1])  

实验结果
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值