基础算法求助(已解决)
一个看起来较为基础的计算机算法问题,求大神解惑!
(已解决,末尾给出参考答案)
参数
- 给定一组长度为
length
的随机正整数列表list
,list
中元素均小于或等于max
;(注:length > 2
) - 给定正整数参数
mid
、short
、long
,且满足0 < short < long < length
、0 < mid < max
;
条件
从 list
中选取包括首尾元素在内的若干个元素组成一个新的列表 list_cut
,list_cut
需要满足以下几个条件:
list_cut
中各个元素均需小于mid
;list_cut
中相邻元素在list
中的索引值差为gap
, 且满足0 < short <= gap <= long
;
返回值
- 若给定的参数无法选出
list_cut
, 返回 False; - 若给定的参数可以选出多个
list_cut
,则返回所有list_cut
中元素平均值最低的一个。
示例一
# 输入
list = [4, 7, 3, 5, 8, 6, 2, 3, 1, 2]
mid = 5
short, long = 2, 4
# 输出
list_cut = [4, 3, 2, 2]
示例二
# 输入
list = [4, 7, 6, 5, 8, 6, 2, 3, 1, 2]
mid = 5
short, long = 2, 4
# 输出
list_cut = False
参考答案
多谢 @SegmentWarrior 大佬提供的思路与C++
代码;
下面给出我“翻译”并稍加改进后的python
版的答案。
def find_list(nums: list, s: int, l: int, mid: int):
"""
nums: 目标数组
s: short 最短长度
l: long 最长长度
mid: 限制大小
"""
# dp 到当前位置的上一个最优解的 index
n = len(nums)
dp = [-1] * n
dp[0] = 0
for i in range(n-s):
for j in range(i+s, min(i+l+1, n)):
if nums[j] >= mid:
continue
elif dp[i] != -1:
dp[j] = i
if dp[-1] == -1:
return False
res = []
inx = n - 1
while inx > 0:
res.append(nums[inx])
inx = dp[inx]
res.append(nums[0])
return res[::-1]
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
可以用dfs,backtracking或者dp来做
如果这题是OJ的话,dfs和backtracking的复杂度太高,
O(2^n)
可能不能pass如果用DP的话,复杂度是
O(n^2)
C++ 实现的DP算法:
Time: O(n^2)
Space: O(n)
sums
记录了到当前位置最优解的总和div
记录了到当前位置的最优解的个数dp
记录了到当前位置的上一个最优解的index(最后一个index是本身),可以当做linked list来看,用最后的while loop找到list_cut谢谢@CRIMX指出来的错误,先前的代码没有考虑到平均值相等的情况。
代码如下:
Backtracking 代码如下:
res
为最终的list-cut这是我写了老半天的一点儿想法,就算不能完全满足你的要求,也希望你能从中看出些端倪,最后能进行完善!
这是我用
JavaScript
写的,直接复制粘贴运行便可看到效果:1、输入:let list = [2, 9, 9, 9, 9, 9, 9, 9, 9, 2];
2、输入:let list = [4, 7, 3, 5, 8, 6, 2, 3, 1, 2];
3、输入: let list = [4, 7, 6, 5, 8, 6, 2, 3, 1, 2];
只能说水平有限,尽力了!
我的思路是从左到右递归地看,对于每个符合的数字,要么取,要么不取,最后判断最小平均值。
没有说明语言就用 JavaScript 写了一下
你好像忘记了提问题