<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>LeetCode on Lishengxie</title><link>https://lishengxie.top/tags/leetcode/</link><description>Recent content in LeetCode on Lishengxie</description><generator>Hugo</generator><language>zh-cn</language><lastBuildDate>Sun, 04 Feb 2024 18:48:10 +0800</lastBuildDate><atom:link href="https://lishengxie.top/tags/leetcode/index.xml" rel="self" type="application/rss+xml"/><item><title>LeetCode刷题 - KMP算法</title><link>https://lishengxie.top/post/leetcode-kmp/</link><pubDate>Sun, 04 Feb 2024 18:48:10 +0800</pubDate><guid>https://lishengxie.top/post/leetcode-kmp/</guid><description>&lt;p&gt;KMP算法是一种高效的字符串匹配算法，但是之前每次学过之后都会忘记，这次做一下总结加深印象，主要参考了以下链接。&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;a href="https://programmercarl.com/0028.%E5%AE%9E%E7%8E%B0strStr.html"&gt;https://programmercarl.com/0028.%E5%AE%9E%E7%8E%B0strStr.html&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="问题"&gt;问题&lt;/h2&gt;&#10;&lt;p&gt;给定一个字符串&lt;span class="katex-inline"&gt;s&lt;/span&gt;(长度为N)和一个模式串&lt;span class="katex-inline"&gt;t&lt;/span&gt;(长度为M)，如果&lt;span class="katex-inline"&gt;s&lt;/span&gt;中存在&lt;span class="katex-inline"&gt;t&lt;/span&gt;，那么返回模式串第一次出现的起始索引；如果不存在返回-1。对应&lt;a href="https://leetcode.cn/problems/find-the-index-of-the-first-occurrence-in-a-string/description/"&gt;Leetcode 28. 找出字符串中第一个匹配项的下标&lt;/a&gt;&lt;/p&gt;&#10;&lt;h2 id="kmp算法"&gt;KMP算法&lt;/h2&gt;&#10;&lt;p&gt;KMP算法是由D.E.Knuth，J.H.Morris和V.R.Pratt同时发现的一种快速的字符串匹配算法，时间复杂度为&lt;span class="katex-inline"&gt;O(M+N)&lt;/span&gt;。KMP算法的核心思想是&lt;strong&gt;在字符串匹配失败时利用之前已经匹配的信息来做快速回退，避免从头再做匹配&lt;/strong&gt;。KMP算法的核心函数是一个用于求解&lt;code&gt;next&lt;/code&gt;数组的函数，&lt;code&gt;next&lt;/code&gt;数组包含了模式串局部匹配的信息。&lt;/p&gt;&#10;&lt;p&gt;这里代码随想录中给出了关于&lt;code&gt;next&lt;/code&gt;数组的详细解释。&lt;code&gt;next&lt;/code&gt;数组对应自定义的前缀表，其中前缀表是一个和模式串长度相同的数组，前缀表第i个位置的值为[0,i]子字符串的最长相同前后缀的长度；&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;前缀是指不包含最后一个字符的所有以第一个字符开头的连续子串。后缀是指不包含第一个字符的所有以最后一个字符结尾的连续子串；&lt;/li&gt;&#10;&lt;li&gt;举例来说，“aab”的前缀有“a”和“aa”、后缀有“b”和“ab”，“aabaa”的最长相同前后缀长度为2，“aa”的最长相同前后缀长度为1。&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;以下图为例，假设文本串和模式串分别为&lt;code&gt;aabaabaafa&lt;/code&gt;和&lt;code&gt;aabaaf&lt;/code&gt;，前缀表如图中所示。那么在&lt;code&gt;b&lt;/code&gt;和&lt;code&gt;f&lt;/code&gt;不匹配时，此时寻找前缀表中前一位存储的值，查找得到值为2，该值的含义是“aabaa”的最长相同前后缀长度为2，即“aa”。此时我们可以不用从头开始重新匹配，文本串中的匹配指针可以不移动，将模式串中的匹配指针回退到索引2处重新开始匹配即可。&#10;&lt;img src="https://lishengxie.top/uploads/2024/02/prefix-table.png" alt="prefix table" style="zoom:30%;"/&gt;&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;这里为什么可以不回退文本串的匹配指针？&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;blockquote&gt;&#10;&lt;p&gt;因为这里通过回退j指针，找到了从文本串中该位置向前的最长相同前后缀，获得了类似下图的效果。&lt;/p&gt;&#10;&lt;/blockquote&gt;&#10;&lt;img src="https://lishengxie.top/uploads/2024/02/prefix-table1.png" alt="prefix table" style="zoom:30%;"/&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;实际使用中常通过将前缀表统一减1得到next数组，那么如何计算next数组？&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;blockquote&gt;&#10;&lt;p&gt;next数组的计算类似于移动模式串，在模式串和模式串之间做匹配，在移动的过程中计算next数组的值，next数组的计算代码如下所示：&lt;/p&gt;&#10;&lt;/blockquote&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-cpp" data-lang="cpp"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;getNext&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt;&lt;span style="color:#f92672"&gt;*&lt;/span&gt; next, &lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; string&lt;span style="color:#f92672"&gt;&amp;amp;&lt;/span&gt; s){&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; j &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; next[&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; j;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; i &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;; i &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; s.size(); i&lt;span style="color:#f92672"&gt;++&lt;/span&gt;) { &lt;span style="color:#75715e"&gt;// 注意i从1开始&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;while&lt;/span&gt; (j &lt;span style="color:#f92672"&gt;&amp;gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;amp;&amp;amp;&lt;/span&gt; s[i] &lt;span style="color:#f92672"&gt;!=&lt;/span&gt; s[j &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;]) { &lt;span style="color:#75715e"&gt;// 前后缀不相同了&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; j &lt;span style="color:#f92672"&gt;=&lt;/span&gt; next[j]; &lt;span style="color:#75715e"&gt;// 向前回退&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (s[i] &lt;span style="color:#f92672"&gt;==&lt;/span&gt; s[j &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;]) { &lt;span style="color:#75715e"&gt;// 找到相同的前后缀&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; j&lt;span style="color:#f92672"&gt;++&lt;/span&gt;;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; next[i] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; j; &lt;span style="color:#75715e"&gt;// 将j（前缀的长度）赋给next[i]&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;&#10;&lt;li&gt;基于next数组进行文本串和模式串的匹配代码如下：&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-cpp" data-lang="cpp"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;match&lt;/span&gt;(string s, string t) {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; j &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; next[t.size()];&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; getNext(next, t);&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; (&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; i &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;; i &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; s.size(); i&lt;span style="color:#f92672"&gt;++&lt;/span&gt;) {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;while&lt;/span&gt; (j &lt;span style="color:#f92672"&gt;&amp;gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;amp;&amp;amp;&lt;/span&gt; s[i] &lt;span style="color:#f92672"&gt;!=&lt;/span&gt; t[j&lt;span style="color:#f92672"&gt;+&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;]) {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; j &lt;span style="color:#f92672"&gt;=&lt;/span&gt; next[j];&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (s[i] &lt;span style="color:#f92672"&gt;==&lt;/span&gt; s[j&lt;span style="color:#f92672"&gt;+&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;]) {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; j&lt;span style="color:#f92672"&gt;++&lt;/span&gt;;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (j &lt;span style="color:#f92672"&gt;==&lt;/span&gt; (t.size() &lt;span style="color:#f92672"&gt;-&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;)) {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; i &lt;span style="color:#f92672"&gt;-&lt;/span&gt; t.size() &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>算法学习-差分数组</title><link>https://lishengxie.top/post/differential-array/</link><pubDate>Sat, 23 Dec 2023 23:05:16 +0800</pubDate><guid>https://lishengxie.top/post/differential-array/</guid><description>&lt;h2 id="差分数组"&gt;差分数组&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;参考教程：&lt;a href="https://wansuanfa.com/index.php/589"&gt;https://wansuanfa.com/index.php/589&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;leetcode题目：&lt;a href="https://leetcode.cn/problems/corporate-flight-bookings/"&gt;1109. 航班预订统计&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="问题描述"&gt;问题描述&lt;/h2&gt;&#10;&lt;p&gt;给定一个数组，需要频繁地对某个区间内的元素做加减操作，并获取最后的操作结果。常规做法是每次都遍历整个区间然后修改区间内的元素，但是元素的访问需要时间、频繁访问元素会减慢程序的运行时间。因此，可以使用差分数组来进行优化。&lt;/p&gt;&#10;&lt;h2 id="一维差分数组定义"&gt;一维差分数组定义&lt;/h2&gt;&#10;&lt;p&gt;一维差分数组&lt;span class="katex-inline"&gt; d[n] &lt;/span&gt;定义为原始数组&lt;span class="katex-inline"&gt; nums &lt;/span&gt;相邻元素之间的差，即&lt;span class="katex-inline"&gt;d[i]=nums[i]-nums[i-1]&lt;/span&gt;，其中&lt;span class="katex-inline"&gt;d[0]=nums[0]&lt;/span&gt;。这样原数组就是差分数组的前缀和&#10;&lt;/p&gt;&#10;&lt;div class="katex-display"&gt;&#10;nums[i] = \sum_{k=0}^i d[k].&#10;&lt;/div&gt;&lt;p&gt;由此，我们可以改进原来的区间操作，如对区间&lt;span class="katex-inline"&gt;[a,b]&lt;/span&gt;内每个元素加3，那么只需要在区间的两端进行操作即可，即&#10;&lt;/p&gt;&#10;&lt;div class="katex-display"&gt;&#10;d[a] += 3, d[b+1] -= 3&#10;&lt;/div&gt;&lt;h3 id="证明"&gt;证明&lt;/h3&gt;&#10;&lt;p&gt;假设&lt;span class="katex-inline"&gt;nums1&lt;/span&gt;是修改后的数组，&lt;span class="katex-inline"&gt;d1&lt;/span&gt;是修改后的差分数组，其中&lt;span class="katex-inline"&gt;d1[a]=d[a]+3, d1[b+1]=d[b+1]-3&lt;/span&gt;.&lt;/p&gt;&#10;&lt;blockquote&gt;&#10;&lt;p&gt;hugo里面换行公式需要&lt;code&gt;\\\\&lt;/code&gt;四个反斜杠&lt;/p&gt;&#10;&lt;/blockquote&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;对于&lt;span class="katex-inline"&gt;0\leq i \lt a&lt;/span&gt;, &lt;span class="katex-inline"&gt;nums1[i] = \sum_{k=0}^i d1[k] = \sum_{k=0}^i d[k] = nums[i]&lt;/span&gt;.&lt;/li&gt;&#10;&lt;li&gt;对于&lt;span class="katex-inline"&gt;a\leq i \leq b&lt;/span&gt;,&#10;&#10;&lt;div class="katex-display"&gt;&#10;\begin{aligned}&#10;nums1[i] &amp; = \sum_{k=0}^i d1[k] \\\\ &#10;&amp; = \sum_{k=0}^{a-1}d[k] + \sum_{k=a+1}^{b}d[k] + d[a] + 3 \\\\ &#10;&amp; = \sum_{k=0}^i d[k] + 3 \\\\ &#10;&amp; = nums[i]+3&#10;\end{aligned}&#10;&lt;/div&gt;&lt;/li&gt;&#10;&lt;li&gt;对于&lt;span class="katex-inline"&gt;i \gt b&lt;/span&gt;,&#10;&#10;&lt;div class="katex-display"&gt;&#10;\begin{align}&#10;nums1[i] &amp;= \sum_{k=0}^i d1[k]\\\\ &#10;&amp;= \sum_{k=0}^{a-1}d[k] + \sum_{k=a+1}^{b}d[k] + \sum_{k=b+1}^{i}d[k] + d[a] + 3 + d[b] - 3\\\\ &amp;= \sum_{k=0}^i d[k] + 3 - 3\\\\ &#10;&amp;= nums[i].&#10;\end{align}&#10;&lt;/div&gt;&#10;由此，可以证明只修改差分数组的两端即可以修改原数组的整个区间。&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h3 id="代码"&gt;代码&lt;/h3&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-C++" data-lang="C++"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Solution&lt;/span&gt; {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; vector&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; diff;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; vector&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; nums;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;diffNums&lt;/span&gt;() {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; diff[&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; nums[&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;];&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; i &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;; i &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; nums.size(); &lt;span style="color:#f92672"&gt;++&lt;/span&gt;i) {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; diff[i] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; nums[i] &lt;span style="color:#f92672"&gt;-&lt;/span&gt; nums[i&lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;];&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;increment&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; a, &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; b, &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; val) {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; diff[a] &lt;span style="color:#f92672"&gt;+=&lt;/span&gt; val;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (b &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; diff.size())&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; diff[b &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;] &lt;span style="color:#f92672"&gt;-=&lt;/span&gt; val;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;result&lt;/span&gt;() {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; nums[&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; diff[&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;];&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; (&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; i &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;; i &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; diff.size(); i&lt;span style="color:#f92672"&gt;++&lt;/span&gt;)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; nums[i] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; diff[i] &lt;span style="color:#f92672"&gt;+&lt;/span&gt; nums[i &lt;span style="color:#f92672"&gt;-&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;];&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; vector&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; corpFlightBookings(vector&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;vector&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&amp;gt;&amp;amp;&lt;/span&gt; bookings, &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; n) {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; nums.resize(n, &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;);&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; diff.resize(n, &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;);&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; diffNums();&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; (&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; i &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;; i &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; bookings.size(); &lt;span style="color:#f92672"&gt;++&lt;/span&gt;i) {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; increment(bookings[i][&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;]&lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;, bookings[i][&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;]&lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;, bookings[i][&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;]);&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; result();&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; nums;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;};&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="拓展---二维差分数组"&gt;拓展 - 二维差分数组&lt;/h2&gt;&#10;&lt;p&gt;二维差分数组可以在一维差分数组的基础上进行拓展，视为一个平面，定义如下&#10;&lt;/p&gt;</description></item><item><title>LeetCode刷题-二叉树遍历迭代法</title><link>https://lishengxie.top/post/traverse-binary-tree/</link><pubDate>Tue, 17 Oct 2023 20:15:23 +0800</pubDate><guid>https://lishengxie.top/post/traverse-binary-tree/</guid><description>&lt;h2 id="leetcode题目链接"&gt;LeetCode题目链接&lt;/h2&gt;&#10;&lt;p&gt;二叉树的前序遍历：&lt;a href="https://leetcode.cn/problems/binary-tree-preorder-traversal/"&gt;https://leetcode.cn/problems/binary-tree-preorder-traversal/&lt;/a&gt;&#10;二叉树的中序遍历：&lt;a href="https://leetcode.cn/problems/binary-tree-inorder-traversal/"&gt;https://leetcode.cn/problems/binary-tree-inorder-traversal/&lt;/a&gt;&#10;二叉树的后序遍历：&lt;a href="https://leetcode.cn/problems/binary-tree-postorder-traversal/"&gt;https://leetcode.cn/problems/binary-tree-postorder-traversal/&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;二叉树的遍历方法有两种，分别是递归法和迭代法；实际使用中由于系统调用栈有限制，使用递归法可能会导致栈溢出，这里记录三种遍历的迭代做法。最后，介绍二叉树层序遍历的两种方法。&lt;/p&gt;&#10;&lt;p&gt;迭代遍历法借助辅助栈实现，下面是二叉树节点的定义，使用链表实现。&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-cpp" data-lang="cpp"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;struct&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;TreeNode&lt;/span&gt; {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; val;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; TreeNode &lt;span style="color:#f92672"&gt;*&lt;/span&gt;left;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; TreeNode &lt;span style="color:#f92672"&gt;*&lt;/span&gt;right;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; TreeNode() &lt;span style="color:#f92672"&gt;:&lt;/span&gt; val(&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;), left(&lt;span style="color:#66d9ef"&gt;nullptr&lt;/span&gt;), right(&lt;span style="color:#66d9ef"&gt;nullptr&lt;/span&gt;) {}&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; TreeNode(&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; x) &lt;span style="color:#f92672"&gt;:&lt;/span&gt; val(x), left(&lt;span style="color:#66d9ef"&gt;nullptr&lt;/span&gt;), right(&lt;span style="color:#66d9ef"&gt;nullptr&lt;/span&gt;) {}&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; TreeNode(&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; x, TreeNode &lt;span style="color:#f92672"&gt;*&lt;/span&gt;left, TreeNode &lt;span style="color:#f92672"&gt;*&lt;/span&gt;right) &lt;span style="color:#f92672"&gt;:&lt;/span&gt; val(x), left(left), right(right) {}&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; };&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="前序遍历"&gt;前序遍历&lt;/h2&gt;&#10;&lt;p&gt;前序遍历的顺序是中左右，每次先处理中间节点，那么先将根节点入栈，然后将右孩子入栈，再将左孩子入栈。先右后左的原因是因为入栈顺序和处理顺序是相反的。前序遍历的处理代码如下：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-cpp" data-lang="cpp"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Solution&lt;/span&gt; {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; vector&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; preorderTraversal(TreeNode&lt;span style="color:#f92672"&gt;*&lt;/span&gt; root) {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; vector&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; res;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; stack&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;TreeNode&lt;span style="color:#f92672"&gt;*&amp;gt;&lt;/span&gt; st;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (root &lt;span style="color:#f92672"&gt;==&lt;/span&gt; NULL) {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; res;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; st.push(root);&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;while&lt;/span&gt; (&lt;span style="color:#f92672"&gt;!&lt;/span&gt;st.empty()) {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; TreeNode &lt;span style="color:#f92672"&gt;*&lt;/span&gt;cur &lt;span style="color:#f92672"&gt;=&lt;/span&gt; st.top();&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; st.pop();&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; res.push_back(cur&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;val);&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (cur&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;right) st.push(cur&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;right);&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (cur&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;left) st.push(cur&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;left);&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; res;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;};&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="中序遍历"&gt;中序遍历&lt;/h2&gt;&#10;&lt;p&gt;中序遍历处理顺序为左中右，先访问二叉树顶部的节点，随后逐层向下访问直到树最左侧的节点，再开始处理节点，这导致处理节点的顺序和访问节点的顺序不一致。中序遍历的迭代法如下所示：&lt;/p&gt;</description></item><item><title>LeetCode刷题 - 滑动窗口最大值</title><link>https://lishengxie.top/post/leetcode-moving-window-maximum/</link><pubDate>Tue, 17 Oct 2023 20:11:52 +0800</pubDate><guid>https://lishengxie.top/post/leetcode-moving-window-maximum/</guid><description>&lt;h2 id="leetcode刷题---滑动窗口最大值"&gt;LeetCode刷题 - &lt;strong&gt;滑动窗口最大值&lt;/strong&gt;&lt;/h2&gt;&#10;&lt;p&gt;参考链接:&lt;a href="https://programmercarl.com/0239.%E6%BB%91%E5%8A%A8%E7%AA%97%E5%8F%A3%E6%9C%80%E5%A4%A7%E5%80%BC.html"&gt;https://programmercarl.com/0239.%E6%BB%91%E5%8A%A8%E7%AA%97%E5%8F%A3%E6%9C%80%E5%A4%A7%E5%80%BC.html&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;leetcode题目链接：&lt;a href="https://leetcode.cn/problems/sliding-window-maximum/"&gt;https://leetcode.cn/problems/sliding-window-maximum/&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;给你一个整数数组 nums，有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。&lt;/p&gt;&#10;&lt;p&gt;返回滑动窗口中的最大值 。&lt;/p&gt;&#10;&lt;p&gt;示例 1：&lt;/p&gt;&#10;&lt;blockquote&gt;&#10;&lt;p&gt;输入：nums = [1,3,-1,-3,5,3,6,7], k = 3&#10;输出：[3,3,5,5,6,7]&#10;解释：&#10;滑动窗口的位置 最大值&lt;/p&gt;&#10;&lt;hr&gt;&#10;&lt;p&gt;[1 3 -1] -3 5 3 6 7 3&#10;1 [3 -1 -3] 5 3 6 7 3&#10;1 3 [-1 -3 5] 3 6 7 5&#10;1 3 -1 [-3 5 3] 6 7 5&#10;1 3 -1 -3 [5 3 6] 7 6&#10;1 3 -1 -3 5 [3 6 7] 7&lt;/p&gt;&#10;&lt;/blockquote&gt;</description></item></channel></rss>