Leetcode 76.最小覆盖子串 JavaScript (Day 6)

js一刷法一(丑陋)

javascript 复制代码
var minWindow = function(s, t) {
    if(s.length<t.length)  return "";
    
    let m=new Set(s);
    for(let i=0;i<t.length;i++){
        if(!m.has(t[i])) return "";
    }
    
    let ans=[0,1000000000000000000];
    let idx=new Map();
    for(let i=0;i<t.length;i++){
        idx.set(t[i],(idx.get(t[i])??0)+1);
    }
    
    let left=0,right=0;
    while(right<s.length){
        if(idx.has(s[right])) idx.set(s[right],idx.get(s[right])-1);
        while([...idx.values()].every(x=>x<=0)){
            if(left===right) return s[right];
            if(right-left<ans[1]-ans[0]) ans=[left,right];
            if(idx.has(s[left])) idx.set(s[left],idx.get(s[left])+1);
            left++;
        }
        right++;
        }
     
     while([...idx.values()].every(x=>x<=0)){
            if(left===right) return s[right];
            if(right-left<ans[1]-ans[0]) ans=[left,right];
            if(idx.has(s[left])) idx.set(s[left],idx.get(s[left])+1);
            left++;
        }
        if(ans[1]==1000000000000000000) return "";
        return s.slice(ans[0], ans[1] + 1);
};

js一刷法一(优化版)

javascript 复制代码
var minWindow = function(s, t) {
    if (s.length < t.length) return "";

    let need = t.length;
    let map = new Map();

    for (let c of t) {
        map.set(c, (map.get(c) ?? 0) + 1);
    }

    let left = 0;
    let ans = [0, Infinity];

    for (let right = 0; right < s.length; right++) {
        let c = s[right];
        if (map.has(c)) {
            if (map.get(c) > 0) need--;
            map.set(c, map.get(c) - 1);
        }

        while (need === 0) {
            if (right - left < ans[1] - ans[0]) {
                ans = [left, right];
            }

            let d = s[left];
            if (map.has(d)) {
                map.set(d, map.get(d) + 1);
                if (map.get(d) > 0) need++;
            }
            left++;
        }
    }

    return ans[1] === Infinity ? "" : s.slice(ans[0], ans[1] + 1);
};

思路完全相同,只不过一开始我是想用之前一个题思路,先将t存入hash,然后遇到符合条件的就-1,优化后用need(t的长度)来记录,need=0时候,说明找到了
算法核心:左指针不动,右指针不断往右,当窗口里包含了所有符合条件的字符后,从左边缩短窗口,左指针右移,所以说left在right动之前,永远指向的是有效字符,因为无效的在循环中清除了

js一刷法二(无敌)

javascript 复制代码
var minWindow = function (s, t) {
    const arr=new Array(128).fill(0);

    for(const i of t){
        arr[i.charCodeAt(0)]--;
    }

    let left=0,right=0,count=0,start=-1;
    let len=s.length+1;
    while(right<s.length){
        if(arr[s.charCodeAt(right)]<0){
            count++;
        }
        arr[s.charCodeAt(right)]++;
        while(left<=right&&arr[s.charCodeAt(left)]>0){
            arr[s.charCodeAt(left)]--;
            left++;
        }
        
        
        if(count===t.length&&right-left+1<len){
            len=right-left+1;
            start=left;    
        }
        right++;
    }
    return start===-1?"":s.slice(start,start+len);

};

算法核心:长度可变的滑动窗口,因为字符串中数字大小写字母不方便来比较,所以全部转化成ASCII码来比较,创建一个长度为128的数组,对应0-127的ASCII码,可以表示26个大小写字母,0-9的数字
数组中

>0 无效元素
=0 符合要求,刚好在窗口内
<0 不在窗口内

先把数组全部初始化为0,要找的字符全部初始化为-1,然后向右遍历,并+1,原来为-1的加一后变为0,为在窗口内的有效字符,无用的字符和有用但重复的字符+1后>0,在后续的循环中可以被清除
用start记录起点 用len来更新长度,找到最小的len

语法注意点:
想要获取数组/字符串arr中的一部分,并且不破坏原数组,用slice(i,j),可以将arr[i]~arr[j-1]存储在新数组中并返回

arr.charCodeAt[i] 将arr[i]转化成ASCII码

相关推荐
程序员-King.8 小时前
day158—回溯—全排列(LeetCode-46)
算法·leetcode·深度优先·回溯·递归
月挽清风8 小时前
代码随想录第七天:
数据结构·c++·算法
小O的算法实验室9 小时前
2026年AEI SCI1区TOP,基于改进 IRRT*-D* 算法的森林火灾救援场景下直升机轨迹规划,深度解析+性能实测
算法·论文复现·智能算法·智能算法改进
小郭团队9 小时前
2_1_七段式SVPWM (经典算法)算法理论与 MATLAB 实现详解
嵌入式硬件·算法·硬件架构·arm·dsp开发
充值修改昵称9 小时前
数据结构基础:从二叉树到多叉树数据结构进阶
数据结构·python·算法
利刃大大9 小时前
【Vue】Vue2 和 Vue3 的区别
前端·javascript·vue.js
Deepoch10 小时前
Deepoc数学大模型:发动机行业的算法引擎
人工智能·算法·机器人·发动机·deepoc·发动机行业
Lhuu(重开版10 小时前
JS:正则表达式和作用域
开发语言·javascript·正则表达式
浅念-10 小时前
C语言小知识——指针(3)
c语言·开发语言·c++·经验分享·笔记·学习·算法
Hcoco_me10 小时前
大模型面试题84:是否了解 OpenAI 提出的Clip,它和SigLip有什么区别?为什么SigLip效果更好?
人工智能·算法·机器学习·chatgpt·机器人