【问题标题】:Convert nested 'for' loop to single 'for' loop in java [closed]在java中将嵌套的'for'循环转换为单个'for'循环[关闭]
【发布时间】:2018-01-19 14:15:41
【问题描述】:
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 循环优化为单个 for 循环。代码的执行时间应该在 2 秒以下,这个需要 2 秒。这里 k,l,r,v 可以是 0 到 10^9 范围内的 int 值。

【问题讨论】:

  • 这里有两个循环并不是导致超时的原因。您更有可能阻止输入。
  • 不改变你的代码做什么?不是
  • 计时问题不是循环的嵌套而是在sc.nextLong
  • 请展示你的努力?
  • ... 执行时间低于 2s? kr 的输入和值是什么?不清楚你在问什么,(虚构的)VTC。

标签: java loops nested


【解决方案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;
}

而不是继续为每个l,r 范围增加delta 中的值,这只是存储一个“delta”数组:这将一个+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 的相应元素增加的数量。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-11-06
    • 1970-01-01
    • 1970-01-01
    • 2020-11-26
    • 1970-01-01
    • 1970-01-01
    • 2019-04-15
    • 1970-01-01
    相关资源
    最近更新 更多