Java&C++题解与拓展——leetcode467.环绕字符串中唯一的子字符串【么的新知识】

108 阅读2分钟
每日一题做题记录,参考官方和三叶的题解

题目要求

在这里插入图片描述

思路:动态规划

  • 遍历pp寻找其中存在的各种ss的子串,定义数组dpdp存放子串的长度:
    • dp[i]dp[i]指以当前字符为结尾且存在于ss中的子串的最长长度;
    • 事实上这个子串长度刚好等于这个子串拥有的更小的子串的数量(以当前字符为结尾);
    • 比如当前pp为『……vabc……』
      • ……
      • 遍历到a时,(dp[a]=)dp[0]=1dp[0]=1,它所拥有的子串包括“a”,共11个;
      • 遍历到b时,(dp[b]=)dp[1]=2dp[1]=2,它所拥有的子串包括“b”、“ab”,共22个;
      • 遍历到c时,(dp[c]=)dp[2]=3dp[2]=3,它所拥有的子串包括“c”、“bc”、“abc”,共33个;
      • ……
  • 最后只需要把所有的dpdp内容加起来就好了。

Java

class Solution {
    public int findSubstringInWraproundString(String p) {
        int[] dp = new int [26];
        int len = 0;
        for(int i = 0; i < p.length(); ++i) {
            if(i > 0 && (p.charAt(i) - p.charAt(i - 1) + 26) % 26 == 1) // 两字符相邻
                len++;
            else
                len = 1;
            dp[p.charAt(i) - 'a'] = Math.max(dp[p.charAt(i) - 'a'], len); // 更新最长长度
        }
        return Arrays.stream(dp).sum(); // 累加所有长度
    }
}
  • 时间复杂度:O(n)O(n),其中nn为字符串pp的长度
  • 空间复杂度:O(Σ)O(|Σ|),取决于字符集大小、其实就是个常数复杂度,对本题来讲就是26个小写字母

C++

class Solution {
public:
    int findSubstringInWraproundString(string p) {
        vector<int> dp(26);
        int len = 0;
        for(int i = 0; i < p.length(); ++i) {
            if(i > 0 && (p[i] - p[i - 1] + 26) % 26 == 1) // 两字符相邻
                len++;
            else
                len = 1;
            dp[p[i] - 'a'] = max(dp[p[i] - 'a'], len); // 更新最长长度
        }
        return accumulate(dp.begin(), dp.end(), 0);
    }
};
  • 时间复杂度:O(n)O(n)
  • 空间复杂度:O(Σ)O(|Σ|),取决于字符集大小、其实就是个常数复杂度,对本题来讲就是26个小写字母

Rust

impl Solution {
    pub fn find_substring_in_wrapround_string(p: String) -> i32 {
        let mut dp = vec![0;26];
        let mut len = 0;
        let pab = p.as_bytes();
        for i in 0..p.len() {
            if i > 0 && (pab[i] - pab[i - 1] + 26) % 26 == 1 { // 两字符相邻
                len += 1;
            }
            else {
                len = 1;
            }
            dp[(pab[i] - b'a') as usize] = dp[(pab[i] - b'a') as usize].max(len); // 更新最长长度
        }
        dp.iter().sum() // 累加所有长度
    }
}
  • 时间复杂度:O(n)O(n)
  • 空间复杂度:O(Σ)O(|Σ|),取决于字符集大小、其实就是个常数复杂度,对本题来讲就是26个小写字母

总结

一个平平无奇动态规划中等题,三叶姐姐一个树状数组给我整懵了、大材小用了属于是,感觉反而兜了一圈,不如定义一个临时的lenlen


欢迎指正与讨论!