【每日一题】-467.环绕字符串中唯一的子字符串[mid]

题目

  1. 环绕字符串中唯一的子字符串

把字符串 s 看作是 “abcdefghijklmnopqrstuvwxyz” 的无限环绕字符串,所以 s 看起来是这样的:

"...zabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcd...." . 

现在给定另一个字符串 p 。返回 s 中 唯一 的 p 的 非空子串 的数量 。

思路

  1. 统计子串的长度,遇到相邻的就对当前子串的长度+1;

  2. 否则将当前子串长度置为1,表示自身长度;

  3. 最终以字典形式存储的时候,key是字符,value 是最长子串长度

  4. 这里的最长子串的长度是对于以该字符出现的历史长度中最长的;

  5. collections.defaultdict类的介绍:
    defaultdict是Python内建dict类的一个子类,第一个参数为default_factory属性提供初始值,默认为None。它覆盖一个方法并添加一个可写实例变量。它的其他功能与dict相同,但会为一个不存在的键提供默认值,从而避免KeyError异常。

代码

class Solution:
    def findSubstringInWraproundString(self, p: str) -> int:
        # 子串的长度代表以该子串结尾的子串个数
        n = len(p) 
        dp = defaultdict(int)
        cnt = 0
        for i in range(n):
            if i>0 and (ord(p[i])-ord(p[i-1]))%26 == 1:
                cnt += 1 # 如果是相邻的元素以该元素
            else:
                cnt = 1
            
            dp[p[i]] = max(dp[p[i]],cnt) # 这里使用的是字典存放,也就是对应的字母结尾的最大长度,
            # 刚开始对于这个最大长度还是有一点绕,这里的意思是之前已经出现过以该字符结尾的长度如果大于当前统计的长度,不应该更新
            print("dp:",i,dp[p[i]],"cnt:",cnt)
        return sum(dp.values())
        print(dp)

class Solution {
public:
    int findSubstringInWraproundString(string p) {
        int n = p.size();
        int cnt = 0;
        vector<int> dp(26);
        for(int i=0;i<n;i++)
        {
            if (i>0 && (p[i]-p[i-1])%26==1)
            {
                cnt += 1;
            }
            else
            {
                cnt = 1;
            }
            dp[p[i]-'a'] = max(dp[p[i]-'a'],cnt); // 这里要将字符转换为数字
            //cout<<dp[dp[i]];
        }
        return accumulate(dp.begin(),dp.end(),0);


        return 0;
    }
};

accumulate带有三个形参:头两个形参指定要累加的元素范围,第三个形参则是累加的初值。
accumulate函数将它的一个内部变量设置为指定的初始值,然后在此初值上累加输入范围内所有元素的值。accumulate算法返回累加的结果,其返回类型就是其第三个实参的类型。
可以使用accumulate把string型的vector容器中的元素连接起来:

posted @ 2022-05-25 23:01  jucw  阅读(34)  评论(0编辑  收藏  举报