最小覆盖子串Java版(力扣)

简介: 最小覆盖子串Java版(力扣)


最小覆盖子串


给你一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字符的子串,则返回空字符串 “” 。

注意:如果 s 中存在这样的子串,我们保证它是唯一的答案。


示例 1:

输入:s = “ADOBECODEBANC”, t = “ABC”

输出:"BANC"


示例 2:

输入:s = “a”, t = “a”

输出:"a"


提示:

1 <= s.length, t.length <= 105

s 和 t 由英文字母组成


题意:在字符串s中找到能覆盖字符串t的最小子串。

思路:滑动窗口。


正确代码:


class Solution {
    public String minWindow(String s, String t) {
        if(s.length()<t.length()) return "";
        HashMap<Character,Integer> needs = new HashMap<>();
        HashMap<Character,Integer> window = new HashMap<>();
        //统计每个字符出现了多少次,以key-value的形式记录
        for (int i = 0; i < t.length(); i++) {
            needs.put(t.charAt(i),needs.getOrDefault(t.charAt(i),0)+1);
        }
        //System.out.println("needs.size(): "+needs.size());
        int left =0,right=0;
        int valid =0; //记录多少个字符串符合了条件,valid==needs.size() 就证明全部包含了
        //start : 最小符合子串的起始位置    len:最小符合子串的长度
        int start =0,len =Integer.MAX_VALUE;
        while(right<s.length()){
            char c1= s.charAt(right);
            if(needs.containsKey(c1)){
                window.put(c1,window.getOrDefault(c1,0)+1);
                if(window.get(c1).equals(needs.get(c1))){
                    valid++;
                }
            }
            right++;
            //判断是否需要收缩
            while(valid==needs.size()){
                if(right-left<len){
                    len = right-left;
                    start=left;
                }
                char c2 =s.charAt(left);
                left++;
                if(needs.containsKey(c2)){
                    window.put(c2,window.put(c2,0)-1);
                    if(window.get(c2)<needs.get(c2)){
                        valid--;
                    }
                }
            }
        }
        String a = Integer.toString(len);
        return a.equals(Integer.toString(Integer.MAX_VALUE) )? "" : s.substring(start, start + len);
    }
}

完整代码(含测试代码):

package com.Keafmd.February.day11;
import java.util.HashMap;
/**
 * Keafmd
 *
 * @ClassName: MinimumWindowSubstring
 * @Description: 最小覆盖子串 https://leetcode-cn.com/problems/minimum-window-substring/
 * @author: 牛哄哄的柯南
 * @Date: 2021-03-11 9:08
 * @Blog: https://keafmd.blog.csdn.net/
 */
public class MinimumWindowSubstring {
    public static void main(String[] args) {
        String s = "ADOBECODEBANC", t = "ABC";
        //String s = "a", t = "aa";
        //String s = "a", t = "b";
        Solution03111 solution03111 = new Solution03111();
        String re = solution03111.minWindow(s,t);
        System.out.println(re);
    }
}
class Solution03111 {
    public String minWindow(String s, String t) {
        if(s.length()<t.length()) return "";
        HashMap<Character,Integer> needs = new HashMap<>();
        HashMap<Character,Integer> window = new HashMap<>();
        //统计每个字符出现了多少次,以key-value的形式记录
        for (int i = 0; i < t.length(); i++) {
            needs.put(t.charAt(i),needs.getOrDefault(t.charAt(i),0)+1);
        }
        //System.out.println("needs.size(): "+needs.size());
        int left =0,right=0;
        int valid =0; //记录多少个字符串符合了条件,valid==needs.size() 就证明全部包含了
        //start : 最小符合子串的起始位置    len:最小符合子串的长度
        int start =0,len =Integer.MAX_VALUE;
        while(right<s.length()){
            char c1= s.charAt(right);
            if(needs.containsKey(c1)){
                window.put(c1,window.getOrDefault(c1,0)+1);
                if(window.get(c1).equals(needs.get(c1))){
                    valid++;
                }
            }
            right++;
            //判断是否需要收缩
            while(valid==needs.size()){
                if(right-left<len){
                    len = right-left;
                    start=left;
                }
                char c2 =s.charAt(left);
                left++;
                if(needs.containsKey(c2)){
                    window.put(c2,window.put(c2,0)-1);
                    if(window.get(c2)<needs.get(c2)){
                        valid--;
                    }
                }
            }
        }
        String a = Integer.toString(len);
        return a.equals(Integer.toString(Integer.MAX_VALUE) )? "" : s.substring(start, start + len);
    }
}

输出结果:

BANC
Process finished with exit code 0


相关文章
|
Java 编译器 API
【小家Java】Lombok的使用详解(最详尽的解释,覆盖讲解所有可用注解),解决@Builder.Default默认值问题(下)
【小家Java】Lombok的使用详解(最详尽的解释,覆盖讲解所有可用注解),解决@Builder.Default默认值问题(下)
【小家Java】Lombok的使用详解(最详尽的解释,覆盖讲解所有可用注解),解决@Builder.Default默认值问题(下)
|
3月前
|
Java
2696. 删除子串后的字符串最小长度 --力扣 --JAVA
给你一个仅由 大写 英文字符组成的字符串 s 。 你可以对此字符串执行一些操作,在每一步操作中,你可以从 s 中删除 任一个 "AB" 或 "CD" 子字符串。 通过执行操作,删除所有 "AB" 和 "CD" 子串,返回可获得的最终字符串的 最小 可能长度。 注意,删除子串后,重新连接出的字符串可能会产生新的 "AB" 或 "CD" 子串。
19 0
|
4月前
|
Java 测试技术
828. 统计子串中的唯一字符 --力扣 --JAVA
我们定义了一个函数 countUniqueChars(s) 来统计字符串 s 中的唯一字符,并返回唯一字符的个数。
38 2
|
9月前
|
算法 Java
【技术分享-真题实战】求最长无重复字符子串 (Java)
【题目来源:Leetcode-3】字符串、哈希表、字串
|
11月前
|
Java 索引
Java每日一练(20230512) 最大间距、串联子串、最长回文子串
Java每日一练(20230512) 最大间距、串联子串、最长回文子串
70 0
|
Java
给定一个字符串和一个子串。子串中的字符可能重复,输出子串出现的次数。(Java实现)
给定一个字符串和一个子串。子串中的字符可能重复,输出子串出现的次数。(Java实现)
101 0
给定一个字符串和一个子串。子串中的字符可能重复,输出子串出现的次数。(Java实现)
|
Java 测试技术
第十一届蓝桥杯A组省赛试题 H: 子串分值(Java)
第十一届蓝桥杯A组省赛试题 H: 子串分值(Java)
128 0
|
Java Python
Java和Python覆盖/重写函数的比较
Java和Python覆盖/重写函数的比较
148 0
|
前端开发 Java 索引
Java 中数组 binarySearch 方法and拷贝对象工具类CopyUtils-可忽略覆盖Null值详解
[1] 该搜索键在范围内,但不是数组元素,由1开始计数,得“ - 插入点索引值”; [2] 该搜索键在范围内,且是数组元素,由0开始计数,得搜索值的索引值; [3] 该搜索键不在范围内,且小于范围(数组)内元素,返回–(fromIndex + 1); [4] 该搜索键不在范围内,且大于范围(数组)内元素,返回 –(toIndex + 1)。
108 0
Java 中数组 binarySearch 方法and拷贝对象工具类CopyUtils-可忽略覆盖Null值详解