当前位置: 首页 > news >正文

力扣(leetcode)题目总结——辅助栈篇

leetcode 经典题分类

  • 链表
  • 数组
  • 字符串
  • 哈希表
  • 二分法
  • 双指针
  • 滑动窗口
  • 递归/回溯
  • 动态规划
  • 二叉树
  • 辅助栈

本系列专栏:点击进入 leetcode题目分类 关注走一波


前言:本系列文章初衷是为了按类别整理出力扣(leetcode)最经典题目,一共100多道题,每道题都给出了非常详细的解题思路算法步骤代码实现。很多同学刚开始刷题都是按照力扣顺序刷题,其实这样对新手不太适用,刷题效果也很不好。因为力扣题目顺序是随机的,并没有按照算法分类,导致同一类型的算法强化训练不够,最后刷完也是迷迷糊糊的。所以本系列文章就是来帮你完成算法分类,针对每种算法做强化训练,保证让你以后遇到题目直接秒杀!

文章目录

  • leetcode 经典题分类
    • 有效的括号
    • 最长有效括号
    • 接雨水
    • 柱状图中最大的矩形


有效的括号

【题目描述】

给定一个只包括 ‘(’,‘)’,‘{’,‘}’,‘[’,‘]’ 的字符串s,判断字符串是否有效。

有效字符串需满足:

  • 左括号必须用相同类型的右括号闭合;

  • 左括号必须以正确的顺序闭合;

  • 每个右括号都有一个对应的相同类型的左括号。

【输入输出实例】

示例 1:

输入:s = “()”
输出:true

示例 2:

输入:s = “()[]{}”
输出:true

示例 3:

输入:s = “(]”
输出:false

【算法思路】

先来分析一下,这里有三种不匹配的情况:

  • 字符串里左方向的括号多余了,所以不匹配;

  • 括号没有多余,但是括号的类型没有匹配上;

  • 字符串里右方向的括号多余了,所以不匹配;

针对三种不匹配情况的代码:

  • 第一种情况:已经遍历完了字符串,但是栈不为空,说明有相应的左括号没有右括号来匹配,所以return false;

  • 第二种情况:遍历字符串匹配的过程中,发现栈里没有要匹配的字符,所以return false;

  • 第三种情况:遍历字符串匹配的过程中,栈已为空,没有匹配的括号,说明右括号没有找到对应的左括号,所以return false。

匹配成功的情况:

​ 字符串遍历完之后,栈是空的,就说明全都匹配了。

技巧:

在遇到左括号时,不要让左括号本身入栈,而让相应的右括号入栈。则在遇到右括号匹配时,就只需要比较当前右括号和栈顶元素相不相等就可以了,比左括号入栈代码实现更简单。

【算法描述】

//括号匹配是使用辅助栈解决
bool isValid(string s)
{stack<char> sta;    //辅助栈for(char ch : s)     //遍历给定的括号字符串{switch(ch){//技巧:遇到左括号就入栈其对应的右括号case '(':sta.push(')');break;case '[':sta.push(']');break;case '{':sta.push('}');break;default:     //遇到右括号就检查是否匹配,检查本身与栈顶元素是否一样if(sta.empty() || sta.top() != ch)    //栈为空 或 本身与栈顶元素不一样,都说明括号不匹配{return false;}sta.pop();    //若一样,则出栈}}return sta.empty();    //最后若有未出栈的元素说明,有不匹配的项
}

最长有效括号

【题目描述】

给你一个只包含 ‘(’ 和 ‘)’ 的字符串,找出最长有效(格式正确且连续)括号子串的长度。

【输入输出实例】

示例 1:

输入:s = “(()”
输出:2

示例 2:

输入:s = “)()())”
输出:4

示例 3:

