2021-12-26数组链表day3
滑动窗口思想
题目1:
给你一个字符串 s
、一个字符串 t
。返回 s
中涵盖 t
所有字符的最小子串。如果 s
中不存在涵盖 t
所有字符的子串,则返回空字符串 ""
。
注意:
- 对于
t
中重复字符,我们寻找的子字符串中该字符数量必须不少于t
中该字符数量。 - 如果
s
中存在这样的子串,我们保证它是唯一的答案。
示例 1:
输入:s = "ADOBECODEBANC", t = "ABC" 输出:"BANC"
示例 2:
输入:s = "a", t = "a" 输出:"a"
示例 3:
输入: s = "a", t = "aa" 输出: "" 解释: t 中两个字符 'a' 均应包含在 s 的子串中, 因此没有符合条件的子字符串,返回空字符串。
提示:
1 <= s.length, t.length <= 105
s
和t
由英文字母组成
进阶:你能设计一个在
o(n)
时间内解决此问题的算法吗?class Solution { public String minWindow(String s, String t) { int[] tmap=new int[52]; int[] smap=new int[52]; int l=0,r=0; for (int i=0;i<t.length();i++){ //前面26个小写,后面大写 if ('a'<=t.charAt(i)) tmap[t.charAt(i)-'a'+26]++; else tmap[t.charAt(i)-'A']++; } int max=10000,index=-1; while (r<s.length()){ if ('a'<=s.charAt(r)) smap[s.charAt(r)-'a'+26]++; else smap[s.charAt(r)-'A']++; r++;
//当前满足条件时,尽量缩小左边界 while (check(tmap,smap)){
//判断是否更新过答案,如果没有,先更新解 if (index==-1) { index=l; max=r-l; } if ('a'<=s.charAt(l)) smap[s.charAt(l)-'a'+26]--; else smap[s.charAt(l)-'A']--; if (check(tmap,smap)) { l++;
//左边界可以缩小,判断是否比当前解更小,更新解 if (r-l<max){ index=l; max=r-l; } }else{ if ('a'<=s.charAt(l)) smap[s.charAt(l)-'a'+26]++; else smap[s.charAt(l)-'A']++; break; } } } //没有更新解则返回空字符串 return index!=-1?s.substring(index,index+max):""; } public boolean check(int[] a,int[] b){ for (int i=0;i<a.length;i++){ if (a[i]>b[i]) return false; } return true; } }
题目2:
给你两个字符串 s1
和 s2
,写一个函数来判断 s2
是否包含 s1
的排列。如果是,返回 true
;否则,返回 false
。
换句话说,s1
的排列之一是 s2
的 子串 。
示例 1:
输入:s1 = "ab" s2 = "eidbaooo" 输出:true 解释:s2 包含 s1 的排列之一 ("ba").
示例 2:
输入:s1= "ab" s2 = "eidboaoo" 输出:false
提示:
1 <= s1.length, s2.length <= 104
s1
和s2
仅包含小写字母
1 class Solution { 2 public boolean checkInclusion(String s1, String s2) { 3 int[] count=new int[26]; 4 int[] ans=new int[26]; 5 for (int i=0;i<s1.length();i++){ 6 count[s1.charAt(i)-'a']++; 7 } 8 int l=0,r=0,len=s2.length(); 9 while (r<len){ 10 ans[s2.charAt(r)-'a']++; 11 r++; 12 if (r>=s1.length()){ 13 if (r>s1.length()){ 14 ans[s2.charAt(l)-'a']--; 15 l++; 16 } 17 if (check(count,ans)){ 18 return true; 19 } 20 } 21 //System.out.println(Arrays.toString(ans)); 22 } 23 return false; 24 } 25 26 public boolean check(int[] a,int[] b){ 27 for (int i=0;i<a.length;i++){ 28 if (a[i]>b[i]) return false; 29 } 30 return true; 31 } 32 }
固定长度的滑动窗口
题3:
给定两个字符串 s
和 p
,找到 s
中所有 p
的 异位词 的子串,返回这些子串的起始索引。不考虑答案输出的顺序。
异位词 指由相同字母重排列形成的字符串(包括相同的字符串)。
示例 1:
输入: s = "cbaebabacd", p = "abc" 输出: [0,6] 解释: 起始索引等于 0 的子串是 "cba", 它是 "abc" 的异位词。 起始索引等于 6 的子串是 "bac", 它是 "abc" 的异位词。
示例 2:
输入: s = "abab", p = "ab" 输出: [0,1,2] 解释: 起始索引等于 0 的子串是 "ab", 它是 "ab" 的异位词。 起始索引等于 1 的子串是 "ba", 它是 "ab" 的异位词。 起始索引等于 2 的子串是 "ab", 它是 "ab" 的异位词。
提示:
1 <= s.length, p.length <= 3 * 104
s
和p
仅包含小写字母
1 class Solution { 2 public List<Integer> findAnagrams(String s, String p) { 3 if (s.length()<p.length()){ 4 return new ArrayList<>(); 5 }else{ 6 int[] a=new int[26]; 7 for (int i = 0; i < p.length(); i++) { 8 a[p.charAt(i)-'a']+=1; 9 } 10 int[] b=new int[26]; 11 ArrayList<Integer> arrayList = new ArrayList<>(); 12 String temp=s.substring(0,p.length()); 13 for (int i = 0; i <= s.length()-p.length(); i++) { 14 if (i==0){ 15 for (int j = 0; j < temp.length(); j++) { 16 b[temp.charAt(j)-'a']+=1; 17 } 18 }else{ 19 b[s.charAt(i-1)-'a']-=1; 20 b[s.charAt(i+p.length()-1)-'a']+=1; 21 } 22 if (Arrays.equals(a,b)){ 23 arrayList.add(i); 24 } 25 } 26 return arrayList; 27 } 28 } 29 }
题4:
给定一个字符串 s
,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:
输入: s = "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc",所以其
长度为 3。
示例 2:
输入: s = "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b"
,所以其长度为 1。
示例 3:
输入: s = "pwwkew" 输出: 3 解释: 因为无重复字符的最长子串是"wke"
,所以其长度为 3。 请注意,你的答案必须是 子串 的长度,"pwke"
是一个子序列,不是子串。
示例 4:
输入: s = "" 输出: 0
提示:
0 <= s.length <= 5 * 104
s
由英文字母、数字、符号和空格组成
1 class Solution { 2 public int lengthOfLongestSubstring(String s) { 3 Map<Character,Integer> map=new HashMap<>(); 4 int l=0,r=0,len=s.length(),max=0; 5 while (r<len) { 6 if (map.containsKey(s.charAt(r))&&map.get(s.charAt(r))!=0){ 7 while (l<r&&s.charAt(l)!=s.charAt(r)){ 8 map.put(s.charAt(l),map.get(s.charAt(l))-1); 9 l++; 10 } 11 //System.out.println(map+" "+r); 12 if (l!=r) { 13 map.put(s.charAt(l),map.get(s.charAt(l))-1); 14 l++; 15 } 16 //System.out.println(map+" "+r); 17 }else { 18 map.put(s.charAt(r),1); 19 r++; 20 max=Math.max(max,r-l); 21 //System.out.println(map+" "+r); 22 } 23 } 24 return max; 25 } 26 }