Javascript算法(滑块窗口、螺旋矩阵)

滑块窗口

JS滑块窗口算法,即滑动窗口算法(Sliding Window),在JavaScript中的应用场景主要集中在处理字符串和数组等数据结构中的子串或子数组问题。这种算法通过维护一个窗口,并移动窗口的两个边界(左右指针)来优化暴力枚举的时间复杂度,从而提高算法的执行效率。以下是一些具体的应用场景及案例:

应用场景

  1. 字符串匹配问题:在较长的字符串中查找是否存在一个较短的字符串(或模式)。
  2. 最长子串或子数组问题:查找满足特定条件的最长子串或子数组。
function lengthOfLongestSubstring(s){
 
    let maxLength=0;//做大子串的长度
    let currentLength=0;
    let charIndexMap={};//字符及其索引的映射
    let left=0;//窗口的左边界
    
    for(let right=0;right<s.length;right++){
    
        const char=s[right];
        
        //如果字符已经在窗口中存在,则更新左边界【key1】
        if(charIndexMap[char]>=left){
            left=charIndexMap[char]+1;
        }
        
        //更新字符的索引
        charIndexMap[char]=right;
        
        //更新当前窗口的长度
        currentLength=right-left+1;
        
        //更新最大长度【key2】
        maxLength=Math.max(maxLength,currentLength);
    }
    
    return maxLength
    
}
// 示例用法  
const inputString = "abcabcbb";  
console.log(`最长的不重复子串的长度是: ${lengthOfLongestSubstring(inputString)}`);
  1. 最小覆盖子串问题(难):在给定条件下,查找覆盖特定内容的最小子串。
  2. 字符串排列问题:判断一个字符串是否包含另一个字符串的所有字符(不考虑顺序和数量)。
  3. 求解字符串或数组的性质:如最大值、最小值、和、平均值等。

ae09aa0cf82a48f4b72e6530e8193164.png

/**
 * @param {number} target
 * @param {number[]} nums
 * @return {number}
 */
var minSubArrayLen = function(target, nums) {
    let left=0;
    let curSum=0;
    let minValue=0;
    let minLength=nums.length;
    for(right=0;right<nums.length;right++){
        curSum+=nums[right];
        //核心if与while?持续满足条件滑?[key]
        while(curSum>=target){
          let curLength=right-left+1;
           //[key2]
          minValue=Math.min(curLength,minLength)  
          curSum-=nums[left]
          left++; 
        }  
    }
    return minValue;
    
};

 水果篮子(Map)

d32b0298181c438691718ec77dc694ee.png

/**
 * @param {number[]} fruits
 * @return {number}
 */
var totalFruit = function(fruits) {
    let maxNumber=0;
    let fruitMap=new Map();
    let left=0;
    for(let right=0;right<fruits.length;right++){
        let fruit=fruits[right];
        fruitMap.set(fruit,(fruitMap.get(fruit)||0)+1);
        while(fruitMap.size>2){
            let leftFruit=fruits[left];
            fruitMap.set(leftFruit,fruitMap.get(leftFruit)-1);
            if(fruitMap.get(leftFruit)===0){
                fruitMap.delete(leftFruit);
            };
            left++;
        }
        maxNumber=Math.max(maxNumber,right-left+1)
        
    }
    return maxNumber;
};

螺旋矩阵

螺旋矩阵是指一个呈螺旋状的矩阵,其数字从第一行开始,向右、向下、向左、向上依次变大,如此循环直至填满整个矩阵。以下是对螺旋矩阵的详细解释:

一、定义与特点

  1. 定义:螺旋矩阵是一个二维数组(或表格),其中的数字按照螺旋式的顺序进行填充。
  2. 特点
    • 填充顺序:从外圈开始,顺时针或逆时针逐层向中心推进。
    • 数字递增:每一层的数字都比前一层的数字大,且在同一层中,数字也是递增的。

