<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://zlxydl.github.io/feed.xml" rel="self" type="application/atom+xml" /><link href="https://zlxydl.github.io/" rel="alternate" type="text/html" /><updated>2026-05-12T08:40:06+00:00</updated><id>https://zlxydl.github.io/feed.xml</id><title type="html">zlxydl’s blog</title><subtitle>zlxydl的个人技术博客</subtitle><entry><title type="html">力扣146</title><link href="https://zlxydl.github.io/lk146/" rel="alternate" type="text/html" title="力扣146" /><published>2026-05-12T00:00:00+00:00</published><updated>2026-05-12T00:00:00+00:00</updated><id>https://zlxydl.github.io/lk146</id><content type="html" xml:base="https://zlxydl.github.io/lk146/"><![CDATA[<h1 id="lk146">lk146</h1>

<p><a href="https://leetcode.cn/problems/lru-cache/description/">146. LRU 缓存</a></p>

<p>LRU缓存主要是实现<em>get()</em>和<em>put()</em>两个函数，均要求O(1)的时间复杂度</p>

<p>第一版get()函数是根据指定的key返回value,最初的做法是维护一个双链表list，然后根据key找value，找到的话，使用remove函数删除节点并重新插入最后面。这种做法存在疏漏，一是遍历操作会带来O(n)的时间复杂度，二来remove函数仅支持传入value,并且也会带来O(n)的时间复杂度（使用erase函数即可）</p>

<p>第一版的put函数思路如下，遍历list，如果元素存在的话先删除再插入最后面，和之前一样也是remove函数使用有误，外加遍历的复杂度过高；如果没找到，先判断是否满载，再按需插入</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// 请你设计并实现一个满足  LRU (最近最少使用) 缓存 约束的数据结构。</span>
<span class="c1">// 实现 LRUCache 类：</span>
<span class="c1">// LRUCache(int capacity) 以 正整数 作为容量 capacity 初始化 LRU 缓存</span>
<span class="c1">// int get(int key) 如果关键字 key 存在于缓存中，则返回关键字的值，否则返回 -1 。</span>
<span class="c1">// void put(int key, int value) 如果关键字 key 已经存在，则变更其数据值 value ；</span>
<span class="c1">// 如果不存在，则向缓存中插入该组 key-value 。如果插入操作导致关键字数量超过 capacity ，则应该 逐出 最久未使用的关键字。</span>
<span class="c1">// 函数 get 和 put 必须以 O(1) 的平均时间复杂度运行。</span>
<span class="k">class</span> <span class="nc">LRUCache</span> <span class="p">{</span>
<span class="nl">public:</span>
    <span class="n">LRUCache</span><span class="p">(</span><span class="kt">int</span> <span class="n">capacity</span><span class="p">)</span> <span class="p">{</span>
        <span class="n">cap</span> <span class="o">=</span> <span class="n">capacity</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="kt">int</span> <span class="n">get</span><span class="p">(</span><span class="kt">int</span> <span class="n">key</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">for</span> <span class="p">(</span><span class="n">pair</span><span class="o">&lt;</span><span class="kt">int</span><span class="p">,</span><span class="kt">int</span><span class="o">&gt;</span> <span class="n">iter</span> <span class="o">:</span> <span class="n">list</span><span class="p">)</span> <span class="p">{</span>
            <span class="k">if</span> <span class="p">(</span><span class="n">iter</span><span class="p">.</span><span class="n">first</span> <span class="o">==</span> <span class="n">key</span><span class="p">)</span> <span class="p">{</span>
                <span class="kt">int</span> <span class="n">val</span> <span class="o">=</span> <span class="n">iter</span><span class="p">.</span><span class="n">second</span> <span class="p">;</span>
                <span class="c1">// remove不能直接传迭代器进去，erase函数可以</span>
                <span class="n">list</span><span class="p">.</span><span class="n">remove</span><span class="p">(</span><span class="n">iter</span><span class="p">);</span>
                <span class="n">list</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="n">pair</span><span class="o">&lt;</span><span class="kt">int</span><span class="p">,</span><span class="kt">int</span><span class="o">&gt;</span><span class="p">(</span><span class="n">key</span><span class="p">,</span><span class="n">val</span><span class="p">));</span>
                <span class="k">return</span> <span class="n">val</span> <span class="p">;</span>
            <span class="p">}</span>
        <span class="p">}</span>
        <span class="k">return</span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span>
    <span class="p">}</span>
    <span class="kt">void</span> <span class="n">put</span><span class="p">(</span><span class="kt">int</span> <span class="n">key</span><span class="p">,</span> <span class="kt">int</span> <span class="n">value</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">for</span> <span class="p">(</span><span class="n">pair</span><span class="o">&lt;</span><span class="kt">int</span><span class="p">,</span><span class="kt">int</span><span class="o">&gt;</span> <span class="n">iter</span> <span class="o">:</span> <span class="n">list</span><span class="p">)</span> <span class="p">{</span>
            <span class="k">if</span> <span class="p">(</span><span class="n">iter</span><span class="p">.</span><span class="n">first</span> <span class="o">==</span> <span class="n">key</span><span class="p">)</span> <span class="p">{</span>
                <span class="n">list</span><span class="p">.</span><span class="n">remove</span><span class="p">(</span><span class="n">iter</span><span class="p">);</span>
                <span class="n">list</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="n">pair</span><span class="o">&lt;</span><span class="kt">int</span><span class="p">,</span><span class="kt">int</span><span class="o">&gt;</span><span class="p">(</span><span class="n">key</span><span class="p">,</span><span class="n">value</span><span class="p">));</span>
                <span class="k">return</span><span class="p">;</span>
            <span class="p">}</span>
        <span class="p">}</span>
        <span class="k">if</span> <span class="p">(</span><span class="n">list</span><span class="p">.</span><span class="n">size</span><span class="p">()</span> <span class="o">==</span> <span class="n">cap</span><span class="p">)</span> <span class="n">list</span><span class="p">.</span><span class="n">pop_front</span><span class="p">();</span>
        <span class="n">list</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="n">pair</span><span class="o">&lt;</span><span class="kt">int</span><span class="p">,</span><span class="kt">int</span><span class="o">&gt;</span><span class="p">(</span><span class="n">key</span><span class="p">,</span><span class="n">value</span><span class="p">));</span>
    <span class="p">}</span>
