获得数组int的排列所需的最小移动次数?

时间:2014-07-23 12:12:43

标签: arrays algorithm int sequence permutation

您有一系列d[0] , d[1], d[2] , d[3] ,..,d[n]。在每次移动中,您可以将任何d [i]增加1或2或5 i:0增加到n。将序列转换为[1,2,3,..,n] if it's possible else return -1. 1<=n<=1000的排列所需的最小移动次数

我的方法是在升序数组中对给定数组进行排序,而不是通过添加1或2或5对其进行计数。但在许多情况下它失败了。Some of my classmates did this in exam using this method but they read question wrong so read question carefully .

e.g。 [1,1,3,2,1]比答案是4因为我们可以分别加0,1,2,2,2得到[1,2,5,4,3]所以答案是4。

[1,2,3,4,1] =&gt; [1,1,2,3,4]我们将使用排序方法[0,1,1,1,1]获得4,但答案是2,因为我们可以在[1]中添加[2 + 2]来获得[1,2,1,1] ,3,4,5]。

同样

[1,2,3,1] =&gt; [1,1,2,3]到[1,2,3,4]需要3次转换但是答案是2,因为添加[1 + 2]到1我们可以得到[1,2,3,4]。

另一种方法可以用作i don't have any proof for correctness

Algorithm
    input "n" is number of element , array "a" which contains input element 
    initialize cnt = 0 ;
    initialize boolarray[n] ={0};
    1. for i=0...n  boolarray[a[i]]=1;
    2. put all  element in sorted order whose boolarray[a[i]]=0 for i=0...n
    3. Now make boolarray[a[i]]=1; for i=0..n and count
      how many additions are required  .
    4. return count ;

根据我的说法,这个问题将导致0或更多,因为除了这种情况,当任何d [i] i = 0..n大于输入数时,可以使用1,2和5生成任何数字。

How to solve this correctly ? 

欢迎任何答案和建议。

2 个答案:

答案 0 :(得分:1)

您的问题可以转换为weighted bipartite matching问题: -

  
      
  1. 图的第一部分p1是当前数组编号作为节点。
  2.   
  3. 图的第二部分p2是数字1到n。
  4.   
  5. 如果我们可以在它添加1,2,5以在p2中创建节点,则在p1到节点p2的节点之间存在边缘。
  6.   
  7. 加权二分匹配可以使用匈牙利算法
  8. 来解决   

修改: -

如果您正在评估最小移动次数,则可以使用unweighted bipartite matching。您可以使用 hopcroft-karp算法,在您的情况下在O(n^1.5)中运行,作为图表中的边数E = O(n)

答案 1 :(得分:0)

创建一个数组count,其中包含我们在基础数组中有特定数字的频率

input    1 1 3 2 1
count    3 1 1 0 0

现在遍历此数组并计算步骤

sum = 0

for i: 1..n
    while count[i] > 1                   // as long as we have spare numbers

        missing = -1                     // find the biggest empty spot which is bigger than the number at i
        for x: n..i+1                    // look for the biggest missing
            if count[x] > 0 continue     // this one is not missing
            missing = x
            break;

        if missing == -1 return -1       // no empty spot found

        sum += calcCost(i, missing)
        count[i]--
        count[missing]++

 return sum    

calcCost必须贪心