二、构造方法

  1. 确定边界:对于n行m列的螺旋矩阵,首先需要确定其四个边界,即左边界、右边界、上边界和下边界。
  2. 填充过程
    • 从上边界开始,向右填充数字,直到右边界。
    • 然后从右边界开始,向下填充数字,直到下边界。
    • 接着从下边界开始,向左填充数字,直到左边界。
    • 最后从左边界开始,向上填充数字,直到上边界。
    • 完成一层填充后,更新边界,继续下一层的填充,直到填满整个矩阵。

三、应用场景

螺旋矩阵在多个领域有着广泛的应用,包括但不限于:

  1. 数据可视化:螺旋矩阵能提供独特的视觉效果,便于观察数据的趋势和分布。
  2. 图像处理:在图像处理中,螺旋矩阵可以用于图像变换、滤波等操作。
  3. 算法训练:生成和处理螺旋矩阵是对算法逻辑和控制流程的一次良好锻炼。
  4. 游戏开发:螺旋矩阵可以用于生成迷宫地图等游戏元素。

dcbc710798ca4eebb766e46c759b36f4.png

99fcb248692f4d8f9248d433e51a6eb8.png

var generateMatrix = function(n) {
    let startX = startY = 0;   // 起始位置
    let loop = Math.floor(n/2);   // 旋转圈数
    let mid = Math.floor(n/2);    // 中间位置
    let offset = 1;    // 控制每一层填充元素个数
    let count = 1;     // 更新填充数字
    let res = new Array(n).fill(0).map(() => new Array(n).fill(0));

    while (loop--) {
        let row = startX, col = startY;
        // 上行从左到右(左闭右开)
        for (; col < n - offset; col++) {
            res[row][col] = count++;
        }
        // 右列从上到下(左闭右开)
        for (; row < n - offset; row++) {
            res[row][col] = count++;
        }
        // 下行从右到左(左闭右开)
        for (; col > startY; col--) {
            res[row][col] = count++;
        }
        // 左列做下到上(左闭右开)
        for (; row > startX; row--) {
            res[row][col] = count++;
        }

        // 更新起始位置
        startX++;
        startY++;

        // 更新offset
        offset += 1;
    }
    // 如果n为奇数的话,需要单独给矩阵最中间的位置赋值【key1】
    if (n % 2 === 1) {
        res[mid][mid] = count;
    }
    return res;
};

 56f3b627779444c0a1e1646ee0cd3c0a.png

mid的计算及填充:
同样的原理,本题的mid计算也存在上述差异;

1.如果min(rows,columns)为偶数,则不需要在最后单独
2.考虑矩阵最中间位置的赋值 如果min(rows, columns)为奇数,则矩阵最中间位置不只是[mid][mid],而是会留下来一个特殊的中间行或者中间列,具体是中间行还是中间列,要看rows和columns的大小,如果rows>columns,则是中间列,相反,则是中间行.

/**
 * @param {number[][]} matrix
 * @return {number[]}
 */
var spiralOrder = function(matrix) {
    let startX=0;
    let startY=0;
    let rowCount=matrix.length;
    let columnCount=matrix[0].length;
    let loop=Math.floor((Math.min(rowCount,columnCount))/2);
    let mid=Math.floor((Math.min(rowCount,columnCount))/2);
    let offset=1;
    let count=0;
    let res=[];
    while(loop--){
        let row=startX;
        let col=startY;
        for(;col<columnCount-offset;col++){
            res[count]=matrix[row][col];
            count++
        }
        for(;row<rowCount-offset;row++){
            res[count]=matrix[row][col];
            count++;
        }
        for(;col>startY;col--){
            res[count]=matrix[row][col];
            count++;
        }
        for(;row>startX;row--){
            res[count]=matrix[row][col];
            count++;
        }
        startX++;
        startY++;
        offset++;
    }
    //核心分析,剩下的,若最小为偶数,则直接可以循环掉
    //若为奇数,则可能剩下一行或一列,分情况考虑(比较columCount与rowCount大学)
    if((Math.min(rowCount,columnCount))%2){
        let row=mid;
        let column=mid;
         if(rowCount>=columnCount){
            for(;row<mid+rowCount-columnCount+1;row++){
                res[count++]=matrix[row][column];
            }
         }else{
            for(;column<mid+columnCount-rowCount+1;column++){
                res[count++]=matrix[row][column];
            }
         }
    }
    return res;
};

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/895882.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Linux命令进阶·vi\vim编辑器详细命令介绍

