📌  相关文章
📜  具有不同相邻字符的最长子序列(1)

📅  最后修改于: 2023-12-03 14:50:06.709000             🧑  作者: Mango

题目介绍:具有不同相邻字符的最长子序列

问题描述

给定一个字符串,找到该字符串中最长的子序列,使得相邻字符不相同。

例如:给定字符串是"abababcdefababcdab",最后答案为"abcdef"。

解题思路
动态规划

我们可以用 dp[i] 表示的是以i结尾的最长不同相邻子序列长度,最后结果要在 dp 数组中选出最大的结果。

状态转移方程为:如果 S[i] 与 S[i-1] 不等,则 dp[i] = dp[i-1]+1;否则 dp[i] = 1。

我们需要注意的是,每一次 dp 的时候,都要记录一下当前最长的不同相邻子序列。

双指针+滑动窗口

我们可以用两个指针,分别指向子串的左端点和右端点。每次判断子串的右端点是否可以扩展,直到不能扩展为止。当右端点不能扩展时,我们就移动左端点,直到满足相邻字符不相同为止。

代码实现
动态规划
def find_longest_subsequence(s: str) -> str:
    max_dp, max_len, last_char = 0, 0, ''
    dp = [0] * len(s)
    for i in range(len(s)):
        if s[i] != last_char:
            dp[i] = dp[i-1] + 1 if i > 0 else 1
        else:
            dp[i] = 1
        if dp[i] > max_dp:
            max_dp = dp[i]
            max_len = i
        last_char = s[i]
    return s[max_len-max_dp+1:max_len+1]
双指针+滑动窗口
def find_longest_subsequence(s: str) -> str:
    left, right, max_len = 0, 0, 0
    while right < len(s):
        if s[right] == s[right-1]:
            left = right
        else:
            if right-left+1 > max_len:
                max_len = right-left+1
                max_index = right
        right += 1
    return s[max_index-max_len+1:max_index+1]
总结

本题考察了动态规划和滑动窗口两种算法,它们都能够解决此类问题。动态规划是自底向上的,计算子问题来求解原问题;而滑动窗口则是在原问题上进行的,不断改变窗口的大小来求解最优解。在面试中,选择哪种算法,取决于题目本身的特点。