这个挑战是从入学考试到封闭数字网络安全课程。无论如何,它与网络安全无关,只是为了测试学生的逻辑和编码技能。
任务
编写一个程序,该程序从数组中删除条目,以便以严格的降序对其余值进行排序,并且在所有其他可能的降序中将其总和最大化。
输入输出
输入将是整数值的数组严格地大于0
和所有彼此不同。您可以自由选择是从文件,命令行还是标准输入中读取输入。
输出将是输入之一的降序子数组,其总和大于任何其他可能的降序子数组。
注意: [5, 4, 3, 2]
是的子数组[5, 4, 1, 3, 2]
,即使4
和3
不相邻。只是因为1
弹出了。
暴力解决方案
当然,最简单的解决方案是在给定数组的所有可能组合中进行迭代,并搜索具有最大和的排序后的数组,即在Python中:
import itertools
def best_sum_desc_subarray(ary):
best_sum_so_far = 0
best_subarray_so_far = []
for k in range(1, len(ary)):
for comb in itertools.combinations(ary, k):
if sum(comb) > best_sum_so_far and all(comb[j] > comb[j+1] for j in range(len(comb)-1)):
best_subarray_so_far = list(comb)
best_sum_so_far = sum(comb)
return best_subarray_so_far
不幸的是,由于检查数组是否已排序并计算其元素的总和为,并且由于此操作的完成时间为从到,因此渐近时间复杂度为
挑战
您的目标是实现比上述蛮力更好的时间复杂性。渐近时间复杂度最小的解决方案是挑战的胜者。如果两个解具有相同的渐近时间复杂度,则获胜者将是最小的渐近空间复杂度。
注意: 即使大量,您也可以考虑读取,写入和比较原子。
注意: 如果有两个或多个解决方案,请返回其中一个。
测试用例
Input: [200, 100, 400]
Output: [400]
Input: [4, 3, 2, 1, 5]
Output: [4, 3, 2, 1]
Input: [50, 40, 30, 20, 10]
Output: [50, 40, 30, 20, 10]
Input: [389, 207, 155, 300, 299, 170, 158, 65]
Output: [389, 300, 299, 170, 158, 65]
Input: [19, 20, 2, 18, 13, 14, 8, 9, 4, 6, 16, 1, 15, 12, 3, 7, 17, 5, 10, 11]
Output: [20, 18, 16, 15, 12, 7, 5]
Input: [14, 12, 24, 21, 6, 10, 19, 1, 5, 8, 17, 7, 9, 15, 23, 20, 25, 11, 13, 4, 3, 22, 18, 2, 16]
Output: [24, 21, 19, 17, 15, 13, 4, 3, 2]
Input: [25, 15, 3, 6, 24, 30, 23, 7, 1, 10, 16, 29, 12, 13, 22, 8, 17, 14, 20, 11, 9, 18, 28, 21, 26, 27, 4, 2, 19, 5]
Output: [25, 24, 23, 22, 17, 14, 11, 9, 4, 2]