标签:count pLength leetcode438 int 异位 ++ lo 字符串 diff
438. 找到字符串中所有字母异位词
方法一:简单滑动窗口
满足异位词条件:
(1)s中子串s' 与 目标字符串p的长度相等
(2)s'与p中字母相同(对排列方式没有要求)
算法思路:在字符串s中构造一个长度与字符串p的长度相同的滑动窗口截取子串s‘,并在窗口中维护每种字母的数量。当s'的每种字母数量与目标串p的每种字母数量相同,则说明当前窗口为字符串p的异位词。
技巧:可以使用数组记录字符串每种字母的个数,最后比较s'与p的记录数组即可。
public List<Integer> findAnagrams(String s, String p) {
int[] pCount = new int[26];
List<Integer> result = new ArrayList<>();
int sLength = s.length();
int pLength = p.length();
if (sLength < pLength) {
return result;
}
for (int i = 0; i < pLength; i++) {
++pCount[p.charAt(i) - 'a'];
}
int lo = 0;
int hi = pLength;
// [lo,hi)
while (hi <= sLength) {
int[] sCount = new int[26];
int x = lo;
for (int i = lo; i < hi; i++) {
++sCount[s.charAt(i) - 'a'];
}
if (Arrays.equals(sCount, pCount)) {
result.add(x);
}
// 滑动窗口
hi++;
lo++;
}
return result;
}
方法二 :改进滑动窗口
方法一中每次都需要对子串s' 进行重新统计,然后再一一比较。可以每次仅仅考虑lo收缩减少的那个字母以及hi扩张增加的字母。使用diff表示当前存在的数量不同的字母种数。
public List<Integer> findAnagrams(String s, String p) {
int[] count = new int[26];
List<Integer> result = new ArrayList<>();
int sLength = s.length();
int pLength = p.length();
if (sLength < pLength) {
return result;
}
for (int i = 0; i < pLength; i++) {
--count[p.charAt(i) - 'a'];
++count[s.charAt(i) - 'a'];
}
//指示子串s'与字符串中不同字母的种数
int diff = 0;
for (int i = 0; i < 26; i++) {
if (count[i] != 0) {
diff++;
}
}
if (diff == 0) {
result.add(0);
}
int lo = 0;
for (; lo < sLength - pLength; ) {
// 出lo
char ch = s.charAt(lo);
if (count[ch - 'a'] == 0) {
diff++;
} else if (count[ch - 'a'] == 1) {
diff--;
}
--count[ch - 'a'];
char ch1 = s.charAt(lo + pLength);
if (count[ch1 - 'a'] == -1) {
diff--;
} else if (count[ch1 - 'a'] == 0) {
diff++;
}
++count[ch1 - 'a'];
lo++;
if (diff == 0) {
result.add(lo);
}
}
// [lo,hi)
return result;
}
标签:count,pLength,leetcode438,int,异位,++,lo,字符串,diff 来源: https://www.cnblogs.com/k-young/p/16585295.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。