应用转换以使数组排序

时间:2015-04-04 05:22:49

标签: algorithm dynamic-programming

我们给出M个数字,每个数字都有一个与之关联的值列表。我们可以用列表中的任何一个数字来改变它(它也只在1到M之间)。

所以我们有(它的最大尺寸可以是200 X 200):

vector<vector<int>> transformations

现在我们有另一个带有N个整数的数组,我们希望按升序排序。

注意:我们只能更改一次。

我们需要告诉要更改的最小数字以使其排序。如果不可能,那么我们还必须返回-1作为答案,否则要更改最小字母数。

此数组中的每个数字只能更改一次。所以我认为必须有一些动态编程可以帮助解决这个问题。 N可以高达200000.我想到了贪婪的解决方案,但是在某些情况下它不会起作用。

比如说我们有M = 3和矢量变换矢量如下:

1->{1,2}
2->{1,2}
3->{3,4}
4->{3,4}

现在如果N = 4并且数组是[2,1,3,4]那么答案是2,因为我们可以改变2-> 1和1-> 2

但是如果转换是相同的,N = 4,数组是[3,4,1,2]那么答案是-1,因为我们永远无法对其进行排序。

1 个答案:

答案 0 :(得分:0)

可以使用动态编程通过遵循下一个递归公式来解决:

  • i是一个索引
  • x是可以填充每个索引的集合中的值(可以很容易地转换为基于这些值的索引)


 D(0)(x) = 1   | x is not the original value    //1 value array is sorted
 D(0)(x) = 0   | x is the original value
 D(i)(x) = min{D(i-1)(y) +1 | y < x} U { D(i-1)(y) | y<x, y is original value}  U {INFINITY}

我们的想法是为i,x中的每个值取最小值:

  • D(i-1)(y) +1 | y < x} - 任何交换
  • { D(i-1)(y) | y<x, y is original value} - 无需交换
  • {INFINITY} - 无法将排序数组输入此位置

Python代码:

orig = [2,1,3,4] 
vals = [[1,2],[1,2],[3,4],[3,4]]
D = [[1,1]]
for x in range(len(vals[0])):
    if vals[0][x] == orig[0]:
        D[0][x] = 0
    else: 
        vals[0][x] = 1
for i in range(1,len(orig)):
    D.append([max_int32, max_int32])
print D
for i in range(1,len(orig)):
    for x in range(len(vals[i])):
        for y in range(len(vals[i-1])):
            if vals[i-1][y] < vals[i][x] and vals[i][x] != orig[i]:

                D[i][x] = min(D[i][x],D[i-1][y] + 1)
            elif vals[i-1][y] < vals[i][x]:
                D[i][x] = min(D[i][x],D[i-1][y])
print min(D[len(orig)-1])   

对于其他数组,需要相应地修改origvals,例如[3,4,1,2]

orig = [3,4,1,2] 
vals = [[3,4],[3,4],[1,2],[1,2]]

此处max_int32表示无法完成 - 您可以轻松将其更改为-1