LeetCode 467 - Unique Substrings in Wraparound String - Medium (Python)

Consider the string s to be the infinite wraparound string of "abcdefghijklmnopqrstuvwxyz", so s will look like this: "...zabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcd....".

Now we have another string p. Your job is to find out how many unique non-empty substrings of p are present in s. In particular, your input is the string p and you need to output the number of different non-empty substrings of p in the string s.

Note: p consists of only lowercase English letters and the size of p might be over 10000.

Example 1:

Input: "a"
Output: 1

Explanation: Only the substring "a" of string "a" is in the string s.

Example 2:

Input: "cac"
Output: 2
Explanation: There are two substrings "a", "c" of string "cac" in the string s.

Example 3:

Input: "zab"
Output: 6
Explanation: There are six substrings "z", "a", "b", "za", "ab", "zab" of string "zab" in the string s.

题意: 在字符串中找到属于'zabcdefghijklmnopqrstuvwxyz'的unique substring的数量。一开始的想法是dfs,但是会超时。第二种做法是用dp来做。
思路:dp[i] 表示此时到i这个地方可以形成的local最长的substring的数量是多少。如果题目没有规定unique的话,那我们用一个dp数组来update就可以(如果p[i- 1] + p[i] 在
pattern里,那么dp[i] = dp[i-1]+1), 但是题目要求是unique,所以我们可以把dp转成map的数据结构,key是字符,value是到这个字符可以形成的substring 数量。这样可以避免重复计算。
比如'zababc'。在我们遇到第二个a的时候,因为a已经在map中了,不会出现重复的情况了。
步骤:1 初始化一个dp map。counter = collections.defaultdict(int). 初始化一个变量max_length来update可以对于每一个字符来说,最多的数量。(对于一个字符来说,最长的长度也就是其可以形成的
最大的数量。)
2 counter[p[0]] = 1. max_length= 1
3 dp的transaction function。对于p从1开始到最后进行遍历,如果p[i-1]+p[i] 在pattern中,那么max_length +=1, 同时update counter[p[i]]。 如果不在pattern中,那么这时候我们把
max_length重置为1. count[p[i]] = max(count[p[i]], max_length)
4 最后返回的答案是sum(count.values())

时间复杂度:O(n) n是len(p) 因为我们遍历了一遍p
空间复杂度:O(n) 最坏的情况,p中没有重复的元素,所以我们需要开一个size为n的空间。

class Solution:
    def findSubstringInWraproundString(self, p: str) -> int:
        if not p or len(p) == 0:
            return 0 
        count = collections.defaultdict(int)
        pattern = 'zabcdefghijklmnopqrstuvwxyz'
        
        max_length = 1 
        count[p[0]] = 1 
        for i in range(1, len(p)):
            if p[i-1] + p[i] in pattern:
                max_length += 1 
            else:
                max_length = 1 
            count[p[i]] = max(count[p[i]], max_length)
      
        return sum(count.values())

猜你喜欢

转载自www.cnblogs.com/sky37/p/12242046.html
今日推荐