LeetCode-刷题记录-滑动窗口合集(本篇blog会持续更新哦~)

news2024/11/19 10:36:49

一、滑动窗口概述

滑动窗口(Sliding Window)是一种用于解决数组(或字符串)中子数组(或子串)问题的有效算法。

在这里插入图片描述

Sliding Window核心思想:

滑动窗口技术的基本思想是维护一个窗口(一般是一个子数组或子串),该窗口在数组上滑动,并在滑动过程中更新窗口的内容。

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

通过滑动窗口,可以在 ( O(n) ) 的时间复杂度内解决很多子数组(子串)问题,其中 ( n ) 是数组(字符串)的长度。

基本步骤:

  1. 初始化窗口: 定义一个窗口的起始位置和结束位置,通常是两个指针 leftright
  2. 滑动窗口: 不断地增加 right 指针来扩大窗口,直到窗口满足某个条件为止。

在这里插入图片描述

  1. 更新窗口: 一旦满足条件,尝试缩小窗口大小,即增加 left 指针,直到条件不满足为止。
  2. 记录结果: 在滑动窗口的过程中,根据题目要求来记录最终的结果。

二、习题合集

1.LeetCode 209 长度最小的子数组

在这里插入图片描述

  • 滑动窗口O(N)解法:
class Solution {
    public int minSubArrayLen(int target, int[] nums) {
        int n = nums.length;  // 数组的长度
        int ans = Integer.MAX_VALUE;  // 初始化结果为最大值,用于存储最短子数组的长度
        int l = 0;  // 左指针,指向滑动窗口的起始位置
        int sum = 0;  // 记录滑动窗口内元素的和
        
        for (int r = 0; r < n; r++) {  // 右指针,扩展滑动窗口
            sum += nums[r];  // 将右指针指向的元素加入窗口
            
            while (sum >= target) {  // 当窗口内元素和大于等于目标值时,尝试缩小窗口
                ans = Math.min(ans, r - l + 1);  // 更新最短子数组的长度
                sum -= nums[l];  // 缩小窗口,左指针向右移动,减少窗口内的元素和
                l++;  // 左指针右移
            }
        }
        
        return ans == Integer.MAX_VALUE ? 0 : ans;  // 如果找不到满足条件的子数组,返回0;否则返回最短子数组的长度
    }
}


2.LeetCode 3 无重复字符的最长子串

在这里插入图片描述


  • 第一版滑动窗口
class Solution {
    public int lengthOfLongestSubstring(String s) {
        Map<Character, Integer> map = new HashMap<>(); // 创建一个哈希表,用来记录字符及其出现的最后位置
        int n = s.length(); // 字符串的长度
        int l = 0, ans = 0; // l表示当前不重复子串的起始位置,ans用来记录最长不重复子串的长度
        
        for (int r = 0; r < n; r++) {
            char c = s.charAt(r); // 获取当前字符
            if (map.containsKey(c)) {
               
                //如果曾经出现的 字母 还在窗口内 —— l更新到 该位置+1
                //如果曾经出现的 字母 已不在当前窗口内了—— 则不需要更新
                l = Math.max(l,map.get(c)+1);
            
            }
            map.put(c, r); // 更新当前字符的最后出现位置为当前索引r
            ans = Math.max(ans, r - l + 1); // 更新最长不重复子串的长度
        }
        
        return ans; // 返回最长不重复子串的长度
    }
}

要理解 left = Math.max(left,map.get(s.charAt(i)) + 1);需要回归到滑动窗口的原理上。

窗口中始终是无重复字母的字符串。 我们通过窗口的左界和右界控制窗口。

右界不用特意操作,因为它是+1,+1地涨上去,记得在循环里+1就好。

左界:每当有一个字符曾经出现过,就需要判断左界。

重点来了:

若,被判断的字符上一次出现的位置就在滑动窗口内,即 [ i,j ] 内, 则需要left改变位置,改变为该字符上次出现位置+1。也就是left = map.get(s.charAt(i)) + 1的情况。

例如:

abcdb中,窗口正常运行到abcd时,下一个字符为b,b上一次出现在实在窗口里,所以需要把left设置为上一次出现的位置+1的位置,得到新的窗口为cdb,不然你不这样设置,窗口里有重复的字符(bcdb),不符合窗口的定义。

