今天和大家分享的是动态规划经典问题:最长递增子序列问题解答。(似乎BAT等各大公司都喜欢在面试的时候对动态规划系列经典问题进行笔试。
求其最长递增子序列(LIS)。如果该序列的一个子序列
其满足且
那么该子序列称为该序列的递增子序列。最长递增子序列就是最长的递增子序列,可能不是唯一的。比如序列为5,2,8,6,3,6,9,7,那么其一个最长递增子序列为2,3,6,9。
如果采用暴力穷举,那么时间复杂度是O(2^n),这是难以让人接收的。可以采用动态规划的方式,将问题拆分,我们可以考虑以某一个元素ak为结束元素的最长递增子序列,这里记其长度为L[k],如果我们把所有的情况都计算出来,找到最长的那么就是原问题的最长递增子序列。然后我们要考虑这个子问题是否可以用比其更小的问题递归出来。答案是可以的,如果我们已经知道了L[1],L[2],…,L[k-1],我们可以遍历它们,如果某个元素aj恰好是不大于ak,那么这个递增子序列可以后面加上生成新的递增子序列,并且长度为L[j]+1。我们遍历a1,a2……ak-1,找出最大值就是L[k]。递归公式为:
上面是可以计算出序列的最长递增子序列的长度,时间复杂度为O(n^2)。如果你想得到最终的最长递增子序列,那么可以记录上面递归公式中遍历时的最长情况下的前接元素索引,然后通过这些索引可以重构出最长递增子序列,具体可以参见下面的代码。