有空就刷,继续做简单的题
题1:数组中两元素的最大乘积
题目描述
给你一个整数数组 nums,请你选择数组的两个不同下标 i 和 j,使 (nums[i]-1)*(nums[j]-1) 取得最大值。
请你计算并返回该式的最大值。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/maximum-product-of-two-elements-in-an-array
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题思路
很简单的一题,先排序,再取出最后两个数字减一后求积
提交代码
class Solution:
def maxProduct(self, nums: List[int]) -> int:
nums.sort()
return (nums[-1]-1) * (nums[-2]-1)
提交情况
还不错
题2:构造矩形
题目描述
作为一位web开发者, 懂得怎样去规划一个页面的尺寸是很重要的。 现给定一个具体的矩形页面面积,你的任务是设计一个长度为 L 和宽度为 W 且满足以下要求的矩形的页面。要求:
-
你设计的矩形页面必须等于给定的目标面积。
-
宽度 W 不应大于长度 L,换言之,要求 L >= W 。
-
长度 L 和宽度 W 之间的差距应当尽可能小。
你需要按顺序输出你设计的页面的长度 L 和宽度 W。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/construct-the-rectangle
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
![](/qrcode.jpg)
解题思路
看似挺简单,不过还是要动下脑筋
先对area开方取整,作为w的最大值,用area/w取余,如果取余为0就得到了w和l,如果不为0就让w自减,直到满足取余为0为止。
提交代码
class Solution:
def constructRectangle(self, area: int) -> List[int]:
w = int(area**0.5)
while area%w != 0:
w = w - 1
return [int(area/w), w]
提交情况
效率一般
题3:和为零的N个唯一整数
题目描述
给你一个整数 n,请你返回 任意 一个由 n 个 各不相同 的整数组成的数组,并且这 n 个数相加和为 0 。
示例 1:
输入:n = 5
输出:[-7,-1,1,3,4]
解释:这些数组也是正确的 [-5,-1,1,2,3],[-3,-1,2,-2,4]。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/find-n-unique-integers-sum-up-to-zero
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题思路
分两种情况:
- n为奇数时,直接返回int(-n/2)到int(n/2)中间所有的整数
- n为偶数时,返回int(-n/2)到int(n/2)中间所有的整数,并移除0
提交代码
class Solution:
def sumZero(self, n: int) -> List[int]:
if n%2 == 0:
a = list(range(int(-n/2), int(n/2+1)))
a.remove(0)
else:
a = list(range(int(-n/2), int(n/2)+1))
return a
注意用range函数时,正数要+1
提交情况
效率不错
题4:和为s的连续正数序列
题目描述
输入一个正整数 target ,输出所有和为 target 的连续正整数序列(至少含有两个数)。
序列内的数字由小到大排列,不同序列按照首个数字从小到大排列。
示例 1:
输入:target = 9
输出:[[2,3,4],[4,5]]
示例 2:
输入:target = 15
输出:[[1,2,3,4,5],[4,5,6],[7,8]]
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/he-wei-sde-lian-xu-zheng-shu-xu-lie-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题思路&代码
这个题目其实挺有意思,也挺有难度。
就我这个数学基础已经忘到见底的渣渣来说,最先想到的就是暴(憨)力(憨)解法,怎么个暴力法呢,就是把所有的连续数列全部切片出来,挨个切片求和,求和结果等于target的就取出来,,没错,就是这么暴力。不多说,上代码
def fcs(target):
# 首先把完整的数列先列表出来
# 至于为啥最后一个数是int(target/2) + 1,动动脑就清楚了
n = list(range(1, int(target/2) + 2))
# 新建一个切片列表,首先附上完整的列表
all_cut = [n]
# 第一个循环就是对列表进行切片
for i in range(2, len(n)):
for j in range(len(n) - i + 1):
all_cut.append(n[j:(j+i)])
s = []
# 循环查找符合条件的切片
# 为啥要逆序呢,因为从前面我的切片来看,我是先从少数据列表的开始的,
# 少的列表自然数据会大一些,所以为了符合题目要求,需要逆序切片列表
for li in all_cut[::-1]:
if sum(li) == target:
s.append(li)
return s
至于结果咋样,不多说,上图片
哈哈,果然暴力解法不行
至于这个方法是不是正确的呢,我拿spyder跑了一下2到99的所有数据,还阔以嘛
也就是说算法应该没问题,就是效率太低。
其他优化解法呢?
其实这题可以用滑动窗口来解
什么叫滑动窗口
看上面这张图,比如target=9,首先我把1~9都列表出来,连续正整数求和=9,那么右边那个数肯定不会大于列表的中位数9,搞两个指针,左边的指针i从1开始,右边的指针j从i+1开始到5结束
指针内的所有数据求和,如果和小于9,指针j向右滑动一个单位,如果和大于9,那左边的指针i向右滑动一个单位。
这个思路感觉有点意思,那么开始写代码吧
class Solution:
def findContinuousSequence(self, target: int) -> List[List[int]]:
i = 1
j = 2
re = []
while j <= target//2 + 1:
current_sum = sum(list(range(i, j + 1)))
if current_sum < target:
j = j + 1
elif current_sum > target:
i = i + 1
else:
re.append(list(range(i, j + 1)))
j = j + 1
return re
这段代码的执行情况:
一般般,不过这已经是我能想到的最好的解题思路了,当然还有更好的思路,参考大佬的解题思路。
【详解】滑动窗口法 -> 求根法 -> 间隔法,一山还有一山高
来源:力扣(LeetCode)
好吧,今天就到这里,最后这题有点费脑子。