若,不在滑动窗口内,则不用管。 不用管是因为:窗口中字符串没有重复字符。窗口符合定义。所以left = left。 left = left就表示这个窗口暂时不变。

在这里插入图片描述


  • 第二版优化的滑动窗口:
class Solution {
    public int lengthOfLongestSubstring(String s) {
        // 记录字符上一次出现的位置
        int[] last = new int[128]; // 创建一个长度为128的整型数组,用来记录ASCII码表中每个字符上一次出现的位置
        for(int i = 0; i < 128; i++) {
            last[i] = -1; // 初始化数组,所有字符的上一次出现位置都设为-1,表示尚未出现过
        }
        int n = s.length(); // 字符串s的长度

        int res = 0; // 用于记录最长的不重复子串的长度
        int start = 0; // 窗口开始位置,用来维护当前不重复子串的起始位置
        for(int i = 0; i < n; i++) {
            int index = s.charAt(i); // 获取当前字符的ASCII码作为索引
            start = Math.max(start, last[index] + 1); // 更新窗口的起始位置,确保不重复的起点
            res = Math.max(res, i - start + 1); // 更新最大的不重复子串长度
            last[index] = i; // 更新当前字符的最后出现位置为当前索引i
        }

        return res; // 返回最长的不重复子串的长度
    }
}

3.LeetCode 187 重复的DNA序列

在这里插入图片描述

  • 哈希表法~
class Solution {
    public List<String> findRepeatedDnaSequences(String s) {
        List<String> ans = new ArrayList<>(); // 用于存放重复的DNA序列
        int n = s.length(); 
        if (n < 10) return ans; // 如果字符串长度小于10,直接返回空列表,因为无法形成长度为10的序列
        Map<String, Integer> map = new HashMap<>(); // 创建一个哈希表,用来记录每个长度为10的子序列及其出现的次数
        map.put(s.substring(0, 10), 1); // 初始化,将第一个长度为10的子序列放入哈希表中
        
        for (int i = 1; i + 10 <= n; i++) { // 从第二个子序列开始遍历到倒数第十个子序列
            String ss = s.substring(i, i + 10); // 获取当前长度为10的子序列
            if (map.getOrDefault(ss, 0) == 1) { // 如果该子序列已经在哈希表中出现过一次
                ans.add(ss); // 将该子序列加入结果列表
            }
            map.put(ss, map.getOrDefault(ss, 0) + 1); // 更新哈希表中该子序列的出现次数
        }
        
        return ans; // 返回重复的DNA序列列表
    }
}
  • 滑动窗口法~
class Solution {
    // 滑动窗口法查找重复的长度为10的DNA序列
    public List<String> findRepeatedDnaSequences(String s) {
        List<String> ans = new ArrayList<>(); // 用于存放重复的DNA序列
        int n = s.length(); // 字符串的长度
        if (n < 10) return ans; // 如果字符串长度小于10,直接返回空列表,因为无法形成长度为10的序列

        StringBuilder sb = new StringBuilder(s.substring(0, 10)); // 初始化第一个长度为10的子串
        Set<String> set = new HashSet<>(); // 使用集合来记录出现过的子串
        set.add(sb.toString()); // 将第一个子串添加到集合中

        for (int i = 1; i + 10 <= n; i++) {
            String str = s.substring(i, i + 10); // 获取当前长度为10的子串

            if (set.contains(str)) { // 如果集合中已经包含当前子串
                if (!ans.contains(str)) // 且列表中还未包含该子串
                    ans.add(str); // 将该子串添加到列表中
            } else { // 如果集合中不包含当前子串
                set.add(str); // 将当前子串添加到集合中
            }
        }

        return ans; // 返回存放了重复DNA序列的列表
    }
}


4.LeetCode 424 替换后的最长重复字符

在这里插入图片描述
在这里插入图片描述

  • 核心思想:

相同的最长子字符串(窗口) = 窗口内最大字符个数 + 反转次数

一旦 窗口长度 - 窗口内最大字符个数 > 反转次数 窗口开始移动

