Leetcode记录库题方法篇之一:计数法
简介
六、字符串
结论
一些很主观的东西,归根到底可能还是自己的实力不够:
计数法类似于计数排序以及哈希表的思想,一般用于有关字符的问题中,不使用字符的索引作为某个字符的标志,而是使用字符本身的ASCII码值作为暂存数组的索引。
1 242. 有效的字母异位词
思路描述
- 使用HashMap的思想
- 遍历第一个字符串记录每一个字符的出现次数,然后遍历第二个字符串的过程中减少字符的次数,最后查看所有字符的出现次数是不是归零了。
- 时间复杂度O(n),空间O(1)
代码实现
java代码:
class Solution {
public boolean isAnagram(String s, String t) {
int[] ch = new int[26];
for(int c : s.toCharArray()){
ch[c - 'a']++;
}
for(int c : t.toCharArray()){
ch[c - 'a']--;
}
for(int i : ch){
if(i != 0) return false;
}
return true;
}
}
注意事项
- 注意事项
拓展延伸
- 拓展延伸
2 409. 最长回文串
思路描述
- 没用什么思想
- 时间复杂度O(n),空间O(1)
代码实现
java代码:
class Solution {
public int longestPalindrome(String s) {
int[] ch = new int[58]; // 48 -> 0, 65 -> A, 97 -> a, 122 -> z
int len = 0;
for(char c: s.toCharArray()){
ch[c - 'A']++;
}
for(int i: ch){
if(i % 2 == 0) len += i; // 字符个数是偶数的来者不拒全都要
if(i % 2 == 1) {
len += i - 1; // 字符个数为奇数的,减去一变成偶数全都收下
}
}
if(len < s.length()) len++; // 如果最后还小于s的长度时,随便再取一个放到正中间
return len;
}
}
注意事项
- 注意事项
拓展延伸
- 拓展延伸
3 205. 同构字符串
思路描述
- 对于一个字符串我们用它的字符j作为数组索引,然后只记录它上次出现的位置,进行遍历字符串对比。
- 时间复杂度O(n),空间O(1)
代码实现
java代码:
class Solution {
public boolean isIsomorphic(String s, String t) {
int[] sc = new int[256];
int[] tc = new int[256];
for(int i = 0; i < s.length(); i++){
if(sc[s.charAt(i)] == tc[t.charAt(i)]){
sc[s.charAt(i)] = i + 1;
tc[t.charAt(i)] = i + 1;
} else {
return false;
}
}
return true;
}
}
注意事项
- 注意事项
拓展延伸
- 拓展延伸
3 76. 最小覆盖子串
思路描述
- 双指针,滑动窗口,计数法
- 时间复杂度O(n),空间复杂度O(1)
代码实现
java代码:
class Solution {
public String minWindow(String s, String t) {
// 双指针?滑动窗口
int sn = s.length(), tn = t.length();
if (sn < tn) {
return "";
}
int[] charArr = new int[128];
int cnt = tn; // t中的字母个数
for (int i = 0; i < tn; i++) {
charArr[t.charAt(i)]++; // 对应的字母位置计数,计数法
}
int l = 0, r = 0, ansL = 0, ansR = 0, min = sn + 1; // min是窗口大小,最初给一个较大的值
while (r < sn) {
while (r < sn && cnt != 0) {
if (charArr[s.charAt(r)] > 0) {
cnt--; // 没有被覆盖的字母个数减一
}
charArr[s.charAt(r)]--; // 字母计数减一
r++; // 指针右移,注意在不满足循环条件时 r 已经指向下一个位置了
}
if (r == sn && cnt != 0 && min == sn + 1) { // 如果r == sn 了,但是cnt还没有清空,而且也并没有进行过缩减窗口的操作,说明t中有s中没有的字母
return "";
}
while (l < r && cnt == 0) { // 缩减窗口
if (charArr[s.charAt(l)] < 0) {
charArr[s.charAt(l)]++;
l++;
} else {
if (min > r - l) { // 记录新的满足要求的窗口大小
ansL = l;
ansR = r;
min = r - l;
}
charArr[s.charAt(l)]++; // 对应的字母位置重新计数
l++;
cnt++;
}
}
}
return s.substring(ansL, ansR);
}
}
注意事项
- 注意事项
拓展延伸
- a