目录 1. 什么是 vim&#xff1f; 2. vi\vim 模式介绍 2.1 命令模式&#xff08;Command mode&#xff09; 2.2 输入模式&#xff08;Insert mode&#xff09; 2.3 底线命令模式&#xff08;Last line mode&#xff09; 3. vi\vim 的使用 4. 命令介绍 1. 什么是 …

微信小程序-自定义组件

文章目录 微信小程序-自定义组件概述创建和使用数据、方法和属性slot 插槽默认插槽具名插槽 组件样式注意项样式隔离 数据监听组件间通信父传子子传父获取子组件实例 生命周期组件的生命周期组件所在页面的生命周期App、Page与Component生命周期对比冷启动保留当前页面和关闭当…

诺奖印证产业方向,AI先行者晶泰科技开拓黄金赛道

2024年诺贝尔奖揭晓的各奖项中&#xff0c;AI领域无疑成为“最大赢家”。 从诺贝尔物理学奖被授予两名AI科学家&#xff0c;到诺贝尔化学奖表彰三位科学家“用人工智能&#xff08;AI&#xff09;破译蛋白质的密码”&#xff0c;本届诺贝尔奖“含AI量”之高引起市场热议。 值…

如何将 Elasticsearch 与流行的 Ruby 工具结合使用

作者&#xff1a;来自 Elastic Fernando Briano 了解如何将 Elasticsearch 与一些流行的 Ruby 库一起使用。 在这篇博文中&#xff0c;我们将介绍如何将 Elasticsearch 与一些流行的 Ruby 工具结合使用。我们将实现 Ruby 客户端 “入门”指南 中介绍的常用 API。如果你点击该链…

【从零开发Mybatis】引入XNode和XPathParser

引言 在上文&#xff0c;我们发现直接使用 DOM库去解析XML 配置文件&#xff0c;非常复杂&#xff0c;也很不方便&#xff0c;需要编写大量的重复代码来处理 XML 文件的读取和解析&#xff0c;代码可读性以及可维护性相当差&#xff0c;使用起来非常不灵活。 因此&#xff0c…

深度学习:对评论信息的情感分析,建立模型,自动识别评论信息的情绪状态完整代码实现

评论 思考&#xff1a;向模型中传递数据时&#xff0c;需要提前处理好数据 1、目标&#xff1a;将评论内容转换为词向量。 2、每个词/字转换为词向量长度(维度)200 3、每一次传入的词/字的个数是否就是评论的长度? 应该是固定长度&#xff0c;每次传入数据与图像相似…

DIY我的世界磁力方块

引子 小朋友喜欢我的世界&#xff0c;就像当年我那代对俄罗斯方块的执着&#xff0c;考虑电子游戏伤眼睛&#xff0c;所以最近开始给小朋友买磁力方块。 一个将近1元多的价格&#xff0c;催生我DIY的念头。 正文 Freecad图&#xff0c;A,B,C,D处 放磁铁 5.14g 材料费 最后的成…

Axure中继器单选、多选和重置

亲爱的小伙伴&#xff0c;在您浏览之前&#xff0c;烦请关注一下&#xff0c;在此深表感谢&#xff01; 课程主题&#xff1a;Axure中继器单选、多选和重置 主要内容&#xff1a;根据查询条件&#xff0c;通过单选、多选和重置&#xff0c;从中继器中得到数据 应用场景&…

DockerCompose快速部署Java项目、nginx前端和mysql数据库到centos虚拟机

简介&#xff1a;整理自&#xff1a;SpringCloud微服务开发与实战&#xff0c;java黑马商城项目微服务实战开发&#xff08;涵盖MybatisPlus、Docker、MQ、ES、Redis高级等&#xff09;课程的飞书文档。 DockerCompose介绍 大家可以看到&#xff0c;我们部署一个简单的java项…

stm32实现esp8266连接到TCP服务器(二)未完

