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:

3. 无重复字符的最长子串labuladong 题解思路

难度中等

给定一个字符串 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 }

 

posted on 2021-12-26 15:41  阿ming  阅读(8)  评论(0编辑  收藏  举报

导航