给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:
输入: "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
示例 2:
输入: "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。
解答如下,如有纰漏疑惑,还请指出。
public class p76 {
// t也可能是重复的String
// window-> [l,r]
// r-l+1<t.size r+=1
// r-l+1==t.size 满足要求 return
// r-l+1>t.size 不满足要求 r++ 满足要求l++
public String minWindow(String s, String t) {
if (t.length() > s.length())
return "";
int[] tmask = new int[64], smask = new int[64];
char[] tchs = t.toCharArray(), schs = s.toCharArray();
for (char ch : tchs)
tmask[ch - 'A'] += 1;
String result = s;
int l = 0, r = -1, min = s.length() + 1;
while (l + t.length() <= s.length()) {
// [l,r]长度不够
while (r - l + 1 < t.length()) {
if (r + 1 < s.length()) {
smask[schs[++r] - 'A'] += 1;
} else {
break;
}
}
int i = 0;
for (; i < 64; ++i) {
if (smask[i] < tmask[i])
break;
}
// 不满足
if (i < 64) {
if (r + 1 < s.length()) {
smask[schs[++r] - 'A'] += 1;
} else {
smask[schs[l++] - 'A'] -= 1;
}
} else {
if (r - l + 1 == t.length()) {// 最短情况
return s.substring(l, r + 1);
} else {
if (r - l + 1 < min) {
min = r - l + 1;
System.out.printf("[%d,%d]\n", l, r + 1);
result = s.substring(l, r + 1);
}
smask[schs[l++] - 'A'] -= 1;
}
}
}
return min == s.length() + 1 ? "" : result;
}
}