<span class="nl">private:</span>
    <span class="kt">int</span> <span class="n">cap</span> <span class="p">;</span>
    <span class="n">list</span><span class="o">&lt;</span><span class="n">pair</span><span class="o">&lt;</span><span class="kt">int</span><span class="p">,</span><span class="kt">int</span><span class="o">&gt;&gt;</span> <span class="n">list</span><span class="p">;</span>
<span class="p">};</span>
</code></pre></div></div>

<p>以下是第二版</p>

<p>使用一个map存储从key到迭代器的映射，用空间换时间。</p>

<p>需要注意的是迭代器的写法<em>unordered_map&lt;int, list&lt;pair&lt;int, int»::iterator&gt;</em></p>

<p>这里涉及一个新的函数splice，函数签名如下：<em>void splice(const_iterator pos, list&amp; other, const_iterator it)</em></p>

<p>功能是把第三个参数（迭代器）指向的元素，以O(1)的时间复杂度移动到第一个参数指定的位置</p>

<p>第二个参数other，顾名思义，该函数可以把当前list的迭代器指向的元素，移动到另一个list的指定位置</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">class</span> <span class="nc">LRUCache</span> <span class="p">{</span>
<span class="nl">public:</span>
    <span class="n">LRUCache</span><span class="p">(</span><span class="kt">int</span> <span class="n">capacity</span><span class="p">)</span> <span class="p">{</span>
        <span class="n">cap</span> <span class="o">=</span> <span class="n">capacity</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="kt">int</span> <span class="n">get</span><span class="p">(</span><span class="kt">int</span> <span class="n">key</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">if</span> <span class="p">(</span><span class="k">const</span> <span class="k">auto</span> <span class="n">it</span> <span class="o">=</span> <span class="n">key_to_iter</span><span class="p">.</span><span class="n">find</span><span class="p">(</span><span class="n">key</span><span class="p">);</span> <span class="n">it</span> <span class="o">!=</span> <span class="n">key_to_iter</span><span class="p">.</span><span class="n">end</span><span class="p">())</span> <span class="p">{</span>
            <span class="kt">int</span> <span class="n">val</span> <span class="o">=</span> <span class="n">it</span><span class="o">-&gt;</span><span class="n">second</span><span class="o">-&gt;</span><span class="n">second</span> <span class="p">;</span>
            <span class="n">cache</span><span class="p">.</span><span class="n">splice</span><span class="p">(</span><span class="n">cache</span><span class="p">.</span><span class="n">end</span><span class="p">()</span> <span class="p">,</span> <span class="n">cache</span> <span class="p">,</span> <span class="n">it</span><span class="o">-&gt;</span><span class="n">second</span><span class="p">)</span> <span class="p">;</span>
            <span class="n">key_to_iter</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">=</span> <span class="o">--</span><span class="n">cache</span><span class="p">.</span><span class="n">end</span><span class="p">();</span>
            <span class="k">return</span> <span class="n">val</span> <span class="p">;</span>
        <span class="p">}</span>
        <span class="k">return</span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="kt">void</span> <span class="n">put</span><span class="p">(</span><span class="kt">int</span> <span class="n">key</span><span class="p">,</span> <span class="kt">int</span> <span class="n">value</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">if</span> <span class="p">(</span><span class="k">auto</span> <span class="n">it</span> <span class="o">=</span> <span class="n">key_to_iter</span><span class="p">.</span><span class="n">find</span><span class="p">(</span><span class="n">key</span><span class="p">);</span> <span class="n">it</span> <span class="o">==</span> <span class="n">key_to_iter</span><span class="p">.</span><span class="n">end</span><span class="p">())</span> <span class="p">{</span>
            <span class="k">if</span> <span class="p">(</span><span class="n">cache</span><span class="p">.</span><span class="n">size</span><span class="p">()</span> <span class="o">==</span> <span class="n">cap</span><span class="p">)</span> <span class="p">{</span>
                <span class="n">key_to_iter</span><span class="p">.</span><span class="n">erase</span><span class="p">(</span><span class="n">cache</span><span class="p">.</span><span class="n">front</span><span class="p">().</span><span class="n">first</span><span class="p">);</span>
                <span class="n">cache</span><span class="p">.</span><span class="n">pop_front</span><span class="p">();</span>
            <span class="p">}</span>
            <span class="n">cache</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="n">pair</span><span class="o">&lt;</span><span class="kt">int</span><span class="p">,</span><span class="kt">int</span><span class="o">&gt;</span><span class="p">(</span><span class="n">key</span><span class="p">,</span><span class="n">value</span><span class="p">));</span>
            <span class="n">key_to_iter</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">=</span> <span class="o">--</span><span class="n">cache</span><span class="p">.</span><span class="n">end</span><span class="p">();</span>
        <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
            <span class="n">it</span><span class="o">-&gt;</span><span class="n">second</span><span class="o">-&gt;</span><span class="n">second</span> <span class="o">=</span> <span class="n">value</span> <span class="p">;</span>
           <span class="n">cache</span><span class="p">.</span><span class="n">splice</span><span class="p">(</span><span class="n">cache</span><span class="p">.</span><span class="n">end</span><span class="p">()</span> <span class="p">,</span> <span class="n">cache</span> <span class="p">,</span> <span class="n">it</span><span class="o">-&gt;</span><span class="n">second</span><span class="p">)</span> <span class="p">;</span>
            <span class="n">key_to_iter</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">=</span> <span class="o">--</span><span class="n">cache</span><span class="p">.</span><span class="n">end</span><span class="p">();</span>
        <span class="p">}</span>
    <span class="p">}</span>
    <span class="kt">void</span> <span class="n">print</span><span class="p">()</span> <span class="p">{</span>
        <span class="k">for</span> <span class="p">(</span><span class="n">pair</span><span class="o">&lt;</span><span class="kt">int</span><span class="p">,</span><span class="kt">int</span><span class="o">&gt;</span> <span class="n">it</span> <span class="o">:</span> <span class="n">cache</span><span class="p">)</span> <span class="p">{</span>
            <span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="s">"key : "</span> <span class="o">&lt;&lt;</span> <span class="n">it</span><span class="p">.</span><span class="n">first</span> <span class="o">&lt;&lt;</span> <span class="s">" value : "</span> <span class="o">&lt;&lt;</span> <span class="n">it</span><span class="p">.</span><span class="n">second</span> <span class="o">&lt;&lt;</span> <span class="n">endl</span><span class="p">;</span>
        <span class="p">}</span>
    <span class="p">}</span>

