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