最小覆盖子串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


相关文章
|
6月前
|
Java
383. 赎金信 --力扣 --JAVA
给你两个字符串:ransomNote 和 magazine ,判断 ransomNote 能c里面的字符构成。 如果可以,返回 true ;否则返回 false 。 magazine 中的每个字符只能在 ransomNote 中使用一次。
44 1
|
6月前
|
Java
1276. 不浪费原料的汉堡制作方案 --力扣 --JAVA
圣诞活动预热开始啦,汉堡店推出了全新的汉堡套餐。为了避免浪费原料,请你帮他们制定合适的制作计划。 给你两个整数 tomatoSlices 和 cheeseSlices,分别表示番茄片和奶酪片的数目。不同汉堡的原料搭配如下: 巨无霸汉堡:4 片番茄和 1 片奶酪 小皇堡:2 片番茄和 1 片奶酪 请你以 [total_jumbo, total_small]([巨无霸汉堡总数,小皇堡总数])的格式返回恰当的制作方案,使得剩下的番茄片 tomatoSlices 和奶酪片 cheeseSlices 的数量都是 0。 如果无法使剩下的番茄片 tomatoSlices 和奶酪片 cheeseSlic
52 0
|
6月前
|
Java
2866. 美丽塔 II --力扣 --JAVA
给你一个长度为 n 下标从 0 开始的整数数组 maxHeights 。 你的任务是在坐标轴上建 n 座塔。第 i 座塔的下标为 i ,高度为 heights[i] 。 如果以下条件满足,我们称这些塔是 美丽 的: 1 <= heights[i] <= maxHeights[i] heights 是一个 山脉 数组。 如果存在下标 i 满足以下条件,那么我们称数组 heights 是一个 山脉 数组: 对于所有 0 < j <= i ,都有 heights[j - 1] <= heights[j] 对于所有 i <= k < n - 1 ,都有 heights[k + 1] <= he
95 0
|
6月前
|
存储 Java 索引
350. 两个数组的交集 II --力扣 --JAVA
给你两个整数数组 nums1 和 nums2 ,请你以数组形式返回两数组的交集。返回结果中每个元素出现的次数,应与元素在两个数组中都出现的次数一致(如果出现次数不一致,则考虑取较小值)。可以不考虑输出结果的顺序。
49 0
|
6月前
|
存储 Java
17. 电话号码的字母组合 --力扣 --JAVA
给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。 给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。
55 0
|
5月前
|
Java
P9242 [蓝桥杯 2023 省 B] 接龙数列JAVA,边权为1的最短路问题,洛谷P9242 [蓝桥杯 2023 省 B] 接龙数列​编辑力扣1926.迷宫离入口最近的出口力扣433.
P9242 [蓝桥杯 2023 省 B] 接龙数列JAVA,边权为1的最短路问题,洛谷P9242 [蓝桥杯 2023 省 B] 接龙数列​编辑力扣1926.迷宫离入口最近的出口力扣433.
|
6月前
|
存储 Java
JAVA数据结构刷题 -- 力扣二叉树
JAVA数据结构刷题 -- 力扣二叉树
56 0
|
6月前
|
安全 Java
1599. 经营摩天轮的最大利润 -- 力扣 --JAVA
你正在经营一座摩天轮,该摩天轮共有 4 个座舱 ,每个座舱 最多可以容纳 4 位游客 。你可以 逆时针 轮转座舱,但每次轮转都需要支付一定的运行成本 runningCost 。摩天轮每次轮转都恰好转动 1 / 4 周。 给你一个长度为 n 的数组 customers , customers[i] 是在第 i 次轮转(下标从 0 开始)之前到达的新游客的数量。这也意味着你必须在新游客到来前轮转 i 次。每位游客在登上离地面最近的座舱前都会支付登舱成本 boardingCost ,一旦该座舱再次抵达地面,他们就会离开座舱结束游玩。 你可以随时停下摩天轮,即便是 在服务所有游客之前 。如果你决定
82 1
|
6月前
|
Java
100148. 最小数字游戏 --力扣 -- JAVA
你有一个下标从 0 开始、长度为 偶数 的整数数组 nums ,同时还有一个空数组 arr 。Alice 和 Bob 决定玩一个游戏,游戏中每一轮 Alice 和 Bob 都会各自执行一次操作。游戏规则如下: 每一轮,Alice 先从 nums 中移除一个 最小 元素,然后 Bob 执行同样的操作。 接着,Bob 会将移除的元素添加到数组 arr 中,然后 Alice 也执行同样的操作。 游戏持续进行,直到 nums 变为空。 返回结果数组 arr 。
59 0
|
6月前
|
Java
2696. 删除子串后的字符串最小长度 --力扣 --JAVA
给你一个仅由 大写 英文字符组成的字符串 s 。 你可以对此字符串执行一些操作,在每一步操作中,你可以从 s 中删除 任一个 "AB" 或 "CD" 子字符串。 通过执行操作,删除所有 "AB" 和 "CD" 子串,返回可获得的最终字符串的 最小 可能长度。 注意,删除子串后,重新连接出的字符串可能会产生新的 "AB" 或 "CD" 子串。
39 0
下一篇
无影云桌面