public int characterReplacement(String s, int k) {
        int n = s.length();
        if(n<2) return n;
        int ans = 0; // 用于存储最长连续相同字符的子串的长度
        int maxFreq = 0; // 用于存储当前窗口内出现次数最多的字符的次数
        char[] c = s.toCharArray();
        int[] freq = new int[26]; // 记录当前窗口内每个字符出现的次数
        int left = 0; // 滑动窗口的左边界

        for (int right = 0; right < n; right++) {
            ++freq[c[right] - 'A']; // 更新右边界字符的出现次数
            maxFreq = Math.max(maxFreq, freq[c[right] - 'A']); // 更新最大出现次数

            // 如果当前窗口的大小减去出现次数最多的字符的次数大于k,则需要缩小窗口
            // 使得窗口内可以通过替换字符使其变成连续相同字符的子串
            if (right - left + 1 > maxFreq + k) {
                freq[c[left] - 'A']--; // 缩小窗口时,更新左边界字符的出现次数
                left++; // 缩小窗口
            }

            // 更新最长连续相同字符的子串的长度
            ans = Math.max(ans, right - left + 1);
        }
        return ans;
    }

5.LeetCode 438 找到字符串中所有字母异位词

在这里插入图片描述

  • 详细的思路都在注释里面了哈~
 public List<Integer> findAnagrams(String s, String p) {
        //在长度为26的int数组target中存储字符串p中对应字符(a~z)出现的次数
        //如p="abc",则target为[1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
        //如p="bbdfeee",则target为[0,2,0,1,3,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
        int[] target = new int[26];
        for (int i = 0; i < p.length(); i++) {
            target[p.charAt(i) - 'a']++;
        }
        //双指针构建滑动窗口原理:
        //1.右指针right先向右滑动并在window中存储对应字符出现次数
        //2.当左右指针间的字符数量(包括左右指针位置的字符)与p长度相同时开始比较
        //3.比较完成后,左右指针均向右滑动一位,再次比较
        //4.以后一直重复2、3,直到end指针走到字符串s的末尾
        int left = 0, right = 0;
        int[] window = new int[26];//构建一个与target类似的,存储了字符串s从left位置到right位置的窗口中字符对应出现次数的数组
        List<Integer> ans = new ArrayList<Integer>();
        while (right < s.length()) {
            window[s.charAt(right) - 'a']++;//每次右指针right滑动,字符串s的right位置的字符出现次数加1
            if (right - left + 1 == p.length()) {
                if (Arrays.equals(window, target)) ans.add(left);//通过Arrays.equals方法,当window数组与target数组相等即为异或词
                window[s.charAt(left) - 'a']--;//比较完成后,字符串s的left位置的字符出现次数减1(减1是因为左指针下一步要向右滑动)
                left++;//左指针向右滑动
            }
            right++;//右指针向右滑动
        }
        return ans;
    }

6.LeetCode 567 字符串的排列

在这里插入图片描述

这道题其实跟上一题有异曲同工之妙~🤣

  • 直接贴代码啦~ 思路在注释里~
class Solution {
    public boolean checkInclusion(String s1, String s2) {
        int n = s2.length();
        if (n < s1.length())
            return false; // 如果 s2 的长度小于 s1 的长度,直接返回 false,因为无法包含 s1 的排列

        int[] target = new int[26]; // 目标字符串 s1 的字符频率统计数组
        for (char c : s1.toCharArray()) {
            ++target[c - 'a']; // 统计 s1 中每个字符的出现次数
        }

        int l = 0, r = 0;
        int[] window = new int[26]; // 滑动窗口中的字符频率统计数组
        while (r < n) {
            ++window[s2.charAt(r) - 'a']; // 将 s2 中当前右边界字符加入窗口,并增加计数

            if (r - l + 1 == s1.length()) { // 当窗口大小等于 s1 的长度时进行判断
                if (Arrays.equals(target, window)) {
                    return true; // 如果窗口内的字符频率与 s1 相同,则找到了 s1 的一个排列,返回 true
                } else {
                    --window[s2.charAt(l) - 'a']; // 否则,移动左边界,将左边界字符移出窗口,并减少计数
                    ++l; // 左边界右移,缩小窗口
                }
            }
            ++r; // 右边界右移,扩大窗口
        }
        return false; // 扫描完整个字符串 s2 后没有找到 s1 的排列,返回 false
    }
}


7. LeetCode 和相同的二元子数组

在这里插入图片描述

  • 前缀和+哈希表法~

在这里插入图片描述

要找到全部的子数组和为goal,直觉上我们需要找到所有前缀和里的i和j

