Leetcode 3302. Find the Lexicographically Smallest Valid Sequence

1. 解题思路

这一题的话由于至多只能够修改一个字符,因此,我们就是要考察每一个字符前正向的最大公共子序列的长度和其后方的从后往前的最大公共子序列的长度。如果两者相加不小于目标目标字符串word2的长度减一,即表示调整当前位置上的字符的话即可获得一个子串使之与目标字符串word2相同。

然后,我们定位到第一个满足上述条件的位置,通过调整该位置获得的字符串就是最优的选项。

最后,我们找到调整该位置所能够获得字符串的index即可。

2. 代码实现

给出python代码实现如下:

class Solution:
    def validSequence(self, word1: str, word2: str) -> List[int]:
        n, m = len(word1), len(word2)
        if m == 1:
            return [0]
        
        # prefix
        prefix = [0 for _ in word1]
        i, j = 0, 0
        while j < m:
            while i < n and word1[i] != word2[j]:
                prefix[i] = j
                i += 1
            if i >= n:
                break
            j += 1
            prefix[i] = j
            i += 1
        while i < n:
            prefix[i] = j
            i += 1

        # suffix
        i, j = n-1, m-1
        suffix = [0 for _ in word1]
        while j >= 0:
            while i >= 0 and word1[i] != word2[j]:
                suffix[i] = m-1-j
                i -= 1
            if i < 0:
                break
            j -= 1
            suffix[i] = m-1-j
            i -= 1
        while i >= 0:
            suffix[i] = m-1-j
            i -= 1

        # find target idx
        idx = -1
        if word1[0] != word2[0] and suffix[1] >= m-1:
            idx = 0
        else:
            for i in range(1, n-1):
                if prefix[i-1] + suffix[i+1] >= m-1 and prefix[i] != prefix[i-1]+1:
                    idx = i
                    break
        if idx == -1 and prefix[n-2] >= m-1:
            idx = n-1

        # get all the index
        if idx == -1:
            return []
        i, j = 0, 0
        ans = []
        while j < m:
            while i < idx and word1[i] != word2[j]:
                i += 1
            if i >= idx:
                break
            ans.append(i)
            j += 1
            i += 1
        if j < m:
            ans.append(i)
            i += 1
            j += 1
        while j < m:
            while i < n and word1[i] != word2[j]:
                i += 1
            if i >= n:
                break
            ans.append(i)
            j += 1
            i += 1
        return ans

提交代码评测得到:耗时1200ms,占用内存55.7MB。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值