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

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

现在我们有了另一个字符串 p 。你需要的是找出 s 中有多少个唯一的 p 的非空子串,尤其是当你的输入是字符串 p ,你需要输出字符串 s 中 p 的不同的非空子串的数目。

注意: p 仅由小写的英文字母组成,p 的大小可能超过 10000。

示例 1:

输入: "a"
输出: 1
解释: 字符串 S 中只有一个"a"子字符。

示例 2:

输入: "cac"
输出: 2
解释: 字符串 S 中的字符串“cac”只有两个子串“a”、“c”。.

示例 3:

输入: "zab"
输出: 6
解释: 在字符串 S 中有六个子串“z”、“a”、“b”、“za”、“ab”、“zab”。.

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/unique-substrings-in-wraparound-string
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解题思路及方法

这题乍一看挺难,实际上确实难。但是仔细读题后可以发现,其实求的就是p中以每个字母结尾的最长连续子串长度的长度和。比如示例3,以z结尾的最长连续子串为z,长度1,以a结尾的最长连续子串为a,za,长度2,以b结尾的最长连续子串为b,ab,zab,长度3,即所求为1+2+3=6。
又比如"abcdefghijklmnopqrstuvwxyzabc"中,以a结尾的最长连续子串长度有两个,分别是第一个a,长度1,第二个a,长度27,但我们只用存27,覆盖第一个a的长度,因为27里面就包含了第一个a的字串a。
所以说我们只需要创建一个长度为26的整型数组,用来p中以每个字母结尾的最长连续子串长度,最后求和即为所求。

class Solution {
    public int findSubstringInWraproundString(String p) {
        // 记录p中以每个字母结尾的最长连续子串长度
        int[] countChar = new int[26];
        // 记录最长连续子串长度
        int count = 0;
        for (int i = 0; i < p.length(); i++) {
            // 判断字符是否连续
            if (i > 0 && (p.charAt(i) - p.charAt(i - 1) == 1 || p.charAt(i) - p.charAt(i - 1) == -25)) {
                count++;
            } else {
                count = 1;
            }
            countChar[p.charAt(i) - 'a'] = Math.max(countChar[p.charAt(i) - 'a'], count);
        }
        int res = 0;
        for (int i : countChar) {
            res += i;
        }

        return res;
    }
}

结果如下:

你可能感兴趣的:(467. 环绕字符串中唯一的子字符串)