输入:s = “()(()”
输出:2

示例 4:

输入:s = “”
输出:0

【算法思路】

创建一个大小为len的容器来表示各个括号的是否可匹配。用栈模拟一遍括号匹配,将所有无法匹配的括号的位置全部置1。例如:"()(()“对应为[0, 0, 1, 0, 0];再例如:”)()((())"的对应为[1, 0, 0, 1, 0, 0, 0, 0]。

经过这样的处理后,此题就变成了寻找最长的连续0的长度

【算法描述】

int longestValidParentheses(string s) 
{int len = s.size();vector<int> v(len);  //用来表示该位置的括号是否可匹配:无法匹配的括号的位置全部置1stack<int> stk;  //栈内存放括号下标int maxLong = 0;  //记录括号匹配的最大长度for(int i = 0; i < len; i++){if(s[i] == '(')  //遇到左括号就入栈{stk.push(i);}else  //遇到右括号就判断{if(stk.empty())  //多余的右括号是不需要的,标记1{v[i] = 1;}else  //匹配成功{stk.pop();}}}while(!stk.empty())  //未匹配的左括号是不需要的,标记1{v[stk.top()] = 1;stk.pop();}// 寻找标记与标记之间的最大长度,即找最长的连续的0的长度int num = 0;for(int i = 0; i < len; i++){if(v[i] == 0){num++;}else{maxLong = max(maxLong, num);num = 0;}}maxLong = max(maxLong, num);  return maxLong;
}

接雨水

【题目描述】

给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。

【输入输出实例】

示例 1:

在这里插入图片描述

输入:height = [0,1,0,2,1,0,1,3,2,1,2,1]
输出:6

示例 2:

输入:height = [4,2,0,3,2,5]
输出:9

【算法思路】

首先,要知道单调栈是按照行方向来计算雨水,如图:

单调栈内元素的顺序:从栈头到栈底的顺序应该是从小到大的顺序。因为一旦发现要添加的柱子高度大于栈顶元素,此时就出现凹槽了,栈头元素就是凹槽底部的柱子,栈头第二个元素就是凹槽左边的柱子,而添加的元素就是凹槽右边的柱子。如图:

因为长就是通过柱子的高度来计算,宽是通过柱子之间的下标来计算,通过长*宽来计算雨水面积,所以栈中应该存放下标,计算的时候用下标对应的柱子高度即可。

算法过程就是:用单调栈不断入栈每个柱子对应的下标,当要入栈的柱子高度大于栈顶元素时,要先将元素出栈保留,即为凹槽的底部bottom。此时的栈顶元素为凹槽左边的柱子left,要入栈的柱子为凹槽右边的柱子right。则可算出这个凹槽中盛放水的高度:

rainHeight = min(height[left], height[right]) - height[temp];

宽度为:rainWidth = right - left - 1;

则可算出该凹槽中盛放水的体积,根据上述操作遍历(不断入栈出栈)完每根柱子,将得到的雨水量相加起来即可。

【算法描述】

//双指针法(超时)
int trap(vector<int>& height) 
{int len = height.size();  int sum = 0;  //记录接的雨水for(int i = 1; i < len - 1; i++)  //遍历每列(除第一列和最后一列,因为它们不会接雨水){int maxLeft = 0;  //左边最高柱子的高度int maxRight = 0;  //右边最高柱子的高度for(int left = i - 1; left >= 0; left--)  //找左边最高柱子{maxLeft = max(maxLeft, height[left]);}for(int right = i + 1; right < len; right++)  //找右边最高柱子{maxRight = max(maxRight, height[right]);if(maxRight > maxLeft)  //因为最后要取两者最小,所以只要超过左边最高柱子,直接退出{break;}}int rainHeight = min(maxLeft, maxRight) - height[i];  //计算雨水高度sum += (rainHeight > 0) ? rainHeight : 0;}return sum;
}//动态规划——相当于双指针法,只是用动态规划来提前求出每个柱子的最大左边柱子和最大右边柱子
int trap(vector<int>& height) 
{int len = height.size();  int sum = 0;  //记录接的雨水vector<int> maxLeft(len);  //记录第i列左边柱子最大高度vector<int> maxRight(len);  //记录第i列右边柱子最大高度maxLeft[0] = height[0];  //初始化maxRight[len-1] = height[len-1];//记录每个柱子左边柱子最大高度for(int i = 1; i < len-1; i++){maxLeft[i] = max(maxLeft[i-1], height[i]);}//记录每个柱子右边柱子最大高度for(int i = len-2; i > 0; i--){maxRight[i] = max(maxRight[i+1], height[i]);}//遍历每列算雨水量再求和for(int i = 1; i < len - 1; i++){int rainHeight = min(maxLeft[i-1], maxRight[i+1]) - height[i];sum += (rainHeight > 0) ? rainHeight : 0;}return sum;
}//单调栈
int trap(vector<int>& height) 
{int sum = 0;  //记录接的雨水stack<int> s;  //单调栈s.push(0);for(int i = 1; i < height.size(); i++){//如果栈不空并且当前指向的高度大于栈顶高度就一直循环while(!s.empty() && height[i] > height[s.top()]){int temp = height[s.top()]; //取出要出栈的元素s.pop();  //出栈if(!s.empty()) //出栈一个后如果栈不为空,就开始算雨水{int rainHeight = min(height[i], height[s.top()]) - temp;  //计算雨水高度:-temp相当于是减去i和s.top()两列构成容器的底部柱子的高度int rainWidth = i - s.top() - 1;  //雨水宽度sum += rainHeight * rainWidth;  //雨水量}}s.push(i);  //每根柱子要入栈}return sum;
}

柱状图中最大的矩形

【题目描述】

给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为1。

求在该柱状图中,能够勾勒出来的矩形的最大面积。

【输入输出实例】

示例 1:

在这里插入图片描述

输入:heights = [2,1,5,6,2,3]
输出:10

示例 2:

在这里插入图片描述

输入:heights = [2,4]
输出:4

【算法思路】

本题目与42、接雨水非常相似,也是有三种方法,如下:

(1)双指针法和动态规划

接雨水是找每列中左侧最高的柱子和右侧最高的柱子。找到后该列的雨水高度可得到,宽度为1,就可得到该列的雨水量,再把每列的雨水累加起来即可;

本题是找每个柱子左右两侧最后一个大于等于该柱子高度的柱子。找到后勾勒出来的矩形的宽度为左右两侧这两列的下标差,高度就是本列柱子的高度,则可计算出本列勾勒出来最大矩形的面积,再把每列勾勒出来的矩形面积求出来,再找最大。

(2)单调栈

接雨水是找每个柱子左右两边第一个大于该柱子高度的柱子,而本题是找每个柱子左右两边第一个小于该柱子的柱子。所以从栈头到栈底的顺序应该是从大到小的顺序。

在这里插入图片描述

如上图,可知只有栈里从大到小的顺序,才能保证栈顶元素找到左右两边第一个小于栈顶元素的柱子。

其实就是栈顶和栈顶的下一个元素以及要入栈的三个元素组成了我们要求最大面积的高度和宽度。其中栈顶元素为矩形高度,栈顶的下一个元素以及要入栈的元素的下标构成了矩阵的宽度。

其实可以把这个过程想象成锯木板,如果木板都是递增的那我很开心不用管。如果突然遇到一块木板 i 矮了一截,那我就先找之前最戳出来的一块(其实就是第 i-1 块),计算一下这个木板单独的面积,然后把它锯成次高的,这是因为我之后的计算都再也用不着这块木板本身的高度了。再然后如果发现次高的仍然比现在这个 i 木板高,那我继续单独计算这个次高木板的面积(应该是第 i-1 和 i-2 块组成的木板),再把它俩锯短。直到发现不需要锯就比第 i 块矮了,那我继续开开心心往右找更高的。当然为了避免到了最后一直都是递增的,所以可以在最后加一块高度为0的木板。

这个算法的关键点是把那些戳出来的木板早点单独拎出来计算,然后就用不着这个值了。

【算法描述】

//双指针法——超时
int largestRectangleArea(vector<int>& heights) {int n = heights.size();int maxArea = 0;  //记录矩形的最大面积for(int i = 0; i < n; i++)  //遍历每根柱子{int left = i - 1;int right = i + 1;//找左边最后一个大于等于heights[i]的下标for(; left >= 0; left--){if(heights[left] < heights[i]){break;}}//找右边最后一个大于等于heights[i]的下标for(; right < n; right++){if(heights[right] < heights[i]){break;}}int height = heights[i];  //矩形高度int width = right - left - 1;  //矩形宽度maxArea = max(maxArea, height*width);  //计算最大面积}return maxArea;
}//动态规划
int largestRectangleArea(vector<int>& heights) 
{int n = heights.size();int maxArea = 0;   //记录矩形的最大面积vector<int> left(n);vector<int> right(n);left[0] = -1;    //初始化right[n-1] = n;//记录每个柱子左边第一个高度小于该柱子的下标for(int i = 1; i < n; i++){int index = i - 1;while(index >= 0 && heights[i] <= heights[index]){index = left[index];   //动态规划更新,上一次已经求过,不用重复求}left[i] = index;}//记录每个柱子右边第一个高度小于该柱子的下标for(int i = n - 2; i >= 0; i--){int index = i + 1;while(index < n && heights[i] <= heights[index]){index = right[index];  //动态规划更新,上一次已经求过,不用重复求}right[i] = index;}//计算矩形的最大面积for(int i = 0; i < n; i++){int height = heights[i];  //矩形高度int width = right[i] - left[i] - 1;   //矩形宽度maxArea = max(maxArea, height*width);   //计算最大面积}return maxArea;
}//单调栈
int largestRectangleArea(vector<int>& heights) {heights.insert(heights.begin(), 0);   //数组头部加入元素0heights.push_back(0);   //数组尾部加入元素0int maxArea = 0;   //记录矩形的最大面积stack<int> s;   //单调栈(递减)s.push(0);for(int i = 1; i < heights.size(); i++)  //遍历各柱子{while(heights[i] < heights[s.top()]){int height = heights[s.top()];   //矩形高度//int width = i - s.top();  //这时得到的矩形宽度没有把之前出栈的柱子宽度算上,因为之前出栈的柱子高度肯定大于它后面的柱子高度,所以才被出栈,那么要把前面已出栈的柱子宽度也要算上s.pop();int width = i - s.top() - 1;   //矩形宽度:把前面已出栈的宽度也要算上            maxArea = max(maxArea, height*width);  //计算最大面积}s.push(i);}return maxArea;
}

恭喜你全部读完啦!古人云:温故而知新。赶紧收藏关注起来,用之前再翻一翻吧~


📣推荐阅读

C/C++后端开发面试总结:点击进入 后端开发面经 关注走一波

C++重点知识:点击进入 C++重点知识 关注走一波

力扣(leetcode)题目分类:点击进入 leetcode题目分类 关注走一波

相关文章:

力扣(leetcode)题目总结——辅助栈篇

leetcode 经典题分类 链表数组字符串哈希表二分法双指针滑动窗口递归/回溯动态规划二叉树辅助栈 本系列专栏&#xff1a;点击进入 leetcode题目分类 关注走一波 前言&#xff1a;本系列文章初衷是为了按类别整理出力扣&#xff08;leetcode&#xff09;最经典题目&#xff0c…...

如何处理 iOS 客户端内 Webview H5 中后台播放的音视频问题

目录 问题描述Page Visibility API 的应用什么是 Page Visibility API&#xff1f;使用 Page Visibility API 暂停音视频完整解决方案1. 监听媒体的播放和暂停事件2. 防止自动播放3. 结合 Intersection Observer 进行媒体控制4. 手动处理应用生命周期中的事件 问题描述 在 iOS…...

C++的一些模版

1、不限制次数的输入数据 vector<int> nums;int num;while (cin >> num) {nums.push_back(num);if (cin.get() \n) break;}2、取模模版 template<int kcz> struct ModInt { #define T (*this)int x;ModInt() : x(0) {}ModInt(int y) : x(y > 0 ? y : y…...

spring boot整合https协议

整体目录 1. 生成SSL证书 首先&#xff0c;使用keytool生成一个自签名证书。打开命令行工具并运行以下命令&#xff1a; keytool -genkeypair -alias myserver -keyalg RSA -keysize 2048 -keystore keystore.jks -validity 365 这将创建一个名为keystore.jks的文件&#xf…...

服务器开机即占用大量内存,解决

1.服务器开机两分钟不到&#xff0c;内存使用飙升 [rootlocalhost ~]# top #查看是否有了明显的内存占用程序 2.上述未果&#xff0c;查看是否有违规的开机自启项 [rootlocalhost ~]# chkconfig --list 3.上述无果&#xff0c;查看开启启动加载项内容 上网搜后&#xff…...

Keil uvision的edition

0 Preface/Foreword 0.1 参考网址 https://zhuanlan.zhihu.com/p/456069876 1 Keil版本介绍 版本介绍&#xff1a; Keil Lite&#xff08;免费版&#xff09;&#xff1a;最多32KB代码&#xff0c;无法使用中间件Keil Essential&#xff08;基础版&#xff09;&#xff1a;没…...

[每周一更]-(第123期):模拟面试|消息队列面试思路解析

文章目录 22|消息队列:消息队列可以用来解决什么问题?1. 你用过消息队列吗?主要用来解决什么问题?异步、削峰和解耦你能各举一个例子吗?2. 你用的是哪个消息队列?为什么使用它而不用别的消息队列?3. 为什么你一定要用消息队列?不用行不行?不用有什么缺点?4. 在对接多…...

游戏引擎学习第12天

视频参考:https://www.bilibili.com/video/BV1yom9YnEWY 这节没讲什么东西&#xff0c;主要是改了一下音频的代码 后面有介绍一些alloc 和malloc,VirtualAlloc 的东西 _alloca 函数&#xff08;或 alloca&#xff09;分配的是栈内存&#xff0c;它的特点是&#xff1a; 生命周…...

深入理解Flutter生命周期函数之StatefulWidget(一)

目录 前言 1.为什么需要生命周期函数 2.开发过程中常用的生命周期函数 1.initState() 2.didChangeDependencies() 3.build() 4.didUpdateWidget() 5.setState() 6.deactivate() 7.dispose() 3.Flutter生命周期总结 1.调用顺序 2.函数调用时机以及主要作用 4.生…...

413: Quick Sort

解法&#xff1a; #include <bits/stdc.h> using namespace std; const int N1e55; int a[N]; int n;int main(int argc, char** argv) {cin>>n;for (int i0;i<n;i) cin>>a[i];sort(a,an);for (int i0;i<n;i) cout<<a[i]<<" "…...

vue之axios根据某个接口创建实例,并设置headers和超时时间,捕捉异常

import axiosNew from axios;//给axios起个别名//创建常量实例 const instanceNew axiosNew.create({//axios中请求配置有baseURL选项&#xff0c;表示请求URL的公共部分&#xff0c;url baseUrl requestUrlbaseURL: baseURL,//设置超时时间为20秒timeout: 20000,headers: {…...

Pandas数据透视表:交叉分析与聚合计算

大家好&#xff0c;在数据分析中&#xff0c;数据透视表&#xff08;Pivot Table&#xff09;是一种强大的工具&#xff0c;用于交叉分析和聚合计算。Pandas库中的数据透视表功能&#xff0c;使我们能够在多维数据中快速生成汇总表、统计特定维度的聚合数据&#xff0c;帮助揭示…...

软件设计师考试大纲

文章目录 一 、考 试 说 明1. 考试目标2. 考试要求3. 考试科目设置 二、考 试 范 围考试科目1:计算机与软件工程知识1. 计算机系统基础知识1.1计算机内数据的表示及运算1.2 其他数学基础知识1.3 计算机硬件基础知识1.3.1 计算机系统的组成、体系结构分类及特性1.3.2 存储系统1.…...

一文说清C++类型转换操作符(cast operator)

一 前言 大家在编程时&#xff0c;一定会遇到要做类型转换的应用场景。 但是&#xff0c;C风格的类型转换太强大&#xff0c;太危险&#xff0c;它允许将一个给定类型转换成我们想要的任何其他类型。 所以在C中&#xff0c;提供了一些更安全和更明确的类型转换操作符&#xff…...

MOSFET电路栅源极GS之间并联电容后,MOS炸管原因分析

1、前言 在介绍&#xff0c;在进行MOSFET相关的电路设计时&#xff0c;可能会遇到MOSFET误导通的问题&#xff0c;为了解决此问题&#xff0c;我们提出了两种方法&#xff0c;一种是增大MOSFET栅极串联电阻的阻值&#xff0c;另外一种是在MOSFET栅-源极之间并联一个电容&#…...

gitHub常用操作

gitHub常用操作 1、把项目拉下来2、添加上游仓库3、进入分支4、从上游仓库拉取更新 1、把项目拉下来 在对应项目的右上角点击fork&#xff0c;fork下来&#xff1a;将远程仓库复制到个人仓库 在创建好的分支文件夹下使用 git clone自己远程仓库下的http地址&#xff08;fork…...

[项目代码] YOLOv5 铁路工人安全帽安全背心识别 [目标检测]

YOLOv5是一种单阶段&#xff08;one-stage&#xff09;检测算法&#xff0c;它将目标检测问题转化为一个回归问题&#xff0c;能够在一次前向传播过程中同时完成目标的分类和定位任务。相较于两阶段检测算法&#xff08;如Faster R-CNN&#xff09;&#xff0c;YOLOv5具有更高的…...

Java 垃圾回收机制(GC)概览

简介 Java垃圾收集、堆和运行时编译器默认选择 jdk1.9开始&#xff0c;默认使用G1收集器&#xff0c;GC Threads的最大数量受堆大小和可用CPU资源限制初始堆大小为物理内存的1/64最大堆大小为物理内存的1/4分层编译器&#xff0c;同时使用C1和C2 JVM 垃圾收集器可以为配置优…...

Kafka节点服役和退役

1 服役新节点 1&#xff09;新节点准备 &#xff08;1&#xff09;关闭 bigdata03&#xff0c;进行一个快照&#xff0c;并右键执行克隆操作。 &#xff08;2&#xff09;开启 bigdata04&#xff0c;并修改 IP 地址。 vi /etc/sysconfig/network-scripts/ifcfg-ens33修改完…...

Git如何简单使用

文章目录 GitGitlabGitLab和GitHub有什么区别?Gitlab简单使用Gitlab常用指令Git Git是一个分布式版本控制系统。 它用于记录文件的修改历史,方便多人协作开发软件等项目。例如一个软件开发团队,成员们会频繁修改代码,Git可以追踪每个人的修改内容、时间等信息。 主要功能…...

使用VSCode开发Django指南

使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架&#xff0c;专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用&#xff0c;其中包含三个使用通用基本模板的页面。在此…...

【杂谈】-递归进化:人工智能的自我改进与监管挑战

递归进化&#xff1a;人工智能的自我改进与监管挑战 文章目录 递归进化&#xff1a;人工智能的自我改进与监管挑战1、自我改进型人工智能的崛起2、人工智能如何挑战人类监管&#xff1f;3、确保人工智能受控的策略4、人类在人工智能发展中的角色5、平衡自主性与控制力6、总结与…...

大型活动交通拥堵治理的视觉算法应用

大型活动下智慧交通的视觉分析应用 一、背景与挑战 大型活动&#xff08;如演唱会、马拉松赛事、高考中考等&#xff09;期间&#xff0c;城市交通面临瞬时人流车流激增、传统摄像头模糊、交通拥堵识别滞后等问题。以演唱会为例&#xff0c;暖城商圈曾因观众集中离场导致周边…...

Frozen-Flask :将 Flask 应用“冻结”为静态文件

Frozen-Flask 是一个用于将 Flask 应用“冻结”为静态文件的 Python 扩展。它的核心用途是&#xff1a;将一个 Flask Web 应用生成成纯静态 HTML 文件&#xff0c;从而可以部署到静态网站托管服务上&#xff0c;如 GitHub Pages、Netlify 或任何支持静态文件的网站服务器。 &am…...

UR 协作机器人「三剑客」:精密轻量担当(UR7e)、全能协作主力(UR12e)、重型任务专家(UR15)

UR协作机器人正以其卓越性能在现代制造业自动化中扮演重要角色。UR7e、UR12e和UR15通过创新技术和精准设计满足了不同行业的多样化需求。其中&#xff0c;UR15以其速度、精度及人工智能准备能力成为自动化领域的重要突破。UR7e和UR12e则在负载规格和市场定位上不断优化&#xf…...

在WSL2的Ubuntu镜像中安装Docker

Docker官网链接: https://docs.docker.com/engine/install/ubuntu/ 1、运行以下命令卸载所有冲突的软件包&#xff1a; for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done2、设置Docker…...

【笔记】WSL 中 Rust 安装与测试完整记录

#工作记录 WSL 中 Rust 安装与测试完整记录 1. 运行环境 系统&#xff1a;Ubuntu 24.04 LTS (WSL2)架构&#xff1a;x86_64 (GNU/Linux)Rust 版本&#xff1a;rustc 1.87.0 (2025-05-09)Cargo 版本&#xff1a;cargo 1.87.0 (2025-05-06) 2. 安装 Rust 2.1 使用 Rust 官方安…...

Webpack性能优化:构建速度与体积优化策略

一、构建速度优化 1、​​升级Webpack和Node.js​​ ​​优化效果​​&#xff1a;Webpack 4比Webpack 3构建时间降低60%-98%。​​原因​​&#xff1a; V8引擎优化&#xff08;for of替代forEach、Map/Set替代Object&#xff09;。默认使用更快的md4哈希算法。AST直接从Loa…...

Redis:现代应用开发的高效内存数据存储利器

一、Redis的起源与发展 Redis最初由意大利程序员Salvatore Sanfilippo在2009年开发&#xff0c;其初衷是为了满足他自己的一个项目需求&#xff0c;即需要一个高性能的键值存储系统来解决传统数据库在高并发场景下的性能瓶颈。随着项目的开源&#xff0c;Redis凭借其简单易用、…...

Qemu arm操作系统开发环境

使用qemu虚拟arm硬件比较合适。 步骤如下&#xff1a; 安装qemu apt install qemu-system安装aarch64-none-elf-gcc 需要手动下载&#xff0c;下载地址&#xff1a;https://developer.arm.com/-/media/Files/downloads/gnu/13.2.rel1/binrel/arm-gnu-toolchain-13.2.rel1-x…...