📜  最长的交替子序列(1)

📅  最后修改于: 2023-12-03 15:40:17.273000             🧑  作者: Mango

最长的交替子序列

交替序列是指序列中相邻两个元素的大小关系不同,例如 {1, 2, 1, 2, 1} 是一个交替序列,而 {1, 2, 2, 1} 则不是。最长的交替子序列即是在一个序列中找到一个最长的交替子序列。

解法
动态规划

定义状态 $dp_i$ 表示以第 $i$ 个元素结尾的最长的交替子序列,$dp_i$ 可以分为两种情况:

  • 第 $i$ 个元素和第 $i-1$ 个元素大小关系相反,即 $a_i > a_{i-1}$ 且 $dp_{i-1}$ 为奇数,或者 $a_i < a_{i-1}$ 且 $dp_{i-1}$ 为偶数,则 $dp_i=dp_{i-1}+1$。
  • 第 $i$ 个元素和第 $i-1$ 个元素大小关系相同,则 $dp_i=1$。

最终的结果为 $\max\limits_{i=1}^n{dp_i}$,其中 $n$ 为序列长度。

时间复杂度:$O(n)$

空间复杂度:$O(n)$

代码

def longest_alternating_subsequence(a):
    n = len(a)
    dp = [1] * n
    for i in range(1, n):
        if (a[i] > a[i-1] and dp[i-1] % 2 == 1) or (a[i] < a[i-1] and dp[i-1] % 2 == 0):
            dp[i] = dp[i-1] + 1
    return max(dp)
贪心算法

贪心算法可以从头开始扫描序列,维护两个值 $up$ 和 $down$,分别表示以当前元素为结尾的最长交替子序列,其中 $up$ 表示最后一个元素比前一个元素大的子序列长度,$down$ 表示最后一个元素比前一个元素小的子序列长度。

当遇到当前元素比前一个元素大时,如果上一个子序列是 $down$,则更新 $up=down+1$,否则 $up$ 不变;当当前元素比前一个元素小时,如果上一个子序列是 $up$,则更新 $down=up+1$,否则 $down$ 不变。

最终结果为 $\max(up, down)$。

时间复杂度:$O(n)$

空间复杂度:$O(1)$

代码

def longest_alternating_subsequence(a):
    n = len(a)
    up, down = 1, 1
    for i in range(1, n):
        if a[i] > a[i-1]:
            up = down + 1
        elif a[i] < a[i-1]:
            down = up + 1
    return max(up, down)
总结

以上两种解法都可以求解最长的交替子序列,动态规划的时间复杂度和空间复杂度都为 $O(n)$,而贪心算法的空间复杂度只有 $O(1)$,但贪心算法需要额外维护两个变量,而动态规划只需要维护一个一维数组,具体选择哪种算法可以根据实际问题的复杂度和数据规模进行选择。