自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(429)
  • 收藏
  • 关注

原创 Leetcode 149 多数元素 | 买卖股票的最佳时机

今天有点小累,来两道easy题打卡吧,明天接着动态规划。

2026-03-30 00:00:40 13

原创 Leetcode 148 最长递增子序列 | 三角形最小路径和

dp [i] = 以 nums [i] 这个数字结尾的最长递增子序列长度必须以第 i 个数结尾!

2026-03-28 15:36:07 239

原创 Lexical依赖版本冲突与标题渲染

修复了因 Lexical 依赖版本冲突导致的 PDF/Doc 导出崩溃问题,以及文档标题更新后的 UI 同步问题。总结依赖管理、错误定位及 Hook 与工具函数选型的经验。

2026-03-28 13:52:11 754

原创 Leetcode 147 零钱兑换 | 单词拆分

i++ ){

2026-03-26 21:45:25 414

原创 万字长文:从零实现 JWT 鉴权

本文系统回顾JWT鉴权实现,详解Express中间件校验、MongoDB用户模型设计,覆盖前后端交互、状态管理与安全实践,完整呈现一套可落地的身份认证方案。

2026-03-26 16:34:03 568

原创 Leetcode 146 爬楼梯 | 打家劫舍

把大问题拆成小问题 → 找到小问题的规律(递推公式)→ 用小问题的答案算出大问题的答案它的核心就是不重复计算,把之前算过的结果存起来,直接用。爬楼梯本质就是斐波那契数列动态规划三步:定义dp[i]写递推公式初始化 + 循环计算代码优先用优化迭代版,效率最高dp[i]= 偷到第 i 间房子时,能偷到的最大金额偷 = 前前一个 + 当前钱不偷 = 前一个的钱选最大的那个!dp [i] = 到第 i 个位置时的答案永远只有2 种选择(99% 的题)

2026-03-25 23:57:52 444

原创 Leetcode 145 回文数 | 加一

给你一个整数x,如果x是一个回文整数,返回true;否则,返回false。回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。121123x = 121truex = -121false从左向右读, 为 -121。从右向左读, 为 121-。因此它不是一个回文数。x = 10false从右向左读, 为 01。因此它不是一个回文数。你能不将整数转为字符串来解决这个问题吗?

2026-03-24 23:45:08 469

原创 AJAX vs Fetch API:Promise 与异步 JavaScript 怎么用?

从 AJAX 到 Fetch,详解 Promise 用法、链式调用与 async/await,掌握现代 JS 异步编程。

2026-03-24 12:02:42 533

原创 Leetcode 144 位1的个数 | 只出现一次的数字

核心思路:遍历 32 位整数的每一位,用1 << i定位第i位,再用运算判断该位是否为 1,统计总数。位运算关键1 << i生成 “掩码”,n & 掩码仅保留第i位的数值,非 0 则说明该位是 1。边界处理:循环固定 32 次,确保覆盖 32 位整数的所有位(包括最高位的符号位)。

2026-03-22 23:51:13 381

原创 万字长文:编辑器集成Vercel AI SDK

本文复盘块级编辑器集成AI SDK全过程,涵盖前端UI插槽注入、后端工具调用、ID约束守卫及流式协议对接等核心机制与问题解决方案。

2026-03-22 20:49:16 595

原创 Leetcode 143 搜索插入位置 | 搜索二维矩阵

这道题的核心是二分查找,必须保证时间复杂度 O (log n),因此不能用遍历(遍历的时间复杂度是 O (n))。二分查找的关键:正确计算mid避免溢出,通过调整leftright缩小查找范围,循环结束后left就是插入位置。无需单独处理 “数组为空”“目标值在开头 / 结尾” 的边界情况,核心逻辑已覆盖所有场景(比如target比所有元素大时,left最终等于数组长度,正好是插入末尾的位置)。核心错误。

2026-03-21 12:36:24 348

原创 高并发下的列表乱序与文档同步

删除一个看似多余的useEffect,不仅修复了高并发下的列表乱序,也让我重新思考了全栈开发中那些“简单粗暴”的实现与后续优化空间。

2026-03-20 11:38:02 1021

原创 Leetcode 142 将有序数组转换为二叉搜索树 | 排序链表

核心逻辑:利用升序数组的中点作为根节点,递归构建左右子树,既满足 BST 的中序遍历特性,又保证平衡(左右子树高度差≤1)。关键细节:选择中点时用避免溢出,递归终止条件是区间无元素(l > r)。灵活性:中点也可选择(右中点),最终结果不同但仍满足 “平衡 BST” 要求(如示例中两种答案均正确)。核心逻辑:JS 版本和 C++ 版本思路完全一致,通过递归选数组中点作为根节点,分别构建左右子树。JS 特有细节:需手动定义TreeNode类,除法后用Math.floor取整,避免浮点数问题。

2026-03-19 23:30:10 378

原创 Leetcode 141 最长公共前缀 | 罗马数字转整数

以第一个字符串为基准,逐字符串对比、逐步缩短公共前缀,是解决该问题最直观且高效的方法。优化点:提前终止循环(前缀为空时直接退出),避免无效遍历,提升实际运行效率。边界处理:必须考虑数组为空、字符串长度为 0 的情况,确保代码鲁棒性。注意substr substring 方法截取公共长度。核心规则:遍历每个字符,若当前值 < 下一个值则减,否则加,最后一个字符直接加。关键工具:用哈希表()存储字符 - 数值映射,实现 O (1) 时间查找。复杂度。

2026-03-18 21:51:16 363

原创 前后端对接: ESM配置与React Router

开发者复盘全栈项目踩坑经历:从ESM模块配置、TS导入后缀到React Router数据流,梳理了架构设计、请求规范和分层逻辑,强调“复盘>有思考地敲代码>盲目CV”的成长理念。

2026-03-18 20:51:53 507

原创 Leetcode 140 括号生成 | 单词搜索

核心规则:生成有效括号的关键是「左括号不超 n,右括号不超左括号」,在生成过程中直接保证有效性,无需事后验证。回溯逻辑:先尝试加左括号(满足条件时),递归到底后回溯;再尝试加右括号(满足条件时),递归到底后回溯。效率优势:这种做法不会生成无效组合,比「生成所有组合再验证」的方式效率高得多(n=8 时尤为明显)。行号x:向上走行号减 1(x-1),向下走行号加 1(x+1列号y:向左走列号减 1(y-1),向右走列号加 1(y+1数组{行偏移, 列偏移}刚好对应这个规则,是行业通用写法。

2026-03-16 23:32:06 372

原创 react-i18next 国际化支持

本文记录基于 React + react-i18next + BlockNote 实现项目国际化过程,解决编辑器语言切换、白屏及内容丢失问题,总结实战踩坑与优化思路。

2026-03-16 22:52:21 553

原创 Leetcode 139 最后一个单词的长度 | 找出字符串中第一个匹配项的下标

单词的长度。

2026-03-15 23:46:19 367

原创 订阅模式实现字符数统计

本文基于订阅模式实现实时字符统计,通过监听编辑器内容变更,结合防抖处理分离计算与渲染,提升前端性能,避免页面卡顿,最终通过自定义 Hook 完成逻辑封装与状态传递。

2026-03-13 23:34:41 514

原创 前端性能优化之首屏提速

本文记录前端首屏优化实践,从包体积分析、Rollup 配置、拆包原则到性能测评踩坑,反思自身技术不足,总结优化经验与误区。

2026-03-12 23:14:24 598

原创 Leetcode 138 全排列 | 组合总和

/ 最终保存所有全排列的结果// 临时保存当前正在构建的排列(比如[1,2])// 标记数字是否被使用(比如used[0]=true表示nums[0]已选)result:最终要返回的答案,是二维数组(每个元素是一个排列)path:记录当前选了哪些数字,比如选了 1 之后 path=[1],再选 2 之后 path=[1,2]used:避免重复选择同一个数字(比如选了 1 之后,不能再选 1)全排列的核心是回溯:通过「选择 - 递归 - 回溯」的流程枚举所有可能的排列,used。

2026-03-12 22:35:42 404

原创 编辑器项目开发复盘:主题切换

本文记录编辑器项目开发复盘,完成主题切换,重新规划本地存储与后端架构,与 UI 布局,深入理解 React Context、工程化主题方案及组件架构,反思学习与成长。

2026-03-11 23:53:25 1207

原创 Leetcode 137 组合 | 电话号码的字母组合

路径(已选数字)+ 选择列表(可选数字)+ 结束条件(选够 k 个数);关键优化点:通过start参数避免重复组合,通过剪枝减少无效遍历;做出选择 → 递归 → 撤销选择,这是所有回溯问题的通用框架。这个框架可以套用到所有组合、排列、子集类的回溯问题中,掌握后就能解决大部分同类题目。变量作用域res和path定义在内部,导致每次递归都会重置,无法累积结果;语法错误:箭头函数少写了,正确是;递归参数错误应该是i+1。

2026-03-11 23:22:12 440

原创 从0到1实现块级编辑器的文件导入

BlockNote导入功能开发复盘:从Markdown有损转换、React useRef脱围操作DOM,到TypeScript扩展接口解决非标准属性冲突,完整记录一个功能背后的思考与踩坑。

2026-03-10 23:10:11 1075

原创 Leetcode 136 最小栈 | 逆波兰表达式求值

/ 主栈:存储所有元素// 辅助栈:存储最小值C++ 的stack是 STL 容器,默认提供push()pop()top()empty()方法,无需自己实现基础栈功能。核心方案:用「主栈 + 辅助栈」实现,辅助栈始终存储当前主栈的最小值,保证getMin()是 O (1) 时间。关键逻辑push时辅助栈仅压入更小 / 相等的元素,pop时仅当弹出的是最小值才同步弹出辅助栈。复杂度。

2026-03-10 21:34:07 379

原创 从0到1实现多格式浏览器文档导出

开发者基于BlockNote生态,通过模块化重构实现了多格式文件导出功能,核心围绕数据转换、Hook封装及细节优化展开。

2026-03-09 23:25:18 490

原创 Leetcode 135 有效的括号 | 简化路径

栈(利用后进先出特性匹配括号顺序);核心逻辑:右括号必须与「最近未匹配」的左括号类型一致;关键细节:遍历中遇到不匹配 / 栈空的右括号直接返回false,遍历结束后栈必须为空才有效。JS 中用数组模拟栈是最常用的方式,push/pop操作时间复杂度都是 O (1),和 C++ 栈效率一致;核心逻辑完全复用 C++ 的思路:右括号匹配最近的左括号,不匹配直接返回 false,最终栈空则有效;关键差异:JS 用对象代替哈希表、用数组代替栈,语法更简洁但逻辑完全等价。核心思路。

2026-03-09 20:39:39 391

原创 今日开发反思:编辑器大纲跳转与数据持久化实践

本文复盘编辑器项目大纲跳转与数据持久化开发过程,记录踩坑经历与解决方案,梳理Hook理解与数据流,见证新手前端成长。

2026-03-08 23:38:24 1023

原创 Leetcode 134 存在重复元素 II | 最长连续序列

核心思路:用哈希集合去重 + 只从「连续序列起点」开始统计长度,保证 O (n) 时间复杂度。关键优化!避免重复遍历,是实现 O (n) 的核心。复杂度:时间 O (n)(每个元素最多访问两次),空间 O (n)(哈希集合存储所有元素)。

2026-03-08 20:13:59 388

原创 Leetcode 133 快乐数 | 字母异位词分组

核心逻辑:通过哈希集合检测平方和计算过程中的循环,避免无限迭代。关键步骤:拆分数字计算平方和 + 哈希集合判重。时间 / 空间复杂度:时间复杂度 O (log n)(每次计算平方和,数字位数减少),空间复杂度 O (log n)(集合存储的数的个数)。如果想优化空间复杂度,还可以用「快慢指针法」(不用哈希集合),原理类似检测链表环:慢指针每次算 1 次平方和,快指针每次算 2 次平方和,若相遇则说明有循环,不是快乐数;若快指针先到 1,则是快乐数。核心逻辑不变。

2026-03-07 21:31:36 380

原创 Vercel部署: Vite Monorepo踩坑与原理小记

本文记录 Vercel 部署前端项目因找不到 dist 报错的排查过程,理清构建、部署逻辑与浏览器原理,掌握 Vercel 配置优先级与前端工程化核心流程。

2026-03-06 23:04:22 621

原创 Leetcode 132 同构字符串 | 有效的字母异位词

必须同时维护双向映射,只检查单向映射会漏掉「不同字符映射到同一个字符」的错误情况;实现关键:用两个分别存储s→t和t→s,遍历过程中验证映射的一致性;时间 / 空间复杂度:O (n)(n 为字符串长度),每个字符遍历一次,哈希表操作是 O (1) 平均时间复杂度。的核心作用是判断哈希表中是否存在指定的键;这是 C++ 哈希表 / 映射容器的标准查找方式,适用于map等;等价写法更简洁,新手可以优先用这个,逻辑更直观。JS 中用普通对象替代 C++ 的,核心键值对逻辑完全复用;

2026-03-06 20:17:05 380

原创 Leetcode 131 用最少数量的箭引爆气球 | 赎金信

你的错误核心:把 “合并区间(求并集)” 当成了 “找重叠区间(求交集)”,导致区间越合越大,结果错误;正确思路:贪心算法,按气球右边界排序,每支箭射在当前气球的右边界,尽可能覆盖更多后续气球;关键操作:遍历过程中判断当前气球的左边界是否超过上一支箭的位置,超过则新增箭,并更新箭的位置。这个思路的时间复杂度是 O (n log n)(主要是排序的时间),空间复杂度 O (1)(忽略排序的系统空间),符合题目中10^5数据量的要求。统计字符频率 + 校验频率是否满足需求。

2026-03-05 11:20:46 350

原创 Leetcode 130 合并区间 | 插入区间

解决合并区间问题的核心是先排序,后合并,排序保证了相邻区间的可比较性,合并只需遍历一次即可完成;合并的关键判断条件是:当前区间的起始值 ≤ 结果数组最后一个区间的结束值,满足则合并,否则直接加入;时间复杂度主要由排序决定(O(n log n)),遍历合并是O(n),整体为O(n log n),空间复杂度为O(log n)(排序的栈空间)或O(n)(存储结果),符合题目要求。先按起始值升序排序,再遍历合并重叠区间;语法差异主要在:排序回调规则(JS 用数值差,C++ 用布尔值)、数组操作(

2026-03-02 22:58:50 646

原创 Leetcode 129 移除元素 | 轮转数组

核心错误:旋转公式写错(而非),且未处理 k 大于数组长度的情况;原地修改关键:不能直接赋值数组,需逐个把临时数组的值写回原数组;优化思路:三次反转法可实现 O (1) 空间复杂度的原地旋转。不能直接替换数组引用(比如 JS 中nums = res),必须通过索引逐个赋值(C++ 中vector的assign函数是例外(会直接替换原数组内容),但本质也是底层重新赋值。移除元素:双指针,快指针找有效元素,慢指针存有效元素;轮转数组:临时数组 + 取模算索引,或三次反转实现原地轮转。

2026-03-01 18:27:10 835

原创 cpp 10 vector 容器的初始化方式 | static_cast<int>(x) | assign 函数

核心是创建长度为 k、每个元素都是空指针的链表节点指针数组;这种写法适配题目需求:提前预留 k 个位置,不足的部分用nullptr填充,符合「分割成 k 个部分,不足则为 null」的要求;显式指定nullptr比只写(k)更易读,是新手推荐的写法。是 C++ 的静态强制类型转换语法,用于将兼容的类型(如 char)转换为 int,比 C 语言的强制转换更安全,是推荐用法。abs()是标准库的绝对值函数,用于获取数值的非负值,需要包含<cmath>头文件。这行代码的核心目的是。

2026-03-01 18:19:18 631

原创 Leetcode 128 汇总区间

核心逻辑:用start标记区间起点,遍历数组判断连续(),不连续则闭合当前区间,最后处理末尾区间。格式规则:区间起点和终点相同输出"a",不同则输出"a->b"。模板要点:初始化起点→遍历判断连续性→闭合区间→处理最后区间,这个框架可复用解决多数有序数组的区间合并问题。核心错误修正:JS 里结果要初始化为空数组[],不是null;遍历结束必须处理最后一个区间。JS 语法要点:用===做严格相等判断,字符串拼接用模板字符串${}更简洁,数组用push添加元素。解题逻辑不变。

2026-02-26 23:50:52 601

原创 Leetcode 127 删除有序数组中的重复项 | 删除有序数组中的重复项 II

核心解法是双指针法,利用数组 “有序” 的特性,通过慢指针标记唯一元素位置、快指针遍历找新元素,实现原地去重。边界条件要处理:数组为空时直接返回 0。最终返回值是slow + 1(因为慢指针是索引,从 0 开始),数组前slow + 1个元素就是去重后的结果。这个解法完全满足题目 “原地修改、保持相对顺序、返回唯一元素个数” 的所有要求,也是这道题的最优解。核心解法:双指针法,核心判断条件从 “和慢指针当前位置不同” 升级为 “和慢指针前一位位置不同”,实现 “最多保留 2 次” 的逻辑。

2026-02-25 22:04:53 657

原创 Leetcode 126 两数之和 II - 输入有序数组 | 盛最多水的容器

核心优化是找到结果后立即返回,避免无效循环,这是提升执行效率的关键。减少重复的和计算、简化返回逻辑,让代码更简洁且性能更好。双指针法本身已是该问题的最优解法(时间 O (n)、空间 O (1)),优化后保持了最优复杂度,仅提升代码的执行效率和可读性。双指针法的核心是移动较矮的指针,因为盛水量由矮边决定,移动高边无法提升有效高度,只会减少宽度;该解法将时间复杂度从暴力法的 O (n²) 优化到 O (n),是本题的最优解;代码逻辑简洁,关键是理解 “宽度最大优先,逐步优化高度” 的思路。

2026-02-21 23:45:15 685

原创 Leetcode 125 验证回文串 | 判断子序列

核心步骤是预处理字符串(过滤非字母数字 + 转小写)和双指针对比,两步结合即可验证回文串。利用isalnum和tolower函数可以高效完成字符预处理,避免手动判断字符范围的繁琐。双指针法的时间复杂度为 O (n)(n 为原字符串长度),空间复杂度为 O (n)(存储预处理后的字符串),在题目数据范围(2*10^5)内效率足够。如果想优化空间复杂度,可以不单独存储预处理后的字符串,而是在原字符串上直接用双指针跳过非字母数字字符,不过代码可读性会稍低,新手先掌握上述实现方式即可。

2026-02-20 23:37:04 644

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除