题目
https://leetcode.com/problems/unique-substrings-in-wraparound-string/
题解
1、dp 超时版本
class Solution {
public int findSubstringInWraproundString(String p) {
HashSet<Integer>[] arr = new HashSet[26]; // <结尾字母,长度>
for (int i = 0; i < 26; i++) {
arr[i] = new HashSet();
}
arr[p.charAt(0) - 'a'].add(1);
int curLen = 1; // 避免误将断链情况计入结果
for (int i = 1; i < p.length(); i++) {
arr[p.charAt(i) - 'a'].add(1);
if (p.charAt(i) == 'a' && p.charAt(i - 1) == 'z') {
curLen++;
for (int len : arr[25]) {
if (len + 1 <= curLen) arr[0].add(len + 1);
}
} else if (p.charAt(i - 1) == p.charAt(i) - 1) {
curLen++;
for (int len : arr[p.charAt(i - 1) - 'a']) {
if (len + 1 <= curLen) arr[p.charAt(i) - 'a'].add(len + 1);
}
} else {
curLen = 1;
}
}
int result = 0;
for (int i = 0; i < 26; i++) {
result += arr[i].size();
}
return result;
}
}
2、dp 答案版本
参考:Concise Java solution using DP
After failed with pure math solution and time out with DFS solution, I finally realized that this is a DP problem…
The idea is, if we know the max number of unique substrings in p
ends with 'a', 'b', ..., 'z'
, then the summary of them is the answer. Why is that?
- The max number of unique substring ends with a letter equals to the length of max contiguous substring ends with that letter. Example
"abcd"
, the max number of unique substring ends with'd'
is 4, apparently they are"abcd", "bcd", "cd" and "d"
. - If there are overlapping, we only need to consider the longest one because it covers all the possible substrings. Example:
"abcdbcd"
, the max number of unique substring ends with'd'
is 4 and all substrings formed by the 2nd"bcd"
part are covered in the 4 substrings already. - No matter how long is a contiguous substring in
p
, it is ins
sinces
has infinite length. - Now we know the max number of unique substrings in
p
ends with'a', 'b', ..., 'z'
and those substrings are all ins
. Summary is the answer, according to the question.
Hope I made myself clear…
class Solution {
public int findSubstringInWraproundString(String p) {
int[] dp = new int[26]; // <结尾字母,以当前字母结尾的最长串长度>
dp[p.charAt(0) - 'a'] = 1;
int curLen = 1;
for (int i = 1; i < p.length(); i++) {
if (p.charAt(i - 1) == p.charAt(i) - 1 || p.charAt(i) == 'a' && p.charAt(i - 1) == 'z') {
curLen++;
} else {
curLen = 1;
}
dp[p.charAt(i) - 'a'] = Math.max(dp[p.charAt(i) - 'a'], curLen);
}
int result = 0;
for (int i = 0; i < 26; i++) {
result += dp[i];
}
return result;
}
}