<span class="nl">private:</span>
    <span class="kt">int</span> <span class="n">cap</span> <span class="p">;</span>
    <span class="n">list</span><span class="o">&lt;</span><span class="n">pair</span><span class="o">&lt;</span><span class="kt">int</span><span class="p">,</span><span class="kt">int</span><span class="o">&gt;&gt;</span> <span class="n">cache</span><span class="p">;</span>
    <span class="n">unordered_map</span><span class="o">&lt;</span><span class="kt">int</span><span class="p">,</span> <span class="n">list</span><span class="o">&lt;</span><span class="n">pair</span><span class="o">&lt;</span><span class="kt">int</span><span class="p">,</span> <span class="kt">int</span><span class="o">&gt;&gt;::</span><span class="n">iterator</span><span class="o">&gt;</span> <span class="n">key_to_iter</span><span class="p">;</span>
<span class="p">};</span>
</code></pre></div></div>]]></content><author><name>zlxydl</name></author><category term="leetcode" /><summary type="html"><![CDATA[lk146 146. LRU 缓存 LRU缓存主要是实现get()和put()两个函数，均要求O(1)的时间复杂度 第一版get()函数是根据指定的key返回value,最初的做法是维护一个双链表list，然后根据key找value，找到的话，使用remove函数删除节点并重新插入最后面。这种做法存在疏漏，一是遍历操作会带来O(n)的时间复杂度，二来remove函数仅支持传入value,并且也会带来O(n)的时间复杂度（使用erase函数即可） 第一版的put函数思路如下，遍历list，如果元素存在的话先删除再插入最后面，和之前一样也是remove函数使用有误，外加遍历的复杂度过高；如果没找到，先判断是否满载，再按需插入 // 请你设计并实现一个满足 LRU (最近最少使用) 缓存 约束的数据结构。 // 实现 LRUCache 类： // LRUCache(int capacity) 以 正整数 作为容量 capacity 初始化 LRU 缓存 // int get(int key) 如果关键字 key 存在于缓存中，则返回关键字的值，否则返回 -1 。 // void put(int key, int value) 如果关键字 key 已经存在，则变更其数据值 value ； // 如果不存在，则向缓存中插入该组 key-value 。如果插入操作导致关键字数量超过 capacity ，则应该 逐出 最久未使用的关键字。 // 函数 get 和 put 必须以 O(1) 的平均时间复杂度运行。 class LRUCache { public: LRUCache(int capacity) { cap = capacity; } int get(int key) { for (pair&lt;int,int&gt; iter : list) { if (iter.first == key) { int val = iter.second ; // remove不能直接传迭代器进去，erase函数可以 list.remove(iter); list.push_back(pair&lt;int,int&gt;(key,val)); return val ; } } return -1; } void put(int key, int value) { for (pair&lt;int,int&gt; iter : list) { if (iter.first == key) { list.remove(iter); list.push_back(pair&lt;int,int&gt;(key,value)); return; } } if (list.size() == cap) list.pop_front(); list.push_back(pair&lt;int,int&gt;(key,value)); } private: int cap ; list&lt;pair&lt;int,int&gt;&gt; list; }; 以下是第二版 使用一个map存储从key到迭代器的映射，用空间换时间。 需要注意的是迭代器的写法unordered_map&lt;int, list&lt;pair&lt;int, int»::iterator&gt; 这里涉及一个新的函数splice，函数签名如下：void splice(const_iterator pos, list&amp; other, const_iterator it) 功能是把第三个参数（迭代器）指向的元素，以O(1)的时间复杂度移动到第一个参数指定的位置 第二个参数other，顾名思义，该函数可以把当前list的迭代器指向的元素，移动到另一个list的指定位置 class LRUCache { public: LRUCache(int capacity) { cap = capacity; } int get(int key) { if (const auto it = key_to_iter.find(key); it != key_to_iter.end()) { int val = it-&gt;second-&gt;second ; cache.splice(cache.end() , cache , it-&gt;second) ; key_to_iter[key] = --cache.end(); return val ; } return -1; } void put(int key, int value) { if (auto it = key_to_iter.find(key); it == key_to_iter.end()) { if (cache.size() == cap) { key_to_iter.erase(cache.front().first); cache.pop_front(); } cache.push_back(pair&lt;int,int&gt;(key,value)); key_to_iter[key] = --cache.end(); } else { it-&gt;second-&gt;second = value ; cache.splice(cache.end() , cache , it-&gt;second) ; key_to_iter[key] = --cache.end(); } } void print() { for (pair&lt;int,int&gt; it : cache) { cout &lt;&lt; "key : " &lt;&lt; it.first &lt;&lt; " value : " &lt;&lt; it.second &lt;&lt; endl; } } private: int cap ; list&lt;pair&lt;int,int&gt;&gt; cache; unordered_map&lt;int, list&lt;pair&lt;int, int&gt;&gt;::iterator&gt; key_to_iter; };]]></summary></entry><entry><title type="html">RAG评估</title><link href="https://zlxydl.github.io/RAG_Assess/" rel="alternate" type="text/html" title="RAG评估" /><published>2026-05-06T00:00:00+00:00</published><updated>2026-05-06T00:00:00+00:00</updated><id>https://zlxydl.github.io/RAG_Assess</id><content type="html" xml:base="https://zlxydl.github.io/RAG_Assess/"><![CDATA[<p>rag</p>]]></content><author><name>zlxydl</name></author><category term="llm" /><summary type="html"><![CDATA[rag]]></summary></entry></feed>