转换嵌套'为'循环到单一' for'循环在java中

时间:2018-01-19 14:15:42

标签: java loops nested

for(i=0;i<k;i++)
{
    l=sc.nextLong();
    r=sc.nextLong();
    v=sc.nextLong();

    for(j=l-1;j<r;j++)
    {
        m=(int)j;
        ar[m]=ar[m]+(long)v;
    }
}

如何将其转换为单个for循环?此代码导致我超时问题。代码的执行时间应低于2秒。这个是2秒。

1 个答案:

答案 0 :(得分:1)

我认为你可以避免两个循环,但是你可以将它设为顺序,而不是嵌套。

long[] delta = new long[ar];
for(i=0;i<k;i++)
{
    l=sc.nextLong();
    r=sc.nextLong();
    v=sc.nextLong();

    if (l-1 < r) {
        m=(int)(l-1);
        delta[m] = v;

        m=(int)r;
        if (m < delta.length) {
          delta[m] = -v;
        }
    }
}

long cumulative = 0;
for (int a = 0; a < ar.length; ++a) {
  cumulative += delta[a];
  ar[a] += cumulative;
}

不是为每个delta范围继续增加l,r中的值,而是仅存储一个&#34; delta&#34; array:这会在索引处存储+v,您可以按v开始递增数组;和-v在您停止的索引处。因此,记录lr之间的范围应增加v现在是O(1)操作,而不是O(r-l)操作。

所以,这个数组的某些部分看起来像:

     2    
 0 0   0 0 0 0 0   0 0 0
                -2

(我只是垂直移动2s以使其更清晰)

如果计算这些元素的累计总和:

     2 2 2 2 2 2  
 0 0             0 0 0 0

换句话说,您可以通过仅存储此范围的开始和结束位置来显示您将增加2的范围。

这是cumulative变量存储的内容:它只是左边delta数组中所有元素的总和,包括当前位置。这就是增加ar的相应元素的数量。