找到最小数量的片段,以便可以重新排列原始序列以形成所需的序列(时间限制)

时间:2017-04-12 16:40:54

标签: algorithm

任何人都可以给我一个提示如何为下面的问题找到有效的解决方案吗?

我可以解决一些小输入的问题,但是在解决更难的情况时我超过了时间限制(e.x.阵列有450000个元素,时间限制为~5,5秒)。

  

您将获得两个数组,从1到N随机写入   顺序。

     

示例:

// numbers from 1 to 4
int[] o = new int[] { 1, 4, 3, 2 }; // original
int[] d = new int[] { 1, 2, 4, 3 }; // desired
     

找到原始序列的最小数量以便这样做   这些碎片可以重新排列,形成所需的序列。

     

在上面的示例情况中,最小件数为3,作为原始序列:

{1, 4, 3, 2}      // original
     

可分为:

{1}, {4, 3}, {2}
     

可以重新排列这些部分以形成所需的序列:

{1}, {4, 3}, {2}
{1}, {2}, {4, 3}
{1, 2, 4, 3}      // desired

1 个答案:

答案 0 :(得分:4)

这是一个在O(n)中运行的版本。我们的想法是替换数字,使目标数组变为[0,1,2,3,...],然后计算所需切割的数量非常简单。以下是Javascript(link)中的实现:

function solve(o, d) {
  var sub = [], count = 0;
  // make arrays 0-based and calculate substitution
  for (var i = 0; i < d.length; i++) {
    o[i]--;
    d[i]--;
    sub[d[i]] = i;
  }
  // substitute
  for (var i = 0; i < o.length; i++)
    o[i] = sub[o[i]];
  // scan and count
  for (var i = 1; i < o.length; i++)
    if (o[i - 1] + 1 != o[i])
      count++;
  return count + 1; // the number of pieces is the number of required cuts + 1
}

alert(solve([1, 4, 3, 2], [1, 2, 4, 3]));