使用多个FOR循环来提高时间复杂度的最佳方法是什么

时间:2017-12-02 14:58:22

标签: java loops time-complexity

我正在尝试解决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,用于检查更新的数组值,并通过首先得到它们的绝对值来总结它们

所以..在这么多循环之后,复杂性是一场灾难。任何想法如何改进它?

1 个答案:

答案 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。如果我们知道有多少是正数或负数(尝试二分搜索),以及它们如何适合上述情况,那么每个和只是几次乘法,加法和减法。