满足presum[j] - presum[i] == goal——但是这样找i和j需要遍历两次,是O(N2 )的。

故采取哈希表存储前面的所有presum[i] == presum[j] - goal的个数,答案累加即可。

因为只有0和1,所以本题前缀和其实也是统计1的个数。

public int numSubarraysWithSum(int[] nums, int goal) {
    int sum = 0;
    Map<Integer, Integer> cnt = new HashMap<Integer, Integer>();
    int ret = 0;
    
    for (int num : nums) {
        cnt.put(sum, cnt.getOrDefault(sum, 0) + 1); // 记录当前累积和 sum 的出现次数
        sum += num; // 更新累积和 sum
        
        // 统计以当前位置为结束位置,和为 sum - goal 的子数组个数
        ret += cnt.getOrDefault(sum - goal, 0);
    }
    
    return ret;
}
  • sum:累积和,表示从数组开始到当前位置的所有元素之和。对于数组 nums 中的每个元素 num,更新累积和 sum

  • cnt:HashMap,用于记录每个累积和出现的次数。

  • ret:最终的返回结果,表示和为 goal 的子数组的个数。

  • 在更新 sum 后,查看 cnt 中是否有 sum - goal 这个累积和的记录。如果有,则表示从之前某个位置到当前位置,存在一个子数组的和为 goal。累加这个值到 ret 中。

  • sum - goal —>pre[j] - goal ,即找到了pre[i]。 pre[j] - pre[i] = goal。


Eg.

假设输入数组 nums = [1, 0, 1, 0, 1]goal = 2

for (int num : nums) {
        cnt.put(sum, cnt.getOrDefault(sum, 0) + 1); // 记录当前累积和 sum 的出现次数
        sum += num; // 更新累积和 sum
        
        // 统计以当前位置为结束位置,和为 sum - goal 的子数组个数
        ret += cnt.getOrDefault(sum - goal, 0);
    }
  • 第一个元素 1

    • 更新 sum = 1
    • count 更新为 {0: 1, 1: 1},表示累积和为 01 各出现了 1 次。
    • 此时 sum - goal = -1,在 count 中没有 -1 的记录,所以不更新 result
  • 第二个元素 0

    • 更新 sum = 1
    • count 更新为 {0: 1, 1: 2},表示累积和为 0 出现了 1 次,累积和为 1 出现了 2 次。
    • 此时 sum - goal = -1,在 count 中没有 -1 的记录,所以不更新 result
  • 第三个元素 1

    • 更新 sum = 2
    • count 更新为 {0: 1, 1: 2, 2: 1},表示累积和为 0 出现了 1 次,累积和为 1 出现了 2 次,累积和为 2 出现了 1 次。
    • 此时 sum - goal = 0,在 count 中有 0 的记录,所以更新 result += 1,此时 result = 1
  • 第四个元素 0

    • 更新 sum = 2
    • count 更新为 {0: 1, 1: 2, 2: 2},表示累积和为 0 出现了 1 次,累积和为 1 出现了 2 次,累积和为 2 出现了 2 次。
    • 此时 sum - goal = 0,在 count 中有 0 的记录,所以更新 result += 1,此时 result = 2
  • 第五个元素 1

    • 更新 sum = 3
    • count 更新为 {0: 1, 1: 2, 2: 2, 3: 1},表示累积和为 0 出现了 1 次,累积和为 1 出现了 2 次,累积和为 2 出现了 2 次,累积和为 3 出现了 1 次。
    • 此时 sum - goal = 1,在 count 中有 1 的记录,所以更新 result += count[sum - goal],即 result += count[1] = 2,此时 result = 4
  1. 结果
    • 最终返回 result = 4,表示数组 nums 中和为 2 的子数组有 4 个,分别是 [1,0,1][1,0,1,0][0,1,0,1][1,0,1]

  • 滑动窗口~

在这里插入图片描述

class Solution {
    public int numSubarraysWithSum(int[] nums, int goal) {
        int n = nums.length;

        // left1与left2之间夹着的是很多个0
        int left1 = 0, left2 = 0, right = 0;
        int sum1 = 0, sum2 = 0;
        int res = 0;

        // 右边界
        while (right < n) {
            sum1 += nums[right];
            // sum1 要等于 goal+1
            while (left1 <= right && sum1 > goal) {
                sum1 -= nums[left1];
                left1++;
            }
            sum2 += nums[right];
            // sum2 要等于 goal
            while (left2 <= right && sum2 >= goal) {
                sum2 -= nums[left2];
                left2++;
            }
            // 其中的每个0都能算一种情况
            res += left2 - left1;
            // 右指针右移
            right++;
        }
        return res;
    }
}

