首页 > 其他分享 >LeetCode 76.最小覆盖子串

LeetCode 76.最小覆盖子串

时间:2022-11-25 11:32:03浏览次数:72  
标签:子串 字符 窗口 ++ 76 字符串 need 滑动 LeetCode

LeetCode 76.最小覆盖子串题目链接:

​https://leetcode-cn.com/problems/minimum-window-substring/​


题目描述:

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

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


示例 1:

输入:s = "ADOBECODEBANC", t = "ABC"

输出:"BANC"


示例 2:

输入:s = "a", t = "a"

输出:"a"


提示:

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

2. s 和 t 由英文字母组成


题目分析:

这道题我们采用滑动窗口的思想,用l,r分别表示滑动窗口的左右边界,改变l,r来改变滑动窗口的大小。我们用数组need来存储当前滑动窗口中需要各个元素的数量,用字符串t初始化这个need数组。如果滑动窗口包含某个元素,我们就让need数组中同个元素的数量减一,反之加一。我们还需定义一个变量count存放需要的字符数,当遇到一个需要的元素就让这个变量减一,这样可以省下遍历数组need的步骤。首先,我们让左右边界都指向字符串第一个元素,增加r即右边界使滑动窗口增大,直到滑动窗口包含字符串t中的所有元素。然后再让左边界向右移动,缩小滑动窗口大小,使不必要的元素排除在滑动窗口外,直到遇到一个必须包含的元素,这个元素不能排除到滑动窗口外,此时记录此窗口。最后让左边界再右移一个位置,并让右边界右移,寻找下一个符合条件的滑动窗口,重复刚刚的寻找步骤。


题解:

执行用时: 4 ms

内存消耗: 38.5 MB

class Solution {
public String minWindow(String s, String t) {
// 定义变量存放字符串长度
int sLength = s.length();
int tLength = t.length();


// 如果其中一个字符串为空或者字符串s长度比字符串t长度还小
// 说明s中不存在涵盖t所有字符的子串,返回空字符串
if (sLength == 0 || tLength == 0 || sLength < tLength)
return "";


//记录需要的字符的个数
int[] need = new int[128];


// 用字符串t中各元素来初始化need
for (int i = 0; i < tLength; i++)
need[t.charAt(i)]++;


// l是当前左边界,r是当前右边界,size记录窗口大小,count是需求的字符个数,start是最小覆盖串开始的index
int l = 0, r = 0, size = sLength + 1, count = tLength, start = 0;


// 遍历字符串s
while (r < sLength) {


// 获取当前右边界字符
char c = s.charAt(r);


// 需要字符charArrayS[r]
if (need[c] > 0)
// 需求的字符个数减一
count--;


// 把右边的字符加入窗口,需要字符数减一
need[c]--;


// 当前窗口中已经包含t中所有字符
if (count == 0) {
while (need[s.charAt(l)] < 0) {
// 释放左边移动出窗口的字符
need[s.charAt(l)]++;
// 左指针右移
l++;
}
// 不能右移时候挑战最小窗口大小,更新最小窗口开始的start
if (r - l + 1 < size) {
size = r - l + 1;
// 记录下最小值时候的开始位置
start = l;
}
// 左边界向右移动后窗口肯定不能满足了,重新开始循环
need[s.charAt(l)]++;
// 左边界右移
l++;
// 需要字符数加一
count++;
}
// 右边界右移
r++;
}
// 返回结果字符串
return size == (sLength + 1) ? "" : s.substring(start, start + size);
}
}


题目来源:力扣(LeetCode)


标签:子串,字符,窗口,++,76,字符串,need,滑动,LeetCode
From: https://blog.51cto.com/u_15891283/5886077

相关文章

  • leetcode 104. 二叉树的最大深度 js实现
    给定一个二叉树,找出其最大深度。二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。说明: 叶子节点是指没有子节点的节点。示例:给定二叉树 [3,9,20,null,null......
  • leetcode 344. 反转字符串 js实现
    编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 s 的形式给出。不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用O(1)的额外空间解......
  • leetcode 21. 合并两个有序链表 js实现
    将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 示例1:输入:l1=[1,2,4],l2=[1,3,4]输出:[1,1,2,3,4,4]示......
  • leetcode_Day2_35搜索插入位置
    1.题目  2.解一 主要思路:二分法,不多赘述,为题目所给标准解法。3.解二   主要思路:循环对比,自己想的,感觉写的非常冗余,内存占用和速度都很大。不过没学过算法,......
  • leetcode 19. 删除链表的倒数第 N 个结点 js实现
    给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。示例1:输入:head=[1,2,3,4,5],n=2输出:[1,2,3,5]示例2:输入:head=[1],n=1输出:[]示例3:......
  • 算法5: LeetCode_单链表_两数相加
    题目:*给你两个非空的链表,表示两个非负的整数。它们每位数字都是按照逆序的方式存储的,并且每个节点只能存储一位数字。*请你将两个数相加,并以相同形式返回一个......
  • LeetCode刷题记录.Day24
    有效的括号20.有效的括号-力扣(LeetCode)classSolution{public:boolisValid(strings){if(s.size()%2!=0)returnfalse;//奇数必不符合......
  • 力扣 leetcode 795. 区间子数组个数
    问题描述给你一个整数数组nums和两个整数:left及right。找出nums中连续、非空且其中最大元素在范围[left,right]内的子数组,并返回满足条件的子数组的个数。生成......
  • leetcode1552
    两球之间的磁力Category Difficulty Likes Dislikesalgorithms Medium(51.48%) 122 -TagsUnknownCompaniesUnknown在代号为C-137的地球上,Rick发现如果他将两个......
  • #yyds干货盘点# LeetCode 腾讯精选练习 50 题:Nim 游戏
    题目:你和你的朋友,两个人一起玩 Nim游戏:桌子上有一堆石头。你们轮流进行自己的回合, 你作为先手 。每一回合,轮到的人拿掉 1-3块石头。拿掉最后一块石头的人就是获胜者......