我正在尝试解决Java中的 THIS Hackerrank 问题并输出正确的值,但由于超时,我没有通过所有测试(当有大量输入时)因为我最终得到 7“FOR”LOOPS ..你可以建议,因为我对编程有点新意,减少这些for循环的最佳方法是什么。循环执行以下操作:
循环1:在每个空格处拆分输入并将每个值分配给字符串数组
循环2:将String转换为Int并将每个int值分配给数组的Int版本,以便进行计算
循环3:重复循环1,但这次是查询输入
循环4:重复循环2,但这次是查询输入
循环5: OUTER LOOP遍历每个Q
循环6:循环5的内循环1遍历每个数组值并将curr值与curr查询值相加
循环7:循环5的内部循环2,用于检查更新的数组值,并通过首先得到它们的绝对值来总结它们
所以..在这么多循环之后,复杂性是一场灾难。任何想法如何改进它?
答案 0 :(得分:1)
时间复杂度主要取决于最后的嵌套循环。迭代所有查询和整个数组是100000 * 100000 = 10000000000
次迭代,这太多了。您需要迭代这两个数组,但不能以嵌套方式迭代。您只能在任何查询中进行log(100000)
次迭代。问题页面提示二进制搜索,这是对数的,所以应该这样做。
示例输入是[-1, 2, -3]
的数组,其中包含查询[1, -2, 3]
。
数组可以是任何顺序,因此您可以先对数组进行排序以获得[-3, -1, 2]
。
使用第一个查询1
,我们得到数组[-2, 0, 3]
。这里没有足够的时间来迭代数组,所以请考虑答案与初始数组的不同之处:
2
已更改为3
,因此总和增加1
。任何保持正数的数字都会有相同的增长。
-3
已更改为-2
,因此总和减少1
。任何保持负数的数字都会有相同的减少。
-1
已更改为0
,因此总和减少1
。这与上面的相似。
这里没有任何数字可以改变他们的标志,但也要检查他们的情况。如果对数组进行排序,则它们都将是数组中的相邻值。这里,它有助于知道原始数组中任何值范围的总和。这些可以通过存储数组的每个前缀的总和来预先计算。
请注意,如果所有数字开头都是正数可能会更容易,因此您可以将问题转换为[2, 5, 0]
和查询[-3, 1, -2, 3]
的数组,然后不输出第一个答案。
我们知道原始数组的总和为6
,因此新的总和为6 + 1 - 1 - 1 = 5
。如果我们知道有多少是正数或负数(尝试二分搜索),以及它们如何适合上述情况,那么每个和只是几次乘法,加法和减法。