在这里插入图片描述


更新于:

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

汇川H5U小型PLC不用写程序测试EC总线电机

目录 新建工程添加EtherCAT组态添加运动控制轴仿真测试 新建工程 新建一个H5U工程&#xff0c;不使用临时工程 系列选择H5U即可 添加EtherCAT组态 这里在EC总线中添加了一个汇川660的伺服 驱动参数使用默认 添加运动控制轴 新建一个轴Axis_0 将新建的轴和EC组态的660驱动…

springboot中国女篮资讯平台-计算机毕业设计源码12641

目录 1 绪论 1.1 研究背景 1.2 研究现状 1.3论文结构与章节安排 2平台分析 2.1 系统可行性分析 2.1.1硬件可行性分析 2.1.2软件可行性分析 2.1.3经济可行性 2.1.4 操作可行性 2.2系统功能分析 2.3 系统用例分析 2.4本章小结 3平台总体设计 3.1 系统架构设计 3.2…

录屏怎么有声音?录屏声音,2个小技巧

在数字化浪潮中&#xff0c;录屏早已不再是简单的屏幕录制&#xff0c;而是成为了内容创作、教学分享、游戏直播等领域的重要工具。然而&#xff0c;很多人在录屏时常常面临一个问题&#xff1a;录制好的视频没有声音。面对这个难题&#xff0c;录屏怎么有声音&#xff1f;怎样…

Oracle 解决4031错误

一、问题描述 什么是4031错误和4031错误产生的原因: 简单一个句话概括: 由于服务器一直在执行大量的硬解析,导致Oracle 的shared pool Free空间碎片过多,大的chunk不足, 当又一条复杂的sql语句要硬解析时, 缺少1个足够大的Free chunk, 通常就会报4031错误. 二、解决方法 临…

智能合约与企业数字化转型:案例分析与未来展望

随着区块链技术的快速发展&#xff0c;智能合约作为其重要应用之一&#xff0c;正逐渐成为推动企业数字化转型的关键工具。智能合约不仅可以自动执行和验证合同&#xff0c;还能够增强数据安全性、优化业务流程&#xff0c;并提升企业间的信任和透明度。本文将深入探讨智能合约…

PostgreSQL数据库通过索引优化查询

文章目录 1.使用EXPLAIN分析查询计划1.1 Seq Scan&#xff1a;全表顺序扫描&#xff0c; 表示数据库将按顺序扫描整个表&#xff0c;适用于小表或无索引的情况。1.2 Index Scan&#xff1a; 基于索引扫描&#xff0c;但不只是返回索引列的值。1.3 IndexOnly Scan&#xff1a;基…

MySQL数据库-Windows部署MySQL环境

Windows部署MySQL环境​​​​​​ 一、下载mysql数据库 进入MySQL官方网站&#xff08;MySQL :: MySQL DownloadsMySQL&#xff09;&#xff0c;随后按如下红框方式操作&#xff1a; ​ ​ ​ ​ 这里选择的是离线安装&#xff0c;第一个是在线安装 下载好安装包后开始…

昇思25天学习打卡营第十二天|Diffusion扩散模型

背景 提供免费算力支持&#xff0c;有交流群有值班教师答疑的华为昇思训练营进入第十二天了。 今天是第十二天&#xff0c;从第十天开始&#xff0c;进入了应用实战阶段&#xff0c;前九天都是基础入门阶段&#xff0c;具体的学习内容可以看链接 基础学习部分 昇思25天学习打卡…

使用 OpenCV 和 Python 进行车道检测和物体检测(YOLO)

本项目旨在开发一个集车道检测与物体检测功能于一体的智能视觉分析系统&#xff0c;利用先进的计算机视觉技术和深度学习模型&#xff0c;实现实时的道路场景理解和目标识别。系统主要依托OpenCV这一强大的计算机视觉库&#xff0c;以及Python作为编程语言&#xff0c;融合了车…

