最长的子序列 - 无法理解实际的LIS创建

时间:2014-09-01 15:16:27

标签: java c algorithm dynamic-programming

有人可以在文章中解释彼得给出的最后一个算法 How to determine the longest increasing subsequence using dynamic programming? 我无法构建实际的LIS,如何构造父数组。 请用Peter所采用的相同例子来解释。 提前谢谢。

1 个答案:

答案 0 :(得分:0)

彼得的例子中增长最长的子序列实际上是" 2 3 4 5 8",结果长度为5。

通过查看算法末尾的数组S并且S 不是增长最长的子序列,无法获得LIS。

如果我们需要构建LIS,我们需要存储更多信息并修改所呈现的算法。 Peter已经提到存储parent[i]并将S[i]更改为存储索引而不是本文后面部分中的值。

让我修改他提出的算法并定义Si来存储数组Sparent[i]中数字的索引,以存储LIS中结束的前一个数字的索引在array[i]。 使用他的例子:array[] = {2, 6, 3, 4, 1, 2, 9, 5, 8}。请注意,当父数组形成最大长度为1的LIS时,将使用-1

0. S = {} - Initialize S to the empty set
   Si = {}
   parent = {}
1. S = {2} - New largest LIS
   Si = {0}
   parent = {-1}
2. S = {2, 6} - New largest LIS
   Si = {**0**, 1}
   parent = {-1, **0**}
3. S = {2, 3} - Changed 6 to 3
   Si = {**0**, 2}
   parent = {-1, 0, **0**}
4. S = {2, 3, 4} - New largest LIS
   Si = {0, **2**, 3}
   parent = {-1, 0, 0, **2**}
5. S = {1, 3, 4} - Changed 2 to 1
   Si = {4, 2, 3}
   parent = {-1, 0, 0, 2, -1}
6. S = {1, 2, 4} - Changed 3 to 2
   Si = {**4**, 5, 3}
   parent = {-1, 0, 0, 2, -1, **4**}
7. S = {1, 2, 4, 9} - New largest LIS
   Si = {4, 5, **3**, 6}
   parent = {-1, 0, 0, 2, -1, 4, **3**}
8. S = {1, 2, 4, 5} - Changed 9 to 5
   Si = {4, 5, **3**, 7}
   parent = {-1, 0, 0, 2, -1, 4, 3, **3**}
9. S = {1, 2, 4, 5, 8} - New largest LIS
   Si = {4, 5, 3, **7**, 8}
   parent = {-1, 0, 0, 2, -1, 4, 3, 3, 7}

最后,我们得到父数组{-1, 0, 0, 2, -1, 4, 3, 3, 7}

1)通过查看S,我们知道长度为5的LIS在索引8处结束,值为8。 LIS = { ?, ?, ?, ?, 8 }

2)我们现在查看索引8的父级,parent[8]是7,LIS的前一个成员将在索引7中。这是数字5。 LIS = { ?, ?, ?, 5, 8 }

3)我们现在查看索引7的父级(值5),parent[7]是3,LIS的前一个成员将位于索引3中。这是数字4。 LIS = { ?, ?, 4, 5, 8 }

4)我们现在查看索引3的父级(值4),parent[3]是2,LIS的前一个成员将位于索引2中。这是数字3。 LIS = { ?, 3, 4, 5, 8 }

5)我们现在查看索引2的父(值3),parent[2]为0,LIS的前一个成员将在索引0中。这是数字2。 LIS = { 2, 3, 4, 5, 8 }

6)实际LIS为2 3 4 5 8