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])
实验结果