标签:子串 map cnt end start int 最小 76
给你一个字符串 s
、一个字符串 t
。返回 s
中涵盖 t
所有字符的最小子串。如果 s
中不存在涵盖 t
所有字符的子串,则返回空字符串 ""
。
注意:如果 s
中存在这样的子串,我们保证它是唯一的答案。
示例 1:
输入:s = "ADOBECODEBANC", t = "ABC" 输出:"BANC"
示例 2:
输入:s = "a", t = "a" 输出:"a"
提示:
1 <= s.length, t.length <= 105
s
和t
由英文字母组成
思路:
1. 注意到题目的关键:"所有字母的最小子串",也就是说两个串都只能是字母。
2. 于是,可以开辟一个大小为64的数组,来存放数组中字母的频率(Frequency)。准确的说,
通过字母的ASCII码作为数组的索引,开辟空间的大小为26+6+26=58:26个大写字母,26个小写字母,
还有中间的6个非字母 A~Z[65~90] 非字母[91~96] a~z[97~122]
char字符的大小为256, 为了方便还是直接开了256个。
3. 滑动窗口的使用:分两种情况来移动窗口:(这里令当前窗口的左右边界分别为start,end,窗口的大小为winSize= end - start + 1)
先初始化好t字符串中每个字符 出现的次数map
遍历s字符串,字符在map对应的位置的次数进行自减,用cnt统计t字符串字符出现的次数,当cnt == t.length(), 即存在所有字母的子串
1) 当cnt < t.length() end++; 也就是窗口右边界向右移动
2) 当cnt == t.length()
2.1) 当窗口中的字符已经符合要求了,之前保留的字符串 和winSize进行判断,获取最短的子串
2.2)start++,窗口左边界向右移动(恢复map和cnt的计数)
代码实现:
class Solution {
public String minWindow(String s, String t) {
int[] map = new int[256];
for (char c : t.toCharArray()) {
map[c] += 1;
}
int start =0, end = 0;
int n = s.length(), m = t.length();
int cnt = 0;
int res = -1;
String ans = "";
while(end < n) {
char c = s.charAt(end);
map[c] -= 1;
if (map[c] >= 0) {
cnt++;
}
while(cnt == m) {
if (res == -1 || res > end - start + 1) {
ans = s.substring(start, end+1);
res = end - start + 1;
}
c = s.charAt(start);
map[c] += 1;
if (map[c] > 0) {
cnt--;
}
start++;
}
end++;
}
return ans;
}
}
标签:子串,map,cnt,end,start,int,最小,76 来源: https://blog.csdn.net/xiao__jia__jia/article/details/112693835
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。