1.2 连接到TCP Server 1.2.1 使用网络助手&#xff0c;设立TCP服务器 ​ 编辑 1.2.2 连接服务器 ATCIPSTART"TCP","192.168.1.18",8080 //指令&#xff0c;注意双引号逗号都要半角(英文)输入 CONNECT //结果&#xff1a;成功 OK //结果&#xff1a;成功 …

[C++]ecplise C++新建项目跑hello world

测试通过版本&#xff1a; ecplise-cpp 2024-09 ecplise-cpp 2020-09 【前提】 安装好MinGW环境&#xff0c;实际测试不需要下载什么CDT插件就可以运行了。 步骤&#xff1a; &#xff08;1&#xff09;打开ecplise,选择launch 选择File->New->C/C Project 选择C M…

Java_数组的使用

一、数组的介绍 数组可以存放多个同一类型的数据。数组也是一种数据类型&#xff0c;是引用类型。 即&#xff1a;数&#xff08;数据&#xff09;组&#xff08;一组&#xff09;就是一组数据 二、代码演示 public class Array01 {public static void main(String[] args) …

DMAIC赋能智能家居:解锁未来生活新篇章!

从清晨自动拉开的窗帘&#xff0c;到夜晚自动调暗的灯光&#xff0c;每一处细节都透露着科技的温度与智慧的光芒。而在这场智能革命的浪潮中&#xff0c;DMAIC&#xff08;定义Define、测量Measure、分析Analyze、改进Improve、控制Control&#xff09;作为六西格玛管理的核心方…

React之组件渲染性能优化

关键词&#xff1a; shouldComponentUpdate、PureComnent、React.memo、useMemo、useCallback shouldComponentUpdate 与 PureComnent shouldComponentUpdate 与 PureComnent 用于类组件。虽然官方推荐使用函数组件&#xff0c;但我们依然需要对类组件的渲染优化策略有所了解…

10 排序算法:冒泡排序与快速排序(算法原理、算法实现、时间和空间复杂度分析)

目录 1 十大常见的排序算法 1.1 算法的稳定性 2 冒泡排序 2.1 算法原理 2.2 算法实现 2.3 时间空间复杂度分析 2.3.1 时间复杂度分析 2.3.2 空间复杂度分析 3 快速排序 3.1 算法原理 3.1.1 排序思想 3.1.2 递归过程 3.2 示例 3.2.1 示例 1 3.2.2 示例 2 3.2.3 …

RHCE--网络服务

第一章 例行性工作 1、单一执行的例行性工作&#xff08;at&#xff09; 1.1 查看at命令 at的黑名单&#xff08;deny&#xff09;、白名单&#xff08;allow&#xff09;&#xff1b;两个文件若都不存在则只有root用户能使用 at工作调度对应的系统服务 atd&#xff1a;at的…

N9305高品质mp3音频语音芯片ic在早教故事机的应用方案

随着人们对教育的重视程度不断提高&#xff0c;儿童早教机已经成为了很多家庭的教育必备品。N9305音乐芯片在早教故事机中的应用&#xff0c;不仅为孩子们带来了丰富多彩的故事世界&#xff0c;还以其卓越的音质表现和功能&#xff0c;进一步提升了早教体验。 九芯电子N9305高品…

单片机——ADC采样

1、什么是ADC采样&#xff1f; ADC是指将模拟信号转换成数字信号的过程。通俗理解ADC采样就是采集电路中的电压&#xff0c;通过数值的方式表现出来。以STM32F103系列为例&#xff0c;它可以反应0~4095&#xff0c;换句话说&#xff0c;它采集的电压数值上表现为0~4095&#xf…

前端文件流导出

1、前端代码 ​ /** 导出 */ const handleExport async () > {let config {responseType: blob,headers: {Content-Type: application/json,},};const res await getTargetExport(config);const blob new Blob([res]);const fileName PK目标跟进导出列表.xls;const li…

WEB前端作业1

<!DOCTYPE html> <html><head><meta charset"utf-8"><title>用户注册页面</title></head><style type"text/css">#center{text-align: center;background-color: #e9e9e9;}tr td,th{border:1px solid whi…