最长上升子序列问题(Longest Increasing Subsequence,简称LIS)是一个经典的动态规划问题

wufei123 发布于 2023-09-19 阅读(926)

最长上升子序列问题(Longest Increasing Subsequence,简称LIS)是一个经典的动态规划问题。在这个问题中,给定一个无序的整数数组,我们需要找到数组中长度最长的上升子序列。

以下是使用动态规划算法解决最长上升子序列问题的步骤:

最长上升子序列问题(Longest Increasing Subsequence,简称LIS)是一个经典的动态规划问题


初始化:


首先,我们创建一个辅助数组 dpdpdp,其中 dp[i]dp[i]dp[i] 表示以数组第 iii 个元素结尾的最长上升子序列的长度。

初始化 dpdpdp 数组的所有元素为1,因为任何一个单独的元素都可以看作是一个长度为1的最长上升子序列。



动态规划:


从数组的第二个元素开始(索引为1),遍历数组。

对于当前元素 xxx,我们遍历它之前的所有元素(索引从0到i−1i-1i−1),如果发现有一个元素 yyy(yyx > yx>y,那么我们可以将当前元素 xxx 加入到以 yyy 结尾的最长上升子序列中,并更新 dp[i]dp[i]dp[i]。

更新的方法是:dp[i]=max(dp[i],dp[j]+1)dp[i] = max(dp[i], dp[j] + 1)dp[i]=max(dp[i],dp[j]+1),其中 jjj 是所有满足 y



找到最长上升子序列:


在遍历完整个数组后,dpdpdp 数组中的最大值就是最长上升子序列的长度。

为了找到最长上升子序列本身,我们可以从索引为 dpdpdp 数组最大值的元素开始向前遍历,记录该最长上升子序列中的元素。



返回结果:


返回最长上升子序列作为结果。




下面是使用PHP代码实现上述算法的示例:

phpfunction longestIncreasingSubsequence($nums) {    $n = count($nums);    if ($n == 0) {        return 0;    }    $dp = array_fill(0, $n, 1);    $result = 1;    for ($i = 1; $i < $n; $i++) {        for ($j = 0; $j < $i; $j++) {            if ($nums[$i] > $nums[$j]) {                $dp[$i] = max($dp[$i], $dp[$j] + 1);            }        }        $result = max($result, $dp[$i]);    }    // Find the longest increasing subsequence    $sequence = array();    for ($i = 0; $i < $n; $i++) {        if ($dp[$i] == $result) {            $sequence[] = $nums[$i];        }    }    return array($result, $sequence);}


你可以通过调用 longestIncreasingSubsequence 函数并传入一个整数数组来测试这个函数。它将返回一个包含两个元素的数组:第一个元素是最长上升子序列的长度,第二个元素是最长上升子序列本身。


发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。