1. 无重复字符的最长子串(手撕频率非常高)
-
题目要求:给定一个字符串 s ,请你找出其中不含有重复字符的最长子串的长度。
-
代码及思路
- 使用一个hashmap维护已经出现过的字符
- 遍历字符串,当字符已经存在时,根据其上一次出现位置与左边界位置大小比较更新左边界
- 每一次遍历的时候都更新hashm,并且更新最大子串的长度(右边界-左边界+1)
- 代码
public class Solution {
public int lengthOfLongestSubstring(String s) {
if(s.length()<2)return s.length();
int res=0;
Map<Character,Integer> cache=new HashMap<>();
int left=0;
int right=0;
while(right<s.length()){
if(cache.containsKey(s.charAt(right))){
if(cache.get(s.charAt(right))>=left){
left=cache.get(s.charAt(right))+1;
}
}
cache.put(s.charAt(right),right);
res=Math.max(res,right-left+1);
right++;
}
return res;
}
}
2. 找到字符串中所有字母异位词
- 题目要求:给定两个字符串 s 和 p,找到 s 中所有 p 的 异位词 的子串,返回这些子串的起始索引。不考虑答案输出的顺序。
异位词 指由相同字母重排列形成的字符串(包括相同的字符串)。
- 代码及思路
- 使用滑动窗口在s字符串中寻找,滑动窗口大小为p字符串的长度
- 因为是找异位词,因此s的子串和p字符串排序后得到的新字符串应该是相等的(注意:字符串相等不能使用==,要使用equals函数)
- 代码
class Solution {
public List<Integer> findAnagrams(String s, String p) {
List<Integer> res=new ArrayList<>();
if(p.length()>s.length())return res;
char[] pp=p.toCharArray();
Arrays.sort(pp);
String sortp=new String(pp);
int l=p.length();
for(int i=0;i<=s.length()-l;i++){
String temp=s.substring(i,i+l);
char[] tempp=temp.toCharArray();
Arrays.sort(tempp);
String sortemp=new String(tempp);
if(sortemp.equals(sortp))res.add(i);
}
return res;
}
}
3. 最小覆盖子串 题目链接
- 题目要求:给你一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字符的子串,则返回空字符串 “” 。
注意:
对于 t 中重复字符,我们寻找的子字符串中该字符数量必须不少于 t 中该字符数量。
如果 s 中存在这样的子串,我们保证它是唯一的答案。
- 代码及思路
- 用一个哈希表needs存储t字符串中所有的字符及其对应的数量
- 用一个哈希表windows存储遍历s字符串时的和t中字符匹配的字符及其对应的数量
- 当windows中字符数量等于needs中对应数量时,计数加1;当计数等于needs的size时表示当前子串已经能够覆盖t,现在需要循环删除最左边不影响覆盖的字符
- 在删除左边字符时更新最短子串长度
- 代码
class Solution {
public String minWindow(String s, String t) {
Map<Character,Integer> needs=new HashMap<>();
Map<Character,Integer> windows=new HashMap<>();
for(int i=0;i<t.length();i++){
needs.put(t.charAt(i),needs.getOrDefault(t.charAt(i),0)+1);
}
int left=0;
int right=0;
int finalleft=0;
int finalright=0;
int num=0;
int minL=Integer.MAX_VALUE;
while(right<s.length()){
char c=s.charAt(right);
if(needs.containsKey(c)){
windows.put(c,windows.getOrDefault(c,0)+1);
if(windows.get(c).equals(needs.get(c))){
num++;
}
}
right++;
while(num==needs.size()){
int tempL=right-left;
if(tempL<minL){
finalleft=left;
finalright=right;
minL=tempL;
}
char cc=s.charAt(left);
if(needs.containsKey(cc)){
windows.put(cc,windows.get(cc)-1);
if(windows.get(cc)<needs.get(cc)){
num--;
}
}
left++;
}
}
if(minL==Integer.MAX_VALUE)return "";
return s.substring(finalleft,finalright);
}
}