76. 最小覆蓋子串
class Solution {
public String minWindow(String s, String t) {
//needs存儲t的<字符,出現次數>,windows存儲<s中與t中字符相同的字符,出現次數>
HashMap<Character,Integer> needs = new HashMap<>();
HashMap<Character,Integer> windows = new HashMap<>();
//初始化needs
for(int i=0;i<t.length();i++){
//needs.getOrDefault(t.charAt(i),0)+1 含義是:needs如果包含t.charAt(i),
//則取出值+1;不包含取0+1
needs.put(t.charAt(i),needs.getOrDefault(t.charAt(i),0)+1);
}
int left=0;
int right=0;
int count=0;
int minLen= Integer.MAX_VALUE;
int start=0;
int end=0;
while(right <s.length()){
//獲取字符
char temp=s.charAt(right);
//如果是t中字符,在windows裏添加,累計出現次數
if(needs.containsKey(temp)){
windows.put(temp,windows.getOrDefault(temp,0)+1);
//注意:Integer不能用==比較,要用compareTo
if(windows.get(temp).compareTo(needs.get(temp))==0 ){
//字符temp出現次數符合要求,count代表符合要求的字符個數
count++;
}
}
//優化到不滿足情況,right繼續前進找可行解
right++;
//符合要求的字符個數正好是t中所有字符,獲得一個可行解
while(count==needs.size()){
//更新結果
if(right-left<minLen){
start=left;
end=right;
minLen=end-left;
}
//開始進行優化,即縮小區間,刪除s[left],
char c=s.charAt(left);
//當前刪除的字符包含於t,更新Windows中對應出現的次數,如果更新後的次數<t中出現的次數,符合要求的字符數減1,下次判斷count==needs.size()時不滿足情況,
if(needs.containsKey(c)){
windows.put(c,windows.getOrDefault(c,1)-1);
if(windows.get(c)<needs.get(c)){
count--;
}
}
left++;
}
}
//返回覆蓋的最小串
return minLen==Integer.MAX_VALUE ? "":s.substring(start,end);
}
}
438. 找到字符串中所有字母異位詞
class Solution {
public List<Integer> findAnagrams(String s, String p) {
List<Integer> list = new ArrayList<>();
int left = 0 , right = 0;
char[] needs = new char[26]; //相當於hashMap,用於記錄每個字符的個數
char[] windows = new char[26];
for (int i = 0; i < p.length(); i++) {
needs[p.charAt(i)-'a']++;
}
//統計符合要求字符個數
int count =0;
while(right < s.length()){
int ch = s.charAt(right)-'a';
windows[ch]++;
if (needs[ch] > 0 && needs[ch] >= windows[ch]){
count++;
}
//長度滿足條件
while( count == p.length()){
//加入符合要求的結果
if (right + 1 - left == p.length()){
list.add(left);
}
//不符合要求,縮小區間
int ch1 = s.charAt(left)-'a';
if (needs[ch1] > 0){
windows[ch1]--;
if ( windows[ch1] < needs[ch1]){
count--;
}
}
left++;
}
right++;
}
return list;
}
}
3. 無重複字符的最長子串
class Solution {
public int lengthOfLongestSubstring(String s) {
if(s.length()==0) return 0;
HashMap<Character,Integer> map = new HashMap<>();
int left = 0;
int max = 0;//記錄最長子串長度
for(int i = 0;i<s.length();i++){
if(map.containsKey(s.charAt(i))){
left = Math.max(left,map.get(s.charAt(i))+1);
}
map.put(s.charAt(i),i);
max = Math.max(max,i-left+1);
}
return max;
}
}
567. 字符串的排列
class Solution {
public boolean checkInclusion(String s1, String s2) {
int[] S1 = new int[26];
int[] S2 = new int[26];
for(int i = 0;i<s1.length();i++){
S1[s1.charAt(i)-'a']++;
}
int left = 0;
int right = 0;
int count = 0;
while(right<s2.length()){
int ch = s2.charAt(right) - 'a';
S2[ch]++;
if(S1[ch]>0 && S1[ch]>=S2[ch]){
count++;
}
while(count==s1.length()){
if(s1.length()==right-left+1){
return true;
}
int ch1 = s2.charAt(left) - 'a';
if(S1[ch1]>0){
S2[ch1]--;
if(S2[ch1]<S1[ch1]){
count--;
}
}
left++;
}
right++;
}
return false;
}
}
你知道的越多,你不知道的越多。
有道無術,術尚可求,有術無道,止於術。
如有其它問題,歡迎大家留言,我們一起討論,一起學習,一起進步