<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>算法 on Chen Kai Blog</title><link>https://www.chenk.top/zh/tags/%E7%AE%97%E6%B3%95/</link><description>Recent content in 算法 on Chen Kai Blog</description><generator>Hugo</generator><language>zh-CN</language><lastBuildDate>Tue, 13 Sep 2022 09:00:00 +0000</lastBuildDate><atom:link href="https://www.chenk.top/zh/tags/%E7%AE%97%E6%B3%95/index.xml" rel="self" type="application/rss+xml"/><item><title>LeetCode（十）：栈与队列</title><link>https://www.chenk.top/zh/leetcode/10-%E6%A0%88%E4%B8%8E%E9%98%9F%E5%88%97/</link><pubDate>Tue, 13 Sep 2022 09:00:00 +0000</pubDate><guid>https://www.chenk.top/zh/leetcode/10-%E6%A0%88%E4%B8%8E%E9%98%9F%E5%88%97/</guid><description>&lt;p>栈和队列看似平凡，尤其在图算法或动态规划面前更显不起眼，但它们却是面试题中的常客——因为大多数算法问题最终都归结于&lt;strong>访问顺序&lt;/strong>的考察。栈遵循后进先出（LIFO）原则，而队列则是先进先出（FIFO）。加上单调栈、双端队列、优先队列等变体，许多经典问题如括号匹配、下一个更大元素、滑动窗口最值、前 K 大、 BFS 等都能通过它们高效解决。&lt;/p></description></item><item><title>LeetCode（八）：回溯算法</title><link>https://www.chenk.top/zh/leetcode/08-%E5%9B%9E%E6%BA%AF%E7%AE%97%E6%B3%95/</link><pubDate>Sun, 14 Aug 2022 09:00:00 +0000</pubDate><guid>https://www.chenk.top/zh/leetcode/08-%E5%9B%9E%E6%BA%AF%E7%AE%97%E6%B3%95/</guid><description>&lt;p>当你遇到需要“枚举所有可能”的问题时，回溯算法几乎是不二之选——无论是全排列、子集、合法棋盘布局，还是网格中的路径搜索，它都能派上用场。简单来说，回溯是一种“带脑子的暴力搜索”：它一步步构建候选解，一旦发现当前路径违反约束、无法通向合法答案，就立刻放弃，并撤销上一步的选择，恢复到干净的状态，再尝试其他分支。整个过程可以浓缩为三个动作：&lt;strong>选择 → 递归 → 撤销&lt;/strong>。&lt;/p></description></item><item><title>LeetCode（七）：动态规划入门</title><link>https://www.chenk.top/zh/leetcode/07-%E5%8A%A8%E6%80%81%E8%A7%84%E5%88%92%E5%85%A5%E9%97%A8/</link><pubDate>Sat, 30 Jul 2022 09:00:00 +0000</pubDate><guid>https://www.chenk.top/zh/leetcode/07-%E5%8A%A8%E6%80%81%E8%A7%84%E5%88%92%E5%85%A5%E9%97%A8/</guid><description>&lt;p>动态规划在算法圈子里一直有种“高手专属”的光环，很多人觉得它复杂难懂。其实不然——DP 的核心思想特别简单：&lt;strong>同样的子问题只算一次，别重复劳动&lt;/strong>。那些让人头疼的状态定义、转移方程和滚动优化，其实都是围绕这个核心展开的。&lt;/p></description></item><item><title>LeetCode（六）：二叉树遍历与构造</title><link>https://www.chenk.top/zh/leetcode/06-%E4%BA%8C%E5%8F%89%E6%A0%91%E9%81%8D%E5%8E%86%E4%B8%8E%E6%9E%84%E9%80%A0/</link><pubDate>Fri, 15 Jul 2022 09:00:00 +0000</pubDate><guid>https://www.chenk.top/zh/leetcode/06-%E4%BA%8C%E5%8F%89%E6%A0%91%E9%81%8D%E5%8E%86%E4%B8%8E%E6%9E%84%E9%80%A0/</guid><description>&lt;p>二叉树的题目，核心其实不在“树”本身，而在于两点：&lt;strong>访问节点的顺序&lt;/strong>，以及&lt;strong>在处理父节点之前，从子节点那里得到了什么信息&lt;/strong>。只要厘清这两点，前序、中序、后序、层序遍历的区别，递归与迭代的实现方式，乃至由两种遍历序列重建二叉树，甚至求最大深度、验证 BST 等经典题目，都能纳入同一套方法论框架。这篇文章的目的，就是带你彻底掌握这套方法。&lt;/p></description></item><item><title>LeetCode（五）：二分查找</title><link>https://www.chenk.top/zh/leetcode/05-%E4%BA%8C%E5%88%86%E6%9F%A5%E6%89%BE/</link><pubDate>Thu, 30 Jun 2022 09:00:00 +0000</pubDate><guid>https://www.chenk.top/zh/leetcode/05-%E4%BA%8C%E5%88%86%E6%9F%A5%E6%89%BE/</guid><description>&lt;p>二分查找看似简单，实则容易出错。核心思想就是每次把搜索范围缩小一半，但在实际编写时——尤其是在面试这种高压环境下——各种边界条件、死循环和返回值错误等问题就会暴露出来。本文不重复罗列模板代码，而是聚焦于解释模板设计背后的逻辑，即那个核心不变量。只要抓住了这个不变量，那些让人纠结的细节——比如用 &lt;code>&amp;lt;&lt;/code> 还是 &lt;code>&amp;lt;=&lt;/code>，&lt;code>right = mid&lt;/code> 还是 &lt;code>right = mid - 1&lt;/code>——就不再是靠死记硬背的东西，而是可以自然推导出来的结果。&lt;/p></description></item><item><title>LeetCode（四）：滑动窗口技巧</title><link>https://www.chenk.top/zh/leetcode/04-%E6%BB%91%E5%8A%A8%E7%AA%97%E5%8F%A3%E6%8A%80%E5%B7%A7/</link><pubDate>Wed, 15 Jun 2022 09:00:00 +0000</pubDate><guid>https://www.chenk.top/zh/leetcode/04-%E6%BB%91%E5%8A%A8%E7%AA%97%E5%8F%A3%E6%8A%80%E5%B7%A7/</guid><description>&lt;p>如果你曾经写过双重 &lt;code>for&lt;/code> 循环来遍历所有连续子数组，那么&lt;strong>滑动窗口&lt;/strong>很可能就是你缺失的关键优化。它通过&lt;strong>复用已计算的结果&lt;/strong>，将原本 &lt;span class="math-inline">$O(nk)$&lt;/span>
 或 &lt;span class="math-inline">$O(n^2)$&lt;/span>
 的暴力扫描压缩为一次线性遍历。本文将从基本原理出发，深入剖析这一技巧，并通过四道经典 LeetCode 题目加以演练，最后还会介绍其单调队列变体。&lt;/p></description></item><item><title>LeetCode（三）：链表操作</title><link>https://www.chenk.top/zh/leetcode/03-%E9%93%BE%E8%A1%A8%E6%93%8D%E4%BD%9C/</link><pubDate>Tue, 31 May 2022 09:00:00 +0000</pubDate><guid>https://www.chenk.top/zh/leetcode/03-%E9%93%BE%E8%A1%A8%E6%93%8D%E4%BD%9C/</guid><description>&lt;p>链表是最能逼你&lt;strong>用指针思维&lt;/strong>思考的数据结构。数组支持 &lt;span class="math-inline">$O(1)$&lt;/span>
 索引，底层内存布局不用你管。链表只丢给你一个 head 指针，然后问：&lt;em>“接下来怎么办？”&lt;/em> 从索引到引用的这一步跨越，正是链表题频繁出现在面试里的原因。题目描述短，边界条件多，写对很难。它考察的正是优秀工程师的习惯：画图、给指针起名、&lt;strong>解引用前必查 &lt;code>None&lt;/code>&lt;/strong>。&lt;/p></description></item><item><title>LeetCode（二）：双指针技巧</title><link>https://www.chenk.top/zh/leetcode/02-%E5%8F%8C%E6%8C%87%E9%92%88%E6%8A%80%E5%B7%A7/</link><pubDate>Mon, 16 May 2022 09:00:00 +0000</pubDate><guid>https://www.chenk.top/zh/leetcode/02-%E5%8F%8C%E6%8C%87%E9%92%88%E6%8A%80%E5%B7%A7/</guid><description>&lt;p>哈希表靠内存换速度，双指针则反其道而行之：只需一点结构性假设——数组已排序、链表可能存在环、答案落在某个连续窗口内——就能以 &lt;span class="math-inline">$O(n)$&lt;/span>
 时间复杂度和 &lt;span class="math-inline">$O(1)$&lt;/span>
 额外空间解决问题。代码看起来极其简单（两个下标加一个 &lt;code>while&lt;/code> 循环），但却是新手最容易翻车的技巧之一：下标越界、死循环、漏掉重复项、平局时移错指针……各种陷阱层出不穷。要真正掌握它，关键不是死记移动规则，而是围绕 &lt;strong>不变量&lt;/strong> 进行严谨推理。&lt;/p></description></item><item><title>LeetCode（一）：哈希表</title><link>https://www.chenk.top/zh/leetcode/01-%E5%93%88%E5%B8%8C%E8%A1%A8/</link><pubDate>Sun, 01 May 2022 09:00:00 +0000</pubDate><guid>https://www.chenk.top/zh/leetcode/01-%E5%93%88%E5%B8%8C%E8%A1%A8/</guid><description>&lt;p>哈希表是工具箱里的性价比之王：每个元素只占用常数级别的内存，却能把“这个值存在吗？”的查询开销降到接近一条 CPU 指令。很多暴力解法复杂度高达 &lt;span class="math-inline">$O(n^2)$&lt;/span>
，但只要用上哈希表，往往就能直接优化到 &lt;span class="math-inline">$O(n)$&lt;/span>
 的一次遍历。&lt;/p></description></item></channel></rss>