目录
水果成篮
简单的说这一道题 从数组串要求出 最大的子数组串的个数
题目给出了类型 要求出个数 使用 哈希表是个不错的选择

java
public int totalFruit(int[] fruits) {
int n = fruits.length;//水果种类
HashMap <Integer,Integer> map = new HashMap<Integer,Integer>();
int ret = 0;
for(int left = 0,right = 0;right < n;right++){
int in = fruits[right];
map.put(in,map.getOrDefault(in,0)+1);
while(map.size() > 2) {
int out = fruits[left];
map.put(out,map.get(out) - 1);
if(map.get(out) == 0){
map.remove(out);
}
left++;
}
//update
ret = Math.max(ret,right - left+1);
}
return ret;
}
因为数组只存在 '数字串' 所以也可以使用数组建立哈希表 kinds 表示 种类
java
public int totalFruit(int[] fruits) {
int n = fruits.length;
int [] hash =new int [n+1];//水果种类
int ret = 0;
for(int left = 0,right = 0,kinds = 0;right < n;right++){
int in = fruits[right];
if(hash[in] == 0){
kinds++;
}
hash[in]++;
while(kinds > 2){
int out = fruits[left];
hash[out]--;
if(hash[out] == 0){
kinds--;
}
left++;
//update
}
ret = Math.max(ret,right - left+1);
}
return ret;
}
找到字符串所有字母异位词

java
public List<Integer> findAnagrams(String ss, String pp) {
List<Integer> ret = new ArrayList<Integer>();
char[] s = ss.toCharArray();
char[] p = pp.toCharArray();
int[] hash1 = new int[26];
//统计字符串p所出现的个数
for(char ch : p)
hash1[ch - 'a']++;
//统计窗口出现的个数
int[] hash2 = new int[26];
int m =p.length;
for(int right = 0, left = 0 ,count = 0 ; right <s.length;right++){
char in = s[right];
hash2[in - 'a']++;//进窗口
if( hash2[in - 'a'] <= hash1[in - 'a'] )//维护
count++;
if(right - left + 1 > m){
char out = s[left++];
if( hash2[out - 'a'] -- <= hash1[out - 'a'] )
count--;
}
//更新结果
if(count == m)
ret.add(left);
}
return ret;
}
串联所有单词的子串
此题本质上 和 上题 没有大致区别
pluspro 加强版
有些细节需要处理
1)字符串 要每一小短对应 len(数组有多少个小段字符串)
int len =words0.length()
2) 因为有len 的存在所以要对部分做出修改
for(int left = i,right = i ,count = 0; right + len <= s.length(); right += len )
right - left + 1 > len * m
left += len
String in = s.substring(right,right + len);
String out = s.substring(left , left + len);
java
public List<Integer> findSubstring(String s, String[] words) {
List<Integer> ret = new ArrayList<Integer>();
Map<String , Integer> hash1 = new HashMap<String,Integer>();
for(String ch : words)
hash1.put(ch , hash1.getOrDefault(ch , 0) + 1);
int len =words[0].length(), m = words.length;
for(int i = 0; i < len ; i++){
Map <String,Integer> hash2 = new HashMap<String,Integer>();
for(int left = i,right = i ,count = 0; right + len <= s.length(); right += len ){
String in = s.substring(right,right + len);
hash2.put(in , hash2.getOrDefault(in , 0 ) + 1);
if(hash2.get(in) <= hash1.getOrDefault(in , 0))
count++;
if(right - left + 1 > len * m){
String out = s.substring(left , left + len);
if(hash2.get(out) <= hash1.getOrDefault(out , 0))
count--;
hash2.put(out , hash2.get(out) - 1);
left += len;
}
if(count == m)
ret.add(left);
}
}
return ret;
}
最小覆盖字串

java
public String minWindow(String ss, String pp) {
char[] s = ss.toCharArray();
char[] p = pp.toCharArray();
int kinds = 0;//统计有多少种字符
int[] hash1 = new int[128];
for(char ch : p){
if(hash1[ch]++ == 0)
kinds++;
}
int[] hash2 = new int[128];
int minlen = Integer.MAX_VALUE, begin = -1;
for(int left = 0,right = 0,count = 0; right < s.length;right++){
char in = s[right];
hash2[in]++;
if(hash2[in] == hash1[in])
count++;
while(kinds == count){
if(right - left + 1 < minlen){
begin = left;
minlen = right - left + 1;
}
char out = s[left++];
if(hash2[out]-- == hash1[out])
count--;
}
}
if(begin == -1)
return new String();
else
return ss.substring(begin , begin + minlen);
}