【笔试记录】腾讯音乐 | 20230903 | cpp (更新ing)

1 完美数 1.1 题目描述 小红定义一个数为“完美数”&#xff0c;当且仅当该数仅有一个非零数字。例如 5000, 4, 1, 10, 200 都是完美数。 小红拿到了一个大小为 n&#xff08;2 < n < 2000&#xff09;的数组 a&#xff0c;她希望选择数组中的两个元素&#xff08;1 …

KEYSIGHT N1092系列,DCA-M系列采样示波器连接与自检?

KEYSIGHT N1092系列 采样示波器&#xff0c;虽然省去了屏幕和操作系统&#xff0c;但根据不同的型号&#xff0c;可以配备不同数量的光口和电口&#xff0c;满足各种测试需求。本次介绍的具体型号为N1092D&#xff0c;它拥有4个光口&#xff0c;能够进行多种测试。 测试步骤详解…

14-26 剑和侠客 – 预训练模型三部曲3 – 机器人时代来临

概述 在第 1 部分和第 2 部分中&#xff0c;我们讨论了适用于文本和图像任务的预训练模型&#xff0c;并探索了当今常用的模型。我们分析了这些模型的架构以及如何将它们用于特定任务。实现 AGI 所需的两个主要支柱是语言理解和机器的视觉能力。有许多任务与这两种能力有关。 …

日本最新型高达式巨型机器人承担铁路维护任务

日本有制造现实生活中的高达式巨型机器人的历史&#xff0c;但它们往往是用于娱乐目的&#xff0c;而不是实际应用。不过&#xff0c;日本刚刚开始使用一个 40 英尺高的人形机器人来维护铁路线。 大约两年前&#xff0c;西日本铁路公司&#xff08;JR 西日本&#xff09;制造了…

长难句打卡6.26

Too often we believe that a new job, bigger house or better car will be the magic silver bullet that will allow us to finally be content, but the reality is these things have very little lasting impact on our happiness levels. magic silver bullet 灵丹妙药 …

(三)共享模型之管程

线程安全问题 案例 两个线程对初始值为 0 的静态变量一个做自增&#xff0c;一个做自减&#xff0c;各做 5000 次&#xff0c;结果是 0 吗&#xff1f; Slf4j(topic "c.ThreadSafe") public class ThreadSafe {public static int counter 0;public static void …

NFT音乐版权系统的技术难点

NFT音乐版权系统是指利用区块链技术和NFT技术来管理和交易音乐版权的系统。该系统涉及多项技术&#xff0c;其开发和应用存在以下技术难点。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发公司&#xff0c;欢迎交流合作。 1. 音乐作品的数字版权确权 音乐作品的数字…

《向量数据库指南》——Milvus Cloud查询增强如何提升 RAG Pipeline 效果?

查询增强 1.假设性问题 这一方法首先使用LLM为每一条文档块生成一些假设问题,这些文档块可以回答与之对应的假设问题。在RAG阶段,进行一个query-to-query的搜索,先搜索到相关的假设问题,然后找到对应的文档块,再通过它们生成最后的回答。 这里的query-to-query指的是embed…

7月开强化,考研数学保底110分真的很难吗?

七月开始强化是正常时间 不要因为进度而感到焦虑&#xff0c;因为进度是很主观的因素&#xff0c;无法衡量学习效果&#xff01;所以&#xff0c;不要和比人比进度&#xff0c;也不要赶进度&#xff0c;一步一个脚印&#xff0c;踏踏实实的学习才是王道&#xff01; 虽然我不…

MicroCap声学仿真介绍(一)

MicroCap是一款基于电路分析的仿真软件&#xff0c;基于集总参数的电力声的转换&#xff0c;我们可以用这个软件完成常用的声学仿真工作。目前这个软件已经开源了&#xff0c;免费使用&#xff0c;最新版已经到MC12&#xff0c;但里面不自带声学库&#xff0c;后来找到了MC8&am…

react v18 less使用(craco)

方案一、弹出配置&#xff08;不推荐&#xff09; 安装依赖&#xff1a;yarn add less less-loader 首先 执行 yarn eject 弹出配置项文件&#xff08;注意&#xff1a;弹出配置不可逆&#xff01;&#xff09; 在 config 文件夹中 找到 webpack.config.js&#xff0c;在如图…