Leetcode 3458. Select K Disjoint Special Substrings

  • Leetcode 3458. Select K Disjoint Special Substrings
    • 1. 解题思路
    • 2. 代码实现
  • 题目链接:3458. Select K Disjoint Special Substrings

1. 解题思路

这一题我的思路的话就是找出给定的字符串当中做多能得到的特殊子串的数目,然后判断其是否大于给定值 k k k即可。

然后关于如何求字符串能够获得的特殊子串的最大数目,我的思路是使用动态规划的思路。

首先考察每一个字符出现的所有位置,然后将其起始位置进行排序,显然,对每一个特殊子串,其必须要包括全部的其初始字符的全部位置,因此,我们可以根据每一个字符的初始位置和结束位置找出要涵盖所处范围内所有字符的初试和结束位置的最短长度。然后,我们额外判断一下其他字符是否确实都没有出现在对应的范围内,即可判断该选择是否合法。

由此,我们只需要依次考察每一个元素的起始位置要作为特殊子串的起点位置即可找出最多的切分方式。

2. 代码实现

给出python代码实现如下:

class Solution:
    def maxSubstringLength(self, s: str, k: int) -> bool:
        locs = defaultdict(list)
        for i, ch in enumerate(s):
            locs[ch].append(i)
            
        starts = sorted([(indexes[0], ch) for ch, indexes in locs.items()])
        n = len(starts)

        @lru_cache(None)
        def dp(idx):
            if idx >= n:
                return 0
            
            st, ch = starts[idx]
            seen = {ch}
            ed, nxt = locs[ch][-1], idx
            for _st, ch in starts[idx:]:
                if _st > ed:
                    break
                ed = max(ed, locs[ch][-1])
                seen.add(ch)
                nxt += 1
                
            is_allowed = not (st == 0 and ed == len(s)-1)
            for ch, indexes in locs.items():
                if ch in seen:
                    continue
                i = bisect.bisect_left(indexes, st)
                if i < len(indexes) and indexes[i] < ed:
                    is_allowed = False
                    break

            if is_allowed:
                return max(dp(idx+1), 1 + dp(nxt))
            else:
                return dp(idx+1)
        
        return dp(0) >= k     

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

你可能感兴趣的:(leetcode笔记,leetcode,3458,leetcode,medium,leetcode周赛437,动态规划,字符串切分)