<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>ZhouJie&#39;s Blog</title>
  
  <subtitle>向阳而生</subtitle>
  <link href="/atom.xml" rel="self"/>
  
  <link href="http://yoursite.com/"/>
  <updated>2019-12-18T04:25:50.464Z</updated>
  <id>http://yoursite.com/</id>
  
  <author>
    <name>ZhouJie</name>
    
  </author>
  
  <generator uri="http://hexo.io/">Hexo</generator>
  
  <entry>
    <title>刷题汇总（六）leetcode 多线程 / Shell</title>
    <link href="http://yoursite.com/2019/12/17/33/"/>
    <id>http://yoursite.com/2019/12/17/33/</id>
    <published>2019-12-17T13:55:52.000Z</published>
    <updated>2019-12-18T04:25:50.464Z</updated>
    
    <content type="html"><![CDATA[<h3 id="题目来源"><a href="#题目来源" class="headerlink" title="题目来源"></a>题目来源</h3><p> <a href="https://leetcode-cn.com/problemset/all/" target="_blank" rel="noopener">leetcode 多线程 / Shell</a></p><p>相关：<br><a href="https://blog.csdn.net/ffcjjhv/article/details/88409676" target="_blank" rel="noopener">刷题汇总（一）leetcode 精选50题 JavaScript答案总结</a><br><a href="https://blog.csdn.net/ffcjjhv/article/details/96879804" target="_blank" rel="noopener">刷题汇总（二）剑指Offer 66题 C++答案总结</a><br><a href="https://blog.csdn.net/ffcjjhv/article/details/100104411" target="_blank" rel="noopener">刷题汇总（三）leetcode 精选50题 C++答案总结</a><br><a href="https://blog.csdn.net/ffcjjhv/article/details/103195691" target="_blank" rel="noopener">刷题汇总（四）技术类编程题汇总 C++</a><br><a href="https://blog.csdn.net/ffcjjhv/article/details/103381516" target="_blank" rel="noopener">刷题汇总（五）leetcode 热题 HOT 100 C++ 答案总结</a></p><p>这篇文章使用 POSIX 编写多线程 C++ 程序。POSIX Threads 或 Pthreads 提供的 API 可在多种类 Unix POSIX 系统上可用，比如 FreeBSD、NetBSD、GNU/Linux、Mac OS X 和 Solaris。</p><a id="more"></a><blockquote><p>知识点1：创建线程/终止线程</p></blockquote><p> #include &lt;pthread.h&gt;<br>pthread_create (thread, attr, start_routine, arg)<br>pthread_exit (status) </p><blockquote><p>使用 -lpthread 库编译：<br>$ g++ test.cpp -lpthread -o test.o</p></blockquote><h1 id="多线程"><a href="#多线程" class="headerlink" title="多线程"></a>多线程</h1><h2 id="1、按序打印"><a href="#1、按序打印" class="headerlink" title="1、按序打印"></a>1、按序打印</h2><p>我们提供了一个类：</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">public class Foo &#123;</span><br><span class="line">  public void one() &#123; print(&quot;one&quot;); &#125;</span><br><span class="line">  public void two() &#123; print(&quot;two&quot;); &#125;</span><br><span class="line">  public void three() &#123; print(&quot;three&quot;); &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>三个不同的线程将会共用一个 Foo 实例。</p><p>线程 A 将会调用 one() 方法<br>线程 B 将会调用 two() 方法<br>线程 C 将会调用 three() 方法<br>请设计修改程序，以确保 two() 方法在 one() 方法之后被执行，three() 方法在 two() 方法之后被执行。</p><p>示例 1:</p><p>输入: [1,2,3]<br>输出: “onetwothree”<br>解释:<br>有三个线程会被异步启动。<br>输入 [1,2,3] 表示线程 A 将会调用 one() 方法，线程 B 将会调用 two() 方法，线程 C 将会调用 three() 方法。<br>正确的输出是 “onetwothree”。<br>示例 2:</p><p>输入: [1,3,2]<br>输出: “onetwothree”<br>解释:<br>输入 [1,3,2] 表示线程 A 将会调用 one() 方法，线程 B 将会调用 three() 方法，线程 C 将会调用 two() 方法。<br>正确的输出是 “onetwothree”。</p><p>注意:</p><p>尽管输入中的数字似乎暗示了顺序，但是我们并不保证线程在操作系统中的调度顺序。<br>你看到的输入格式主要是为了确保测试的全面性。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;semaphore.h&gt;</span></span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Foo</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="keyword">sem_t</span> t1, t2, t3;</span><br><span class="line"></span><br><span class="line">    Foo() &#123;</span><br><span class="line">        sem_init(&amp;t1,<span class="number">0</span>,<span class="number">1</span>);</span><br><span class="line">        sem_init(&amp;t2,<span class="number">0</span>,<span class="number">0</span>);</span><br><span class="line">        sem_init(&amp;t3,<span class="number">0</span>,<span class="number">0</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">first</span><span class="params">(function&lt;<span class="keyword">void</span>()&gt; printFirst)</span> </span>&#123;</span><br><span class="line">        sem_wait(&amp;t1);</span><br><span class="line">        <span class="comment">// printFirst() outputs "first". Do not change or remove this line.</span></span><br><span class="line">        printFirst();</span><br><span class="line">        sem_post(&amp;t2);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">second</span><span class="params">(function&lt;<span class="keyword">void</span>()&gt; printSecond)</span> </span>&#123;</span><br><span class="line">        sem_wait(&amp;t2);</span><br><span class="line">        <span class="comment">// printSecond() outputs "second". Do not change or remove this line.</span></span><br><span class="line">        printSecond();</span><br><span class="line">        sem_post(&amp;t3);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">third</span><span class="params">(function&lt;<span class="keyword">void</span>()&gt; printThird)</span> </span>&#123;</span><br><span class="line">        sem_wait(&amp;t3);</span><br><span class="line">        <span class="comment">// printThird() outputs "third". Do not change or remove this line.</span></span><br><span class="line">        printThird();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><blockquote><p>知识点2：信号量</p></blockquote><p>#include &lt;semaphore.h&gt;<br>int sem_init(sem_t *sem, int pshared, unsigned int val); // 初始化信号量<br>int sem_wait(sem_t *sem); // 信号量减1<br>int sem_post(sem_t *sem); // 信号量加1<br>int sem_destory(sem_t *sem); // 销毁信号量</p><h2 id="2、交替打印FooBar"><a href="#2、交替打印FooBar" class="headerlink" title="2、交替打印FooBar"></a>2、交替打印FooBar</h2><p>我们提供一个类：</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">class FooBar &#123;</span><br><span class="line">  public void foo() &#123;</span><br><span class="line">    for (int i = 0; i &lt; n; i++) &#123;</span><br><span class="line">      print(&quot;foo&quot;);</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  public void bar() &#123;</span><br><span class="line">    for (int i = 0; i &lt; n; i++) &#123;</span><br><span class="line">      print(&quot;bar&quot;);</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>两个不同的线程将会共用一个 FooBar 实例。其中一个线程将会调用 foo() 方法，另一个线程将会调用 bar() 方法。</p><p>请设计修改程序，以确保 “foobar” 被输出 n 次。</p><p>示例 1:</p><p>输入: n = 1<br>输出: “foobar”<br>解释: 这里有两个线程被异步启动。其中一个调用 foo() 方法, 另一个调用 bar() 方法，”foobar” 将被输出一次。<br>示例 2:</p><p>输入: n = 2<br>输出: “foobarfoobar”</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta"># <span class="meta-keyword">include</span><span class="meta-string">&lt;semaphore.h&gt;</span></span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">FooBar</span> &#123;</span></span><br><span class="line"><span class="keyword">private</span>:</span><br><span class="line">    <span class="keyword">int</span> n;</span><br><span class="line">    <span class="keyword">sem_t</span> t1, t2;</span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    FooBar(<span class="keyword">int</span> n) &#123;</span><br><span class="line">        <span class="keyword">this</span>-&gt;n = n;</span><br><span class="line">        sem_init(&amp;t1,<span class="number">0</span>,<span class="number">1</span>);</span><br><span class="line">        sem_init(&amp;t2,<span class="number">0</span>,<span class="number">0</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">foo</span><span class="params">(function&lt;<span class="keyword">void</span>()&gt; printFoo)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; n; i++) &#123;</span><br><span class="line">            sem_wait(&amp;t1);</span><br><span class="line">            <span class="comment">// printFoo() outputs "foo". Do not change or remove this line.</span></span><br><span class="line">        printFoo();</span><br><span class="line">            sem_post(&amp;t2);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">bar</span><span class="params">(function&lt;<span class="keyword">void</span>()&gt; printBar)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; n; i++) &#123;</span><br><span class="line">            sem_wait(&amp;t2);</span><br><span class="line">            <span class="comment">// printBar() outputs "bar". Do not change or remove this line.</span></span><br><span class="line">        printBar();</span><br><span class="line">            sem_post(&amp;t1);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">FooBar</span> &#123;</span></span><br><span class="line"><span class="keyword">private</span>:</span><br><span class="line">    <span class="keyword">int</span> n;</span><br><span class="line">    <span class="keyword">pthread_mutex_t</span> t1, t2;</span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    FooBar(<span class="keyword">int</span> n) &#123;</span><br><span class="line">        <span class="keyword">this</span>-&gt;n = n;</span><br><span class="line">        pthread_mutex_init(&amp;t1,<span class="literal">NULL</span>);</span><br><span class="line">        pthread_mutex_init(&amp;t2,<span class="literal">NULL</span>);</span><br><span class="line">        pthread_mutex_lock(&amp;t2);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">foo</span><span class="params">(function&lt;<span class="keyword">void</span>()&gt; printFoo)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; n; i++) &#123;</span><br><span class="line">            pthread_mutex_lock(&amp;t1);</span><br><span class="line">            <span class="comment">// printFoo() outputs "foo". Do not change or remove this line.</span></span><br><span class="line">        printFoo();</span><br><span class="line">            pthread_mutex_unlock(&amp;t2);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">bar</span><span class="params">(function&lt;<span class="keyword">void</span>()&gt; printBar)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; n; i++) &#123;</span><br><span class="line">            pthread_mutex_lock(&amp;t2);</span><br><span class="line">            <span class="comment">// printBar() outputs "bar". Do not change or remove this line.</span></span><br><span class="line">        printBar();</span><br><span class="line">            pthread_mutex_unlock(&amp;t1);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><blockquote><p>知识点3：互斥量<br>pthread_mutex_t sum_mutex; //互斥锁<br>pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER //静态初始化<br>pthread_mutex_init( &amp;sum_mutex, NULL ); //动态初始化 初始化成功返回0<br>pthread_mutex_lock( &amp;sum_mutex ); //加锁<br>pthread_mutex_unlock( &amp;sum_mutex ); //释放锁，供其他线程使用<br>pthread_mutex_destroy( &amp;sum_mutex ); //注销锁</p></blockquote><h2 id="3、打印零与奇偶数"><a href="#3、打印零与奇偶数" class="headerlink" title="3、打印零与奇偶数"></a>3、打印零与奇偶数</h2><p>假设有这么一个类：</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">class ZeroEvenOdd &#123;</span><br><span class="line">  public ZeroEvenOdd(int n) &#123; ... &#125;      // 构造函数</span><br><span class="line">  public void zero(printNumber) &#123; ... &#125;  // 仅打印出 0</span><br><span class="line">  public void even(printNumber) &#123; ... &#125;  // 仅打印出 偶数</span><br><span class="line">  public void odd(printNumber) &#123; ... &#125;   // 仅打印出 奇数</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>相同的一个 ZeroEvenOdd 类实例将会传递给三个不同的线程：</p><p>线程 A 将调用 zero()，它只输出 0 。<br>线程 B 将调用 even()，它只输出偶数。<br>线程 C 将调用 odd()，它只输出奇数。<br>每个线程都有一个 printNumber 方法来输出一个整数。请修改给出的代码以输出整数序列 010203040506… ，其中序列的长度必须为 2n。</p><p>示例 1：</p><p>输入：n = 2<br>输出：”0102”<br>说明：三条线程异步执行，其中一个调用 zero()，另一个线程调用 even()，最后一个线程调用odd()。正确的输出为 “0102”。<br>示例 2：</p><p>输入：n = 5<br>输出：”0102030405”</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta"># <span class="meta-keyword">include</span><span class="meta-string">&lt;semaphore.h&gt;</span></span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">ZeroEvenOdd</span> &#123;</span></span><br><span class="line"><span class="keyword">private</span>:</span><br><span class="line">    <span class="keyword">int</span> n;</span><br><span class="line">    <span class="keyword">sem_t</span> t0, t1, t2;</span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    ZeroEvenOdd(<span class="keyword">int</span> n) &#123;</span><br><span class="line">        <span class="keyword">this</span>-&gt;n = n;</span><br><span class="line">        sem_init(&amp;t0,<span class="number">0</span>,<span class="number">1</span>);</span><br><span class="line">        sem_init(&amp;t1,<span class="number">0</span>,<span class="number">0</span>);</span><br><span class="line">        sem_init(&amp;t2,<span class="number">0</span>,<span class="number">0</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// printNumber(x) outputs "x", where x is an integer.</span></span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">zero</span><span class="params">(function&lt;<span class="keyword">void</span>(<span class="keyword">int</span>)&gt; printNumber)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">1</span>;i&lt;=n;i++)&#123;</span><br><span class="line">            sem_wait(&amp;t0);</span><br><span class="line">            printNumber(<span class="number">0</span>);</span><br><span class="line">            <span class="keyword">if</span>(i%<span class="number">2</span>==<span class="number">1</span>) sem_post(&amp;t1);</span><br><span class="line">            <span class="keyword">else</span> sem_post(&amp;t2);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">even</span><span class="params">(function&lt;<span class="keyword">void</span>(<span class="keyword">int</span>)&gt; printNumber)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">2</span>;i&lt;=n;i+=<span class="number">2</span>)&#123;</span><br><span class="line">            sem_wait(&amp;t2);</span><br><span class="line">            printNumber(i);</span><br><span class="line">            sem_post(&amp;t0);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">odd</span><span class="params">(function&lt;<span class="keyword">void</span>(<span class="keyword">int</span>)&gt; printNumber)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">1</span>;i&lt;=n;i+=<span class="number">2</span>)&#123;</span><br><span class="line">            sem_wait(&amp;t1);</span><br><span class="line">            printNumber(i);</span><br><span class="line">            sem_post(&amp;t0);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h2 id="4、H2O-生成"><a href="#4、H2O-生成" class="headerlink" title="4、H2O 生成"></a>4、H2O 生成</h2><p>现在有两种线程，氢 oxygen 和氧 hydrogen，你的目标是组织这两种线程来产生水分子。</p><p>存在一个屏障（barrier）使得每个线程必须等候直到一个完整水分子能够被产生出来。</p><p>氢和氧线程会被分别给予 releaseHydrogen 和 releaseOxygen 方法来允许它们突破屏障。</p><p>这些线程应该三三成组突破屏障并能立即组合产生一个水分子。</p><p>你必须保证产生一个水分子所需线程的结合必须发生在下一个水分子产生之前。</p><p>换句话说:</p><p>如果一个氧线程到达屏障时没有氢线程到达，它必须等候直到两个氢线程到达。<br>如果一个氢线程到达屏障时没有其它线程到达，它必须等候直到一个氧线程和另一个氢线程到达。<br>书写满足这些限制条件的氢、氧线程同步代码。</p><p>示例 1:</p><p>输入: “HOH”<br>输出: “HHO”<br>解释: “HOH” 和 “OHH” 依然都是有效解。<br>示例 2:</p><p>输入: “OOHHHH”<br>输出: “HHOHHO”<br>解释: “HOHHHO”, “OHHHHO”, “HHOHOH”, “HOHHOH”, “OHHHOH”, “HHOOHH”, “HOHOHH” 和 “OHHOHH” 依然都是有效解。</p><p>限制条件:</p><p>输入字符串的总长将会是 3n, 1 ≤ n ≤ 50；<br>输入字符串中的 “H” 总数将会是 2n；<br>输入字符串中的 “O” 总数将会是 n。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta"># <span class="meta-keyword">include</span><span class="meta-string">&lt;semaphore.h&gt;</span></span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">H2O</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="keyword">sem_t</span> h_limit, o_limit, h, o;</span><br><span class="line"></span><br><span class="line">    H2O() &#123;</span><br><span class="line">        sem_init(&amp;h_limit,<span class="number">0</span>,<span class="number">2</span>);</span><br><span class="line">        sem_init(&amp;o_limit,<span class="number">0</span>,<span class="number">1</span>);</span><br><span class="line">        sem_init(&amp;h,<span class="number">0</span>,<span class="number">0</span>);</span><br><span class="line">        sem_init(&amp;o,<span class="number">0</span>,<span class="number">0</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">hydrogen</span><span class="params">(function&lt;<span class="keyword">void</span>()&gt; releaseHydrogen)</span> </span>&#123;</span><br><span class="line">        sem_wait(&amp;h_limit);</span><br><span class="line">        sem_post(&amp;h);</span><br><span class="line">        sem_wait(&amp;o);</span><br><span class="line">        <span class="comment">// releaseHydrogen() outputs "H". Do not change or remove this line.</span></span><br><span class="line">        releaseHydrogen();</span><br><span class="line">        sem_post(&amp;h_limit);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">oxygen</span><span class="params">(function&lt;<span class="keyword">void</span>()&gt; releaseOxygen)</span> </span>&#123;</span><br><span class="line">        sem_wait(&amp;o_limit);</span><br><span class="line">        sem_post(&amp;o);</span><br><span class="line">        sem_post(&amp;o);</span><br><span class="line">        sem_wait(&amp;h);</span><br><span class="line">        sem_wait(&amp;h);</span><br><span class="line">        <span class="comment">// releaseOxygen() outputs "O". Do not change or remove this line.</span></span><br><span class="line">        releaseOxygen();</span><br><span class="line">        sem_post(&amp;o_limit);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h2 id="5、交替打印字符串"><a href="#5、交替打印字符串" class="headerlink" title="5、交替打印字符串"></a>5、交替打印字符串</h2><p>编写一个可以从 1 到 n 输出代表这个数字的字符串的程序，但是：</p><p>如果这个数字可以被 3 整除，输出 “fizz”。<br>如果这个数字可以被 5 整除，输出 “buzz”。<br>如果这个数字可以同时被 3 和 5 整除，输出 “fizzbuzz”。<br>例如，当 n = 15，输出： 1, 2, fizz, 4, buzz, fizz, 7, 8, fizz, buzz, 11, fizz, 13, 14, fizzbuzz。</p><p>假设有这么一个类：</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">class FizzBuzz &#123;</span><br><span class="line">  public FizzBuzz(int n) &#123; ... &#125;               // constructor</span><br><span class="line">  public void fizz(printFizz) &#123; ... &#125;          // only output &quot;fizz&quot;</span><br><span class="line">  public void buzz(printBuzz) &#123; ... &#125;          // only output &quot;buzz&quot;</span><br><span class="line">  public void fizzbuzz(printFizzBuzz) &#123; ... &#125;  // only output &quot;fizzbuzz&quot;</span><br><span class="line">  public void number(printNumber) &#123; ... &#125;      // only output the numbers</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>请你实现一个有四个线程的多线程版  FizzBuzz， 同一个 FizzBuzz 实例会被如下四个线程使用：</p><p>线程A将调用 fizz() 来判断是否能被 3 整除，如果可以，则输出 fizz。<br>线程B将调用 buzz() 来判断是否能被 5 整除，如果可以，则输出 buzz。<br>线程C将调用 fizzbuzz() 来判断是否同时能被 3 和 5 整除，如果可以，则输出 fizzbuzz。<br>线程D将调用 number() 来实现输出既不能被 3 整除也不能被 5 整除的数字。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta"># <span class="meta-keyword">include</span><span class="meta-string">&lt;semaphore.h&gt;</span></span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">FizzBuzz</span> &#123;</span></span><br><span class="line"><span class="keyword">private</span>:</span><br><span class="line">    <span class="keyword">int</span> n;</span><br><span class="line">    <span class="keyword">sem_t</span> t0, t3, t5, t35;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    FizzBuzz(<span class="keyword">int</span> n) &#123;</span><br><span class="line">        <span class="keyword">this</span>-&gt;n = n;</span><br><span class="line">        sem_init(&amp;t0,<span class="number">0</span>,<span class="number">1</span>);</span><br><span class="line">        sem_init(&amp;t3,<span class="number">0</span>,<span class="number">0</span>);</span><br><span class="line">        sem_init(&amp;t5,<span class="number">0</span>,<span class="number">0</span>);</span><br><span class="line">        sem_init(&amp;t35,<span class="number">0</span>,<span class="number">0</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// printFizz() outputs "fizz".</span></span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">fizz</span><span class="params">(function&lt;<span class="keyword">void</span>()&gt; printFizz)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">1</span>;i&lt;=n;i++)&#123;</span><br><span class="line">            <span class="keyword">if</span>(i%<span class="number">3</span>==<span class="number">0</span> &amp;&amp; i%<span class="number">5</span>!=<span class="number">0</span>)&#123;</span><br><span class="line">                sem_wait(&amp;t3);</span><br><span class="line">                printFizz();</span><br><span class="line">                sem_post(&amp;t0);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// printBuzz() outputs "buzz".</span></span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">buzz</span><span class="params">(function&lt;<span class="keyword">void</span>()&gt; printBuzz)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">1</span>;i&lt;=n;i++)&#123;</span><br><span class="line">            <span class="keyword">if</span>(i%<span class="number">3</span>!=<span class="number">0</span> &amp;&amp; i%<span class="number">5</span>==<span class="number">0</span>)&#123;</span><br><span class="line">                sem_wait(&amp;t5);</span><br><span class="line">                printBuzz();</span><br><span class="line">                sem_post(&amp;t0);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// printFizzBuzz() outputs "fizzbuzz".</span></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">fizzbuzz</span><span class="params">(function&lt;<span class="keyword">void</span>()&gt; printFizzBuzz)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">1</span>;i&lt;=n;i++)&#123;</span><br><span class="line">            <span class="keyword">if</span>(i%<span class="number">3</span>==<span class="number">0</span> &amp;&amp; i%<span class="number">5</span>==<span class="number">0</span>)&#123;</span><br><span class="line">                sem_wait(&amp;t35);</span><br><span class="line">                printFizzBuzz();</span><br><span class="line">                sem_post(&amp;t0);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// printNumber(x) outputs "x", where x is an integer.</span></span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">number</span><span class="params">(function&lt;<span class="keyword">void</span>(<span class="keyword">int</span>)&gt; printNumber)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">1</span>;i&lt;=n;i++)&#123;</span><br><span class="line">            sem_wait(&amp;t0);</span><br><span class="line">            <span class="keyword">if</span>(i%<span class="number">3</span>!=<span class="number">0</span> &amp;&amp; i%<span class="number">5</span>!=<span class="number">0</span>)&#123;</span><br><span class="line">                printNumber(i);</span><br><span class="line">                sem_post(&amp;t0);</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">else</span> <span class="keyword">if</span>(i%<span class="number">3</span>==<span class="number">0</span> &amp;&amp; i%<span class="number">5</span>!=<span class="number">0</span>)&#123;</span><br><span class="line">                sem_post(&amp;t3);</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">else</span> <span class="keyword">if</span>(i%<span class="number">3</span>!=<span class="number">0</span> &amp;&amp; i%<span class="number">5</span>==<span class="number">0</span>)&#123;</span><br><span class="line">                sem_post(&amp;t5);</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">else</span>&#123;</span><br><span class="line">                sem_post(&amp;t35);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h2 id="6、哲学家进餐"><a href="#6、哲学家进餐" class="headerlink" title="6、哲学家进餐"></a>6、哲学家进餐</h2><p>5 个沉默寡言的哲学家围坐在圆桌前，每人面前一盘意面。叉子放在哲学家之间的桌面上。（5 个哲学家，5 根叉子）</p><p>所有的哲学家都只会在思考和进餐两种行为间交替。哲学家只有同时拿到左边和右边的叉子才能吃到面，而同一根叉子在同一时间只能被一个哲学家使用。每个哲学家吃完面后都需要把叉子放回桌面以供其他哲学家吃面。只要条件允许，哲学家可以拿起左边或者右边的叉子，但在没有同时拿到左右叉子时不能进食。</p><p>假设面的数量没有限制，哲学家也能随便吃，不需要考虑吃不吃得下。</p><p>设计一个进餐规则（并行算法）使得每个哲学家都不会挨饿；也就是说，在没有人知道别人什么时候想吃东西或思考的情况下，每个哲学家都可以在吃饭和思考之间一直交替下去。<br><img src="https://img-blog.csdnimg.cn/20191212164536598.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZmY2pqaHY=,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"></p><p>问题描述和图片来自维基百科 wikipedia.org</p><p>哲学家从 0 到 4 按 顺时针 编号。请实现函数 void wantsToEat(philosopher, pickLeftFork, pickRightFork, eat, putLeftFork, putRightFork)：</p><p>philosopher 哲学家的编号。<br>pickLeftFork 和 pickRightFork 表示拿起左边或右边的叉子。<br>eat 表示吃面。<br>putLeftFork 和 pickRightFork 表示放下左边或右边的叉子。<br>由于哲学家不是在吃面就是在想着啥时候吃面，所以思考这个方法没有对应的回调。<br>给你 5 个线程，每个都代表一个哲学家，请你使用类的同一个对象来模拟这个过程。在最后一次调用结束之前，可能会为同一个哲学家多次调用该函数。</p><p>示例：</p><p>输入：n = 1<br>输出：[[4,2,1],[4,1,1],[0,1,1],[2,2,1],[2,1,1],[2,0,3],[2,1,2],[2,2,2],[4,0,3],[4,1,2],[0,2,1],[4,2,2],[3,2,1],[3,1,1],[0,0,3],[0,1,2],[0,2,2],[1,2,1],[1,1,1],[3,0,3],[3,1,2],[3,2,2],[1,0,3],[1,1,2],[1,2,2]]<br>解释:<br>n 表示每个哲学家需要进餐的次数。<br>输出数组描述了叉子的控制和进餐的调用，它的格式如下：<br>output[i] = [a, b, c] (3个整数)</p><ul><li>a 哲学家编号。</li><li>b 指定叉子：{1 : 左边, 2 : 右边}.</li><li>c 指定行为：{1 : 拿起, 2 : 放下, 3 : 吃面}。<br>如 [4,2,1] 表示 4 号哲学家拿起了右边的叉子。</li></ul><p>提示：<br>1 &lt;= n &lt;= 60</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta"># <span class="meta-keyword">include</span><span class="meta-string">&lt;semaphore.h&gt;</span></span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">DiningPhilosophers</span> &#123;</span></span><br><span class="line"><span class="keyword">private</span>:</span><br><span class="line">    <span class="keyword">sem_t</span> sem;</span><br><span class="line">    <span class="keyword">pthread_mutex_t</span> mutex[<span class="number">5</span>];</span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    DiningPhilosophers() &#123;</span><br><span class="line">        sem_init(&amp;sem,<span class="number">0</span>,<span class="number">4</span>);</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;<span class="number">5</span>;i++)&#123;</span><br><span class="line">            pthread_mutex_init(&amp;mutex[i],<span class="literal">NULL</span>);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 限定哲学家就餐数量</span></span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">wantsToEat</span><span class="params">(<span class="keyword">int</span> philosopher,</span></span></span><br><span class="line"><span class="function"><span class="params">                    function&lt;<span class="keyword">void</span>()&gt; pickLeftFork,</span></span></span><br><span class="line"><span class="function"><span class="params">                    function&lt;<span class="keyword">void</span>()&gt; pickRightFork,</span></span></span><br><span class="line"><span class="function"><span class="params">                    function&lt;<span class="keyword">void</span>()&gt; eat,</span></span></span><br><span class="line"><span class="function"><span class="params">                    function&lt;<span class="keyword">void</span>()&gt; putLeftFork,</span></span></span><br><span class="line"><span class="function"><span class="params">                    function&lt;<span class="keyword">void</span>()&gt; putRightFork)</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">                    <span class="keyword">int</span> left = philosopher;</span><br><span class="line">                    <span class="keyword">int</span> right = (philosopher+<span class="number">1</span>)%<span class="number">5</span>;</span><br><span class="line"></span><br><span class="line">                    sem_wait(&amp;sem);</span><br><span class="line">                    pthread_mutex_lock(&amp;mutex[left]);</span><br><span class="line">                    pthread_mutex_lock(&amp;mutex[right]);</span><br><span class="line"></span><br><span class="line">                    pickLeftFork();</span><br><span class="line">                    pickRightFork();</span><br><span class="line"></span><br><span class="line">                    eat();</span><br><span class="line"></span><br><span class="line">                    putLeftFork();</span><br><span class="line">                    putRightFork();</span><br><span class="line"></span><br><span class="line">                    pthread_mutex_unlock(&amp;mutex[left]);</span><br><span class="line">                    pthread_mutex_unlock(&amp;mutex[right]);</span><br><span class="line"></span><br><span class="line">                    sem_post(&amp;sem);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta"># <span class="meta-keyword">include</span><span class="meta-string">&lt;semaphore.h&gt;</span></span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">DiningPhilosophers</span> &#123;</span></span><br><span class="line"><span class="keyword">private</span>:</span><br><span class="line">    <span class="keyword">pthread_mutex_t</span> mutex;</span><br><span class="line">    <span class="keyword">pthread_mutex_t</span> forks_mutex[<span class="number">5</span>];</span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    DiningPhilosophers() &#123;</span><br><span class="line">        pthread_mutex_init(&amp;mutex,<span class="literal">NULL</span>);</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;<span class="number">5</span>;i++)&#123;</span><br><span class="line">            pthread_mutex_init(&amp;forks_mutex[i],<span class="literal">NULL</span>);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 同时拿起左右2把叉子</span></span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">wantsToEat</span><span class="params">(<span class="keyword">int</span> philosopher,</span></span></span><br><span class="line"><span class="function"><span class="params">                    function&lt;<span class="keyword">void</span>()&gt; pickLeftFork,</span></span></span><br><span class="line"><span class="function"><span class="params">                    function&lt;<span class="keyword">void</span>()&gt; pickRightFork,</span></span></span><br><span class="line"><span class="function"><span class="params">                    function&lt;<span class="keyword">void</span>()&gt; eat,</span></span></span><br><span class="line"><span class="function"><span class="params">                    function&lt;<span class="keyword">void</span>()&gt; putLeftFork,</span></span></span><br><span class="line"><span class="function"><span class="params">                    function&lt;<span class="keyword">void</span>()&gt; putRightFork)</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">                    <span class="keyword">int</span> left = philosopher;</span><br><span class="line">                    <span class="keyword">int</span> right = (philosopher+<span class="number">1</span>)%<span class="number">5</span>;</span><br><span class="line"></span><br><span class="line">                    pthread_mutex_lock(&amp;mutex);</span><br><span class="line"></span><br><span class="line">                    pthread_mutex_lock(&amp;forks_mutex[left]);</span><br><span class="line">                    pthread_mutex_lock(&amp;forks_mutex[right]);</span><br><span class="line"></span><br><span class="line">                    pickLeftFork();</span><br><span class="line">                    pickRightFork();</span><br><span class="line"></span><br><span class="line">                    pthread_mutex_unlock(&amp;mutex);</span><br><span class="line"></span><br><span class="line">                    eat();</span><br><span class="line"></span><br><span class="line">                    putLeftFork();</span><br><span class="line">                    putRightFork();</span><br><span class="line"></span><br><span class="line">                    pthread_mutex_unlock(&amp;forks_mutex[left]);</span><br><span class="line">                    pthread_mutex_unlock(&amp;forks_mutex[right]);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta"># <span class="meta-keyword">include</span><span class="meta-string">&lt;semaphore.h&gt;</span></span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">DiningPhilosophers</span> &#123;</span></span><br><span class="line"><span class="keyword">private</span>:</span><br><span class="line">    <span class="keyword">pthread_mutex_t</span> forks_mutex[<span class="number">5</span>];</span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    DiningPhilosophers() &#123;</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;<span class="number">5</span>;i++)&#123;</span><br><span class="line">            pthread_mutex_init(&amp;forks_mutex[i],<span class="literal">NULL</span>);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 一部分哲学家优先去获取其左边的叉子，再去获取其右边的叉子；</span></span><br><span class="line">    <span class="comment">// 再让剩余哲学家优先去获取其右边的叉子，再去获取其左边的叉子</span></span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">wantsToEat</span><span class="params">(<span class="keyword">int</span> philosopher,</span></span></span><br><span class="line"><span class="function"><span class="params">                    function&lt;<span class="keyword">void</span>()&gt; pickLeftFork,</span></span></span><br><span class="line"><span class="function"><span class="params">                    function&lt;<span class="keyword">void</span>()&gt; pickRightFork,</span></span></span><br><span class="line"><span class="function"><span class="params">                    function&lt;<span class="keyword">void</span>()&gt; eat,</span></span></span><br><span class="line"><span class="function"><span class="params">                    function&lt;<span class="keyword">void</span>()&gt; putLeftFork,</span></span></span><br><span class="line"><span class="function"><span class="params">                    function&lt;<span class="keyword">void</span>()&gt; putRightFork)</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">                    <span class="keyword">int</span> left = philosopher;</span><br><span class="line">                    <span class="keyword">int</span> right = (philosopher+<span class="number">1</span>)%<span class="number">5</span>;</span><br><span class="line"></span><br><span class="line">                    <span class="keyword">if</span>(philosopher%<span class="number">2</span> == <span class="number">1</span>)&#123;</span><br><span class="line">                        pthread_mutex_lock(&amp;forks_mutex[left]);</span><br><span class="line">                        pthread_mutex_lock(&amp;forks_mutex[right]);</span><br><span class="line">                    &#125;</span><br><span class="line">                    <span class="keyword">else</span>&#123;</span><br><span class="line">                        pthread_mutex_lock(&amp;forks_mutex[right]);</span><br><span class="line">                        pthread_mutex_lock(&amp;forks_mutex[left]);</span><br><span class="line"></span><br><span class="line">                    &#125;</span><br><span class="line"></span><br><span class="line">                    pickLeftFork();</span><br><span class="line">                    pickRightFork();</span><br><span class="line"></span><br><span class="line">                    eat();</span><br><span class="line"></span><br><span class="line">                    putLeftFork();</span><br><span class="line">                    putRightFork();</span><br><span class="line"></span><br><span class="line">                    pthread_mutex_unlock(&amp;forks_mutex[left]);</span><br><span class="line">                    pthread_mutex_unlock(&amp;forks_mutex[right]);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="Shell"><a href="#Shell" class="headerlink" title="Shell"></a>Shell</h1><h2 id="1、统计词频"><a href="#1、统计词频" class="headerlink" title="1、统计词频"></a>1、统计词频</h2><p>写一个 bash 脚本以统计一个文本文件 words.txt 中每个单词出现的频率。</p><p>为了简单起见，你可以假设：</p><p>words.txt只包括小写字母和 ‘ ‘ 。<br>每个单词只由小写字母组成。<br>单词间由一个或多个空格字符分隔。<br>示例:</p><p>假设 words.txt 内容如下：</p><p>the day is sunny the the<br>the sunny is is<br>你的脚本应当输出（以词频降序排列）：</p><p>the 4<br>is 3<br>sunny 2<br>day 1<br>说明:</p><p>不要担心词频相同的单词的排序问题，每个单词出现的频率都是唯一的。<br>你可以使用一行 Unix pipes 实现吗？</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#</span> Read from the file words.txt and output the word frequency list to stdout.</span><br><span class="line">cat words.txt | xargs -n1 | awk '&#123;data[$1] += 1&#125; END &#123;for(str in data) print data[str],str&#125;' | sort -nr | awk '&#123;print $2, $1&#125;'</span><br></pre></td></tr></table></figure><blockquote><p>xargs 用作替换工具，读取输入数据重新格式化后输出<br># cat test.txt<br>a b c d e<br>f g h<br>$ cat test.txt | xargs -n3<br>a b c<br>d e f<br>g h<br>按照数值大小 反向排序<br>$ sort -nr </p></blockquote><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">cat words.txt | xargs -n1 | awk '&#123;data[$1] += 1&#125; END &#123;for(str in data) print str,data[str]&#125;' | sort -nr -k2</span><br></pre></td></tr></table></figure><blockquote><p>将第二列按照数值大小 反向排序<br> $ sort -nr -k2<br> <figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">cat words.txt | awk <span class="string">'&#123;for(i=1;i&lt;=NF;i++) data[$i] += 1&#125; END &#123;for(str in data) print str,data[str]&#125;'</span> | sort -nr -k2</span><br></pre></td></tr></table></figure></p></blockquote> <figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">awk <span class="string">'&#123;for(i=1;i&lt;=NF;i++) data[$i] += 1&#125; END &#123;for(str in data) print str,data[str]&#125;'</span> words.txt | sort -nr -k2</span><br></pre></td></tr></table></figure><blockquote><p>NF    一条记录的字段的数目<br>NR    已经读出的记录数，就是行号，从1开始</p></blockquote><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">cat words.txt | xargs -n1 | sort | uniq -c | sort -nr | awk '&#123;print $2,$1&#125;'</span><br></pre></td></tr></table></figure><blockquote><p>统计各行在文件中出现的次数：<br>$ sort testfile | uniq -c<br>当重复的行并不相邻时，uniq 命令是不起作用的，因此常与sort一起使用</p></blockquote><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">cat words.txt | tr -s ' ' '\n' | sort | uniq -c | sort -nr | awk '&#123;print $2,$1&#125;'</span><br></pre></td></tr></table></figure><blockquote><p>空格改为换行符<br> $ tr -s ‘ ‘ ‘\n’<br>缩减连续重复的字符成指定的单个字符</p></blockquote><h2 id="2、有效电话号码"><a href="#2、有效电话号码" class="headerlink" title="2、有效电话号码"></a>2、有效电话号码</h2><p>给定一个包含电话号码列表（一行一个电话号码）的文本文件 file.txt，写一个 bash 脚本输出所有有效的电话号码。</p><p>你可以假设一个有效的电话号码必须满足以下两种格式： (xxx) xxx-xxxx 或 xxx-xxx-xxxx。（x 表示一个数字）</p><p>你也可以假设每行前后没有多余的空格字符。</p><p>示例:</p><p>假设 file.txt 内容如下：</p><p>987-123-4567<br>123 456 7890<br>(123) 456-7890<br>你的脚本应当输出下列有效的电话号码：</p><p>987-123-4567<br>(123) 456-7890</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># Read from the file file.txt and output all valid phone numbers to stdout.</span></span><br><span class="line">grep -E <span class="string">"^\([0-9]&#123;3&#125;\) [0-9]&#123;3&#125;-[0-9]&#123;4&#125;$|^[0-9]&#123;3&#125;-[0-9]&#123;3&#125;-[0-9]&#123;4&#125;$"</span> file.txt</span><br></pre></td></tr></table></figure><blockquote><p>^ 为匹配输入字符串的开始位置,$ 为匹配输入字符串的结束位置</p></blockquote><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">awk "/^\([0-9]&#123;3&#125;\) [0-9]&#123;3&#125;-[0-9]&#123;4&#125;$|^[0-9]&#123;3&#125;-[0-9]&#123;3&#125;-[0-9]&#123;4&#125;$/" file.txt</span><br></pre></td></tr></table></figure><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">awk "/^\([0-9]&#123;3&#125;\) [0-9]&#123;3&#125;-[0-9]&#123;4&#125;$/ || /^[0-9]&#123;3&#125;-[0-9]&#123;3&#125;-[0-9]&#123;4&#125;$/" file.txt</span><br></pre></td></tr></table></figure><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">awk "/^(\([0-9]&#123;3&#125;\) |[0-9]&#123;3&#125;-)[0-9]&#123;3&#125;-[0-9]&#123;4&#125;$/" file.txt</span><br></pre></td></tr></table></figure><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">grep -P "^(\(\d&#123;3&#125;\) |\d&#123;3&#125;-)\d&#123;3&#125;-\d&#123;4&#125;$" file.txt</span><br></pre></td></tr></table></figure><blockquote><p>grep -E主要是用来支持扩展正则表达式 加上-P（使用Perl的正则引擎）在MAC OS下面man grep是没有-P参数的，新的主流正则引擎已经默认加上了-P参数</p></blockquote><h2 id="3、转置文件"><a href="#3、转置文件" class="headerlink" title="3、转置文件"></a>3、转置文件</h2><p>给定一个文件 file.txt，转置它的内容。</p><p>你可以假设每行列数相同，并且每个字段由 ‘ ‘ 分隔.</p><p>示例:</p><p>假设 file.txt 文件内容如下：</p><p>name age<br>alice 21<br>ryan 30<br>应当输出：</p><p>name alice ryan<br>age 21 30</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># Read from the file file.txt and print its transposed content to stdout.</span></span><br><span class="line">awk <span class="string">'&#123;for(i=1;i&lt;=NF;i++)if(arr[i])&#123;arr[i]=arr[i]" "$i&#125;else&#123;arr[i]=$i&#125;&#125;END&#123;for(key in arr)print arr[key]&#125;'</span> file.txt</span><br></pre></td></tr></table></figure><h2 id="4、第十行"><a href="#4、第十行" class="headerlink" title="4、第十行"></a>4、第十行</h2><p>给定一个文本文件 file.txt，请只打印这个文件中的第十行。</p><p>示例:</p><p>假设 file.txt 有如下内容：</p><p>Line 1<br>Line 2<br>Line 3<br>Line 4<br>Line 5<br>Line 6<br>Line 7<br>Line 8<br>Line 9<br>Line 10<br>你的脚本应当显示第十行：</p><p>Line 10<br>说明:</p><ol><li>如果文件少于十行，你应当输出什么？</li><li>至少有三种不同的解法，请尝试尽可能多的方法来解题。</li></ol><figure class="highlight"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">awk 'NR==10' file.txt</span><br></pre></td></tr></table></figure><blockquote><p>NR在awk中指行号</p></blockquote><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">tail -n +10 file.txt | head -1</span><br></pre></td></tr></table></figure><blockquote><p>tail -n +10 从第 10 行至文件末尾</p></blockquote><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sed -n '10p' file.txt</span><br></pre></td></tr></table></figure><blockquote><p>-n表示只输出匹配行，p表示Print</p></blockquote>]]></content>
    
    <summary type="html">
    
      &lt;h3 id=&quot;题目来源&quot;&gt;&lt;a href=&quot;#题目来源&quot; class=&quot;headerlink&quot; title=&quot;题目来源&quot;&gt;&lt;/a&gt;题目来源&lt;/h3&gt;&lt;p&gt; &lt;a href=&quot;https://leetcode-cn.com/problemset/all/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;leetcode 多线程 / Shell&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;相关：&lt;br&gt;&lt;a href=&quot;https://blog.csdn.net/ffcjjhv/article/details/88409676&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;刷题汇总（一）leetcode 精选50题 JavaScript答案总结&lt;/a&gt;&lt;br&gt;&lt;a href=&quot;https://blog.csdn.net/ffcjjhv/article/details/96879804&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;刷题汇总（二）剑指Offer 66题 C++答案总结&lt;/a&gt;&lt;br&gt;&lt;a href=&quot;https://blog.csdn.net/ffcjjhv/article/details/100104411&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;刷题汇总（三）leetcode 精选50题 C++答案总结&lt;/a&gt;&lt;br&gt;&lt;a href=&quot;https://blog.csdn.net/ffcjjhv/article/details/103195691&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;刷题汇总（四）技术类编程题汇总 C++&lt;/a&gt;&lt;br&gt;&lt;a href=&quot;https://blog.csdn.net/ffcjjhv/article/details/103381516&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;刷题汇总（五）leetcode 热题 HOT 100 C++ 答案总结&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;这篇文章使用 POSIX 编写多线程 C++ 程序。POSIX Threads 或 Pthreads 提供的 API 可在多种类 Unix POSIX 系统上可用，比如 FreeBSD、NetBSD、GNU/Linux、Mac OS X 和 Solaris。&lt;/p&gt;
    
    </summary>
    
      <category term="C++" scheme="http://yoursite.com/categories/C/"/>
    
      <category term="后台开发" scheme="http://yoursite.com/categories/%E5%90%8E%E5%8F%B0%E5%BC%80%E5%8F%91/"/>
    
      <category term="CodeCode" scheme="http://yoursite.com/categories/CodeCode/"/>
    
    
      <category term="C++" scheme="http://yoursite.com/tags/C/"/>
    
      <category term="Leetcode" scheme="http://yoursite.com/tags/Leetcode/"/>
    
      <category term="多线程" scheme="http://yoursite.com/tags/%E5%A4%9A%E7%BA%BF%E7%A8%8B/"/>
    
      <category term="Shell" scheme="http://yoursite.com/tags/Shell/"/>
    
  </entry>
  
  <entry>
    <title>刷题汇总（五）leetcode 热题 HOT 100 C++ 答案总结</title>
    <link href="http://yoursite.com/2019/12/05/32/"/>
    <id>http://yoursite.com/2019/12/05/32/</id>
    <published>2019-12-05T04:14:26.000Z</published>
    <updated>2019-12-18T04:24:59.014Z</updated>
    
    <content type="html"><![CDATA[<h3 id="题目来源"><a href="#题目来源" class="headerlink" title="题目来源"></a>题目来源</h3><p> <a href="https://leetcode-cn.com/problemset/hot-100/" target="_blank" rel="noopener">leetcode 热题 HOT 100题</a></p><p>相关：<br><a href="https://blog.csdn.net/ffcjjhv/article/details/88409676" target="_blank" rel="noopener">刷题汇总（一）leetcode 精选50题 JavaScript答案总结</a><br><a href="https://blog.csdn.net/ffcjjhv/article/details/96879804" target="_blank" rel="noopener">刷题汇总（二）剑指Offer 66题 C++答案总结</a><br><a href="https://blog.csdn.net/ffcjjhv/article/details/100104411" target="_blank" rel="noopener">刷题汇总（三）leetcode 精选50题 C++答案总结</a><br><a href="https://blog.csdn.net/ffcjjhv/article/details/103195691" target="_blank" rel="noopener">刷题汇总（四）技术类编程题汇总 C++</a><br><a href="https://blog.csdn.net/ffcjjhv/article/details/103503745" target="_blank" rel="noopener">刷题汇总（六）leetcode 多线程 / Shell</a></p><p><a href="https://pan.baidu.com/s/1fHto2ckVlwQzgUi8TxYReA" target="_blank" rel="noopener">PDF版 code</a>  （提取码：0wxr ）</p><h1 id="1、两数之和"><a href="#1、两数之和" class="headerlink" title="1、两数之和"></a>1、两数之和</h1><p>给定一个整数数组 nums 和一个目标值 target，请你在该数组中找出和为目标值的那 两个 整数，并返回他们的数组下标。</p><a id="more"></a><p>你可以假设每种输入只会对应一个答案。但是，你不能重复利用这个数组中同样的元素。</p><p>示例:</p><p>给定 nums = [2, 7, 11, 15], target = 9</p><p>因为 nums[0] + nums[1] = 2 + 7 = 9<br>所以返回 [0, 1]</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="comment">// 时间复杂度：O(n)，空间复杂度：O(n)</span></span><br><span class="line">    <span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; twoSum(<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt;&amp; nums, <span class="keyword">int</span> target) &#123;</span><br><span class="line">        <span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; res(<span class="number">2</span>);</span><br><span class="line">        <span class="built_in">unordered_map</span>&lt;<span class="keyword">int</span>,<span class="keyword">int</span>&gt; <span class="built_in">map</span>;</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;nums.size();i++)&#123;</span><br><span class="line">            <span class="keyword">int</span> tmp = target - nums[i];</span><br><span class="line">            <span class="keyword">if</span>(<span class="built_in">map</span>.find(tmp)!=<span class="built_in">map</span>.end())&#123;</span><br><span class="line">                res[<span class="number">0</span>] = i;</span><br><span class="line">                res[<span class="number">1</span>] = <span class="built_in">map</span>[tmp];</span><br><span class="line">                <span class="keyword">break</span>;</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="built_in">map</span>[nums[i]] = i;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="2、两数相加"><a href="#2、两数相加" class="headerlink" title="2、两数相加"></a>2、两数相加</h1><p>给出两个 非空 的链表用来表示两个非负的整数。其中，它们各自的位数是按照 逆序 的方式存储的，并且它们的每个节点只能存储 一位 数字。</p><p>如果，我们将这两个数相加起来，则会返回一个新的链表来表示它们的和。</p><p>您可以假设除了数字 0 之外，这两个数都不会以 0 开头。</p><p>示例：</p><p>输入：(2 -&gt; 4 -&gt; 3) + (5 -&gt; 6 -&gt; 4)<br>输出：7 -&gt; 0 -&gt; 8<br>原因：342 + 465 = 807</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Definition for singly-linked list.</span></span><br><span class="line"><span class="comment"> * struct ListNode &#123;</span></span><br><span class="line"><span class="comment"> *     int val;</span></span><br><span class="line"><span class="comment"> *     ListNode *next;</span></span><br><span class="line"><span class="comment"> *     ListNode(int x) : val(x), next(NULL) &#123;&#125;</span></span><br><span class="line"><span class="comment"> * &#125;;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"> <span class="comment">// 时间复杂度：O(max(m,n))，空间复杂度：O(max(m,n))， 新列表的长度最多为max(m,n)+1</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function">ListNode* <span class="title">addTwoNumbers</span><span class="params">(ListNode* l1, ListNode* l2)</span> </span>&#123;</span><br><span class="line">        ListNode* res = <span class="keyword">new</span> ListNode(<span class="number">0</span>);</span><br><span class="line">        ListNode* head = res;</span><br><span class="line">        <span class="keyword">int</span> flag = <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">while</span>(l1 || l2)&#123;</span><br><span class="line">            <span class="keyword">int</span> x = l1?l1-&gt;val:<span class="number">0</span>;</span><br><span class="line">            <span class="keyword">int</span> y = l2?l2-&gt;val:<span class="number">0</span>;</span><br><span class="line">            head-&gt;next = <span class="keyword">new</span> ListNode((x+y+flag)%<span class="number">10</span>);</span><br><span class="line">            flag = x+y+flag&gt;<span class="number">9</span>?<span class="number">1</span>:<span class="number">0</span>;</span><br><span class="line">            <span class="keyword">if</span>(l1) l1 = l1-&gt;next;</span><br><span class="line">            <span class="keyword">if</span>(l2) l2 = l2-&gt;next;</span><br><span class="line">            head = head-&gt;next;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span>(flag==<span class="number">1</span>)&#123;</span><br><span class="line">            head-&gt;next = <span class="keyword">new</span> ListNode(<span class="number">1</span>);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> res-&gt;next;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="3、无重复字符的最长子串"><a href="#3、无重复字符的最长子串" class="headerlink" title="3、无重复字符的最长子串"></a>3、无重复字符的最长子串</h1><p>给定一个字符串，请你找出其中不含有重复字符的 最长子串 的长度。</p><p>示例 1:</p><p>输入: “abcabcbb”<br>输出: 3<br>解释: 因为无重复字符的最长子串是 “abc”，所以其长度为 3。<br>示例 2:</p><p>输入: “bbbbb”<br>输出: 1<br>解释: 因为无重复字符的最长子串是 “b”，所以其长度为 1。<br>示例 3:</p><p>输入: “pwwkew”<br>输出: 3<br>解释: 因为无重复字符的最长子串是 “wke”，所以其长度为 3。<br>     请注意，你的答案必须是 子串 的长度，”pwke” 是一个子序列，不是子串。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 时间复杂度：O(n)，空间复杂度：O(m)，m 是字符集的大小</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function"><span class="keyword">int</span> <span class="title">lengthOfLongestSubstring</span><span class="params">(<span class="built_in">string</span> s)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">int</span> res = <span class="number">0</span>;</span><br><span class="line">        <span class="built_in">unordered_map</span>&lt;<span class="keyword">char</span>,<span class="keyword">int</span>&gt; <span class="built_in">map</span>;</span><br><span class="line">        <span class="keyword">int</span> i = <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> j=<span class="number">0</span>;j&lt;s.size();j++)&#123;</span><br><span class="line">            <span class="keyword">if</span>(<span class="built_in">map</span>.find(s[j])!=<span class="built_in">map</span>.end())&#123;</span><br><span class="line">                i = max(<span class="built_in">map</span>[s[j]],i);</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="built_in">map</span>[s[j]] = j+<span class="number">1</span>;</span><br><span class="line">            res = max(j-i+<span class="number">1</span>, res);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="4、寻找两个有序数组的中位数"><a href="#4、寻找两个有序数组的中位数" class="headerlink" title="4、寻找两个有序数组的中位数"></a>4、寻找两个有序数组的中位数</h1><p>给定两个大小为 m 和 n 的有序数组 nums1 和 nums2。</p><p>请你找出这两个有序数组的中位数，并且要求算法的时间复杂度为 O(log(m + n))。</p><p>你可以假设 nums1 和 nums2 不会同时为空。</p><p>示例 1:</p><p>nums1 = [1, 3]<br>nums2 = [2]</p><p>则中位数是 2.0<br>示例 2:</p><p>nums1 = [1, 2]<br>nums2 = [3, 4]</p><p>则中位数是 (2 + 3)/2 = 2.5</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="comment">// 时间复杂度：O(log(min(m,n)))，空间复杂度：O(1)O(1)</span></span><br><span class="line">    <span class="function"><span class="keyword">double</span> <span class="title">findMedianSortedArrays</span><span class="params">(<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt;&amp; nums1, <span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt;&amp; nums2)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">if</span>(nums1.size()&gt;nums2.size())</span><br><span class="line">            <span class="keyword">return</span> findMedianSortedArrays(nums2,nums1);</span><br><span class="line">        <span class="keyword">int</span> m = nums1.size(), n = nums2.size();</span><br><span class="line">        <span class="keyword">int</span> lmax1,rmin1,lmax2,rmin2,c1,c2,low=<span class="number">0</span>,heigh=<span class="number">2</span>*m;</span><br><span class="line">        <span class="keyword">while</span>(low &lt;= heigh)&#123;</span><br><span class="line">            <span class="keyword">int</span> c1 = (low+heigh)/<span class="number">2</span>;</span><br><span class="line">            <span class="keyword">int</span> c2 = m+n-c1;</span><br><span class="line">            lmax1 = c1 == <span class="number">0</span>? INT_MIN:nums1[(c1<span class="number">-1</span>)/<span class="number">2</span>];</span><br><span class="line">            rmin1 = c1 == <span class="number">2</span>*m? INT_MAX:nums1[c1/<span class="number">2</span>];</span><br><span class="line">            lmax2 = c2 == <span class="number">0</span>? INT_MIN:nums2[(c2<span class="number">-1</span>)/<span class="number">2</span>];</span><br><span class="line">            rmin2 = c2 == <span class="number">2</span>*n? INT_MAX:nums2[c2/<span class="number">2</span>];</span><br><span class="line">            <span class="keyword">if</span>(lmax1&gt;rmin2) heigh = c1<span class="number">-1</span>;</span><br><span class="line">            <span class="keyword">else</span> <span class="keyword">if</span>(lmax2&gt;rmin1) low = c1+<span class="number">1</span>;</span><br><span class="line">            <span class="keyword">else</span> <span class="keyword">break</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> (max(lmax1,lmax2)+min(rmin1,rmin2))/<span class="number">2.0</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="5、最长回文子串"><a href="#5、最长回文子串" class="headerlink" title="5、最长回文子串"></a>5、最长回文子串</h1><p>给定一个字符串 s，找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。</p><p>示例 1：</p><p>输入: “babad”<br>输出: “bab”<br>注意: “aba” 也是一个有效答案。<br>示例 2：</p><p>输入: “cbbd”<br>输出: “bb”</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="comment">// 时间复杂度：O(n^2)，空间复杂度：O(1)</span></span><br><span class="line">    <span class="function"><span class="built_in">string</span> <span class="title">longestPalindrome</span><span class="params">(<span class="built_in">string</span> s)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">int</span> start=<span class="number">0</span>, len=<span class="number">0</span>;</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;s.size();i++)&#123;</span><br><span class="line">            <span class="keyword">int</span> tmp = max(getsub(i,i,s),getsub(i,i+<span class="number">1</span>,s));</span><br><span class="line">            <span class="keyword">if</span>(tmp&gt;len)&#123;</span><br><span class="line">                len = tmp;</span><br><span class="line">                start = i-(len<span class="number">-1</span>)/<span class="number">2</span>;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> s.substr(start,len);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">int</span> <span class="title">getsub</span><span class="params">(<span class="keyword">int</span> i,<span class="keyword">int</span> j,<span class="built_in">string</span> s)</span></span>&#123;</span><br><span class="line">        <span class="keyword">while</span>(i&gt;=<span class="number">0</span> &amp;&amp; j&lt;s.size() &amp;&amp; s[i]==s[j])&#123;</span><br><span class="line">            i--;</span><br><span class="line">            j++;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> j-i<span class="number">-1</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="6、正则表达式匹配"><a href="#6、正则表达式匹配" class="headerlink" title="6、正则表达式匹配"></a>6、正则表达式匹配</h1><p>给你一个字符串 s 和一个字符规律 p，请你来实现一个支持 ‘.’ 和 ‘*’ 的正则表达式匹配。</p><p>‘.’ 匹配任意单个字符<br>‘*’ 匹配零个或多个前面的那一个元素<br>所谓匹配，是要涵盖 整个 字符串 s的，而不是部分字符串。</p><p>说明:</p><p>s 可能为空，且只包含从 a-z 的小写字母。<br>p 可能为空，且只包含从 a-z 的小写字母，以及字符 . 和 *。<br>示例 1:</p><p>输入:<br>s = “aa”<br>p = “a”<br>输出: false<br>解释: “a” 无法匹配 “aa” 整个字符串。<br>示例 2:</p><p>输入:<br>s = “aa”<br>p = “a*”<br>输出: true<br>解释: 因为 ‘*’ 代表可以匹配零个或多个前面的那一个元素, 在这里前面的元素就是 ‘a’。因此，字符串 “aa” 可被视为 ‘a’ 重复了一次。<br>示例 3:</p><p>输入:<br>s = “ab”<br>p = “.*”<br>输出: true<br>解释: “.*” 表示可匹配零个或多个（’*’）任意字符（’.’）。<br>示例 4:</p><p>输入:<br>s = “aab”<br>p = “c<em>a</em>b”<br>输出: true<br>解释: 因为 ‘*’ 表示零个或多个，这里 ‘c’ 为 0 个, ‘a’ 被重复一次。因此可以匹配字符串 “aab”。<br>示例 5:</p><p>输入:<br>s = “mississippi”<br>p = “mis<em>is</em>p*.”<br>输出: false</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function"><span class="keyword">bool</span> <span class="title">isMatch</span><span class="params">(<span class="built_in">string</span> s, <span class="built_in">string</span> p)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">const</span> <span class="keyword">char</span>* str = s.c_str();</span><br><span class="line">        <span class="keyword">const</span> <span class="keyword">char</span>* pattern = p.c_str();</span><br><span class="line">        <span class="keyword">return</span> match(str,pattern);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">bool</span> <span class="title">match</span><span class="params">(<span class="keyword">const</span> <span class="keyword">char</span>* str, <span class="keyword">const</span> <span class="keyword">char</span>* pattern)</span></span></span><br><span class="line"><span class="function">    </span>&#123;</span><br><span class="line">        <span class="keyword">if</span>(*str == <span class="string">'\0'</span> &amp;&amp; *pattern == <span class="string">'\0'</span>) <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line">        <span class="keyword">if</span>(*str != <span class="string">'\0'</span> &amp;&amp; *pattern == <span class="string">'\0'</span>) <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">        <span class="keyword">if</span>(*(pattern+<span class="number">1</span>) != <span class="string">'*'</span>)&#123;</span><br><span class="line">            <span class="keyword">if</span>(*str==*pattern || *pattern==<span class="string">'.'</span>&amp;&amp;*str!=<span class="string">'\0'</span>)&#123;</span><br><span class="line">                <span class="keyword">return</span> match(str+<span class="number">1</span>,pattern+<span class="number">1</span>);</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">else</span> <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">else</span>&#123;</span><br><span class="line">            <span class="keyword">if</span>(*str==*pattern || *pattern==<span class="string">'.'</span>&amp;&amp;*str!=<span class="string">'\0'</span>)&#123;</span><br><span class="line">                <span class="keyword">return</span> match(str,pattern+<span class="number">2</span>)|| match(str+<span class="number">1</span>,pattern+<span class="number">2</span>)|| match(str+<span class="number">1</span>,pattern);</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">else</span> <span class="keyword">return</span> match(str,pattern+<span class="number">2</span>);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="comment">// 时间复杂度：O(TP)，空间复杂度：O(TP)</span></span><br><span class="line">    <span class="function"><span class="keyword">bool</span> <span class="title">isMatch</span><span class="params">(<span class="built_in">string</span> s, <span class="built_in">string</span> p)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">int</span> l1 = s.size(),l2 = p.size();</span><br><span class="line">        <span class="built_in">vector</span>&lt;<span class="built_in">vector</span>&lt;<span class="keyword">bool</span>&gt;&gt; dp(l1+<span class="number">1</span>,<span class="built_in">vector</span>&lt;<span class="keyword">bool</span>&gt;(l2+<span class="number">1</span>));</span><br><span class="line">        dp[l1][l2]=<span class="literal">true</span>;</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i=l1;i&gt;=<span class="number">0</span>;i--)&#123;</span><br><span class="line">            <span class="keyword">for</span>(<span class="keyword">int</span> j=l2<span class="number">-1</span>;j&gt;=<span class="number">0</span>;j--)&#123;</span><br><span class="line">                <span class="keyword">bool</span> tmp = i&lt;l1 &amp;&amp; ( s[i] == p[j] || p[j] == <span class="string">'.'</span>);</span><br><span class="line">                <span class="keyword">if</span>(j+<span class="number">1</span>&lt;l2 &amp;&amp; p[j+<span class="number">1</span>] == <span class="string">'*'</span>)&#123;</span><br><span class="line">                    dp[i][j] = dp[i][j+<span class="number">2</span>] || tmp &amp;&amp; dp[i+<span class="number">1</span>][j];</span><br><span class="line">                &#125;</span><br><span class="line">                <span class="keyword">else</span>&#123;</span><br><span class="line">                    dp[i][j] = tmp &amp;&amp; dp[i+<span class="number">1</span>][j+<span class="number">1</span>];</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> dp[<span class="number">0</span>][<span class="number">0</span>];</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="7、盛最多水的容器"><a href="#7、盛最多水的容器" class="headerlink" title="7、盛最多水的容器"></a>7、盛最多水的容器</h1><p>给定 n 个非负整数 a1，a2，…，an，每个数代表坐标中的一个点 (i, ai) 。在坐标内画 n 条垂直线，垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0)。找出其中的两条线，使得它们与 x 轴共同构成的容器可以容纳最多的水。</p><p>说明：你不能倾斜容器，且 n 的值至少为 2。</p><p>图中垂直线代表输入数组 [1,8,6,2,5,4,8,3,7]。在此情况下，容器能够容纳水（表示为蓝色部分）的最大值为 49。<br><img src="https://img-blog.csdnimg.cn/20191205113657760.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZmY2pqaHY=,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"><br>示例:</p><p>输入: [1,8,6,2,5,4,8,3,7]<br>输出: 49</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="comment">// 时间复杂度：O(n)，空间复杂度：O(1)</span></span><br><span class="line">    <span class="function"><span class="keyword">int</span> <span class="title">maxArea</span><span class="params">(<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt;&amp; height)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">int</span> res=<span class="number">0</span>;</span><br><span class="line">        <span class="keyword">int</span> i=<span class="number">0</span>,j=height.size()<span class="number">-1</span>;</span><br><span class="line">        <span class="keyword">while</span>(i&lt;j)&#123;</span><br><span class="line">            res = max(res,(j-i)*min(height[i],height[j]));</span><br><span class="line">            <span class="keyword">if</span>(height[i]&lt;height[j]) i++;</span><br><span class="line">            <span class="keyword">else</span> j--;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="8、三数之和"><a href="#8、三数之和" class="headerlink" title="8、三数之和"></a>8、三数之和</h1><p>给定一个包含 n 个整数的数组 nums，判断 nums 中是否存在三个元素 a，b，c ，使得 a + b + c = 0 ？找出所有满足条件且不重复的三元组。</p><p>注意：答案中不可以包含重复的三元组。</p><p>例如, 给定数组 nums = [-1, 0, 1, 2, -1, -4]，</p><p>满足要求的三元组集合为：<br>[<br>  [-1, 0, 1],<br>  [-1, -1, 2]<br>]</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="comment">// 时间复杂度：O(n^2)，空间复杂度：O(1)</span></span><br><span class="line">    <span class="built_in">vector</span>&lt;<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt;&gt; threeSum(<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt;&amp; nums) &#123;</span><br><span class="line">        <span class="built_in">vector</span>&lt;<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt;&gt; res;</span><br><span class="line">        <span class="keyword">if</span>(nums.empty()) <span class="keyword">return</span> res;</span><br><span class="line">        sort(nums.begin(),nums.end());</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;nums.size();i++)&#123;</span><br><span class="line">            <span class="keyword">if</span>(i&gt;=<span class="number">1</span> &amp;&amp; nums[i] == nums[i<span class="number">-1</span>]) <span class="keyword">continue</span>;</span><br><span class="line">            <span class="keyword">if</span>(nums[i]&gt;<span class="number">0</span>) <span class="keyword">break</span>;</span><br><span class="line">            <span class="keyword">int</span> l=i+<span class="number">1</span>,r=nums.size()<span class="number">-1</span>;</span><br><span class="line">            <span class="keyword">while</span>(l&lt;r)&#123;</span><br><span class="line">                <span class="keyword">if</span>(nums[l]+nums[r]+nums[i] &lt; <span class="number">0</span>) l++;</span><br><span class="line">                <span class="keyword">else</span> <span class="keyword">if</span>(nums[l]+nums[r]+nums[i] &gt; <span class="number">0</span>) r--;</span><br><span class="line">                <span class="keyword">else</span>&#123;</span><br><span class="line">                    res.push_back(&#123;nums[i],nums[l],nums[r]&#125;);</span><br><span class="line">                    l++;</span><br><span class="line">                    r--;</span><br><span class="line">                    <span class="keyword">while</span>(l&lt;r &amp;&amp; nums[l]==nums[l<span class="number">-1</span>]) l++;</span><br><span class="line">                    <span class="keyword">while</span>(l&lt;r &amp;&amp; nums[r]==nums[r+<span class="number">1</span>]) r--;</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="9、电话号码的字母组合"><a href="#9、电话号码的字母组合" class="headerlink" title="9、电话号码的字母组合"></a>9、电话号码的字母组合</h1><p>给定一个仅包含数字 2-9 的字符串，返回所有它能表示的字母组合。</p><p>给出数字到字母的映射如下（与电话按键相同）。注意 1 不对应任何字母。<br><img src="https://img-blog.csdnimg.cn/2019120512120264.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZmY2pqaHY=,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"><br>示例:</p><p>输入：”23”<br>输出：[“ad”, “ae”, “af”, “bd”, “be”, “bf”, “cd”, “ce”, “cf”].<br>说明:<br>尽管上面的答案是按字典序排列的，但是你可以任意选择答案输出的顺序。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="comment">// 时间复杂度：O(3^N*4^M)，空间复杂度：O(3^N*4^M)</span></span><br><span class="line">    <span class="built_in">unordered_map</span>&lt;<span class="keyword">char</span>,<span class="built_in">string</span>&gt; <span class="built_in">map</span>&#123;&#123;<span class="string">'2'</span>,<span class="string">"abc"</span>&#125;,&#123;<span class="string">'3'</span>,<span class="string">"def"</span>&#125;,&#123;<span class="string">'4'</span>,<span class="string">"ghi"</span>&#125;,&#123;<span class="string">'5'</span>,<span class="string">"jkl"</span>&#125;,&#123;<span class="string">'6'</span>,<span class="string">"mno"</span>&#125;,&#123;<span class="string">'7'</span>,<span class="string">"pqrs"</span>&#125;,&#123;<span class="string">'8'</span>,<span class="string">"tuv"</span>&#125;,&#123;<span class="string">'9'</span>,<span class="string">"wxyz"</span>&#125;&#125;;</span><br><span class="line"></span><br><span class="line">    <span class="built_in">vector</span>&lt;<span class="built_in">string</span>&gt; letterCombinations(<span class="built_in">string</span> digits) &#123;</span><br><span class="line">        <span class="built_in">vector</span>&lt;<span class="built_in">string</span>&gt; res;</span><br><span class="line">        <span class="keyword">if</span>(digits.empty()) <span class="keyword">return</span> res;</span><br><span class="line">        help(<span class="string">""</span>,digits,res);</span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">help</span><span class="params">(<span class="built_in">string</span> str, <span class="built_in">string</span> digits, <span class="built_in">vector</span>&lt;<span class="built_in">string</span>&gt; &amp;res)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">if</span>(str.size() == digits.size())&#123;</span><br><span class="line">            res.push_back(str);</span><br><span class="line">            <span class="keyword">return</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="built_in">string</span> tmp = <span class="built_in">map</span>[digits[str.size()]];</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;tmp.size();i++)&#123;</span><br><span class="line">            str += tmp[i];</span><br><span class="line">            help(str,digits,res);</span><br><span class="line">            str.pop_back();</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><p>注：可以联系剑指offer27题一起看</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="comment">// 时间复杂度：O(3^N*4^M)，空间复杂度：O(3^N*4^M)</span></span><br><span class="line">    <span class="built_in">vector</span>&lt;<span class="built_in">string</span>&gt; letterCombinations(<span class="built_in">string</span> digits) &#123;</span><br><span class="line">        <span class="built_in">unordered_map</span>&lt;<span class="keyword">char</span>,<span class="built_in">string</span>&gt; <span class="built_in">map</span>&#123;&#123;<span class="string">'2'</span>,<span class="string">"abc"</span>&#125;,&#123;<span class="string">'3'</span>,<span class="string">"def"</span>&#125;,&#123;<span class="string">'4'</span>,<span class="string">"ghi"</span>&#125;,&#123;<span class="string">'5'</span>,<span class="string">"jkl"</span>&#125;,&#123;<span class="string">'6'</span>,<span class="string">"mno"</span>&#125;,&#123;<span class="string">'7'</span>,<span class="string">"pqrs"</span>&#125;,&#123;<span class="string">'8'</span>,<span class="string">"tuv"</span>&#125;,&#123;<span class="string">'9'</span>,<span class="string">"wxyz"</span>&#125;&#125;;</span><br><span class="line">        <span class="built_in">vector</span>&lt;<span class="built_in">string</span>&gt; res;</span><br><span class="line">        <span class="keyword">if</span>(digits.empty()) <span class="keyword">return</span> res;</span><br><span class="line">        <span class="keyword">if</span>(digits.size() == <span class="number">1</span>)&#123;</span><br><span class="line">            <span class="built_in">string</span> tmp = <span class="built_in">map</span>[digits[<span class="number">0</span>]];</span><br><span class="line">            <span class="keyword">for</span>(<span class="keyword">char</span> w : tmp) &#123;</span><br><span class="line">                <span class="function"><span class="built_in">string</span> <span class="title">s</span><span class="params">(<span class="number">1</span>,w)</span></span>;</span><br><span class="line">                res.push_back(s);</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">return</span> res;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="built_in">vector</span>&lt;<span class="built_in">string</span>&gt; last = letterCombinations(digits.substr(<span class="number">0</span>,digits.size()<span class="number">-1</span>));</span><br><span class="line">        <span class="built_in">string</span> tmp = <span class="built_in">map</span>[digits[digits.size()<span class="number">-1</span>]]; <span class="comment">//abc def</span></span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;last.size()||i==<span class="number">0</span>;i++)&#123;</span><br><span class="line">            <span class="keyword">for</span>(<span class="keyword">int</span> j=<span class="number">0</span>;j&lt;tmp.size();j++)&#123;</span><br><span class="line">                res.push_back(last[i]+tmp[j]);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="10、删除链表的倒数第N个节点"><a href="#10、删除链表的倒数第N个节点" class="headerlink" title="10、删除链表的倒数第N个节点"></a>10、删除链表的倒数第N个节点</h1><p>给定一个链表，删除链表的倒数第 n 个节点，并且返回链表的头结点。</p><p>示例：</p><p>给定一个链表: 1-&gt;2-&gt;3-&gt;4-&gt;5, 和 n = 2.</p><p>当删除了倒数第二个节点后，链表变为 1-&gt;2-&gt;3-&gt;5.<br>说明：</p><p>给定的 n 保证是有效的。</p><p>进阶：</p><p>你能尝试使用一趟扫描实现吗？</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Definition for singly-linked list.</span></span><br><span class="line"><span class="comment"> * struct ListNode &#123;</span></span><br><span class="line"><span class="comment"> *     int val;</span></span><br><span class="line"><span class="comment"> *     ListNode *next;</span></span><br><span class="line"><span class="comment"> *     ListNode(int x) : val(x), next(NULL) &#123;&#125;</span></span><br><span class="line"><span class="comment"> * &#125;;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line"><span class="comment">// 时间复杂度：O(n)，空间复杂度：O(1)</span></span><br><span class="line">    <span class="function">ListNode* <span class="title">removeNthFromEnd</span><span class="params">(ListNode* head, <span class="keyword">int</span> n)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">if</span>(!head || n==<span class="number">0</span>) <span class="keyword">return</span> head;</span><br><span class="line">        ListNode* l1 = head;</span><br><span class="line">        ListNode* l2 = head;</span><br><span class="line">        <span class="keyword">int</span> k=<span class="number">0</span>;</span><br><span class="line">        <span class="keyword">while</span>(l1)&#123;</span><br><span class="line">            <span class="keyword">if</span>(k&gt;n) l2 = l2-&gt;next;</span><br><span class="line">            l1 = l1-&gt;next;</span><br><span class="line">            k++;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="comment">// 倒数第k-1个结点l2</span></span><br><span class="line">        <span class="keyword">if</span>(k == n) <span class="keyword">return</span> head-&gt;next;</span><br><span class="line">        l2-&gt;next = l2-&gt;next-&gt;next;</span><br><span class="line">        <span class="keyword">return</span> head;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="11、有效的括号"><a href="#11、有效的括号" class="headerlink" title="11、有效的括号"></a>11、有效的括号</h1><p>给定一个只包括 ‘(‘，’)’，’{‘，’}’，’[‘，’]’ 的字符串，判断字符串是否有效。</p><p>有效字符串需满足：</p><p>左括号必须用相同类型的右括号闭合。<br>左括号必须以正确的顺序闭合。<br>注意空字符串可被认为是有效字符串。</p><p>示例 1:</p><p>输入: “()”<br>输出: true<br>示例 2:</p><p>输入: “()[]{}”<br>输出: true<br>示例 3:</p><p>输入: “(]”<br>输出: false<br>示例 4:</p><p>输入: “([)]”<br>输出: false<br>示例 5:</p><p>输入: “{[]}”<br>输出: true</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line"><span class="comment">// 时间复杂度：O(n)，空间复杂度：O(n)</span></span><br><span class="line">    <span class="function"><span class="keyword">bool</span> <span class="title">isValid</span><span class="params">(<span class="built_in">string</span> s)</span> </span>&#123;</span><br><span class="line">        <span class="built_in">stack</span>&lt;<span class="keyword">char</span>&gt; <span class="built_in">stack</span>;</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;s.size();i++)&#123;</span><br><span class="line">            <span class="keyword">if</span>(<span class="built_in">stack</span>.empty() || !isok(<span class="built_in">stack</span>.top(),s[i]))&#123;</span><br><span class="line">                <span class="built_in">stack</span>.push(s[i]);</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">else</span> <span class="built_in">stack</span>.pop();</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> <span class="built_in">stack</span>.empty();</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">bool</span> <span class="title">isok</span><span class="params">(<span class="keyword">char</span> a, <span class="keyword">char</span> b)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> a==<span class="string">'('</span>&amp;&amp;b==<span class="string">')'</span> || a==<span class="string">'['</span>&amp;&amp;b==<span class="string">']'</span> || a==<span class="string">'&#123;'</span>&amp;&amp;b==<span class="string">'&#125;'</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="12、合并两个有序链表"><a href="#12、合并两个有序链表" class="headerlink" title="12、合并两个有序链表"></a>12、合并两个有序链表</h1><p>将两个有序链表合并为一个新的有序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 </p><p>示例：</p><p>输入：1-&gt;2-&gt;4, 1-&gt;3-&gt;4<br>输出：1-&gt;1-&gt;2-&gt;3-&gt;4-&gt;4</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Definition for singly-linked list.</span></span><br><span class="line"><span class="comment"> * struct ListNode &#123;</span></span><br><span class="line"><span class="comment"> *     int val;</span></span><br><span class="line"><span class="comment"> *     ListNode *next;</span></span><br><span class="line"><span class="comment"> *     ListNode(int x) : val(x), next(NULL) &#123;&#125;</span></span><br><span class="line"><span class="comment"> * &#125;;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line"><span class="comment">// 时间复杂度：O(n+m)，空间复杂度：O(1)</span></span><br><span class="line">    <span class="function">ListNode* <span class="title">mergeTwoLists</span><span class="params">(ListNode* l1, ListNode* l2)</span> </span>&#123;</span><br><span class="line">        ListNode* res = <span class="keyword">new</span> ListNode(<span class="number">0</span>);</span><br><span class="line">        ListNode* head = res;</span><br><span class="line">        <span class="keyword">while</span>(l1 &amp;&amp; l2)&#123;</span><br><span class="line">            <span class="keyword">if</span>(l1-&gt;val&lt;l2-&gt;val)&#123;</span><br><span class="line">                head-&gt;next = l1;</span><br><span class="line">                l1 = l1-&gt;next;</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">else</span>&#123;</span><br><span class="line">                head-&gt;next = l2;</span><br><span class="line">                l2 = l2-&gt;next;</span><br><span class="line">            &#125;</span><br><span class="line">            head = head-&gt;next;</span><br><span class="line">        &#125;</span><br><span class="line">        head-&gt;next = l1?l1:l2;</span><br><span class="line">        <span class="keyword">return</span> res-&gt;next;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="13、括号生成"><a href="#13、括号生成" class="headerlink" title="13、括号生成"></a>13、括号生成</h1><p>给出 n 代表生成括号的对数，请你写出一个函数，使其能够生成所有可能的并且有效的括号组合。</p><p>例如，给出 n = 3，生成结果为：</p><p>[<br>  “((()))”,<br>  “(()())”,<br>  “(())()”,<br>  “()(())”,<br>  “()()()”<br>]</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="comment">// 时间复杂度：O(4^n/sqrt(n))，空间复杂度：O(4^n/sqrt(n))</span></span><br><span class="line">    <span class="built_in">vector</span>&lt;<span class="built_in">string</span>&gt; generateParenthesis(<span class="keyword">int</span> n) &#123;</span><br><span class="line">        <span class="built_in">vector</span>&lt;<span class="built_in">string</span>&gt; res;</span><br><span class="line">        <span class="keyword">if</span>(n==<span class="number">0</span>) <span class="keyword">return</span> &#123;<span class="string">""</span>&#125;;</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;n;i++)&#123;</span><br><span class="line">            <span class="built_in">vector</span>&lt;<span class="built_in">string</span>&gt; left = generateParenthesis(i);</span><br><span class="line">            <span class="built_in">vector</span>&lt;<span class="built_in">string</span>&gt; right = generateParenthesis(n<span class="number">-1</span>-i);</span><br><span class="line">            <span class="keyword">for</span>(<span class="built_in">string</span> l :left)&#123;</span><br><span class="line">                <span class="keyword">for</span>(<span class="built_in">string</span> r :right)&#123;</span><br><span class="line">                    res.push_back(<span class="string">"("</span>+l+<span class="string">")"</span>+r);</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="14、合并K个排序链表"><a href="#14、合并K个排序链表" class="headerlink" title="14、合并K个排序链表"></a>14、合并K个排序链表</h1><p>合并 k 个排序链表，返回合并后的排序链表。请分析和描述算法的复杂度。</p><p>示例:</p><p>输入:<br>[<br>  1-&gt;4-&gt;5,<br>  1-&gt;3-&gt;4,<br>  2-&gt;6<br>]输出: 1-&gt;1-&gt;2-&gt;3-&gt;4-&gt;4-&gt;5-&gt;6</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Definition for singly-linked list.</span></span><br><span class="line"><span class="comment"> * struct ListNode &#123;</span></span><br><span class="line"><span class="comment"> *     int val;</span></span><br><span class="line"><span class="comment"> *     ListNode *next;</span></span><br><span class="line"><span class="comment"> *     ListNode(int x) : val(x), next(NULL) &#123;&#125;</span></span><br><span class="line"><span class="comment"> * &#125;;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line"><span class="comment">// 时间复杂度：O(Nlogk)，空间复杂度：O(1)</span></span><br><span class="line">    <span class="function">ListNode* <span class="title">mergeKLists</span><span class="params">(<span class="built_in">vector</span>&lt;ListNode*&gt;&amp; lists)</span> </span>&#123;</span><br><span class="line">        ListNode* res = <span class="literal">NULL</span>;</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;lists.size();i++)&#123;</span><br><span class="line">            res = mergeTwoLists(res,lists[i]);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function">ListNode* <span class="title">mergeTwoLists</span><span class="params">(ListNode* l1, ListNode* l2)</span> </span>&#123;</span><br><span class="line">        ListNode* res = <span class="keyword">new</span> ListNode(<span class="number">0</span>);</span><br><span class="line">        ListNode* head = res;</span><br><span class="line">        <span class="keyword">while</span>(l1 &amp;&amp; l2)&#123;</span><br><span class="line">            <span class="keyword">if</span>(l1-&gt;val&lt;l2-&gt;val)&#123;</span><br><span class="line">                head-&gt;next = l1;</span><br><span class="line">                l1 = l1-&gt;next;</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">else</span>&#123;</span><br><span class="line">                head-&gt;next = l2;</span><br><span class="line">                l2 = l2-&gt;next;</span><br><span class="line">            &#125;</span><br><span class="line">            head = head-&gt;next;</span><br><span class="line">        &#125;</span><br><span class="line">        head-&gt;next = l1?l1:l2;</span><br><span class="line">        <span class="keyword">return</span> res-&gt;next;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="15、下一个排列"><a href="#15、下一个排列" class="headerlink" title="15、下一个排列"></a>15、下一个排列</h1><p>实现获取下一个排列的函数，算法需要将给定数字序列重新排列成字典序中下一个更大的排列。</p><p>如果不存在下一个更大的排列，则将数字重新排列成最小的排列（即升序排列）。</p><p>必须原地修改，只允许使用额外常数空间。</p><p>以下是一些例子，输入位于左侧列，其相应输出位于右侧列。<br>1,2,3 → 1,3,2<br>3,2,1 → 1,2,3<br>1,1,5 → 1,5,1</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line"><span class="comment">// 时间复杂度：O(n)，空间复杂度：O(1)</span></span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">nextPermutation</span><span class="params">(<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt;&amp; nums)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">int</span> i= nums.size()<span class="number">-2</span>;</span><br><span class="line">        <span class="keyword">while</span>(i&gt;=<span class="number">0</span> &amp;&amp; nums[i]&gt;=nums[i+<span class="number">1</span>])&#123;</span><br><span class="line">            i--;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span>(i&gt;=<span class="number">0</span>) &#123;</span><br><span class="line">            <span class="keyword">int</span> j = nums.size()<span class="number">-1</span>;</span><br><span class="line">            <span class="keyword">while</span>(j&gt;=<span class="number">0</span> &amp;&amp; nums[j]&lt;=nums[i])&#123;</span><br><span class="line">                j--;</span><br><span class="line">            &#125;</span><br><span class="line">            swap(nums[i],nums[j]);</span><br><span class="line">        &#125;</span><br><span class="line">        reverse(nums,i+<span class="number">1</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">reverse</span><span class="params">(<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt;&amp; nums,<span class="keyword">int</span> n)</span></span>&#123;</span><br><span class="line">        <span class="keyword">int</span> l=n,r=nums.size()<span class="number">-1</span>;</span><br><span class="line">        <span class="keyword">while</span>(l&lt;r)&#123;</span><br><span class="line">            swap(nums[l],nums[r]);</span><br><span class="line">            l++;</span><br><span class="line">            r--;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="16、最长有效括号"><a href="#16、最长有效括号" class="headerlink" title="16、最长有效括号"></a>16、最长有效括号</h1><p>给定一个只包含 ‘(‘ 和 ‘)’ 的字符串，找出最长的包含有效括号的子串的长度。</p><p>示例 1:</p><p>输入: “(()”<br>输出: 2<br>解释: 最长有效括号子串为 “()”<br>示例 2:</p><p>输入: “)()())”<br>输出: 4<br>解释: 最长有效括号子串为 “()()”</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line"><span class="comment">// 时间复杂度：O(n)，空间复杂度：O(1)</span></span><br><span class="line">    <span class="function"><span class="keyword">int</span> <span class="title">longestValidParentheses</span><span class="params">(<span class="built_in">string</span> s)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">int</span> l = <span class="number">0</span>, r = <span class="number">0</span> , res = <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;s.size();i++)&#123;</span><br><span class="line">            <span class="keyword">if</span>(s[i] == <span class="string">'('</span>) l++;</span><br><span class="line">            <span class="keyword">if</span>(s[i] == <span class="string">')'</span>) r++;</span><br><span class="line">            <span class="keyword">if</span>(l==r) res = max(res,<span class="number">2</span>*l);</span><br><span class="line">            <span class="keyword">if</span>(r&gt;l) l=r=<span class="number">0</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        l=<span class="number">0</span>,r=<span class="number">0</span>;</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i=s.size()<span class="number">-1</span>;i&gt;=<span class="number">0</span>;i--)&#123;</span><br><span class="line">            <span class="keyword">if</span>(s[i] == <span class="string">'('</span>) l++;</span><br><span class="line">            <span class="keyword">if</span>(s[i] == <span class="string">')'</span>) r++;</span><br><span class="line">            <span class="keyword">if</span>(l==r) res = max(res,<span class="number">2</span>*l);</span><br><span class="line">            <span class="keyword">if</span>(l&gt;r) l=r=<span class="number">0</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="17、搜索旋转排序数组"><a href="#17、搜索旋转排序数组" class="headerlink" title="17、搜索旋转排序数组"></a>17、搜索旋转排序数组</h1><p>假设按照升序排序的数组在预先未知的某个点上进行了旋转。</p><p>( 例如，数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] )。</p><p>搜索一个给定的目标值，如果数组中存在这个目标值，则返回它的索引，否则返回 -1 。</p><p>你可以假设数组中不存在重复的元素。</p><p>你的算法时间复杂度必须是 O(log n) 级别。</p><p>示例 1:</p><p>输入: nums = [4,5,6,7,0,1,2], target = 0<br>输出: 4<br>示例 2:</p><p>输入: nums = [4,5,6,7,0,1,2], target = 3<br>输出: -1</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line"><span class="comment">// 时间复杂度：O(logN)，空间复杂度：O(1)</span></span><br><span class="line">    <span class="function"><span class="keyword">int</span> <span class="title">search</span><span class="params">(<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt;&amp; nums, <span class="keyword">int</span> target)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> help(nums,target,<span class="number">0</span>,nums.size()<span class="number">-1</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="function"><span class="keyword">int</span> <span class="title">help</span><span class="params">(<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt;&amp; nums, <span class="keyword">int</span> target, <span class="keyword">int</span> l, <span class="keyword">int</span> r)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">if</span>(l&gt;r) <span class="keyword">return</span> <span class="number">-1</span>;</span><br><span class="line">        <span class="keyword">int</span> mid = (l+r)/<span class="number">2</span>;</span><br><span class="line">        <span class="keyword">if</span>(nums[mid] == target) <span class="keyword">return</span> mid;</span><br><span class="line">        <span class="keyword">if</span>(nums[mid]&gt;nums[r])&#123; <span class="comment">// 3 4 7 8 1 2  旋转点在右，左顺序</span></span><br><span class="line">            <span class="keyword">if</span>(nums[l]&lt;=target &amp;&amp; target &lt;nums[mid]) <span class="keyword">return</span> help(nums,target,l,mid<span class="number">-1</span>);</span><br><span class="line">            <span class="keyword">else</span> <span class="keyword">return</span> help(nums,target,mid+<span class="number">1</span>,r);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">else</span>&#123; <span class="comment">// 7 8 1 2 3 4</span></span><br><span class="line">            <span class="keyword">if</span>(nums[mid]&lt;target &amp;&amp; target &lt;=nums[r]) <span class="keyword">return</span> help(nums,target,mid+<span class="number">1</span>,r);</span><br><span class="line">            <span class="keyword">else</span> <span class="keyword">return</span> help(nums,target,l,mid<span class="number">-1</span>);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="18、在排序数组中查找元素的第一个和最后一个位置"><a href="#18、在排序数组中查找元素的第一个和最后一个位置" class="headerlink" title="18、在排序数组中查找元素的第一个和最后一个位置"></a>18、在排序数组中查找元素的第一个和最后一个位置</h1><p>给定一个按照升序排列的整数数组 nums，和一个目标值 target。找出给定目标值在数组中的开始位置和结束位置。</p><p>你的算法时间复杂度必须是 O(log n) 级别。</p><p>如果数组中不存在目标值，返回 [-1, -1]。</p><p>示例 1:</p><p>输入: nums = [5,7,7,8,8,10], target = 8<br>输出: [3,4]<br>示例 2:</p><p>输入: nums = [5,7,7,8,8,10], target = 6<br>输出: [-1,-1]</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line"><span class="comment">// 时间复杂度：O(logN)，空间复杂度：O(1)</span></span><br><span class="line">    <span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; searchRange(<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt;&amp; nums, <span class="keyword">int</span> target) &#123;</span><br><span class="line">        <span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; res&#123;<span class="number">-1</span>,<span class="number">-1</span>&#125;;</span><br><span class="line">        <span class="keyword">int</span> l=<span class="number">0</span>,r=nums.size()<span class="number">-1</span>;</span><br><span class="line">        <span class="keyword">while</span>(l&lt;=r)&#123;</span><br><span class="line">            <span class="keyword">int</span> mid=(l+r)/<span class="number">2</span>;</span><br><span class="line">            <span class="keyword">if</span>(nums[mid] == target) &#123;</span><br><span class="line">                help(nums,mid,res);</span><br><span class="line">                <span class="keyword">break</span>;</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">else</span> <span class="keyword">if</span>(nums[mid] &gt; target) r = mid<span class="number">-1</span>;</span><br><span class="line">            <span class="keyword">else</span> l = mid+<span class="number">1</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">help</span><span class="params">(<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; nums, <span class="keyword">int</span> n,<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; &amp;res)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">int</span> l=n,r=n;</span><br><span class="line">        <span class="keyword">while</span>(l&gt;=<span class="number">0</span>&amp;&amp;nums[l]==nums[n])&#123;</span><br><span class="line">            l--;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">while</span>(r&lt;nums.size()&amp;&amp;nums[r]==nums[n])&#123;</span><br><span class="line">            r++;</span><br><span class="line">        &#125;</span><br><span class="line">        res[<span class="number">0</span>]=l+<span class="number">1</span>;</span><br><span class="line">        res[<span class="number">1</span>]=r<span class="number">-1</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="19、组合总和"><a href="#19、组合总和" class="headerlink" title="19、组合总和"></a>19、组合总和</h1><p>给定一个无重复元素的数组 candidates 和一个目标数 target ，找出 candidates 中所有可以使数字和为 target 的组合。<br>candidates 中的数字可以无限制重复被选取。</p><p>说明：<br>所有数字（包括 target）都是正整数。<br>解集不能包含重复的组合。<br>示例 1:</p><p>输入: candidates = [2,3,6,7], target = 7,<br>所求解集为:<br>[<br>  [7],<br>  [2,2,3]<br>]示例 2:</p><p>输入: candidates = [2,3,5], target = 8,<br>所求解集为:<br>[<br>  [2,2,2,2],<br>  [2,3,3],<br>  [3,5]<br>]</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="built_in">vector</span>&lt;<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt;&gt; combinationSum(<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt;&amp; candidates, <span class="keyword">int</span> target) &#123;</span><br><span class="line">        sort(candidates.begin(),candidates.end());</span><br><span class="line">        <span class="built_in">vector</span>&lt;<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt;&gt; res;</span><br><span class="line">        <span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; path;</span><br><span class="line">        dfs(candidates,target,<span class="number">0</span>,path,res);</span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">dfs</span><span class="params">(<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt;&amp; candidates, <span class="keyword">int</span> target, <span class="keyword">int</span> start, <span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; &amp;path, <span class="built_in">vector</span>&lt;<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt;&gt; &amp;res)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">if</span>(target == <span class="number">0</span>) &#123;</span><br><span class="line">            res.push_back(path);</span><br><span class="line">            <span class="keyword">return</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i=start;i&lt;candidates.size()&amp;&amp;target&gt;=candidates[i];i++)&#123;</span><br><span class="line">            path.push_back(candidates[i]);</span><br><span class="line">            dfs(candidates,target-candidates[i],i,path,res);</span><br><span class="line">            path.pop_back();</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="20、接雨水"><a href="#20、接雨水" class="headerlink" title="20、接雨水"></a>20、接雨水</h1><p>给定 n 个非负整数表示每个宽度为 1 的柱子的高度图，计算按此排列的柱子，下雨之后能接多少雨水。<br><img src="https://img-blog.csdnimg.cn/20191205214818602.png" alt="在这里插入图片描述"><br>上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图，在这种情况下，可以接 6 个单位的雨水（蓝色部分表示雨水）。 感谢 Marcos 贡献此图。</p><p>示例:</p><p>输入: [0,1,0,2,1,0,1,3,2,1,2,1]<br>输出: 6</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="comment">// 时间复杂度：O(n)，空间复杂度：O(1)</span></span><br><span class="line">    <span class="function"><span class="keyword">int</span> <span class="title">trap</span><span class="params">(<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt;&amp; height)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">int</span> res = <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">int</span> l = <span class="number">0</span>, r = height.size()<span class="number">-1</span>;</span><br><span class="line">        <span class="keyword">int</span> max_left = <span class="number">0</span>, max_right = <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">while</span>(l&lt;r)&#123;</span><br><span class="line">            <span class="keyword">if</span>(height[l]&lt;height[r])&#123;</span><br><span class="line">                <span class="keyword">if</span>(height[l]&gt;=max_left) max_left = height[l];</span><br><span class="line">                <span class="keyword">else</span> res += max_left-height[l];</span><br><span class="line">                l++;</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">else</span>&#123;</span><br><span class="line">                <span class="keyword">if</span>(height[r]&gt;=max_right) max_right = height[r];</span><br><span class="line">                <span class="keyword">else</span> res += max_right-height[r];</span><br><span class="line">                r--;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="21、全排列"><a href="#21、全排列" class="headerlink" title="21、全排列"></a>21、全排列</h1><p>给定一个没有重复数字的序列，返回其所有可能的全排列。</p><p>示例:</p><p>输入: [1,2,3]<br>输出:<br>[<br>  [1,2,3],<br>  [1,3,2],<br>  [2,1,3],<br>  [2,3,1],<br>  [3,1,2],<br>  [3,2,1]<br>]</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="comment">// 时间复杂度：O(n!)，空间复杂度：O(1)</span></span><br><span class="line">    <span class="built_in">vector</span>&lt;<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt;&gt; permute(<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt;&amp; nums) &#123;</span><br><span class="line">        <span class="built_in">vector</span>&lt;<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt;&gt; res;</span><br><span class="line">        help(nums,res,<span class="number">0</span>);</span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">help</span><span class="params">(<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt;&amp; nums, <span class="built_in">vector</span>&lt;<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt;&gt; &amp;res, <span class="keyword">int</span> k)</span></span>&#123;</span><br><span class="line">        <span class="keyword">if</span>(k==nums.size()<span class="number">-1</span>) res.push_back(nums);</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i=k;i&lt;nums.size();i++)&#123;</span><br><span class="line">            swap(nums[i],nums[k]);</span><br><span class="line">            help(nums,res,k+<span class="number">1</span>);</span><br><span class="line">            swap(nums[i],nums[k]);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="22、旋转图像"><a href="#22、旋转图像" class="headerlink" title="22、旋转图像"></a>22、旋转图像</h1><p>给定一个 n × n 的二维矩阵表示一个图像。<br>将图像顺时针旋转 90 度。</p><p>说明：<br>你必须在原地旋转图像，这意味着你需要直接修改输入的二维矩阵。请不要使用另一个矩阵来旋转图像。</p><p>示例 1:</p><p>给定 matrix =<br>[<br>  [1,2,3],<br>  [4,5,6],<br>  [7,8,9]<br>],</p><p>原地旋转输入矩阵，使其变为:<br>[<br>  [7,4,1],<br>  [8,5,2],<br>  [9,6,3]<br>]示例 2:</p><p>给定 matrix =<br>[<br>  [ 5, 1, 9,11],<br>  [ 2, 4, 8,10],<br>  [13, 3, 6, 7],<br>  [15,14,12,16]<br>], </p><p>原地旋转输入矩阵，使其变为:<br>[<br>  [15,13, 2, 5],<br>  [14, 3, 4, 1],<br>  [12, 6, 8, 9],<br>  [16, 7,10,11]<br>]</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="comment">// 时间复杂度：O(n^2)，空间复杂度：O(1)</span></span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">rotate</span><span class="params">(<span class="built_in">vector</span>&lt;<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt;&gt;&amp; matrix)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">int</span> n= matrix.size();</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;n;i++)&#123;</span><br><span class="line">            <span class="keyword">for</span>(<span class="keyword">int</span> j=i;j&lt;n;j++)&#123;</span><br><span class="line">                swap(matrix[i][j],matrix[j][i]);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;n;i++)&#123;</span><br><span class="line">            <span class="keyword">for</span>(<span class="keyword">int</span> j=<span class="number">0</span>;j&lt;n/<span class="number">2</span>;j++)&#123;</span><br><span class="line">                swap(matrix[i][j],matrix[i][n<span class="number">-1</span>-j]);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="23、字母异位词分组"><a href="#23、字母异位词分组" class="headerlink" title="23、字母异位词分组"></a>23、字母异位词分组</h1><p>给定一个字符串数组，将字母异位词组合在一起。字母异位词指字母相同，但排列不同的字符串。</p><p>示例:</p><p>输入: [“eat”, “tea”, “tan”, “ate”, “nat”, “bat”],<br>输出:<br>[<br>  [“ate”,”eat”,”tea”],<br>  [“nat”,”tan”],<br>  [“bat”]<br>]说明：</p><p>所有输入均为小写字母。<br>不考虑答案输出的顺序。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line"><span class="comment">// 时间复杂度：O(NK)，空间复杂度：O(NK)</span></span><br><span class="line">    <span class="built_in">vector</span>&lt;<span class="built_in">vector</span>&lt;<span class="built_in">string</span>&gt;&gt; groupAnagrams(<span class="built_in">vector</span>&lt;<span class="built_in">string</span>&gt;&amp; strs) &#123;</span><br><span class="line">        <span class="built_in">unordered_map</span>&lt;<span class="built_in">string</span>,<span class="keyword">int</span>&gt; <span class="built_in">map</span>;</span><br><span class="line">        <span class="built_in">vector</span>&lt;<span class="built_in">vector</span>&lt;<span class="built_in">string</span>&gt;&gt; res;</span><br><span class="line">        <span class="keyword">int</span> k = <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;strs.size();i++)&#123;</span><br><span class="line">            <span class="built_in">string</span> str = strs[i];</span><br><span class="line">            <span class="function"><span class="built_in">string</span> <span class="title">node</span><span class="params">(<span class="number">26</span>,<span class="string">'0'</span>)</span></span>; </span><br><span class="line">            <span class="keyword">for</span>(<span class="keyword">int</span> j=<span class="number">0</span>;j&lt;str.size();j++)&#123;</span><br><span class="line">                <span class="keyword">int</span> t = node[str[j]-<span class="string">'a'</span>]-<span class="string">'0'</span>+<span class="number">1</span>;</span><br><span class="line">                node[str[j]-<span class="string">'a'</span>]= <span class="string">'0'</span> + t;</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">if</span>(<span class="built_in">map</span>.find(node)!=<span class="built_in">map</span>.end())&#123;</span><br><span class="line">                res[<span class="built_in">map</span>[node]].push_back(str);</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">else</span>&#123;</span><br><span class="line">                <span class="built_in">map</span>[node] = k;</span><br><span class="line">                res.push_back(<span class="built_in">vector</span>&lt;<span class="built_in">string</span>&gt;&#123;str&#125;);</span><br><span class="line">                k++;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="24、最大子序和"><a href="#24、最大子序和" class="headerlink" title="24、最大子序和"></a>24、最大子序和</h1><p>给定一个整数数组 nums ，找到一个具有最大和的连续子数组（子数组最少包含一个元素），返回其最大和。</p><p>示例:</p><p>输入: [-2,1,-3,4,-1,2,1,-5,4],<br>输出: 6<br>解释: 连续子数组 [4,-1,2,1] 的和最大，为 6。<br>进阶:</p><p>如果你已经实现复杂度为 O(n) 的解法，尝试使用更为精妙的分治法求解。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="comment">// 时间复杂度：O(n)，空间复杂度：O(1)</span></span><br><span class="line">    <span class="function"><span class="keyword">int</span> <span class="title">maxSubArray</span><span class="params">(<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt;&amp; nums)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">int</span> res = INT_MIN;</span><br><span class="line">        <span class="keyword">int</span> add = <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;nums.size();i++)&#123;</span><br><span class="line">            add+=nums[i];</span><br><span class="line">            res=max(res,add);</span><br><span class="line">            <span class="keyword">if</span>(add&lt;<span class="number">0</span>) add=<span class="number">0</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="25、跳跃游戏"><a href="#25、跳跃游戏" class="headerlink" title="25、跳跃游戏"></a>25、跳跃游戏</h1><p>给定一个非负整数数组，你最初位于数组的第一个位置。<br>数组中的每个元素代表你在该位置可以跳跃的最大长度。<br>判断你是否能够到达最后一个位置。</p><p>示例 1:</p><p>输入: [2,3,1,1,4]<br>输出: true<br>解释: 我们可以先跳 1 步，从位置 0 到达 位置 1, 然后再从位置 1 跳 3 步到达最后一个位置。<br>示例 2:</p><p>输入: [3,2,1,0,4]<br>输出: false<br>解释: 无论怎样，你总会到达索引为 3 的位置。但该位置的最大跳跃长度是 0 ， 所以你永远不可能到达最后一个位置。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="comment">// 时间复杂度：O(n)，空间复杂度：O(1)</span></span><br><span class="line">    <span class="function"><span class="keyword">bool</span> <span class="title">canJump</span><span class="params">(<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt;&amp; nums)</span> </span>&#123;</span><br><span class="line">       <span class="keyword">int</span> last = nums.size()<span class="number">-1</span>;</span><br><span class="line">       <span class="keyword">for</span>(<span class="keyword">int</span> i=nums.size()<span class="number">-2</span>;i&gt;=<span class="number">0</span>;i--)&#123;</span><br><span class="line">           <span class="keyword">if</span>(i+nums[i]&gt;=last) last = i;</span><br><span class="line">       &#125;</span><br><span class="line">       <span class="keyword">return</span> last == <span class="number">0</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="26、合并区间"><a href="#26、合并区间" class="headerlink" title="26、合并区间"></a>26、合并区间</h1><p>给出一个区间的集合，请合并所有重叠的区间。</p><p>示例 1:</p><p>输入: [[1,3],[2,6],[8,10],[15,18]]<br>输出: [[1,6],[8,10],[15,18]]<br>解释: 区间 [1,3] 和 [2,6] 重叠, 将它们合并为 [1,6].<br>示例 2:</p><p>输入: [[1,4],[4,5]]<br>输出: [[1,5]]<br>解释: 区间 [1,4] 和 [4,5] 可被视为重叠区间。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line"><span class="comment">// 时间复杂度：O(nlogn)，空间复杂度：O(1)</span></span><br><span class="line">    <span class="built_in">vector</span>&lt;<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt;&gt; merge(<span class="built_in">vector</span>&lt;<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt;&gt;&amp; intervals) &#123;</span><br><span class="line">        <span class="built_in">vector</span>&lt;<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt;&gt; res;</span><br><span class="line">        sort(intervals.begin(),intervals.end(),Sort);</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;intervals.size();i++)&#123;</span><br><span class="line">            <span class="keyword">if</span>(res.empty() || intervals[i][<span class="number">0</span>]&gt;res[res.size()<span class="number">-1</span>][<span class="number">1</span>])</span><br><span class="line">                res.push_back(intervals[i]);</span><br><span class="line">            <span class="keyword">else</span></span><br><span class="line">                res[res.size()<span class="number">-1</span>][<span class="number">1</span>] = max(res[res.size()<span class="number">-1</span>][<span class="number">1</span>],intervals[i][<span class="number">1</span>]);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="function"><span class="keyword">static</span> <span class="keyword">bool</span> <span class="title">Sort</span><span class="params">(<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; &amp;a,<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; &amp;b)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> a[<span class="number">0</span>]&lt;b[<span class="number">0</span>];</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="27、不同路径"><a href="#27、不同路径" class="headerlink" title="27、不同路径"></a>27、不同路径</h1><p>一个机器人位于一个 m x n 网格的左上角 （起始点在下图中标记为“Start” ）。<br>机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角（在下图中标记为“Finish”）。<br>问总共有多少条不同的路径？<br><img src="https://img-blog.csdnimg.cn/20191206115203468.png" alt="在这里插入图片描述"><br>例如，上图是一个7 x 3 的网格。有多少可能的路径？</p><p>说明：m 和 n 的值均不超过 100。</p><p>示例 1:</p><p>输入: m = 3, n = 2<br>输出: 3<br>解释:<br>从左上角开始，总共有 3 条路径可以到达右下角。</p><ol><li>向右 -&gt; 向右 -&gt; 向下</li><li>向右 -&gt; 向下 -&gt; 向右</li><li>向下 -&gt; 向右 -&gt; 向右<br>示例 2:</li></ol><p>输入: m = 7, n = 3<br>输出: 28</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line"><span class="comment">// 时间复杂度：O(nm)，空间复杂度：O(nm)</span></span><br><span class="line">    <span class="function"><span class="keyword">int</span> <span class="title">uniquePaths</span><span class="params">(<span class="keyword">int</span> m, <span class="keyword">int</span> n)</span> </span>&#123;</span><br><span class="line">        <span class="built_in">vector</span>&lt;<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt;&gt; dp(m+<span class="number">1</span>,<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt;(n+<span class="number">1</span>));</span><br><span class="line">        dp[<span class="number">0</span>][<span class="number">0</span>] = <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">1</span>;i&lt;=m;i++)&#123;</span><br><span class="line">            <span class="keyword">for</span>(<span class="keyword">int</span> j=<span class="number">1</span>;j&lt;=n;j++)&#123;</span><br><span class="line">                <span class="keyword">if</span>(i==<span class="number">1</span>||j==<span class="number">1</span>) dp[i][j] = <span class="number">1</span>;</span><br><span class="line">                <span class="keyword">else</span> dp[i][j] = dp[i<span class="number">-1</span>][j]+dp[i][j<span class="number">-1</span>];</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> dp[m][n];</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="28、最小路径和"><a href="#28、最小路径和" class="headerlink" title="28、最小路径和"></a>28、最小路径和</h1><p>给定一个包含非负整数的 m x n 网格，请找出一条从左上角到右下角的路径，使得路径上的数字总和为最小。</p><p>说明：每次只能向下或者向右移动一步。</p><p>示例:</p><p>输入:<br>[<br>  [1,3,1],<br>  [1,5,1],<br>  [4,2,1]<br>]输出: 7<br>解释: 因为路径 1→3→1→1→1 的总和最小。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line"><span class="comment">// 时间复杂度：O(nm)，空间复杂度：O(nm)</span></span><br><span class="line">    <span class="function"><span class="keyword">int</span> <span class="title">minPathSum</span><span class="params">(<span class="built_in">vector</span>&lt;<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt;&gt;&amp; grid)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">int</span> res = INT_MAX;</span><br><span class="line">        <span class="keyword">int</span> m = grid.size(), n = grid[<span class="number">0</span>].size();</span><br><span class="line">        <span class="built_in">vector</span>&lt;<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt;&gt; dp(m,<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt;(n,<span class="number">0</span>));</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;m;i++)&#123;</span><br><span class="line">            <span class="keyword">for</span>(<span class="keyword">int</span> j=<span class="number">0</span>;j&lt;n;j++)&#123;</span><br><span class="line">                <span class="keyword">if</span>(i==<span class="number">0</span>&amp;&amp;j==<span class="number">0</span>) dp[i][j] = grid[i][j];</span><br><span class="line">                <span class="keyword">else</span>&#123;</span><br><span class="line">                    <span class="keyword">if</span>(i==<span class="number">0</span>) dp[i][j] = dp[i][j<span class="number">-1</span>] + grid[i][j];</span><br><span class="line">                    <span class="keyword">else</span> <span class="keyword">if</span>(j==<span class="number">0</span>) dp[i][j] = dp[i<span class="number">-1</span>][j] + grid[i][j];</span><br><span class="line">                    <span class="keyword">else</span> dp[i][j] = min(dp[i][j<span class="number">-1</span>],dp[i<span class="number">-1</span>][j]) + grid[i][j];</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> dp[m<span class="number">-1</span>][n<span class="number">-1</span>];</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="29、爬楼梯"><a href="#29、爬楼梯" class="headerlink" title="29、爬楼梯"></a>29、爬楼梯</h1><p>假设你正在爬楼梯。需要 n 阶你才能到达楼顶。</p><p>每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢？</p><p>注意：给定 n 是一个正整数。</p><p>示例 1：</p><p>输入： 2<br>输出： 2<br>解释： 有两种方法可以爬到楼顶。</p><ol><li>1 阶 + 1 阶</li><li>2 阶<br>示例 2：</li></ol><p>输入： 3<br>输出： 3<br>解释： 有三种方法可以爬到楼顶。</p><ol><li>1 阶 + 1 阶 + 1 阶</li><li>1 阶 + 2 阶</li><li>2 阶 + 1 阶</li></ol><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line"><span class="comment">// 时间复杂度：O(n)，空间复杂度：O(1)</span></span><br><span class="line">    <span class="function"><span class="keyword">int</span> <span class="title">climbStairs</span><span class="params">(<span class="keyword">int</span> n)</span> </span>&#123;</span><br><span class="line">        <span class="comment">// 1 2 3 5</span></span><br><span class="line">        <span class="keyword">int</span> i=<span class="number">0</span>,j=<span class="number">1</span>,k=<span class="number">0</span>;</span><br><span class="line">        <span class="keyword">while</span>(k&lt;n)&#123;</span><br><span class="line">            <span class="keyword">int</span> t = j;</span><br><span class="line">            j = i+j;</span><br><span class="line">            i = t;</span><br><span class="line">            k++;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> j;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="30、编辑距离"><a href="#30、编辑距离" class="headerlink" title="30、编辑距离"></a>30、编辑距离</h1><p>给定两个单词 word1 和 word2，计算出将 word1 转换成 word2 所使用的最少操作数 。</p><p>你可以对一个单词进行如下三种操作：</p><p>插入一个字符<br>删除一个字符<br>替换一个字符<br>示例 1:</p><p>输入: word1 = “horse”, word2 = “ros”<br>输出: 3<br>解释:<br>horse -&gt; rorse (将 ‘h’ 替换为 ‘r’)<br>rorse -&gt; rose (删除 ‘r’)<br>rose -&gt; ros (删除 ‘e’)<br>示例 2:</p><p>输入: word1 = “intention”, word2 = “execution”<br>输出: 5<br>解释:<br>intention -&gt; inention (删除 ‘t’)<br>inention -&gt; enention (将 ‘i’ 替换为 ‘e’)<br>enention -&gt; exention (将 ‘n’ 替换为 ‘x’)<br>exention -&gt; exection (将 ‘n’ 替换为 ‘c’)<br>exection -&gt; execution (插入 ‘u’)</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line"><span class="comment">// 时间复杂度：O(mn)，空间复杂度：O(mn)</span></span><br><span class="line">    <span class="function"><span class="keyword">int</span> <span class="title">minDistance</span><span class="params">(<span class="built_in">string</span> word1, <span class="built_in">string</span> word2)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">int</span> m= word1.size(), n=word2.size();</span><br><span class="line">        <span class="built_in">vector</span>&lt;<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt;&gt; dp(m+<span class="number">1</span>,<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt;(n+<span class="number">1</span>));</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;=m;i++)&#123;</span><br><span class="line">            <span class="keyword">for</span>(<span class="keyword">int</span> j=<span class="number">0</span>;j&lt;=n;j++)&#123;</span><br><span class="line">                <span class="keyword">if</span>(i==<span class="number">0</span>||j==<span class="number">0</span>) dp[i][j]= max(i,j);</span><br><span class="line">                <span class="keyword">else</span> <span class="keyword">if</span>(word1[i<span class="number">-1</span>]==word2[j<span class="number">-1</span>]) dp[i][j] = dp[i<span class="number">-1</span>][j<span class="number">-1</span>];</span><br><span class="line">                <span class="keyword">else</span> dp[i][j]= min(dp[i<span class="number">-1</span>][j],min(dp[i][j<span class="number">-1</span>],dp[i<span class="number">-1</span>][j<span class="number">-1</span>])) + <span class="number">1</span>;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> dp[m][n];</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="31、颜色分类"><a href="#31、颜色分类" class="headerlink" title="31、颜色分类"></a>31、颜色分类</h1><p>给定一个包含红色、白色和蓝色，一共 n 个元素的数组，原地对它们进行排序，使得相同颜色的元素相邻，并按照红色、白色、蓝色顺序排列。</p><p>此题中，我们使用整数 0、 1 和 2 分别表示红色、白色和蓝色。</p><p>注意:<br>不能使用代码库中的排序函数来解决这道题。</p><p>示例:</p><p>输入: [2,0,2,1,1,0]<br>输出: [0,0,1,1,2,2]<br>进阶：</p><p>一个直观的解决方案是使用计数排序的两趟扫描算法。<br>首先，迭代计算出0、1 和 2 元素的个数，然后按照0、1、2的排序，重写当前数组。<br>你能想出一个仅使用常数空间的一趟扫描算法吗？</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line"><span class="comment">// 时间复杂度：O(n)，空间复杂度：O(1)</span></span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">sortColors</span><span class="params">(<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt;&amp; nums)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">int</span> p0 = <span class="number">0</span>, p2 = nums.size()<span class="number">-1</span>, cur = <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">while</span>(cur&lt;=p2)&#123;</span><br><span class="line">            <span class="keyword">if</span>(nums[cur] == <span class="number">0</span>)&#123;</span><br><span class="line">                swap(nums[p0],nums[cur]); </span><br><span class="line">                p0++;</span><br><span class="line">                cur++;</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">else</span> <span class="keyword">if</span>(nums[cur] == <span class="number">2</span>)&#123;</span><br><span class="line">                swap(nums[p2],nums[cur]); </span><br><span class="line">                p2--;</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">else</span> cur++;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="32、最小覆盖子串"><a href="#32、最小覆盖子串" class="headerlink" title="32、最小覆盖子串"></a>32、最小覆盖子串</h1><p>给你一个字符串 S、一个字符串 T，请在字符串 S 里面找出：包含 T 所有字母的最小子串。</p><p>示例：</p><p>输入: S = “ADOBECODEBANC”, T = “ABC”<br>输出: “BANC”<br>说明：</p><p>如果 S 中不存这样的子串，则返回空字符串 “”。<br>如果 S 中存在这样的子串，我们保证它是唯一的答案。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line"><span class="comment">// 时间复杂度：O(S+T)，空间复杂度：O(S+T)</span></span><br><span class="line">    <span class="function"><span class="built_in">string</span> <span class="title">minWindow</span><span class="params">(<span class="built_in">string</span> s, <span class="built_in">string</span> t)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">int</span> start = <span class="number">0</span>, len = INT_MAX;</span><br><span class="line">        <span class="keyword">int</span> l = <span class="number">0</span>, r = <span class="number">0</span>;</span><br><span class="line">        <span class="built_in">unordered_map</span>&lt;<span class="keyword">char</span>,<span class="keyword">int</span>&gt; <span class="built_in">map</span>;</span><br><span class="line">        <span class="built_in">unordered_map</span>&lt;<span class="keyword">char</span>,<span class="keyword">int</span>&gt; match;</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">char</span> c : t) <span class="built_in">map</span>[c]++;</span><br><span class="line">        </span><br><span class="line">        <span class="keyword">int</span> count = <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">while</span>(r&lt;s.size())&#123;</span><br><span class="line">            <span class="keyword">char</span> t = s[r];</span><br><span class="line">            <span class="keyword">if</span>(<span class="built_in">map</span>.count(t))&#123;</span><br><span class="line">                match[t]++;</span><br><span class="line">                <span class="keyword">if</span>(<span class="built_in">map</span>[t] == match[t])&#123;</span><br><span class="line">                    count++;</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">            r++;</span><br><span class="line"></span><br><span class="line">            <span class="keyword">while</span>(<span class="built_in">map</span>.size()==count)&#123;</span><br><span class="line">                <span class="keyword">if</span>(r-l&lt;len)&#123;</span><br><span class="line">                    start = l;</span><br><span class="line">                    len = r-l;</span><br><span class="line">                &#125;</span><br><span class="line">                <span class="keyword">char</span> t2 = s[l];</span><br><span class="line">                <span class="keyword">if</span>(<span class="built_in">map</span>.count(t2))&#123;</span><br><span class="line">                    match[t2]--;</span><br><span class="line">                    <span class="keyword">if</span>(match[t2]&lt;<span class="built_in">map</span>[t2])&#123;</span><br><span class="line">                        count--;</span><br><span class="line">                    &#125;</span><br><span class="line">                &#125;</span><br><span class="line">                l++;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> len == INT_MAX? <span class="string">""</span>:s.substr(start,len);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="33、子集"><a href="#33、子集" class="headerlink" title="33、子集"></a>33、子集</h1><p>给定一组不含重复元素的整数数组 nums，返回该数组所有可能的子集（幂集）。</p><p>说明：解集不能包含重复的子集。</p><p>示例:</p><p>输入: nums = [1,2,3]<br>输出:<br>[<br>  [3],<br>  [1],<br>  [2],<br>  [1,2,3],<br>  [1,3],<br>  [2,3],<br>  [1,2],<br>  []<br>]</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="comment">// 利用二进制，时间复杂度：O(2^n)，空间复杂度：O(2^n)</span></span><br><span class="line">    <span class="built_in">vector</span>&lt;<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt;&gt; subsets(<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt;&amp; nums) &#123;</span><br><span class="line">        <span class="built_in">vector</span>&lt;<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt;&gt; res;</span><br><span class="line">        <span class="keyword">int</span> len = <span class="number">1</span>&lt;&lt;nums.size();</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;len;i++)&#123;</span><br><span class="line">            <span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; tmp;</span><br><span class="line">            <span class="keyword">for</span>(<span class="keyword">int</span> j=<span class="number">0</span>;j&lt;nums.size();j++)&#123;</span><br><span class="line">                <span class="keyword">if</span>(i&amp;(<span class="number">1</span>&lt;&lt;j)) tmp.push_back(nums[j]);</span><br><span class="line">            &#125;</span><br><span class="line">            res.push_back(tmp);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line"><span class="comment">// 时间复杂度：O(2^n)，空间复杂度：O(2^n)</span></span><br><span class="line">    <span class="built_in">vector</span>&lt;<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt;&gt; subsets(<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt;&amp; nums) &#123;</span><br><span class="line">        <span class="built_in">vector</span>&lt;<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt;&gt; res&#123;&#123;&#125;&#125;;</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;nums.size();i++)&#123;</span><br><span class="line">            <span class="keyword">int</span> len = res.size();</span><br><span class="line">            <span class="keyword">for</span>(<span class="keyword">int</span> j=<span class="number">0</span>;j&lt;len;j++)&#123;</span><br><span class="line">                <span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; tmp(res[j]);</span><br><span class="line">                tmp.push_back(nums[i]);</span><br><span class="line">                res.push_back(tmp);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="34、单词搜索"><a href="#34、单词搜索" class="headerlink" title="34、单词搜索"></a>34、单词搜索</h1><p>给定一个二维网格和一个单词，找出该单词是否存在于网格中。</p><p>单词必须按照字母顺序，通过相邻的单元格内的字母构成，其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。</p><p>示例:</p><p>board =<br>[<br>  [‘A’,’B’,’C’,’E’],<br>  [‘S’,’F’,’C’,’S’],<br>  [‘A’,’D’,’E’,’E’]<br>]</p><p>给定 word = “ABCCED”, 返回 true.<br>给定 word = “SEE”, 返回 true.<br>给定 word = “ABCB”, 返回 false.</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function"><span class="keyword">bool</span> <span class="title">exist</span><span class="params">(<span class="built_in">vector</span>&lt;<span class="built_in">vector</span>&lt;<span class="keyword">char</span>&gt;&gt;&amp; board, <span class="built_in">string</span> word)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;board.size();i++)&#123;</span><br><span class="line">            <span class="keyword">for</span>(<span class="keyword">int</span> j=<span class="number">0</span>;j&lt;board[<span class="number">0</span>].size();j++)&#123;</span><br><span class="line">                <span class="keyword">if</span>(help(board,i,j,word,<span class="number">0</span>)) <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="function"><span class="keyword">bool</span> <span class="title">help</span><span class="params">(<span class="built_in">vector</span>&lt;<span class="built_in">vector</span>&lt;<span class="keyword">char</span>&gt;&gt; &amp;board, <span class="keyword">int</span> i, <span class="keyword">int</span> j, <span class="built_in">string</span> word, <span class="keyword">int</span> k)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">if</span>(i&lt;<span class="number">0</span>||i&gt;=board.size()||j&lt;<span class="number">0</span>||j&gt;=board[<span class="number">0</span>].size()||board[i][j]==<span class="string">'*'</span>||board[i][j]!=word[k]) <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">        <span class="keyword">if</span>(k==word.size()<span class="number">-1</span>) <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line">        <span class="keyword">char</span> tmp = board[i][j];</span><br><span class="line">        board[i][j] = <span class="string">'*'</span>;</span><br><span class="line">        <span class="keyword">if</span>(help(board,i<span class="number">-1</span>,j,word,k+<span class="number">1</span>)</span><br><span class="line">        || help(board,i+<span class="number">1</span>,j,word,k+<span class="number">1</span>)</span><br><span class="line">        || help(board,i,j<span class="number">-1</span>,word,k+<span class="number">1</span>)</span><br><span class="line">        || help(board,i,j+<span class="number">1</span>,word,k+<span class="number">1</span>))&#123;</span><br><span class="line">            <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        board[i][j] = tmp;</span><br><span class="line">        <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="35、柱状图中最大的矩形"><a href="#35、柱状图中最大的矩形" class="headerlink" title="35、柱状图中最大的矩形"></a>35、柱状图中最大的矩形</h1><p>给定 n 个非负整数，用来表示柱状图中各个柱子的高度。每个柱子彼此相邻，且宽度为 1 。<br>求在该柱状图中，能够勾勒出来的矩形的最大面积。<br><img src="https://img-blog.csdnimg.cn/20191209113446226.png" alt="在这里插入图片描述"><br>以上是柱状图的示例，其中每个柱子的宽度为 1，给定的高度为 [2,1,5,6,2,3]。<br><img src="https://img-blog.csdnimg.cn/20191209113510223.png" alt="在这里插入图片描述"><br>图中阴影部分为所能勾勒出的最大矩形面积，其面积为 10 个单位。</p><p>示例:</p><p>输入: [2,1,5,6,2,3]<br>输出: 10</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="comment">// 时间复杂度：O(nlogn)，空间复杂度：O(n) 有时候通过有时候超时</span></span><br><span class="line">    <span class="function"><span class="keyword">int</span> <span class="title">largestRectangleArea</span><span class="params">(<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt;&amp; heights)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> help(heights,<span class="number">0</span>,heights.size()<span class="number">-1</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="function"><span class="keyword">int</span> <span class="title">help</span><span class="params">(<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; &amp;heights, <span class="keyword">int</span> l, <span class="keyword">int</span> r)</span></span>&#123;</span><br><span class="line">        <span class="keyword">if</span>(l&gt;r) <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">int</span> low = l;</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i=l;i&lt;=r;i++)&#123;</span><br><span class="line">            <span class="keyword">if</span>(heights[i]&lt;heights[low]) low = i;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> max(heights[low]*(r-l+<span class="number">1</span>),max(help(heights,l,low<span class="number">-1</span>),help(heights,low+<span class="number">1</span>,r)));</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="comment">// 时间复杂度：O(n)，空间复杂度：O(n)</span></span><br><span class="line">    <span class="function"><span class="keyword">int</span> <span class="title">largestRectangleArea</span><span class="params">(<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt;&amp; heights)</span> </span>&#123;        </span><br><span class="line">        <span class="built_in">stack</span>&lt;<span class="keyword">int</span>&gt; st;</span><br><span class="line">        heights.push_back(<span class="number">0</span>);</span><br><span class="line">        <span class="keyword">int</span> size = heights.size();</span><br><span class="line">        <span class="keyword">int</span> res = <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; size; i++) &#123;</span><br><span class="line">            <span class="keyword">while</span> (!st.empty() &amp;&amp; heights[st.top()] &gt;= heights[i]) &#123;</span><br><span class="line">                <span class="keyword">int</span> val = st.top();</span><br><span class="line">                st.pop();</span><br><span class="line">                res = max(res, heights[val] * (st.empty() ? i : (i - st.top() - <span class="number">1</span>)));</span><br><span class="line">            &#125;</span><br><span class="line">            st.push(i);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">    &#125; </span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="36、最大矩形"><a href="#36、最大矩形" class="headerlink" title="36、最大矩形"></a>36、最大矩形</h1><p>给定一个仅包含 0 和 1 的二维二进制矩阵，找出只包含 1 的最大矩形，并返回其面积。</p><p>示例:</p><p>输入:<br>[<br>  [“1”,”0”,”1”,”0”,”0”],<br>  [“1”,”0”,”1”,”1”,”1”],<br>  [“1”,”1”,”1”,”1”,”1”],<br>  [“1”,”0”,”0”,”1”,”0”]<br>]输出: 6</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line"><span class="comment">// 时间复杂度：O(n*m)，空间复杂度：O(m)</span></span><br><span class="line">    <span class="function"><span class="keyword">int</span> <span class="title">maximalRectangle</span><span class="params">(<span class="built_in">vector</span>&lt;<span class="built_in">vector</span>&lt;<span class="keyword">char</span>&gt;&gt;&amp; matrix)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">if</span>(matrix.empty()) <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">int</span> res = <span class="number">0</span>;</span><br><span class="line">        <span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; vec(matrix[<span class="number">0</span>].size(),<span class="number">0</span>);</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;matrix.size();i++)&#123;</span><br><span class="line">            <span class="keyword">for</span>(<span class="keyword">int</span> j=<span class="number">0</span>;j&lt;matrix[<span class="number">0</span>].size();j++)&#123;</span><br><span class="line">                vec[j] = matrix[i][j]==<span class="string">'1'</span>?vec[j]+<span class="number">1</span>:<span class="number">0</span>;</span><br><span class="line">            &#125;</span><br><span class="line">            res = max(res,help(vec));</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="function"><span class="keyword">int</span> <span class="title">help</span><span class="params">(<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; &amp;vec)</span></span>&#123;</span><br><span class="line">        <span class="built_in">stack</span>&lt;<span class="keyword">int</span>&gt; <span class="built_in">stack</span>;</span><br><span class="line">        <span class="keyword">int</span> res = <span class="number">0</span>;</span><br><span class="line">        vec.push_back(<span class="number">0</span>);</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;vec.size();i++)&#123;</span><br><span class="line">            <span class="keyword">while</span>(!<span class="built_in">stack</span>.empty()&amp;&amp;vec[<span class="built_in">stack</span>.top()]&gt;=vec[i])&#123;</span><br><span class="line">                <span class="keyword">int</span> tmp = <span class="built_in">stack</span>.top();</span><br><span class="line">                <span class="built_in">stack</span>.pop();</span><br><span class="line">                res = max(res,vec[tmp]*(<span class="built_in">stack</span>.empty()?i:(i-<span class="built_in">stack</span>.top()<span class="number">-1</span>)));</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="built_in">stack</span>.push(i);</span><br><span class="line">        &#125;</span><br><span class="line">        vec.pop_back();</span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="37、二叉树的中序遍历"><a href="#37、二叉树的中序遍历" class="headerlink" title="37、二叉树的中序遍历"></a>37、二叉树的中序遍历</h1><p>给定一个二叉树，返回它的中序 遍历。</p><p>示例:</p><p>输入: [1,null,2,3]</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">1</span><br><span class="line"> \</span><br><span class="line">  2</span><br><span class="line"> /</span><br><span class="line">3</span><br></pre></td></tr></table></figure><p>输出: [1,3,2]<br>进阶: 递归算法很简单，你可以通过迭代算法完成吗？</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Definition for a binary tree node.</span></span><br><span class="line"><span class="comment"> * struct TreeNode &#123;</span></span><br><span class="line"><span class="comment"> *     int val;</span></span><br><span class="line"><span class="comment"> *     TreeNode *left;</span></span><br><span class="line"><span class="comment"> *     TreeNode *right;</span></span><br><span class="line"><span class="comment"> *     TreeNode(int x) : val(x), left(NULL), right(NULL) &#123;&#125;</span></span><br><span class="line"><span class="comment"> * &#125;;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="comment">// 时间复杂度：O(n)，空间复杂度：O(logn) 递归</span></span><br><span class="line">    <span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; inorderTraversal(TreeNode* root) &#123;</span><br><span class="line">        <span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; res;</span><br><span class="line">        help(res,root);</span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">help</span><span class="params">(<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; &amp;res, TreeNode* root)</span></span>&#123;</span><br><span class="line">        <span class="keyword">if</span>(!root) <span class="keyword">return</span>;</span><br><span class="line">        help(res,root-&gt;left);</span><br><span class="line">        res.push_back(root-&gt;val);</span><br><span class="line">        help(res,root-&gt;right);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="comment">// 时间复杂度：O(n)，空间复杂度：O(n) 栈</span></span><br><span class="line">    <span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; inorderTraversal(TreeNode* root) &#123;</span><br><span class="line">        <span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; res;</span><br><span class="line">        <span class="built_in">stack</span>&lt;TreeNode*&gt; <span class="built_in">stack</span>;</span><br><span class="line">        TreeNode* cur = root;</span><br><span class="line">        <span class="keyword">while</span>(cur || !<span class="built_in">stack</span>.empty())&#123;</span><br><span class="line">            <span class="keyword">while</span>(cur)&#123;</span><br><span class="line">                <span class="built_in">stack</span>.push(cur);</span><br><span class="line">                cur = cur-&gt;left;</span><br><span class="line">            &#125;</span><br><span class="line">            cur = <span class="built_in">stack</span>.top();</span><br><span class="line">            <span class="built_in">stack</span>.pop();</span><br><span class="line">            res.push_back(cur-&gt;val);</span><br><span class="line">            cur = cur-&gt;right;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="comment">// 时间复杂度：O(n)，空间复杂度：O(n) 线索二叉树</span></span><br><span class="line">    <span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; inorderTraversal(TreeNode* root) &#123;</span><br><span class="line">        <span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; res;</span><br><span class="line">        TreeNode* cur = root;</span><br><span class="line">        TreeNode* next;</span><br><span class="line">        <span class="keyword">while</span>(cur)&#123;</span><br><span class="line">            <span class="keyword">if</span>(!cur-&gt;left)&#123;</span><br><span class="line">                res.push_back(cur-&gt;val);</span><br><span class="line">                cur = cur-&gt;right;</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">else</span>&#123;</span><br><span class="line">                next = cur-&gt;left;</span><br><span class="line">                <span class="keyword">while</span>(next-&gt;right)&#123;</span><br><span class="line">                    next = next-&gt;right;</span><br><span class="line">                &#125;</span><br><span class="line">                next-&gt;right = cur;</span><br><span class="line">                TreeNode* tmp = cur;</span><br><span class="line">                cur = cur-&gt;left;</span><br><span class="line">                tmp-&gt;left = <span class="literal">NULL</span>;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="38、不同的二叉搜索树"><a href="#38、不同的二叉搜索树" class="headerlink" title="38、不同的二叉搜索树"></a>38、不同的二叉搜索树</h1><p>给定一个整数 n，求以 1 … n 为节点组成的二叉搜索树有多少种？</p><p>示例:</p><p>输入: 3<br>输出: 5<br>解释:<br>给定 n = 3, 一共有 5 种不同结构的二叉搜索树:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">1         3     3      2      1</span><br><span class="line"> \       /     /      / \      \</span><br><span class="line">  3     2     1      1   3      2</span><br><span class="line"> /     /       \                 \</span><br><span class="line">2     1         2                 3</span><br></pre></td></tr></table></figure><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="comment">// 时间复杂度：O(n^2)，空间复杂度：O(n)</span></span><br><span class="line">    <span class="function"><span class="keyword">int</span> <span class="title">numTrees</span><span class="params">(<span class="keyword">int</span> n)</span> </span>&#123;</span><br><span class="line">        <span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; res(n+<span class="number">1</span>);</span><br><span class="line">        res[<span class="number">0</span>] = <span class="number">1</span>;</span><br><span class="line">        res[<span class="number">1</span>] = <span class="number">1</span>;</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">2</span>;i&lt;=n;i++)&#123;</span><br><span class="line">            <span class="keyword">for</span>(<span class="keyword">int</span> j=<span class="number">1</span>;j&lt;=i;j++)&#123;</span><br><span class="line">                res[i] += res[j<span class="number">-1</span>]*res[i-j];</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> res[n];</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="39、验证二叉搜索树"><a href="#39、验证二叉搜索树" class="headerlink" title="39、验证二叉搜索树"></a>39、验证二叉搜索树</h1><p>给定一个二叉树，判断其是否是一个有效的二叉搜索树。</p><p>假设一个二叉搜索树具有如下特征：</p><p>节点的左子树只包含小于当前节点的数。<br>节点的右子树只包含大于当前节点的数。<br>所有左子树和右子树自身必须也是二叉搜索树。<br>示例 1:</p><p>输入:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">  2</span><br><span class="line"> /  \</span><br><span class="line">1    3</span><br></pre></td></tr></table></figure><p>输出: true<br>示例 2:</p><p>输入:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">  5</span><br><span class="line"> /  \</span><br><span class="line">1    4</span><br><span class="line">    /  \</span><br><span class="line">    3   6</span><br></pre></td></tr></table></figure><p>输出: false<br>解释: 输入为: [5,1,4,null,null,3,6]。<br>     根节点的值为 5 ，但是其右子节点值为 4 。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Definition for a binary tree node.</span></span><br><span class="line"><span class="comment"> * struct TreeNode &#123;</span></span><br><span class="line"><span class="comment"> *     int val;</span></span><br><span class="line"><span class="comment"> *     TreeNode *left;</span></span><br><span class="line"><span class="comment"> *     TreeNode *right;</span></span><br><span class="line"><span class="comment"> *     TreeNode(int x) : val(x), left(NULL), right(NULL) &#123;&#125;</span></span><br><span class="line"><span class="comment"> * &#125;;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="comment">// 时间复杂度：O(n)，空间复杂度：O(n) 中序遍历递增</span></span><br><span class="line">    <span class="function"><span class="keyword">bool</span> <span class="title">isValidBST</span><span class="params">(TreeNode* root)</span> </span>&#123;</span><br><span class="line">        <span class="built_in">stack</span>&lt;TreeNode*&gt; <span class="built_in">stack</span>;</span><br><span class="line">        TreeNode* cur = root;</span><br><span class="line">        <span class="comment">//int tmp = INT_MIN; // 测试用例用[-2147483648]卡边界值过分了。。。</span></span><br><span class="line">        <span class="keyword">long</span> tmp = LONG_MIN;</span><br><span class="line">        <span class="keyword">while</span>(cur || !<span class="built_in">stack</span>.empty())&#123;</span><br><span class="line">            <span class="keyword">while</span>(cur)&#123;</span><br><span class="line">                <span class="built_in">stack</span>.push(cur);</span><br><span class="line">                cur=cur-&gt;left;</span><br><span class="line">            &#125;</span><br><span class="line">            cur = <span class="built_in">stack</span>.top();</span><br><span class="line">            <span class="built_in">stack</span>.pop();</span><br><span class="line">            <span class="keyword">if</span>(cur-&gt;val&lt;=tmp)&#123;</span><br><span class="line">                <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">            &#125;</span><br><span class="line">            tmp = cur-&gt;val;</span><br><span class="line">            cur = cur-&gt;right;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="40、对称二叉树"><a href="#40、对称二叉树" class="headerlink" title="40、对称二叉树"></a>40、对称二叉树</h1><p>给定一个二叉树，检查它是否是镜像对称的。</p><p>例如，二叉树 [1,2,2,3,4,4,3] 是对称的。</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">    1</span><br><span class="line">   / \</span><br><span class="line">  2   2</span><br><span class="line"> / \ / \</span><br><span class="line">3  4 4  3</span><br></pre></td></tr></table></figure><p>但是下面这个 [1,2,2,null,3,null,3] 则不是镜像对称的:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">  1</span><br><span class="line"> / \</span><br><span class="line">2   2</span><br><span class="line"> \   \</span><br><span class="line"> 3    3</span><br></pre></td></tr></table></figure><p>说明:</p><p>如果你可以运用递归和迭代两种方法解决这个问题，会很加分。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Definition for a binary tree node.</span></span><br><span class="line"><span class="comment"> * struct TreeNode &#123;</span></span><br><span class="line"><span class="comment"> *     int val;</span></span><br><span class="line"><span class="comment"> *     TreeNode *left;</span></span><br><span class="line"><span class="comment"> *     TreeNode *right;</span></span><br><span class="line"><span class="comment"> *     TreeNode(int x) : val(x), left(NULL), right(NULL) &#123;&#125;</span></span><br><span class="line"><span class="comment"> * &#125;;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line"><span class="comment">// 时间复杂度：O(n)，空间复杂度：O(n) 递归</span></span><br><span class="line">    <span class="function"><span class="keyword">bool</span> <span class="title">isSymmetric</span><span class="params">(TreeNode* root)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">if</span>(!root) <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line">        <span class="keyword">return</span> help(root-&gt;left,root-&gt;right);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="function"><span class="keyword">bool</span> <span class="title">help</span><span class="params">(TreeNode* l,TreeNode* r)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">if</span>(!l &amp;&amp; !r) <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line">        <span class="keyword">if</span>(!l || !r) <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">        <span class="keyword">return</span> l-&gt;val==r-&gt;val &amp;&amp; help(l-&gt;right,r-&gt;left) &amp;&amp; help(l-&gt;left,r-&gt;right);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line"><span class="comment">// 时间复杂度：O(n)，空间复杂度：O(n) 迭代</span></span><br><span class="line">    <span class="function"><span class="keyword">bool</span> <span class="title">isSymmetric</span><span class="params">(TreeNode* root)</span> </span>&#123;</span><br><span class="line">        <span class="built_in">queue</span>&lt;TreeNode*&gt; <span class="built_in">queue</span>;</span><br><span class="line">        <span class="built_in">queue</span>.push(root);</span><br><span class="line">        <span class="built_in">queue</span>.push(root);</span><br><span class="line">        <span class="keyword">while</span>(!<span class="built_in">queue</span>.empty())&#123;</span><br><span class="line">            TreeNode* t1 = <span class="built_in">queue</span>.front();</span><br><span class="line">            <span class="built_in">queue</span>.pop();</span><br><span class="line">            TreeNode* t2 = <span class="built_in">queue</span>.front();</span><br><span class="line">            <span class="built_in">queue</span>.pop();</span><br><span class="line">            <span class="keyword">if</span>(!t1 &amp;&amp; !t2) <span class="keyword">continue</span>;</span><br><span class="line">            <span class="keyword">if</span>(!t1 || !t2) <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">            <span class="keyword">if</span>(t1-&gt;val != t2-&gt;val) <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">            <span class="built_in">queue</span>.push(t1-&gt;left);</span><br><span class="line">            <span class="built_in">queue</span>.push(t2-&gt;right);</span><br><span class="line">            <span class="built_in">queue</span>.push(t2-&gt;left);</span><br><span class="line">            <span class="built_in">queue</span>.push(t1-&gt;right);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="41、二叉树的层次遍历"><a href="#41、二叉树的层次遍历" class="headerlink" title="41、二叉树的层次遍历"></a>41、二叉树的层次遍历</h1><p>给定一个二叉树，返回其按层次遍历的节点值。 （即逐层地，从左到右访问所有节点）。</p><p>例如:<br>给定二叉树: [3,9,20,null,null,15,7],</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">  3</span><br><span class="line"> / \</span><br><span class="line">9  20</span><br><span class="line">  /  \</span><br><span class="line"> 15   7</span><br></pre></td></tr></table></figure><p>返回其层次遍历结果：</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">[</span><br><span class="line">  [3],</span><br><span class="line">  [9,20],</span><br><span class="line">  [15,7]</span><br><span class="line">]</span><br></pre></td></tr></table></figure><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Definition for a binary tree node.</span></span><br><span class="line"><span class="comment"> * struct TreeNode &#123;</span></span><br><span class="line"><span class="comment"> *     int val;</span></span><br><span class="line"><span class="comment"> *     TreeNode *left;</span></span><br><span class="line"><span class="comment"> *     TreeNode *right;</span></span><br><span class="line"><span class="comment"> *     TreeNode(int x) : val(x), left(NULL), right(NULL) &#123;&#125;</span></span><br><span class="line"><span class="comment"> * &#125;;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line"><span class="comment">// 时间复杂度：O(n)，空间复杂度：O(n) </span></span><br><span class="line">    <span class="built_in">vector</span>&lt;<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt;&gt; levelOrder(TreeNode* root) &#123;</span><br><span class="line">        <span class="built_in">vector</span>&lt;<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt;&gt; res;</span><br><span class="line">        <span class="built_in">queue</span>&lt;TreeNode*&gt; <span class="built_in">queue</span>;</span><br><span class="line">        <span class="keyword">if</span>(root) <span class="built_in">queue</span>.push(root);</span><br><span class="line">        <span class="keyword">while</span>(!<span class="built_in">queue</span>.empty())&#123;</span><br><span class="line">            <span class="keyword">int</span> count = <span class="built_in">queue</span>.size();</span><br><span class="line">            <span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; tmp;</span><br><span class="line">            <span class="keyword">while</span>(count!=<span class="number">0</span>)&#123;</span><br><span class="line">                tmp.push_back(<span class="built_in">queue</span>.front()-&gt;val);</span><br><span class="line">                count--;</span><br><span class="line">                <span class="keyword">if</span>(<span class="built_in">queue</span>.front()-&gt;left) <span class="built_in">queue</span>.push(<span class="built_in">queue</span>.front()-&gt;left);</span><br><span class="line">                <span class="keyword">if</span>(<span class="built_in">queue</span>.front()-&gt;right) <span class="built_in">queue</span>.push(<span class="built_in">queue</span>.front()-&gt;right);</span><br><span class="line">                <span class="built_in">queue</span>.pop();</span><br><span class="line">            &#125;</span><br><span class="line">            res.push_back(tmp);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">        </span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="42、二叉树的最大深度"><a href="#42、二叉树的最大深度" class="headerlink" title="42、二叉树的最大深度"></a>42、二叉树的最大深度</h1><p>给定一个二叉树，找出其最大深度。</p><p>二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。</p><p>说明: 叶子节点是指没有子节点的节点。</p><p>示例：<br>给定二叉树 [3,9,20,null,null,15,7]，</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">  3</span><br><span class="line"> / \</span><br><span class="line">9  20</span><br><span class="line">  /  \</span><br><span class="line"> 15   7</span><br></pre></td></tr></table></figure><p>返回它的最大深度 3 。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Definition for a binary tree node.</span></span><br><span class="line"><span class="comment"> * struct TreeNode &#123;</span></span><br><span class="line"><span class="comment"> *     int val;</span></span><br><span class="line"><span class="comment"> *     TreeNode *left;</span></span><br><span class="line"><span class="comment"> *     TreeNode *right;</span></span><br><span class="line"><span class="comment"> *     TreeNode(int x) : val(x), left(NULL), right(NULL) &#123;&#125;</span></span><br><span class="line"><span class="comment"> * &#125;;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line"><span class="comment">// 时间复杂度：O(n)，空间复杂度：O(logn) </span></span><br><span class="line">    <span class="function"><span class="keyword">int</span> <span class="title">maxDepth</span><span class="params">(TreeNode* root)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">if</span>(!root) <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">return</span> max(maxDepth(root-&gt;left),maxDepth(root-&gt;right))+<span class="number">1</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="43、从前序与中序遍历序列构造二叉树"><a href="#43、从前序与中序遍历序列构造二叉树" class="headerlink" title="43、从前序与中序遍历序列构造二叉树"></a>43、从前序与中序遍历序列构造二叉树</h1><p>根据一棵树的前序遍历与中序遍历构造二叉树。</p><p>注意:<br>你可以假设树中没有重复的元素。</p><p>例如，给出</p><p>前序遍历 preorder = [3,9,20,15,7]<br>中序遍历 inorder = [9,3,15,20,7]<br>返回如下的二叉树：</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">  3</span><br><span class="line"> / \</span><br><span class="line">9  20</span><br><span class="line">  /  \</span><br><span class="line"> 15   7·</span><br></pre></td></tr></table></figure><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Definition for a binary tree node.</span></span><br><span class="line"><span class="comment"> * struct TreeNode &#123;</span></span><br><span class="line"><span class="comment"> *     int val;</span></span><br><span class="line"><span class="comment"> *     TreeNode *left;</span></span><br><span class="line"><span class="comment"> *     TreeNode *right;</span></span><br><span class="line"><span class="comment"> *     TreeNode(int x) : val(x), left(NULL), right(NULL) &#123;&#125;</span></span><br><span class="line"><span class="comment"> * &#125;;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line"><span class="comment">// 时间复杂度：O(n)，空间复杂度：O(n) </span></span><br><span class="line">    <span class="function">TreeNode* <span class="title">buildTree</span><span class="params">(<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt;&amp; preorder, <span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt;&amp; inorder)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> help(preorder,<span class="number">0</span>,preorder.size()<span class="number">-1</span>,inorder,<span class="number">0</span>,inorder.size()<span class="number">-1</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="function">TreeNode* <span class="title">help</span><span class="params">(<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt;&amp; pre,<span class="keyword">int</span> pl,<span class="keyword">int</span> pr,<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt;&amp; vin,<span class="keyword">int</span> vl,<span class="keyword">int</span> vr)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">if</span>(pl&gt;pr || vl&gt;vr) <span class="keyword">return</span> <span class="literal">NULL</span>;</span><br><span class="line">        TreeNode* head = <span class="keyword">new</span> TreeNode(pre[pl]);</span><br><span class="line">        <span class="keyword">int</span> i;</span><br><span class="line">        <span class="keyword">for</span>(i=vl;i&lt;=vr;i++)&#123;</span><br><span class="line">            <span class="keyword">if</span>(vin[i]==pre[pl]) <span class="keyword">break</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">int</span> num = i-vl;</span><br><span class="line">        head-&gt;left=help(pre,pl+<span class="number">1</span>,pl+num,vin,vl,vl+num<span class="number">-1</span>);</span><br><span class="line">        head-&gt;right=help(pre,pl+num+<span class="number">1</span>,pr,vin,vl+num+<span class="number">1</span>,vr);</span><br><span class="line">        <span class="keyword">return</span> head;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="44、二叉树展开为链表"><a href="#44、二叉树展开为链表" class="headerlink" title="44、二叉树展开为链表"></a>44、二叉树展开为链表</h1><p>给定一个二叉树，原地将它展开为链表。</p><p>例如，给定二叉树</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">    1</span><br><span class="line">   / \</span><br><span class="line">  2   5</span><br><span class="line"> / \   \</span><br><span class="line">3   4   6</span><br></pre></td></tr></table></figure><p>将其展开为：</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">1</span><br><span class="line"> \</span><br><span class="line">  2</span><br><span class="line">   \</span><br><span class="line">    3</span><br><span class="line">     \</span><br><span class="line">      4</span><br><span class="line">       \</span><br><span class="line">        5</span><br><span class="line">         \</span><br><span class="line">          6</span><br></pre></td></tr></table></figure><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Definition for a binary tree node.</span></span><br><span class="line"><span class="comment"> * struct TreeNode &#123;</span></span><br><span class="line"><span class="comment"> *     int val;</span></span><br><span class="line"><span class="comment"> *     TreeNode *left;</span></span><br><span class="line"><span class="comment"> *     TreeNode *right;</span></span><br><span class="line"><span class="comment"> *     TreeNode(int x) : val(x), left(NULL), right(NULL) &#123;&#125;</span></span><br><span class="line"><span class="comment"> * &#125;;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="comment">// 先序遍历 线索二叉树</span></span><br><span class="line">    <span class="comment">// 时间复杂度：O(n)，空间复杂度：O(1) </span></span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">flatten</span><span class="params">(TreeNode* root)</span> </span>&#123;</span><br><span class="line">        TreeNode* cur = root;</span><br><span class="line">        TreeNode* next;</span><br><span class="line">        <span class="keyword">while</span>(cur)&#123;</span><br><span class="line">            <span class="keyword">if</span>(!cur-&gt;left)&#123;</span><br><span class="line">                cur = cur-&gt;right;</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">else</span>&#123;</span><br><span class="line">                next = cur-&gt;left;</span><br><span class="line">                <span class="keyword">while</span>(next-&gt;right)&#123;</span><br><span class="line">                    next = next-&gt;right;</span><br><span class="line">                &#125;</span><br><span class="line">                next-&gt;right = cur-&gt;right;</span><br><span class="line">                cur-&gt;right = cur-&gt;left;</span><br><span class="line">                cur-&gt;left = <span class="literal">NULL</span>;</span><br><span class="line">                cur = cur-&gt;right;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">/*</span></span><br><span class="line"><span class="comment">    // 中序遍历 线索二叉树</span></span><br><span class="line"><span class="comment">    vector&lt;int&gt; inorderTraversal(TreeNode* root) &#123;</span></span><br><span class="line"><span class="comment">        vector&lt;int&gt; res;</span></span><br><span class="line"><span class="comment">        TreeNode* cur = root;</span></span><br><span class="line"><span class="comment">        TreeNode* next;</span></span><br><span class="line"><span class="comment">        while(cur)&#123;</span></span><br><span class="line"><span class="comment">            if(!cur-&gt;left)&#123;</span></span><br><span class="line"><span class="comment">                res.push_back(cur-&gt;val);</span></span><br><span class="line"><span class="comment">                cur = cur-&gt;right;</span></span><br><span class="line"><span class="comment">            &#125;</span></span><br><span class="line"><span class="comment">            else&#123;</span></span><br><span class="line"><span class="comment">                next = cur-&gt;left;</span></span><br><span class="line"><span class="comment">                while(next-&gt;right)&#123;</span></span><br><span class="line"><span class="comment">                    next = next-&gt;right;</span></span><br><span class="line"><span class="comment">                &#125;</span></span><br><span class="line"><span class="comment">                next-&gt;right = cur;</span></span><br><span class="line"><span class="comment">                TreeNode* tmp = cur;</span></span><br><span class="line"><span class="comment">                cur = cur-&gt;left;</span></span><br><span class="line"><span class="comment">                tmp-&gt;left = NULL;</span></span><br><span class="line"><span class="comment">            &#125;</span></span><br><span class="line"><span class="comment">        &#125;</span></span><br><span class="line"><span class="comment">        return res;</span></span><br><span class="line"><span class="comment">    &#125;</span></span><br><span class="line"><span class="comment">    */</span></span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="45、买卖股票的最佳时机"><a href="#45、买卖股票的最佳时机" class="headerlink" title="45、买卖股票的最佳时机"></a>45、买卖股票的最佳时机</h1><p>给定一个数组，它的第 i 个元素是一支给定股票第 i 天的价格。</p><p>如果你最多只允许完成一笔交易（即买入和卖出一支股票），设计一个算法来计算你所能获取的最大利润。</p><p>注意你不能在买入股票前卖出股票。</p><p>示例 1:</p><p>输入: [7,1,5,3,6,4]<br>输出: 5<br>解释: 在第 2 天（股票价格 = 1）的时候买入，在第 5 天（股票价格 = 6）的时候卖出，最大利润 = 6-1 = 5 。<br>     注意利润不能是 7-1 = 6, 因为卖出价格需要大于买入价格。<br>示例 2:</p><p>输入: [7,6,4,3,1]<br>输出: 0<br>解释: 在这种情况下, 没有交易完成, 所以最大利润为 0。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line"><span class="comment">// 时间复杂度：O(n)，空间复杂度：O(1) </span></span><br><span class="line">    <span class="function"><span class="keyword">int</span> <span class="title">maxProfit</span><span class="params">(<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt;&amp; prices)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">int</span> res = <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">int</span> minp = INT_MAX;</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;prices.size();i++)&#123;</span><br><span class="line">            minp=min(minp,prices[i]);</span><br><span class="line">            res = max(res,prices[i]-minp);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="46、二叉树中的最大路径和"><a href="#46、二叉树中的最大路径和" class="headerlink" title="46、二叉树中的最大路径和"></a>46、二叉树中的最大路径和</h1><p>给定一个非空二叉树，返回其最大路径和。</p><p>本题中，路径被定义为一条从树中任意节点出发，达到任意节点的序列。该路径至少包含一个节点，且不一定经过根节点。</p><p>示例 1:</p><p>输入: [1,2,3]</p><pre><code>  1 / \2   3</code></pre><p>输出: 6<br>示例 2:</p><p>输入: [-10,9,20,null,null,15,7]</p><p>   -10<br>   / <br>  9  20<br>    /  <br>   15   7</p><p>输出: 42</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Definition for a binary tree node.</span></span><br><span class="line"><span class="comment"> * struct TreeNode &#123;</span></span><br><span class="line"><span class="comment"> *     int val;</span></span><br><span class="line"><span class="comment"> *     TreeNode *left;</span></span><br><span class="line"><span class="comment"> *     TreeNode *right;</span></span><br><span class="line"><span class="comment"> *     TreeNode(int x) : val(x), left(NULL), right(NULL) &#123;&#125;</span></span><br><span class="line"><span class="comment"> * &#125;;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line"><span class="comment">// 时间复杂度：O(n)，空间复杂度：O(logn) </span></span><br><span class="line">    <span class="function"><span class="keyword">int</span> <span class="title">maxPathSum</span><span class="params">(TreeNode* root)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">int</span> res=INT_MIN;</span><br><span class="line">        help(root,res);</span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="function"><span class="keyword">int</span> <span class="title">help</span><span class="params">(TreeNode* root,<span class="keyword">int</span> &amp;res)</span></span>&#123; <span class="comment">// 从root向下走的最长距离</span></span><br><span class="line">        <span class="keyword">if</span>(!root) <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">int</span> l = max(<span class="number">0</span>, help(root-&gt;left,res));</span><br><span class="line">        <span class="keyword">int</span> r = max(<span class="number">0</span>, help(root-&gt;right,res));</span><br><span class="line">        res = max(res,root-&gt;val+l+r);</span><br><span class="line">        <span class="keyword">return</span> root-&gt;val+max(l,r);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="47、最长连续序列"><a href="#47、最长连续序列" class="headerlink" title="47、最长连续序列"></a>47、最长连续序列</h1><p>给定一个未排序的整数数组，找出最长连续序列的长度。</p><p>要求算法的时间复杂度为 O(n)。</p><p>示例:</p><p>输入: [100, 4, 200, 1, 3, 2]<br>输出: 4<br>解释: 最长连续序列是 [1, 2, 3, 4]。它的长度为 4。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line"><span class="comment">// 时间复杂度：O(n)，空间复杂度：O(n) </span></span><br><span class="line">    <span class="function"><span class="keyword">int</span> <span class="title">longestConsecutive</span><span class="params">(<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt;&amp; nums)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">int</span> res = <span class="number">0</span>;</span><br><span class="line">        <span class="built_in">set</span>&lt;<span class="keyword">int</span>&gt; s(nums.begin(),nums.end());</span><br><span class="line">        <span class="built_in">set</span>&lt;<span class="keyword">int</span>&gt;::iterator it;</span><br><span class="line">        <span class="keyword">for</span>(it = s.begin();it!=s.end();it++)&#123;</span><br><span class="line">            <span class="keyword">int</span> beg = *it;</span><br><span class="line">            <span class="keyword">if</span>(s.find(beg<span class="number">-1</span>)==s.end())&#123;</span><br><span class="line">                <span class="keyword">int</span> len = <span class="number">1</span>;</span><br><span class="line">                <span class="keyword">while</span>(s.find(beg+<span class="number">1</span>)!=s.end())&#123;</span><br><span class="line">                    len++;</span><br><span class="line">                    beg++;</span><br><span class="line">                &#125;</span><br><span class="line">                res=max(res,len);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="48、只出现一次的数字"><a href="#48、只出现一次的数字" class="headerlink" title="48、只出现一次的数字"></a>48、只出现一次的数字</h1><p>给定一个非空整数数组，除了某个元素只出现一次以外，其余每个元素均出现两次。找出那个只出现了一次的元素。</p><p>说明：</p><p>你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗？</p><p>示例 1:</p><p>输入: [2,2,1]<br>输出: 1<br>示例 2:</p><p>输入: [4,1,2,1,2]<br>输出: 4</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line"><span class="comment">// 时间复杂度：O(n)，空间复杂度：O(1) </span></span><br><span class="line">    <span class="function"><span class="keyword">int</span> <span class="title">singleNumber</span><span class="params">(<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt;&amp; nums)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">int</span> res;</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> num:nums) res^=num;</span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="49、单词拆分"><a href="#49、单词拆分" class="headerlink" title="49、单词拆分"></a>49、单词拆分</h1><p>给定一个非空字符串 s 和一个包含非空单词列表的字典 wordDict，判定 s 是否可以被空格拆分为一个或多个在字典中出现的单词。</p><p>说明：</p><p>拆分时可以重复使用字典中的单词。<br>你可以假设字典中没有重复的单词。<br>示例 1：</p><p>输入: s = “leetcode”, wordDict = [“leet”, “code”]<br>输出: true<br>解释: 返回 true 因为 “leetcode” 可以被拆分成 “leet code”。<br>示例 2：</p><p>输入: s = “applepenapple”, wordDict = [“apple”, “pen”]<br>输出: true<br>解释: 返回 true 因为 “applepenapple” 可以被拆分成 “apple pen apple”。<br>     注意你可以重复使用字典中的单词。<br>示例 3：</p><p>输入: s = “catsandog”, wordDict = [“cats”, “dog”, “sand”, “and”, “cat”]<br>输出: false</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line"><span class="comment">// 时间复杂度：O(n^2)，空间复杂度：O(n) </span></span><br><span class="line">    <span class="comment">// dp[i]表示字符串s的前i个字符能否拆分成wordDict</span></span><br><span class="line">    <span class="function"><span class="keyword">bool</span> <span class="title">wordBreak</span><span class="params">(<span class="built_in">string</span> s, <span class="built_in">vector</span>&lt;<span class="built_in">string</span>&gt;&amp; wordDict)</span> </span>&#123;</span><br><span class="line">        <span class="built_in">vector</span>&lt;<span class="keyword">bool</span>&gt; flag(s.size()+<span class="number">1</span>,<span class="literal">false</span>);</span><br><span class="line">        <span class="built_in">unordered_set</span>&lt;<span class="built_in">string</span>&gt; <span class="built_in">set</span>(wordDict.begin(),wordDict.end());</span><br><span class="line">        flag[<span class="number">0</span>] = <span class="literal">true</span>;</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">1</span>;i&lt;=s.size();i++)&#123;</span><br><span class="line">            <span class="keyword">for</span>(<span class="keyword">int</span> j=<span class="number">0</span>;j&lt;i;j++)&#123;</span><br><span class="line">                <span class="keyword">if</span>(flag[j] &amp;&amp; <span class="built_in">set</span>.find(s.substr(j,i-j))!=<span class="built_in">set</span>.end())&#123;</span><br><span class="line">                    flag[i]=<span class="literal">true</span>;</span><br><span class="line">                    <span class="keyword">break</span>;</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> flag[s.size()];</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="50、环形链表"><a href="#50、环形链表" class="headerlink" title="50、环形链表"></a>50、环形链表</h1><p>给定一个链表，判断链表中是否有环。</p><p>为了表示给定链表中的环，我们使用整数 pos 来表示链表尾连接到链表中的位置（索引从 0 开始）。 如果 pos 是 -1，则在该链表中没有环。</p><p>示例 1：</p><p>输入：head = [3,2,0,-4], pos = 1<br>输出：true<br>解释：链表中有一个环，其尾部连接到第二个节点。<br><img src="https://img-blog.csdnimg.cn/20191211120556730.png" alt="在这里插入图片描述"><br>示例 2：</p><p>输入：head = [1,2], pos = 0<br>输出：true<br>解释：链表中有一个环，其尾部连接到第一个节点。<br><img src="https://img-blog.csdnimg.cn/20191211120559471.png" alt="在这里插入图片描述"><br>示例 3：</p><p>输入：head = [1], pos = -1<br>输出：false<br>解释：链表中没有环。<br><img src="https://img-blog.csdnimg.cn/20191211120611689.png" alt="在这里插入图片描述"><br>进阶：</p><p>你能用 O(1)（即，常量）内存解决此问题吗？</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Definition for singly-linked list.</span></span><br><span class="line"><span class="comment"> * struct ListNode &#123;</span></span><br><span class="line"><span class="comment"> *     int val;</span></span><br><span class="line"><span class="comment"> *     ListNode *next;</span></span><br><span class="line"><span class="comment"> *     ListNode(int x) : val(x), next(NULL) &#123;&#125;</span></span><br><span class="line"><span class="comment"> * &#125;;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line"><span class="comment">// 时间复杂度：O(n)，空间复杂度：O(1) </span></span><br><span class="line">    <span class="function"><span class="keyword">bool</span> <span class="title">hasCycle</span><span class="params">(ListNode *head)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">if</span>(!head) <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">        ListNode * fast = head;</span><br><span class="line">        ListNode * slow = head;</span><br><span class="line">        <span class="keyword">while</span>(fast &amp;&amp; fast-&gt;next)&#123;</span><br><span class="line">            fast = fast-&gt;next-&gt;next;</span><br><span class="line">            slow = slow-&gt;next;</span><br><span class="line">            <span class="keyword">if</span>(fast == slow) <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure>]]></content>
    
    <summary type="html">
    
      &lt;h3 id=&quot;题目来源&quot;&gt;&lt;a href=&quot;#题目来源&quot; class=&quot;headerlink&quot; title=&quot;题目来源&quot;&gt;&lt;/a&gt;题目来源&lt;/h3&gt;&lt;p&gt; &lt;a href=&quot;https://leetcode-cn.com/problemset/hot-100/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;leetcode 热题 HOT 100题&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;相关：&lt;br&gt;&lt;a href=&quot;https://blog.csdn.net/ffcjjhv/article/details/88409676&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;刷题汇总（一）leetcode 精选50题 JavaScript答案总结&lt;/a&gt;&lt;br&gt;&lt;a href=&quot;https://blog.csdn.net/ffcjjhv/article/details/96879804&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;刷题汇总（二）剑指Offer 66题 C++答案总结&lt;/a&gt;&lt;br&gt;&lt;a href=&quot;https://blog.csdn.net/ffcjjhv/article/details/100104411&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;刷题汇总（三）leetcode 精选50题 C++答案总结&lt;/a&gt;&lt;br&gt;&lt;a href=&quot;https://blog.csdn.net/ffcjjhv/article/details/103195691&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;刷题汇总（四）技术类编程题汇总 C++&lt;/a&gt;&lt;br&gt;&lt;a href=&quot;https://blog.csdn.net/ffcjjhv/article/details/103503745&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;刷题汇总（六）leetcode 多线程 / Shell&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://pan.baidu.com/s/1fHto2ckVlwQzgUi8TxYReA&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;PDF版 code&lt;/a&gt;  （提取码：0wxr ）&lt;/p&gt;
&lt;h1 id=&quot;1、两数之和&quot;&gt;&lt;a href=&quot;#1、两数之和&quot; class=&quot;headerlink&quot; title=&quot;1、两数之和&quot;&gt;&lt;/a&gt;1、两数之和&lt;/h1&gt;&lt;p&gt;给定一个整数数组 nums 和一个目标值 target，请你在该数组中找出和为目标值的那 两个 整数，并返回他们的数组下标。&lt;/p&gt;
    
    </summary>
    
      <category term="C++" scheme="http://yoursite.com/categories/C/"/>
    
      <category term="后台开发" scheme="http://yoursite.com/categories/%E5%90%8E%E5%8F%B0%E5%BC%80%E5%8F%91/"/>
    
      <category term="CodeCode" scheme="http://yoursite.com/categories/CodeCode/"/>
    
    
      <category term="C++" scheme="http://yoursite.com/tags/C/"/>
    
      <category term="Leetcode" scheme="http://yoursite.com/tags/Leetcode/"/>
    
  </entry>
  
  <entry>
    <title>技术类编程题汇总 C++ 刷题记录</title>
    <link href="http://yoursite.com/2019/12/02/31/"/>
    <id>http://yoursite.com/2019/12/02/31/</id>
    <published>2019-12-02T03:57:52.000Z</published>
    <updated>2019-12-18T04:25:10.503Z</updated>
    
    <content type="html"><![CDATA[<h1 id="腾讯2018春招技术类编程题汇总"><a href="#腾讯2018春招技术类编程题汇总" class="headerlink" title="腾讯2018春招技术类编程题汇总"></a>腾讯2018春招技术类编程题汇总</h1><h2 id="1、翻转数列"><a href="#1、翻转数列" class="headerlink" title="1、翻转数列"></a>1、翻转数列</h2><p>小Q定义了一种数列称为翻转数列:<br>给定整数n和m, 满足n能被2m整除。对于一串连续递增整数数列1, 2, 3, 4…, 每隔m个符号翻转一次, 最初符号为’-‘;。<br>例如n = 8, m = 2, 数列就是: -1, -2, +3, +4, -5, -6, +7, +8.<br>而n = 4, m = 1, 数列就是: -1, +2, -3, + 4.<br>小Q现在希望你能帮他算算前n项和为多少。</p><a id="more"></a><p>输入描述:<br>输入包括两个整数n和m(2 &lt;= n &lt;= 109, 1 &lt;= m), 并且满足n能被2m整除。</p><p>输出描述:<br>输出一个整数, 表示前n项和。</p><p>输入例子1:<br>8 2</p><p>输出例子1:<br>8</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;iostream&gt;</span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> <span class="built_in">std</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 暴力法 case通过率为80.00%，超时</span></span><br><span class="line"><span class="function"><span class="keyword">long</span> <span class="keyword">long</span> <span class="title">fun</span><span class="params">(<span class="keyword">int</span> n, <span class="keyword">int</span> m)</span> </span>&#123;</span><br><span class="line"><span class="keyword">long</span> <span class="keyword">long</span> res = <span class="number">0</span>;</span><br><span class="line"><span class="keyword">int</span> k = <span class="number">0</span>, flag = <span class="number">-1</span>;</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; n/m; i++)&#123;</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">int</span> j = <span class="number">0</span>; j &lt; m; j++)&#123;</span><br><span class="line">k = flag * (<span class="built_in">abs</span>(k) + <span class="number">1</span>);</span><br><span class="line">res += k;</span><br><span class="line">&#125;</span><br><span class="line">flag *= <span class="number">-1</span>;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 找规律：第一个加号值加上第一个减号值,差值刚好是m,共有n/2对</span></span><br><span class="line"><span class="comment">// -1, -2, +3, +4, -5, -6, +7, +8</span></span><br><span class="line"><span class="function"><span class="keyword">long</span> <span class="keyword">long</span> <span class="title">fun2</span><span class="params">(<span class="keyword">int</span> n, <span class="keyword">int</span> m)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">return</span> n/<span class="number">2</span>*m;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span> </span>&#123;</span><br><span class="line"><span class="keyword">int</span> n, m;</span><br><span class="line"><span class="built_in">cin</span> &gt;&gt; n &gt;&gt; m;</span><br><span class="line"></span><br><span class="line"><span class="built_in">cout</span> &lt;&lt; fun2(n,m) &lt;&lt; <span class="built_in">endl</span>;</span><br><span class="line"><span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="2、纸牌游戏"><a href="#2、纸牌游戏" class="headerlink" title="2、纸牌游戏"></a>2、纸牌游戏</h2><p>牛牛和羊羊正在玩一个纸牌游戏。这个游戏一共有n张纸牌, 第i张纸牌上写着数字ai。<br>牛牛和羊羊轮流抽牌, 牛牛先抽, 每次抽牌他们可以从纸牌堆中任意选择一张抽出, 直到纸牌被抽完。<br>他们的得分等于他们抽到的纸牌数字总和。<br>现在假设牛牛和羊羊都采用最优策略, 请你计算出游戏结束后牛牛得分减去羊羊得分等于多少。</p><p>输入描述:<br>输入包括两行。<br>第一行包括一个正整数n(1 &lt;= n &lt;= 105),表示纸牌的数量。<br>第二行包括n个正整数ai(1 &lt;= ai &lt;= 109),表示每张纸牌上的数字。</p><p>输出描述:<br>输出一个整数, 表示游戏结束后牛牛得分减去羊羊得分等于多少。</p><p>输入例子1:<br>32 7 4</p><p>输出例子1:<br>5</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;iostream&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;vector&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;queue&gt;</span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> <span class="built_in">std</span>;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line"><span class="keyword">int</span> n;</span><br><span class="line"><span class="built_in">cin</span> &gt;&gt; n;</span><br><span class="line">priority_queue&lt;<span class="keyword">int</span>, <span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt;,less&lt;<span class="keyword">int</span>&gt;&gt; card;</span><br><span class="line"><span class="keyword">int</span> t;</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; n; i++)&#123;</span><br><span class="line"><span class="built_in">cin</span> &gt;&gt; t;</span><br><span class="line">card.push(t);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">int</span> res = <span class="number">0</span>;</span><br><span class="line"><span class="keyword">int</span> flag = <span class="number">1</span>;</span><br><span class="line"><span class="keyword">while</span> (!card.empty())&#123;</span><br><span class="line"><span class="keyword">int</span> c = card.top();</span><br><span class="line">res += flag*c;</span><br><span class="line">flag *= <span class="number">-1</span>;</span><br><span class="line">card.pop();</span><br><span class="line">&#125;</span><br><span class="line"><span class="built_in">cout</span> &lt;&lt; res &lt;&lt; <span class="built_in">endl</span>;</span><br><span class="line"><span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="3、贪吃的小Q"><a href="#3、贪吃的小Q" class="headerlink" title="3、贪吃的小Q"></a>3、贪吃的小Q</h2><p>小Q的父母要出差N天，走之前给小Q留下了M块巧克力。小Q决定每天吃的巧克力数量不少于前一天吃的一半，但是他又不想在父母回来之前的某一天没有巧克力吃，请问他第一天最多能吃多少块巧克力</p><p>输入描述:<br>每个输入包含一个测试用例。<br>每个测试用例的第一行包含两个正整数，表示父母出差的天数N(N&lt;=50000)和巧克力的数量M(N&lt;=M&lt;=100000)。</p><p>输出描述:<br>输出一个数表示小Q第一天最多能吃多少块巧克力。</p><p>输入例子1:<br>3 7</p><p>输出例子1:<br>4</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;iostream&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;cmath&gt;</span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> <span class="built_in">std</span>;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">fun</span><span class="params">(<span class="keyword">int</span> n, <span class="keyword">int</span> m)</span></span>&#123;</span><br><span class="line"><span class="keyword">int</span> start = <span class="built_in">ceil</span>(m / <span class="number">2.0</span>);</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">int</span> i = start; i &gt;= <span class="number">1</span>; i--)&#123;</span><br><span class="line"><span class="keyword">int</span> t = <span class="number">0</span>;</span><br><span class="line"><span class="keyword">int</span> ti = i;</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">int</span> j = <span class="number">0</span>; j &lt; n; j++)&#123;</span><br><span class="line">t += ti;</span><br><span class="line"><span class="keyword">if</span> (ti != <span class="number">1</span>)</span><br><span class="line">ti = <span class="built_in">ceil</span>(ti / <span class="number">2.0</span>);</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">if</span> (t &lt;= m)</span><br><span class="line"><span class="keyword">return</span> i;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line"><span class="keyword">int</span> n, m;</span><br><span class="line"><span class="built_in">cin</span> &gt;&gt; n &gt;&gt; m;</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> (n == <span class="number">1</span>)</span><br><span class="line"><span class="built_in">cout</span> &lt;&lt; m &lt;&lt; <span class="built_in">endl</span>;</span><br><span class="line"><span class="keyword">else</span></span><br><span class="line"><span class="built_in">cout</span> &lt;&lt; fun(n, m) &lt;&lt; <span class="built_in">endl</span>;</span><br><span class="line"><span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="4、小Q的歌单"><a href="#4、小Q的歌单" class="headerlink" title="4、小Q的歌单"></a>4、小Q的歌单</h2><p>小Q有X首长度为A的不同的歌和Y首长度为B的不同的歌，现在小Q想用这些歌组成一个总长度正好为K的歌单，每首歌最多只能在歌单中出现一次，在不考虑歌单内歌曲的先后顺序的情况下，请问有多少种组成歌单的方法。</p><p>输入描述:<br>每个输入包含一个测试用例。<br>每个测试用例的第一行包含一个整数，表示歌单的总长度K(1&lt;=K&lt;=1000)。<br>接下来的一行包含四个正整数，分别表示歌的第一种长度A(A&lt;=10)和数量X(X&lt;=100)以及歌的第二种长度B(B&lt;=10)和数量Y(Y&lt;=100)。保证A不等于B。</p><p>输出描述:<br>输出一个整数,表示组成歌单的方法取模。因为答案可能会很大,输出对1000000007取模的结果。</p><p>输入例子1:<br>52 3 3 3</p><p>输出例子1:<br>9</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;iostream&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;vector&gt;</span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> <span class="built_in">std</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">// n选k组合数C(n,k) = C(n-1,k) + C(n-1,k-1）</span></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">CreatSelect</span><span class="params">(<span class="built_in">vector</span>&lt;<span class="built_in">vector</span>&lt;<span class="keyword">long</span> <span class="keyword">long</span>&gt;&gt; &amp;arr)</span></span>&#123;</span><br><span class="line">arr[<span class="number">0</span>][<span class="number">0</span>] = <span class="number">1</span>;</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">1</span>; i &lt;= <span class="number">100</span>; i++)&#123;</span><br><span class="line">arr[i][<span class="number">0</span>] = <span class="number">1</span>;</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">int</span> j = <span class="number">1</span>; j &lt;= <span class="number">100</span>; j++)&#123;</span><br><span class="line">arr[i][j] = (arr[i - <span class="number">1</span>][j] + arr[i - <span class="number">1</span>][j - <span class="number">1</span>] )% <span class="number">1000000007</span>;</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">long</span> <span class="keyword">long</span> <span class="title">fun</span><span class="params">(<span class="keyword">int</span> k, <span class="keyword">int</span> a, <span class="keyword">int</span> x, <span class="keyword">int</span> b, <span class="keyword">int</span> y, <span class="built_in">vector</span>&lt;<span class="built_in">vector</span>&lt;<span class="keyword">long</span> <span class="keyword">long</span>&gt;&gt; arr)</span></span>&#123;</span><br><span class="line"><span class="keyword">long</span> <span class="keyword">long</span> res = <span class="number">0</span>;</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i &lt;= k / a &amp;&amp; i &lt;= x; i++)&#123;</span><br><span class="line"><span class="keyword">if</span> ((k - a*i) % b == <span class="number">0</span> &amp;&amp; (k - a*i) / b &lt;= y)&#123;</span><br><span class="line"><span class="comment">// x里选i个a，y里选(k - a*i) / b个b</span></span><br><span class="line">res = (res + arr[x][i] * arr[y][(k - a*i) / b] % <span class="number">1000000007</span>) % <span class="number">1000000007</span>;</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line"><span class="keyword">int</span> k;</span><br><span class="line"><span class="built_in">cin</span> &gt;&gt; k;</span><br><span class="line"><span class="keyword">int</span> a, b, x, y;</span><br><span class="line"><span class="built_in">cin</span> &gt;&gt; a &gt;&gt; x &gt;&gt; b &gt;&gt; y;</span><br><span class="line"></span><br><span class="line"><span class="built_in">vector</span>&lt;<span class="built_in">vector</span>&lt;<span class="keyword">long</span> <span class="keyword">long</span>&gt;&gt; arr(<span class="number">101</span>, <span class="built_in">vector</span>&lt;<span class="keyword">long</span> <span class="keyword">long</span>&gt;(<span class="number">101</span>));</span><br><span class="line">CreatSelect(arr);</span><br><span class="line"></span><br><span class="line"><span class="built_in">cout</span> &lt;&lt; fun(k, a, x, b, y, arr)  &lt;&lt; <span class="built_in">endl</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="5、安排机器"><a href="#5、安排机器" class="headerlink" title="5、安排机器"></a>5、安排机器</h2><p>小Q的公司最近接到m个任务, 第i个任务需要xi的时间去完成, 难度等级为yi。<br>小Q拥有n台机器, 每台机器最长工作时间zi, 机器等级wi。<br>对于一个任务,它只能交由一台机器来完成, 如果安排给它的机器的最长工作时间小于任务需要的时间, 则不能完成,如果完成这个任务将获得200 * xi + 3 * yi收益。</p><p>对于一台机器,它一天只能完成一个任务, 如果它的机器等级小于安排给它的任务难度等级, 则不能完成。</p><p>小Q想在今天尽可能的去完成任务, 即完成的任务数量最大。如果有多种安排方案,小Q还想找到收益最大的那个方案。小Q需要你来帮助他计算一下。</p><p>输入描述:<br>输入包括N + M + 1行,<br>输入的第一行为两个正整数n和m(1 &lt;= n, m &lt;= 100000), 表示机器的数量和任务的数量。<br>接下来n行,每行两个整数zi和wi(0 &lt; zi &lt; 1000, 0 &lt;= wi &lt;= 100), 表示每台机器的最大工作时间和机器等级。<br>接下来的m行,每行两个整数xi和yi(0 &lt; xi &lt; 1000, 0 &lt;= yi&lt;= 100), 表示每个任务需要的完成时间和任务的难度等级。</p><p>输出描述:<br>输出两个整数, 分别表示最大能完成的任务数量和获取的收益。</p><p>输入例子1:<br>1 2<br>100 3<br>100 2<br>100 1</p><p>输出例子1:<br>1 20006</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;iostream&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;vector&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;cstring&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;algorithm&gt;</span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> <span class="built_in">std</span>;</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">struct</span>  <span class="title">Node</span> &#123;</span></span><br><span class="line"><span class="keyword">int</span> time, grade;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">bool</span> <span class="title">Cmp</span><span class="params">(<span class="keyword">const</span> Node &amp;a, <span class="keyword">const</span> Node &amp;b)</span> </span>&#123;</span><br><span class="line"><span class="keyword">if</span> (a.time == b.time)</span><br><span class="line"><span class="keyword">return</span> a.grade &gt; b.grade;</span><br><span class="line"><span class="keyword">return</span> a.time &gt; b.time;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// case通过率为90.00%，超时</span></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span> </span>&#123;</span><br><span class="line"><span class="keyword">int</span> n, m; <span class="comment">//机器的数量和任务的数量 1 &lt;= n, m &lt;= 100000</span></span><br><span class="line"><span class="built_in">cin</span> &gt;&gt; n &gt;&gt; m;</span><br><span class="line"><span class="built_in">vector</span>&lt;Node&gt; machine(n);</span><br><span class="line"><span class="built_in">vector</span>&lt;Node&gt; task(m);</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; n; i++)&#123;</span><br><span class="line"><span class="built_in">cin</span> &gt;&gt; machine[i].time &gt;&gt; machine[i].grade;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; m; i++)&#123;</span><br><span class="line"><span class="built_in">cin</span> &gt;&gt; task[i].time &gt;&gt; task[i].grade;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">sort(machine.begin(), machine.end(), Cmp);</span><br><span class="line">sort(task.begin(), task.end(), Cmp);</span><br><span class="line"></span><br><span class="line"><span class="keyword">int</span> res = <span class="number">0</span>, value = <span class="number">0</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">bool</span>* flag = <span class="keyword">new</span> <span class="keyword">bool</span>[n];</span><br><span class="line"><span class="built_in">memset</span>(flag, <span class="literal">true</span>, n);</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; m; i++)&#123;</span><br><span class="line"><span class="keyword">int</span> min_grade = <span class="number">101</span>;</span><br><span class="line"><span class="keyword">int</span> min_j;</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">int</span> j = <span class="number">0</span>; j &lt; n; j++)&#123;</span><br><span class="line"><span class="keyword">if</span> (flag[j])&#123;</span><br><span class="line"><span class="keyword">if</span> (task[i].time &lt;= machine[j].time)&#123;</span><br><span class="line"><span class="keyword">if</span> (task[i].grade &lt;= machine[j].grade &amp;&amp; machine[j].grade &lt; min_grade)&#123;</span><br><span class="line">min_grade = machine[j].grade;</span><br><span class="line">min_j = j;</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">else</span>&#123;</span><br><span class="line"><span class="keyword">break</span>;</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">if</span> (min_grade != <span class="number">101</span>)&#123;</span><br><span class="line">res++;</span><br><span class="line">value += <span class="number">200</span> * task[i].time + <span class="number">3</span> * task[i].grade;</span><br><span class="line">flag[min_j] = <span class="literal">false</span>;</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">delete</span>[] flag;</span><br><span class="line"></span><br><span class="line"><span class="built_in">cout</span> &lt;&lt; res &lt;&lt; <span class="string">" "</span> &lt;&lt; value &lt;&lt; <span class="built_in">endl</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="6、画家小Q"><a href="#6、画家小Q" class="headerlink" title="6、画家小Q"></a>6、画家小Q</h2><p>画家小Q又开始他的艺术创作。小Q拿出了一块有NxM像素格的画板, 画板初始状态是空白的,用’X’表示。<br>小Q有他独特的绘画技巧,每次小Q会选择一条斜线, 如果斜线的方向形如’/‘,即斜率为1,小Q会选择这条斜线中的一段格子,都涂画为蓝色,用’B’表示;如果对角线的方向形如’&#39;,即斜率为-1,小Q会选择这条斜线中的一段格子,都涂画为黄色,用’Y’表示。<br>如果一个格子既被蓝色涂画过又被黄色涂画过,那么这个格子就会变成绿色,用’G’表示。<br>小Q已经有想画出的作品的样子, 请你帮他计算一下他最少需要多少次操作完成这幅画。</p><p>输入描述:<br>每个输入包含一个测试用例。<br>每个测试用例的第一行包含两个正整数N和M(1 &lt;= N, M &lt;= 50), 表示画板的长宽。<br>接下来的N行包含N个长度为M的字符串, 其中包含字符’B’,’Y’,’G’,’X’,分别表示蓝色,黄色,绿色,空白。整个表示小Q要完成的作品。</p><p>输出描述:<br>输出一个正整数, 表示小Q最少需要多少次操作完成绘画。</p><p>输入例子1:<br>4 4<br>YXXB<br>XYGX<br>XBYY<br>BXXY</p><p>输出例子1:<br>3</p><p>例子说明1:<br>XXXX<br>XXXX<br>XXXX<br>XXXX<br>-&gt;<br>YXXX<br>XYXX<br>XXYX<br>XXXY<br>-&gt;<br>YXXB<br>XYBX<br>XBYX<br>BXXY<br>-&gt;<br>YXXB<br>XYGX<br>XBYY<br>BXXY</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;iostream&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;vector&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;string&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> <span class="built_in">std</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">int</span> n, m; <span class="comment">//N和M(1 &lt;= N, M &lt;= 50), 表示画板的长宽</span></span><br><span class="line"><span class="built_in">vector</span>&lt;<span class="built_in">vector</span>&lt;<span class="keyword">char</span>&gt;&gt; arr;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">fun_b</span><span class="params">(<span class="keyword">int</span> i, <span class="keyword">int</span> j)</span></span>&#123;</span><br><span class="line"><span class="keyword">if</span> (i &gt;= <span class="number">0</span> &amp;&amp; i &lt; n &amp;&amp; j &gt;= <span class="number">0</span> &amp;&amp; j &lt; m &amp;&amp; (arr[i][j] == <span class="string">'B'</span> || arr[i][j] == <span class="string">'G'</span>))&#123;</span><br><span class="line"><span class="keyword">if</span> (arr[i][j] == <span class="string">'B'</span>) </span><br><span class="line">arr[i][j] = <span class="string">'X'</span>;</span><br><span class="line"><span class="keyword">else</span> </span><br><span class="line">arr[i][j] = <span class="string">'Y'</span>;</span><br><span class="line">fun_b(i - <span class="number">1</span>,j + <span class="number">1</span>);</span><br><span class="line">fun_b(i + <span class="number">1</span>, j - <span class="number">1</span>);</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">return</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">fun_y</span><span class="params">(<span class="keyword">int</span> i, <span class="keyword">int</span> j)</span></span>&#123;</span><br><span class="line"><span class="keyword">if</span> (i &gt;= <span class="number">0</span> &amp;&amp; i &lt; n &amp;&amp; j &gt;= <span class="number">0</span> &amp;&amp; j &lt; m &amp;&amp; (arr[i][j] == <span class="string">'Y'</span> || arr[i][j] == <span class="string">'G'</span>))&#123;</span><br><span class="line"><span class="keyword">if</span> (arr[i][j] == <span class="string">'Y'</span>) </span><br><span class="line">arr[i][j] = <span class="string">'X'</span>;</span><br><span class="line"><span class="keyword">else</span> </span><br><span class="line">arr[i][j] = <span class="string">'B'</span>;</span><br><span class="line">fun_y(i + <span class="number">1</span>, j + <span class="number">1</span>);</span><br><span class="line">fun_y(i - <span class="number">1</span>, j - <span class="number">1</span>);</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">return</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment">YXXB</span></span><br><span class="line"><span class="comment">XYGX</span></span><br><span class="line"><span class="comment">XBYY</span></span><br><span class="line"><span class="comment">BXXY</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">fun</span><span class="params">()</span> </span>&#123;</span><br><span class="line"><span class="keyword">int</span> res = <span class="number">0</span>;</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; n; i++)&#123;</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">int</span> j = <span class="number">0</span>; j &lt; m; j++)&#123;</span><br><span class="line"><span class="keyword">if</span> (arr[i][j] == <span class="string">'B'</span>)&#123;</span><br><span class="line">fun_b(i, j);</span><br><span class="line">res++;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">if</span> (arr[i][j] == <span class="string">'Y'</span>)&#123;</span><br><span class="line">fun_y(i, j);</span><br><span class="line">res++;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">if</span> (arr[i][j] == <span class="string">'G'</span>)&#123;</span><br><span class="line">fun_b(i, j);</span><br><span class="line">fun_y(i, j);</span><br><span class="line">res += <span class="number">2</span>;</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span> </span>&#123;</span><br><span class="line"><span class="built_in">cin</span> &gt;&gt; n &gt;&gt; m; </span><br><span class="line">arr = <span class="built_in">vector</span>&lt;<span class="built_in">vector</span>&lt;<span class="keyword">char</span>&gt;&gt; (n, <span class="built_in">vector</span>&lt;<span class="keyword">char</span>&gt;(m));</span><br><span class="line"><span class="built_in">string</span> str;</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; n; i++)&#123;</span><br><span class="line"><span class="built_in">cin</span> &gt;&gt; str;</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">int</span> j = <span class="number">0</span>; j &lt; m; j++)&#123;</span><br><span class="line">arr[i][j] = str[j];</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br><span class="line"> </span><br><span class="line"><span class="built_in">cout</span> &lt;&lt; fun() &lt;&lt; <span class="built_in">endl</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h1 id="腾讯2017秋招笔试编程题"><a href="#腾讯2017秋招笔试编程题" class="headerlink" title="腾讯2017秋招笔试编程题"></a>腾讯2017秋招笔试编程题</h1><h2 id="1、编码"><a href="#1、编码" class="headerlink" title="1、编码"></a>1、编码</h2><p>假定一种编码的编码范围是a ~ y的25个字母，从1位到4位的编码，如果我们把该编码按字典序排序，形成一个数组如下： a, aa, aaa, aaaa, aaab, aaac, … …, b, ba, baa, baaa, baab, baac … …, yyyw, yyyx, yyyy 其中a的Index为0，aa的Index为1，aaa的Index为2，以此类推。 编写一个函数，输入是任意一个编码，输出这个编码对应的Index.</p><p>输入描述:<br>输入一个待编码的字符串,字符串长度小于等于100.</p><p>输出描述:<br>输出这个编码的index</p><p>输入例子1:<br>baca</p><p>输出例子1:<br>16331</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;iostream&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;vector&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;string&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> <span class="built_in">std</span>;</span><br><span class="line"></span><br><span class="line"><span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; loop = &#123; <span class="number">0</span>, <span class="number">1</span>, <span class="number">26</span>, <span class="number">651</span>, <span class="number">16276</span> &#125;;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">fun</span><span class="params">(<span class="built_in">string</span> str)</span> </span>&#123;</span><br><span class="line"><span class="keyword">int</span> res = <span class="number">0</span>, len = str.size();</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; len; i++)&#123;</span><br><span class="line">res += (str[i] - <span class="string">'a'</span>)*loop[<span class="number">4</span> -i]+<span class="number">1</span>;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">return</span> res<span class="number">-1</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span> </span>&#123;</span><br><span class="line"><span class="built_in">string</span> str;</span><br><span class="line"></span><br><span class="line"><span class="keyword">while</span> (<span class="built_in">cin</span> &gt;&gt; str)&#123;</span><br><span class="line"><span class="built_in">cout</span> &lt;&lt; fun(str) &lt;&lt; <span class="built_in">endl</span>;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="2、游戏任务标记"><a href="#2、游戏任务标记" class="headerlink" title="2、游戏任务标记"></a>2、游戏任务标记</h2><p>游戏里面有很多各式各样的任务，其中有一种任务玩家只能做一次，这类任务一共有1024个，任务ID范围[1,1024]。请用32个unsigned int类型来记录着1024个任务是否已经完成。初始状态都是未完成。 输入两个参数，都是任务ID，需要设置第一个ID的任务为已经完成；并检查第二个ID的任务是否已经完成。 输出一个参数，如果第二个ID的任务已经完成输出1，如果未完成输出0。如果第一或第二个ID不在[1,1024]范围，则输出-1。</p><p>输入描述:<br>输入包括一行,两个整数表示人物ID.</p><p>输出描述:<br>输出是否完成</p><p>输入例子1:<br>1024 1024</p><p>输出例子1:<br>1</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;iostream&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> <span class="built_in">std</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">unsigned</span> <span class="keyword">int</span> flag[<span class="number">32</span>];</span><br><span class="line"></span><br><span class="line"><span class="comment">// unsigned int为32位，32个unsigned int为32*32=1024</span></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">fun</span><span class="params">(<span class="keyword">int</span> n, <span class="keyword">int</span> m)</span> </span>&#123;</span><br><span class="line"><span class="comment">// Index(N) = N / 32 = N &gt;&gt; 5;</span></span><br><span class="line"><span class="comment">// Position(N) = N % 32 = N &amp; 31; （对于2的幂的数才能）</span></span><br><span class="line"><span class="keyword">int</span> index, position;</span><br><span class="line">index = (n - <span class="number">1</span>) &gt;&gt; <span class="number">5</span>;</span><br><span class="line">position = (n<span class="number">-1</span>) &amp; <span class="number">31</span>;</span><br><span class="line">flag[index] |= <span class="number">1</span> &lt;&lt; position;</span><br><span class="line"><span class="keyword">if</span> (m &gt;= <span class="number">1</span> &amp;&amp; m &lt;= <span class="number">1024</span>)&#123;</span><br><span class="line">index = (m - <span class="number">1</span>) &gt;&gt; <span class="number">5</span>;</span><br><span class="line">position = (m - <span class="number">1</span>) &amp; <span class="number">31</span>;</span><br><span class="line"><span class="keyword">return</span> (flag[index]&amp;(<span class="number">1</span>&lt;&lt;position))!=<span class="number">0</span>;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">return</span> <span class="number">-1</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span> </span>&#123;</span><br><span class="line"><span class="keyword">int</span> n,m;</span><br><span class="line"><span class="built_in">cin</span> &gt;&gt; n &gt;&gt; m;</span><br><span class="line"></span><br><span class="line"><span class="built_in">cout</span> &lt;&lt; fun(n, m) &lt;&lt; <span class="built_in">endl</span>;</span><br><span class="line"><span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="3、素数对"><a href="#3、素数对" class="headerlink" title="3、素数对"></a>3、素数对</h2><p>给定一个正整数，编写程序计算有多少对质数的和等于输入的这个正整数，并输出结果。输入值小于1000。<br>如，输入为10, 程序应该输出结果为2。（共有两对质数的和为10,分别为(5,5),(3,7)）</p><p>输入描述:<br>输入包括一个整数n,(3 ≤ n &lt; 1000)</p><p>输出描述:<br>输出对数</p><p>输入例子1:<br>10</p><p>输出例子1:<br>2</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;iostream&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> <span class="built_in">std</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 质数：只能被１和本身整除，最小质数为２</span></span><br><span class="line"><span class="function"><span class="keyword">bool</span> <span class="title">is_zhishu</span><span class="params">(<span class="keyword">int</span> x)</span> </span>&#123;</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">2</span>; i*i &lt;= x; i++)&#123;</span><br><span class="line"><span class="keyword">if</span> (x%i == <span class="number">0</span>)</span><br><span class="line"><span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">fun</span><span class="params">(<span class="keyword">int</span> n)</span> </span>&#123;</span><br><span class="line"><span class="keyword">int</span> res = <span class="number">0</span>;</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">2</span>; i &lt;= n / <span class="number">2</span>; i++)&#123;</span><br><span class="line"><span class="keyword">if</span> (is_zhishu(i) &amp;&amp; is_zhishu(n - i))</span><br><span class="line">res++;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span> </span>&#123;</span><br><span class="line"><span class="keyword">int</span> n;</span><br><span class="line"><span class="built_in">cin</span> &gt;&gt; n;</span><br><span class="line"></span><br><span class="line"><span class="built_in">cout</span> &lt;&lt; fun(n) &lt;&lt; <span class="built_in">endl</span>;</span><br><span class="line"><span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="4、geohash编码"><a href="#4、geohash编码" class="headerlink" title="4、geohash编码"></a>4、geohash编码</h2><p>geohash编码：geohash常用于将二维的经纬度转换为字符串，分为两步：第一步是经纬度的二进制编码，第二步是base32转码。<br>此题考察纬度的二进制编码：算法对纬度[-90, 90]通过二分法进行无限逼近（取决于所需精度，本题精度为6）。注意，本题进行二分法逼近过程中只采用向下取整来进行二分，针对二分中间值属于右区间。算法举例如下： 针对纬度为80进行二进制编码过程：<br>1) 区间[-90, 90]进行二分为[-90, 0),[0, 90]，成为左右区间，可以确定80为右区间，标记为1；<br>2) 针对上一步的右区间[0, 90]进行二分为[0, 45),[45, 90]，可以确定80是右区间，标记为1；<br>3) 针对[45, 90]进行二分为[45, 67),[67,90],可以确定80为右区间，标记为1；<br>4) 针对[67,90]进行二分为[67, 78),[78,90]，可以确定80为右区间，标记为1；<br>5) 针对[78, 90]进行二分为[78, 84),[84, 90]，可以确定80为左区间，标记为0；<br>6) 针对[78, 84)进行二分为[78, 81), [81, 84)，可以确定80为左区间，标记为0；</p><p>输入描述:<br>输入包括一个整数n,(-90 ≤ n ≤ 90)</p><p>输出描述:<br>输出二进制编码</p><p>输入例子1:<br>80</p><p>输出例子1:<br>111100</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;iostream&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;string&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;cmath&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> <span class="built_in">std</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">// -66</span></span><br><span class="line"><span class="function"><span class="built_in">string</span> <span class="title">fun</span><span class="params">(<span class="keyword">int</span> n)</span> </span>&#123;</span><br><span class="line"><span class="built_in">string</span> res;</span><br><span class="line"><span class="keyword">int</span> k = <span class="number">0</span>;</span><br><span class="line"><span class="keyword">int</span> l = <span class="number">-90</span>, r = <span class="number">90</span>;</span><br><span class="line"><span class="keyword">while</span> (k != <span class="number">6</span>)&#123;</span><br><span class="line"><span class="keyword">int</span> mid = <span class="built_in">floor</span>((l + r) / <span class="number">2.0</span>);</span><br><span class="line"><span class="keyword">if</span> (mid &lt;= n)&#123;</span><br><span class="line">res.push_back(<span class="string">'1'</span>);</span><br><span class="line">l = mid;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">else</span>&#123;</span><br><span class="line">res.push_back(<span class="string">'0'</span>);</span><br><span class="line">r = mid;</span><br><span class="line">&#125;</span><br><span class="line">k++;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="built_in">string</span> <span class="title">fun2</span><span class="params">(<span class="keyword">int</span> n)</span> </span>&#123;</span><br><span class="line"><span class="built_in">string</span> res;</span><br><span class="line"><span class="keyword">int</span> k = <span class="number">0</span>;</span><br><span class="line"><span class="keyword">int</span> l = <span class="number">-90</span>, r = <span class="number">90</span>;</span><br><span class="line"><span class="keyword">while</span> (k != <span class="number">6</span>)&#123;</span><br><span class="line"><span class="keyword">int</span> mid = l + r &gt; <span class="number">0</span> ? <span class="built_in">floor</span>((l + r) / <span class="number">2.0</span>) : -<span class="built_in">floor</span>(-(l + r) / <span class="number">2.0</span>);</span><br><span class="line"><span class="keyword">if</span> (mid &lt;= n)&#123;</span><br><span class="line">res.push_back(<span class="string">'1'</span>);</span><br><span class="line">l = mid;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">else</span>&#123;</span><br><span class="line">res.push_back(<span class="string">'0'</span>);</span><br><span class="line">r = mid;</span><br><span class="line">&#125;</span><br><span class="line">k++;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span> </span>&#123;</span><br><span class="line"><span class="keyword">int</span> n; <span class="comment">// (-90 ≤ n ≤ 90)</span></span><br><span class="line"><span class="built_in">cin</span> &gt;&gt; n;</span><br><span class="line"></span><br><span class="line"><span class="built_in">cout</span> &lt;&lt; fun2(n) &lt;&lt; <span class="built_in">endl</span>;</span><br><span class="line"><span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>注：题中向下取整存在歧义</p><h1 id="腾讯2017暑期实习生编程题"><a href="#腾讯2017暑期实习生编程题" class="headerlink" title="腾讯2017暑期实习生编程题"></a>腾讯2017暑期实习生编程题</h1><h2 id="1、构造回文"><a href="#1、构造回文" class="headerlink" title="1、构造回文"></a>1、构造回文</h2><p>给定一个字符串s，你可以从中删除一些字符，使得剩下的串是一个回文串。如何删除才能使得回文串最长呢？<br>输出需要删除的字符个数。</p><p>输入描述:</p><p>输入数据有多组，每组包含一个字符串s，且保证:1&lt;=s.length&lt;=1000.</p><p>输出描述:</p><p>对于每组数据，输出一个整数，代表最少需要删除的字符个数。</p><p>输入例子1:<br>abcda<br>google</p><p>输出例子1:<br>22</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;iostream&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;string&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;vector&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;algorithm&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> <span class="built_in">std</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 求原字符串和其反串的最大公共子序列的长度</span></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">fun</span><span class="params">(<span class="built_in">string</span> s1, <span class="built_in">string</span> s2)</span> </span>&#123;</span><br><span class="line"><span class="keyword">if</span> (s1.size() == <span class="number">1</span>) <span class="keyword">return</span> <span class="number">1</span>;</span><br><span class="line"><span class="keyword">int</span> len = s1.size();</span><br><span class="line"><span class="built_in">vector</span>&lt;<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt;&gt; arr(len + <span class="number">1</span>, <span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt;(len + <span class="number">1</span>));</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i &lt;= len; i++)&#123;</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">int</span> j = <span class="number">0</span>; j &lt;= len; j++)&#123;</span><br><span class="line"><span class="keyword">if</span> (i == <span class="number">0</span> || j == <span class="number">0</span>)&#123;</span><br><span class="line">arr[i][j] =<span class="number">0</span>;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">else</span> <span class="keyword">if</span> (s1[i<span class="number">-1</span>] == s2[j<span class="number">-1</span>])&#123;</span><br><span class="line">arr[i][j] = arr[i - <span class="number">1</span>][j - <span class="number">1</span>] + <span class="number">1</span>;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">else</span>&#123;</span><br><span class="line">arr[i][j] = max(arr[i][j - <span class="number">1</span>], arr[i<span class="number">-1</span>][j]);</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">return</span> arr[len][len];</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span> </span>&#123;</span><br><span class="line"><span class="built_in">string</span> s; <span class="comment">// 1 &lt;= s.length &lt;= 1000</span></span><br><span class="line"><span class="keyword">while</span> (<span class="built_in">cin</span> &gt;&gt; s)&#123;</span><br><span class="line"><span class="built_in">string</span> s2 = s;</span><br><span class="line">reverse(s2.begin(), s2.end());</span><br><span class="line"><span class="built_in">cout</span> &lt;&lt; s.size()-fun(s,s2) &lt;&lt; <span class="built_in">endl</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="2、算法基础-字符移位"><a href="#2、算法基础-字符移位" class="headerlink" title="2、算法基础-字符移位"></a>2、算法基础-字符移位</h2><p>小Q最近遇到了一个难题：把一个字符串的大写字母放到字符串的后面，各个字符的相对位置不变，且不能申请额外的空间。<br>你能帮帮小Q吗？</p><p>输入描述:</p><p>输入数据有多组，每组包含一个字符串s，且保证:1&lt;=s.length&lt;=1000.</p><p>输出描述:</p><p>对于每组数据，输出移位后的字符串。</p><p>输入例子1:<br>AkleBiCeilD</p><p>输出例子1:<br>kleieilABCD</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;iostream&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;string&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> <span class="built_in">std</span>;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">bool</span> <span class="title">is_upper</span><span class="params">(<span class="keyword">char</span> c)</span></span>&#123;</span><br><span class="line"><span class="keyword">return</span> c &gt;= <span class="string">'A'</span> &amp;&amp; c &lt;= <span class="string">'Z'</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="built_in">string</span> <span class="title">fun</span><span class="params">(<span class="built_in">string</span> &amp;s)</span> </span>&#123;</span><br><span class="line"><span class="keyword">if</span> (s.size() == <span class="number">1</span>) <span class="keyword">return</span> s;</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; s.size(); i++)&#123;</span><br><span class="line"><span class="keyword">if</span> (is_upper(s[i]))&#123;</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">int</span> j = i + <span class="number">1</span>; j &lt; s.size(); j++)&#123;</span><br><span class="line"><span class="keyword">if</span> (!is_upper(s[j]))&#123;</span><br><span class="line"><span class="keyword">int</span>  k = j;</span><br><span class="line"><span class="keyword">char</span> t = s[j];</span><br><span class="line"><span class="keyword">while</span> (k&gt;i)&#123;</span><br><span class="line">s[k] = s[k - <span class="number">1</span>];</span><br><span class="line">k--;</span><br><span class="line">&#125;</span><br><span class="line">s[i] = t;</span><br><span class="line"><span class="keyword">break</span>;</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">return</span> s;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span> </span>&#123;</span><br><span class="line"><span class="built_in">string</span> s; <span class="comment">// 1 &lt;= s.length &lt;= 1000</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">while</span> (<span class="built_in">cin</span> &gt;&gt; s)&#123;</span><br><span class="line"><span class="built_in">cout</span> &lt;&lt; fun(s) &lt;&lt; <span class="built_in">endl</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="3、有趣的数字"><a href="#3、有趣的数字" class="headerlink" title="3、有趣的数字"></a>3、有趣的数字</h2><p>小Q今天在上厕所时想到了这个问题：有n个数，两两组成二元组，相差最小的有多少对呢？相差最大呢？</p><p>输入描述:</p><p> 输入包含多组测试数据。<br> 对于每组测试数据：<br> N - 本组测试数据有n个数<br> a1,a2…an - 需要计算的数据<br> 保证:<br> 1&lt;=N&lt;=100000,0&lt;=ai&lt;=INT_MAX.</p><p>输出描述:</p><p>对于每组数据，输出两个数，第一个数表示差最小的对数，第二个数表示差最大的对数。</p><p>输入例子1:<br>645 12 45 32 5 6</p><p>输出例子1:<br>1 2</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;iostream&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;vector&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;algorithm&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> <span class="built_in">std</span>;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">fun</span><span class="params">(<span class="keyword">int</span> n,<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; &amp;vec)</span> </span>&#123;</span><br><span class="line"><span class="keyword">int</span> min_count = <span class="number">0</span>, max_count = <span class="number">0</span>;</span><br><span class="line"><span class="keyword">if</span> (n &gt; <span class="number">1</span>)&#123;</span><br><span class="line">sort(vec.begin(), vec.end());</span><br><span class="line"><span class="keyword">if</span> (vec[<span class="number">0</span>] == vec[n - <span class="number">1</span>])&#123; <span class="comment">// 11111</span></span><br><span class="line">min_count = n*(n - <span class="number">1</span>) / <span class="number">2</span>;</span><br><span class="line">max_count = n*(n - <span class="number">1</span>) / <span class="number">2</span>;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">else</span>&#123;</span><br><span class="line"><span class="comment">// min</span></span><br><span class="line"><span class="keyword">int</span> min = vec[<span class="number">1</span>] - vec[<span class="number">0</span>];</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; n - <span class="number">1</span>; i++)&#123;</span><br><span class="line"><span class="keyword">if</span> (vec[i + <span class="number">1</span>] - vec[i] &lt; min)&#123;</span><br><span class="line">min = vec[i + <span class="number">1</span>] - vec[i];</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">if</span> (min == <span class="number">0</span>)&#123; <span class="comment">// 11233</span></span><br><span class="line"><span class="keyword">int</span> time;</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; n; i++)&#123;</span><br><span class="line">time = <span class="number">1</span>;</span><br><span class="line"><span class="keyword">while</span> (i + <span class="number">1</span> &lt; n &amp;&amp; vec[i + <span class="number">1</span>] == vec[i])&#123;</span><br><span class="line">time++;</span><br><span class="line">i++;</span><br><span class="line">&#125;</span><br><span class="line">min_count += time*(time - <span class="number">1</span>)/<span class="number">2</span>;</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">else</span>&#123; <span class="comment">// 12457</span></span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; n - <span class="number">1</span>; i++)&#123;</span><br><span class="line"><span class="keyword">if</span> (vec[i + <span class="number">1</span>] - vec[i] == min)&#123;</span><br><span class="line">min_count++;</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// max</span></span><br><span class="line"><span class="keyword">int</span> max = vec[n - <span class="number">1</span>] - vec[<span class="number">0</span>];</span><br><span class="line"><span class="keyword">int</span> l = <span class="number">0</span>, r = <span class="number">0</span>;</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; n; i++)&#123;</span><br><span class="line"><span class="keyword">if</span> (vec[i] == vec[<span class="number">0</span>]) l++;</span><br><span class="line"><span class="keyword">else</span> <span class="keyword">break</span>;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">int</span> i = n - <span class="number">1</span>; i &gt;= <span class="number">0</span>; i--)&#123;</span><br><span class="line"><span class="keyword">if</span> (vec[i] == vec[n<span class="number">-1</span>]) r++;</span><br><span class="line"><span class="keyword">else</span> <span class="keyword">break</span>;</span><br><span class="line">&#125;</span><br><span class="line">max_count = l*r;</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="built_in">cout</span> &lt;&lt; min_count &lt;&lt; <span class="string">" "</span> &lt;&lt; max_count &lt;&lt; <span class="built_in">endl</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span> </span>&#123;</span><br><span class="line"><span class="keyword">int</span> n;</span><br><span class="line"><span class="keyword">while</span> (<span class="built_in">cin</span> &gt;&gt; n)&#123;</span><br><span class="line"><span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; vec(n);</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; n; i++)&#123;</span><br><span class="line"><span class="built_in">cin</span> &gt;&gt; vec[i];</span><br><span class="line">&#125;</span><br><span class="line">fun(n, vec);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h1 id="腾讯2016研发工程师编程题"><a href="#腾讯2016研发工程师编程题" class="headerlink" title="腾讯2016研发工程师编程题"></a>腾讯2016研发工程师编程题</h1><h2 id="1、生成格雷码"><a href="#1、生成格雷码" class="headerlink" title="1、生成格雷码"></a>1、生成格雷码</h2><p>在一组数的编码中，若任意两个相邻的代码只有一位二进制数不同， 则称这种编码为格雷码(Gray Code)，请编写一个函数，使用递归的方法生成N位的格雷码。</p><p>给定一个整数n，请返回n位的格雷码，顺序为从0开始。</p><p>测试样例：<br>1返回：[“0”,”1”]</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/*n: 0   1    2     3</span></span><br><span class="line"><span class="comment">     0   0   00   000</span></span><br><span class="line"><span class="comment">     1   10   100</span></span><br><span class="line"><span class="comment">      110</span></span><br><span class="line"><span class="comment">      11  010</span></span><br><span class="line"><span class="comment">              01</span></span><br><span class="line"><span class="comment">  011</span></span><br><span class="line"><span class="comment">  111</span></span><br><span class="line"><span class="comment">  101</span></span><br><span class="line"><span class="comment">  001</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">GrayCode</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line"><span class="comment">// 题目不严谨case通过率为9.09% </span></span><br><span class="line"><span class="comment">// 用例:2</span></span><br><span class="line"><span class="comment">// 对应输出应该为:["00","01","11","10"]</span></span><br><span class="line"><span class="comment">// 你的输出为:["00","10","11","01"]</span></span><br><span class="line">    <span class="built_in">vector</span>&lt;<span class="built_in">string</span>&gt; getGray2(<span class="keyword">int</span> n) &#123;</span><br><span class="line">        <span class="keyword">if</span> (n == <span class="number">0</span>) <span class="keyword">return</span>&#123; <span class="string">"0"</span> &#125;;</span><br><span class="line">        <span class="built_in">vector</span>&lt;<span class="built_in">string</span>&gt; res&#123; <span class="string">"0"</span>, <span class="string">"1"</span> &#125;;</span><br><span class="line">        <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">1</span>; i &lt; n; i++)&#123;</span><br><span class="line">            <span class="keyword">for</span> (<span class="keyword">int</span> j = <span class="number">0</span>; j &lt; res.size(); j++)&#123;</span><br><span class="line">                res[j].push_back(<span class="string">'0'</span>);</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">for</span> (<span class="keyword">int</span> j = res.size()<span class="number">-1</span>; j &gt;=<span class="number">0</span>; j--)&#123;</span><br><span class="line">                <span class="built_in">string</span> t = res[j];</span><br><span class="line">                t[t.size() - <span class="number">1</span>] = <span class="string">'1'</span>;</span><br><span class="line">                res.push_back(t);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line"><span class="built_in">vector</span>&lt;<span class="built_in">string</span>&gt; getGray(<span class="keyword">int</span> n) &#123;</span><br><span class="line">        <span class="keyword">if</span> (n == <span class="number">0</span>) <span class="keyword">return</span>&#123; <span class="string">"0"</span> &#125;;</span><br><span class="line">        <span class="built_in">vector</span>&lt;<span class="built_in">string</span>&gt; res&#123; <span class="string">"0"</span>, <span class="string">"1"</span> &#125;;</span><br><span class="line">        <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">1</span>; i &lt; n; i++)&#123;</span><br><span class="line">            <span class="keyword">for</span> (<span class="keyword">int</span> j = <span class="number">0</span>; j &lt; res.size(); j++)&#123;</span><br><span class="line">                res[j]=<span class="string">'0'</span> + res[j];</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">for</span> (<span class="keyword">int</span> j = res.size()<span class="number">-1</span>; j &gt;=<span class="number">0</span>; j--)&#123;</span><br><span class="line">                <span class="built_in">string</span> t = res[j];</span><br><span class="line">                t[<span class="number">0</span>] = <span class="string">'1'</span>;</span><br><span class="line">                res.push_back(t);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h2 id="2、微信红包"><a href="#2、微信红包" class="headerlink" title="2、微信红包"></a>2、微信红包</h2><p>春节期间小明使用微信收到很多个红包，非常开心。在查看领取红包记录时发现，某个红包金额出现的次数超过了红包总数的一半。请帮小明找到该红包金额。写出具体算法思路和代码实现，要求算法尽可能高效。</p><p>给定一个红包的金额数组gifts及它的大小n，请返回所求红包的金额。</p><p>若没有金额超过总数的一半，返回0。<br>测试样例：<br>[1,2,3,2,2],5<br>返回：2</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Gift</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="comment">/*</span></span><br><span class="line"><span class="comment">     如果重复的次数超过一半的话，一定有相邻的数字相同这种情况的</span></span><br><span class="line"><span class="comment">     对数组同时去掉两个不同的数字，到最后剩下的一个数就是该数字</span></span><br><span class="line"><span class="comment">    */</span></span><br><span class="line">    <span class="function"><span class="keyword">int</span> <span class="title">getValue</span><span class="params">(<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; gifts, <span class="keyword">int</span> n)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">int</span> res = gifts[<span class="number">0</span>], time = <span class="number">1</span>;</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">1</span>;i&lt;gifts.size();i++)&#123;</span><br><span class="line">            <span class="keyword">if</span>(gifts[i]==res) time++;</span><br><span class="line">            <span class="keyword">else</span>&#123;</span><br><span class="line">                time--;</span><br><span class="line">                <span class="keyword">if</span>(time == <span class="number">0</span>)&#123;</span><br><span class="line">                    res = gifts[i];</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        time = <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;gifts.size();i++)&#123;</span><br><span class="line">            <span class="keyword">if</span>(gifts[i] == res) time++;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> time&gt;gifts.size()/<span class="number">2</span>?res:<span class="number">0</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure>]]></content>
    
    <summary type="html">
    
      &lt;h1 id=&quot;腾讯2018春招技术类编程题汇总&quot;&gt;&lt;a href=&quot;#腾讯2018春招技术类编程题汇总&quot; class=&quot;headerlink&quot; title=&quot;腾讯2018春招技术类编程题汇总&quot;&gt;&lt;/a&gt;腾讯2018春招技术类编程题汇总&lt;/h1&gt;&lt;h2 id=&quot;1、翻转数列&quot;&gt;&lt;a href=&quot;#1、翻转数列&quot; class=&quot;headerlink&quot; title=&quot;1、翻转数列&quot;&gt;&lt;/a&gt;1、翻转数列&lt;/h2&gt;&lt;p&gt;小Q定义了一种数列称为翻转数列:&lt;br&gt;给定整数n和m, 满足n能被2m整除。对于一串连续递增整数数列1, 2, 3, 4…, 每隔m个符号翻转一次, 最初符号为’-‘;。&lt;br&gt;例如n = 8, m = 2, 数列就是: -1, -2, +3, +4, -5, -6, +7, +8.&lt;br&gt;而n = 4, m = 1, 数列就是: -1, +2, -3, + 4.&lt;br&gt;小Q现在希望你能帮他算算前n项和为多少。&lt;/p&gt;
    
    </summary>
    
      <category term="C++" scheme="http://yoursite.com/categories/C/"/>
    
      <category term="后台开发" scheme="http://yoursite.com/categories/%E5%90%8E%E5%8F%B0%E5%BC%80%E5%8F%91/"/>
    
      <category term="CodeCode" scheme="http://yoursite.com/categories/CodeCode/"/>
    
    
      <category term="C++" scheme="http://yoursite.com/tags/C/"/>
    
      <category term="后台开发" scheme="http://yoursite.com/tags/%E5%90%8E%E5%8F%B0%E5%BC%80%E5%8F%91/"/>
    
      <category term="技术类编程题" scheme="http://yoursite.com/tags/%E6%8A%80%E6%9C%AF%E7%B1%BB%E7%BC%96%E7%A8%8B%E9%A2%98/"/>
    
  </entry>
  
  <entry>
    <title>3D微信小游戏 轮盘控制模块 three.js</title>
    <link href="http://yoursite.com/2019/11/11/30/"/>
    <id>http://yoursite.com/2019/11/11/30/</id>
    <published>2019-11-11T08:05:00.000Z</published>
    <updated>2019-12-18T04:23:15.671Z</updated>
    
    <content type="html"><![CDATA[<p><img src="https://img-blog.csdnimg.cn/20191111131456936.gif" alt="在这里插入图片描述"></p><h1 id="一、场景构造"><a href="#一、场景构造" class="headerlink" title="一、场景构造"></a>一、场景构造</h1><h2 id="three-js基础"><a href="#three-js基础" class="headerlink" title="three.js基础"></a>three.js基础</h2><p>如果是刚接触3D引擎，关于three.js的基础知识可以参考之前的博客<a href="https://blog.csdn.net/ffcjjhv/article/details/86632320" target="_blank" rel="noopener">Three.js+tween.js 基础(一)</a> 中的基本概念篇部分。（场景 、相机 、渲染器 、添加对象）</p><h2 id="微信小游戏中使用three"><a href="#微信小游戏中使用three" class="headerlink" title="微信小游戏中使用three"></a>微信小游戏中使用three</h2><p>使用<strong>微信开发者工具</strong>创建新的小游戏模板，AppID选择测试号，得到的是飞机大战的源文件，在这个基础上进行修改。</p><a id="more"></a><p><img src="https://img-blog.csdnimg.cn/20191111133219542.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZmY2pqaHY=,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"><br>game.js:</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> <span class="string">'./js/libs/weapp-adapter'</span></span><br><span class="line"><span class="keyword">import</span> <span class="string">'./js/libs/symbol'</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> Main <span class="keyword">from</span> <span class="string">'./js/main'</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">new</span> Main()</span><br></pre></td></tr></table></figure><p>game.json:</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">&#123;</span><br><span class="line">    <span class="string">"deviceOrientation"</span>: <span class="string">"landscapeRight"</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>改为横屏游戏。</p><p>最后，清空images、audio和js文件夹。添加 <a href="https://github.com/zj19941113/wegame3D/tree/master/js/libs" target="_blank" rel="noopener">libs</a> 和main.js空文件到js文件夹。</p><p>最终得到：<br><img src="https://img-blog.csdnimg.cn/20191111132758739.png" alt="在这里插入图片描述"><br>代码部分的修改在main.js。</p><h2 id="静止的场景"><a href="#静止的场景" class="headerlink" title="静止的场景"></a>静止的场景</h2><p><a href="https://github.com/zj19941113/wegame3D/blob/master/js/1.js" target="_blank" rel="noopener">main.js</a></p><p>代码主体部分：</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 引入three</span></span><br><span class="line"><span class="keyword">import</span> * <span class="keyword">as</span> THREE <span class="keyword">from</span> <span class="string">'libs/three.js'</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 一些全局变量</span></span><br><span class="line"><span class="keyword">var</span> Colors = &#123; ... &#125;</span><br><span class="line"><span class="keyword">var</span> WIDTH = <span class="built_in">window</span>.innerWidth;</span><br><span class="line"><span class="keyword">var</span> HEIGHT = <span class="built_in">window</span>.innerHeight;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> Sea = <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123; ... &#125;</span><br><span class="line"><span class="keyword">var</span> Cloud = <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123; ... &#125;</span><br><span class="line"><span class="keyword">var</span> Sky = <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123; ... &#125;</span><br><span class="line"><span class="keyword">var</span> AirPlane = <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123; ... &#125;</span><br><span class="line"><span class="keyword">var</span> Pilot = <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123; ... &#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 游戏主函数</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> <span class="class"><span class="keyword">class</span> <span class="title">Main</span> </span>&#123;</span><br><span class="line">  <span class="keyword">constructor</span>() &#123;</span><br><span class="line">    <span class="comment">// 创建场景，相机和渲染器</span></span><br><span class="line">    <span class="keyword">this</span>.createScene();</span><br><span class="line">    <span class="comment">// 添加光源</span></span><br><span class="line">    <span class="keyword">this</span>.createLights();</span><br><span class="line">    <span class="keyword">this</span>.start()</span><br><span class="line">  &#125;</span><br><span class="line">  createScene() &#123; ... &#125;</span><br><span class="line">  createLights() &#123; ... &#125;</span><br><span class="line">  createPlane() &#123; ... &#125;</span><br><span class="line">  createSea() &#123; ... &#125;</span><br><span class="line">  createSky() &#123; ... &#125;</span><br><span class="line"></span><br><span class="line">  start() &#123;</span><br><span class="line">    <span class="comment">// 添加对象 </span></span><br><span class="line">    <span class="keyword">this</span>.createPlane();</span><br><span class="line">    <span class="keyword">this</span>.createSea();</span><br><span class="line">    <span class="keyword">this</span>.createSky();</span><br><span class="line"></span><br><span class="line">    <span class="built_in">window</span>.requestAnimationFrame(<span class="keyword">this</span>.loop.bind(<span class="keyword">this</span>), canvas);</span><br><span class="line">  &#125;</span><br><span class="line">  update() &#123;</span><br><span class="line"></span><br><span class="line">  &#125;</span><br><span class="line">  loop() &#123;</span><br><span class="line">    <span class="keyword">this</span>.update()</span><br><span class="line">    <span class="keyword">this</span>.renderer.render(<span class="keyword">this</span>.scene, <span class="keyword">this</span>.camera);</span><br><span class="line">    <span class="built_in">window</span>.requestAnimationFrame(<span class="keyword">this</span>.loop.bind(<span class="keyword">this</span>), canvas);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p><img src="https://img-blog.csdnimg.cn/20191111141450928.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZmY2pqaHY=,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"></p><h2 id="动画渲染"><a href="#动画渲染" class="headerlink" title="动画渲染"></a>动画渲染</h2><p><a href="https://github.com/zj19941113/wegame3D/blob/master/js/2.js" target="_blank" rel="noopener">main.js</a></p><p>修改update()：</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">update() &#123;</span><br><span class="line">  <span class="comment">// 转动大海和云</span></span><br><span class="line">  <span class="keyword">this</span>.sea.mesh.rotation.z += <span class="number">.005</span>;</span><br><span class="line">  <span class="keyword">this</span>.sky.rotation.z += <span class="number">.01</span>;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 更新每帧的飞机</span></span><br><span class="line">  <span class="keyword">this</span>.updatePlane();</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 更新每帧的海浪</span></span><br><span class="line">  <span class="keyword">this</span>.sea.moveWaves();</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>添加 updatePlane()，更新每帧的飞机</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">updatePlane() &#123;</span><br><span class="line">    <span class="keyword">this</span>.airplane.propeller.rotation.x += <span class="number">0.3</span>;</span><br><span class="line">    <span class="keyword">this</span>.airplane.pilot.updateHairs();</span><br><span class="line">  &#125;</span><br></pre></td></tr></table></figure><p>为 Pilot 添加原型函数 updateHairs() ，让头发飘起来:</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line">Pilot.prototype.updateHairs = <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 获得头发</span></span><br><span class="line">  <span class="keyword">var</span> hairs = <span class="keyword">this</span>.hairsTop.children;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 根据 angleHairs 的角度更新头发</span></span><br><span class="line">  <span class="keyword">var</span> l = hairs.length;</span><br><span class="line">  <span class="keyword">for</span> (<span class="keyword">var</span> i = <span class="number">0</span>; i &lt; l; i++) &#123;</span><br><span class="line">    <span class="keyword">var</span> h = hairs[i];</span><br><span class="line">    <span class="comment">// 每根头发将周期性的基础上原始大小的75%至100%之间作调整。</span></span><br><span class="line">    h.scale.y = <span class="number">.75</span> + <span class="built_in">Math</span>.cos(<span class="keyword">this</span>.angleHairs + i / <span class="number">3</span>) * <span class="number">.25</span>;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="comment">// 在下一帧增加角度</span></span><br><span class="line">  <span class="keyword">this</span>.angleHairs += <span class="number">0.16</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>更新每帧的海浪，为 Sea 添加原型函数 moveWaves() :</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line">Sea.prototype.moveWaves = <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 获取顶点</span></span><br><span class="line">  <span class="keyword">var</span> verts = <span class="keyword">this</span>.mesh.geometry.vertices;</span><br><span class="line">  <span class="keyword">var</span> l = verts.length;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">for</span> (<span class="keyword">var</span> i = <span class="number">0</span>; i &lt; l; i++) &#123;</span><br><span class="line">    <span class="keyword">var</span> v = verts[i];</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 获取关联的值</span></span><br><span class="line">    <span class="keyword">var</span> vprops = <span class="keyword">this</span>.waves[i];</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 更新顶点的位置</span></span><br><span class="line">    v.x = vprops.x + <span class="built_in">Math</span>.cos(vprops.ang) * vprops.amp;</span><br><span class="line">    v.y = vprops.y + <span class="built_in">Math</span>.sin(vprops.ang) * vprops.amp;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 下一帧自增一个角度</span></span><br><span class="line">    vprops.ang += vprops.speed;</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 告诉渲染器代表大海的几何体发生改变</span></span><br><span class="line">  <span class="comment">// 事实上，为了维持最好的性能</span></span><br><span class="line">  <span class="comment">// Three.js 会缓存几何体和忽略一些修改</span></span><br><span class="line">  <span class="comment">// 除非加上这句</span></span><br><span class="line">  <span class="keyword">this</span>.mesh.geometry.verticesNeedUpdate = <span class="literal">true</span>;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">this</span>.mesh.rotation.z += <span class="number">.005</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p><img src="https://img-blog.csdnimg.cn/20191111143643241.gif" alt="在这里插入图片描述"></p><h1 id="二、轮盘控制"><a href="#二、轮盘控制" class="headerlink" title="二、轮盘控制"></a>二、轮盘控制</h1><h2 id="创建UI部分"><a href="#创建UI部分" class="headerlink" title="创建UI部分"></a>创建UI部分</h2><p><a href="https://github.com/zj19941113/wegame3D/blob/master/js/3.js" target="_blank" rel="noopener">main.js</a></p><p>轮盘控制，分数信息，技能按钮这些部分和游戏主体分开，都创建在UI部分，使用新的场景和正交相机，需要保证在各个机型位置相对不变。这里只添加轮盘控制，分数信息，技能按钮以后再写。。。。<br>修改 start() 、loop() ：</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line">start() &#123;</span><br><span class="line">    <span class="comment">// 添加对象 </span></span><br><span class="line">    <span class="keyword">this</span>.createPlane();</span><br><span class="line">    <span class="keyword">this</span>.createSea();</span><br><span class="line">    <span class="keyword">this</span>.createSky();</span><br><span class="line">    <span class="keyword">this</span>.createUI();</span><br><span class="line"></span><br><span class="line">    <span class="built_in">window</span>.requestAnimationFrame(<span class="keyword">this</span>.loop.bind(<span class="keyword">this</span>), canvas);</span><br><span class="line">  &#125;</span><br><span class="line">loop() &#123;</span><br><span class="line">    <span class="keyword">this</span>.update()</span><br><span class="line">    <span class="keyword">this</span>.renderer.render(<span class="keyword">this</span>.scene, <span class="keyword">this</span>.camera);</span><br><span class="line">    <span class="keyword">this</span>.ui.render(<span class="keyword">this</span>.renderer);</span><br><span class="line">    <span class="built_in">window</span>.requestAnimationFrame(<span class="keyword">this</span>.loop.bind(<span class="keyword">this</span>), canvas);</span><br><span class="line">  &#125;</span><br></pre></td></tr></table></figure><p>添加 createUI()</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">createUI() &#123;</span><br><span class="line">  <span class="comment">// 利用新建一个场景，并创建一个正交相机</span></span><br><span class="line">  <span class="comment">// 把UI元素放在这个场景里，渲染的时候同时渲染多个场景</span></span><br><span class="line">  <span class="keyword">this</span>.ui = <span class="keyword">new</span> UI();</span><br><span class="line">  <span class="comment">// 创建轮盘</span></span><br><span class="line">  <span class="keyword">var</span> controller = <span class="keyword">new</span> Controller();</span><br><span class="line">  <span class="comment">// console.log(controller)；</span></span><br><span class="line">  controller.mesh.position.set(<span class="number">30</span> + controller.controllerRadius - WIDTH * <span class="number">0.5</span>, <span class="number">20</span> + controller.controllerRadius - HEIGHT * <span class="number">0.5</span>, <span class="number">0</span>);</span><br><span class="line">  <span class="keyword">this</span>.controller = controller;</span><br><span class="line">  <span class="keyword">this</span>.ui.add(<span class="keyword">this</span>.controller.mesh);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>添加 UI 及其原型函数 add()、render()</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> UI = <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="keyword">this</span>.scene = <span class="keyword">new</span> THREE.Scene();</span><br><span class="line">  <span class="keyword">this</span>.camera = <span class="keyword">new</span> THREE.OrthographicCamera(WIDTH / <span class="number">-2</span>, WIDTH / <span class="number">2</span>, HEIGHT / <span class="number">2</span>, HEIGHT / <span class="number">-2</span>, <span class="number">0</span>, <span class="number">10000</span>);</span><br><span class="line">  <span class="keyword">this</span>.camera.position.z = <span class="number">10000</span>;</span><br><span class="line">&#125;</span><br><span class="line">UI.prototype.add = <span class="function"><span class="keyword">function</span> (<span class="params">obj</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">this</span>.scene.add(obj);</span><br><span class="line">&#125;</span><br><span class="line">UI.prototype.render = <span class="function"><span class="keyword">function</span> (<span class="params">renderer</span>) </span>&#123;</span><br><span class="line">  renderer.clearDepth();</span><br><span class="line">  renderer.render(<span class="keyword">this</span>.scene, <span class="keyword">this</span>.camera);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>添加轮盘 Controller</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> Controller = <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="keyword">this</span>.mesh = <span class="keyword">new</span> THREE.Object3D();</span><br><span class="line">  <span class="keyword">var</span> controllerRadius = HEIGHT * <span class="number">0.17</span> &gt; <span class="number">105</span> ? <span class="number">105</span> : HEIGHT * <span class="number">0.17</span>;</span><br><span class="line">  <span class="keyword">this</span>.controllerRadius = controllerRadius;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 创建轮盘</span></span><br><span class="line">  <span class="keyword">var</span> geometry = <span class="keyword">new</span> THREE.CircleGeometry(controllerRadius, <span class="number">32</span>);</span><br><span class="line">  <span class="keyword">var</span> material = <span class="keyword">new</span> THREE.LineBasicMaterial(&#123; <span class="attr">color</span>: <span class="number">0xf7d9aa</span> &#125;);</span><br><span class="line">  geometry.vertices.shift();</span><br><span class="line">  <span class="keyword">var</span> circle = <span class="keyword">new</span> THREE.LineLoop(geometry, material);</span><br><span class="line">  <span class="keyword">this</span>.mesh.add(circle);</span><br><span class="line"></span><br><span class="line">  <span class="keyword">var</span> geometry = <span class="keyword">new</span> THREE.CircleGeometry(controllerRadius, <span class="number">32</span>);</span><br><span class="line">  <span class="keyword">var</span> material = <span class="keyword">new</span> THREE.MeshBasicMaterial(&#123;</span><br><span class="line">    color: <span class="number">0xffffff</span>,</span><br><span class="line">    transparent: <span class="literal">true</span>,</span><br><span class="line">    opacity: <span class="number">0.1</span></span><br><span class="line">  &#125;);</span><br><span class="line">  <span class="keyword">var</span> bgcircle = <span class="keyword">new</span> THREE.Mesh(geometry, material);</span><br><span class="line">  <span class="keyword">this</span>.mesh.add(bgcircle);</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 创建当前位置</span></span><br><span class="line">  <span class="keyword">var</span> wheel = <span class="keyword">new</span> THREE.Object3D();</span><br><span class="line">  wheel.name = <span class="string">"wheel"</span>;</span><br><span class="line">  <span class="keyword">var</span> geometry = <span class="keyword">new</span> THREE.CircleGeometry(controllerRadius * <span class="number">0.33</span>, <span class="number">32</span>);</span><br><span class="line">  <span class="keyword">var</span> material = <span class="keyword">new</span> THREE.MeshBasicMaterial(&#123;</span><br><span class="line">    color: <span class="number">0xffffff</span>,</span><br><span class="line">    transparent: <span class="literal">true</span>,</span><br><span class="line">    opacity: <span class="number">0.1</span></span><br><span class="line">  &#125;);</span><br><span class="line">  <span class="keyword">var</span> circle1 = <span class="keyword">new</span> THREE.Mesh(geometry, material);</span><br><span class="line">  wheel.add(circle1);</span><br><span class="line"></span><br><span class="line">  <span class="keyword">var</span> geometry = <span class="keyword">new</span> THREE.CircleGeometry(controllerRadius * <span class="number">0.33</span> - <span class="number">2</span>, <span class="number">32</span>);</span><br><span class="line">  <span class="keyword">var</span> material = <span class="keyword">new</span> THREE.MeshBasicMaterial(&#123;</span><br><span class="line">    color: <span class="number">0x201D13</span>,</span><br><span class="line">    transparent: <span class="literal">true</span>,</span><br><span class="line">    opacity: <span class="number">0.1</span></span><br><span class="line">  &#125;);</span><br><span class="line">  <span class="keyword">var</span> circle2 = <span class="keyword">new</span> THREE.Mesh(geometry, material);</span><br><span class="line">  wheel.add(circle2);</span><br><span class="line"></span><br><span class="line">  <span class="keyword">this</span>.mesh.add(wheel);</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 创建指向标</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p><img src="https://img-blog.csdnimg.cn/20191111152138245.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZmY2pqaHY=,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"></p><h2 id="轮盘控制"><a href="#轮盘控制" class="headerlink" title="轮盘控制"></a>轮盘控制</h2><p><a href="https://github.com/zj19941113/wegame3D/blob/master/js/main.js" target="_blank" rel="noopener">main.js</a></p><p>start()中添加事件监听，update()中更新每帧的鼠标位置和轮盘</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line">start() &#123;</span><br><span class="line">    <span class="comment">// 添加对象 </span></span><br><span class="line">    <span class="keyword">this</span>.createPlane();</span><br><span class="line">    <span class="keyword">this</span>.createSea();</span><br><span class="line">    <span class="keyword">this</span>.createSky();</span><br><span class="line">    <span class="keyword">this</span>.createUI();</span><br><span class="line"></span><br><span class="line">    <span class="keyword">this</span>.mousePos = &#123; <span class="attr">x</span>: <span class="number">0</span>, <span class="attr">y</span>: <span class="number">0</span> &#125;;</span><br><span class="line">    <span class="comment">// 初始化事件监听</span></span><br><span class="line">    <span class="keyword">this</span>.touchEvent();</span><br><span class="line"></span><br><span class="line">    <span class="built_in">window</span>.requestAnimationFrame(<span class="keyword">this</span>.loop.bind(<span class="keyword">this</span>), canvas);</span><br><span class="line">  &#125;</span><br><span class="line">update() &#123;</span><br><span class="line">    <span class="comment">// 转动大海和云</span></span><br><span class="line">    <span class="keyword">this</span>.sea.mesh.rotation.z += <span class="number">.005</span>;</span><br><span class="line">    <span class="keyword">this</span>.sky.rotation.z += <span class="number">.01</span>;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 更新每帧的飞机</span></span><br><span class="line">    <span class="keyword">this</span>.updatePlane();</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 更新每帧的海浪</span></span><br><span class="line">    <span class="keyword">this</span>.sea.moveWaves();</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 更新每帧的鼠标位置</span></span><br><span class="line">    <span class="keyword">this</span>.updatePosition();</span><br><span class="line">  &#125;</span><br></pre></td></tr></table></figure><p>添加 touchEvent() 事件监听，实时更新 mousePos</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br></pre></td><td class="code"><pre><span class="line">touchEvent() &#123;</span><br><span class="line">    canvas.addEventListener(<span class="string">'touchstart'</span>, (<span class="function">(<span class="params">e</span>) =&gt;</span> &#123;</span><br><span class="line">      e.preventDefault()</span><br><span class="line"></span><br><span class="line">      <span class="keyword">var</span> radius = <span class="keyword">this</span>.controller.controllerRadius;</span><br><span class="line"></span><br><span class="line">      <span class="keyword">var</span> tx = (e.touches[<span class="number">0</span>].clientX - <span class="number">30</span> - radius) / radius;</span><br><span class="line">      <span class="keyword">var</span> ty = (HEIGHT -e.touches[<span class="number">0</span>].clientY - <span class="number">20</span> - radius) / radius;</span><br><span class="line"></span><br><span class="line">      <span class="keyword">if</span> (<span class="keyword">this</span>.checkIsFingerOnController(tx, ty)) &#123;</span><br><span class="line">        <span class="keyword">this</span>.touched = <span class="literal">true</span>;</span><br><span class="line">        <span class="keyword">this</span>.controller.mesh.children[<span class="number">2</span>].children[<span class="number">1</span>].material.opacity = <span class="number">0.3</span>;</span><br><span class="line">        <span class="keyword">this</span>.mousePos = &#123; <span class="attr">x</span>: tx, <span class="attr">y</span>: ty &#125;;</span><br><span class="line">      &#125;</span><br><span class="line"></span><br><span class="line">    &#125;).bind(<span class="keyword">this</span>))</span><br><span class="line"></span><br><span class="line">    canvas.addEventListener(<span class="string">'touchmove'</span>, (<span class="function">(<span class="params">e</span>) =&gt;</span> &#123;</span><br><span class="line">      e.preventDefault()</span><br><span class="line">      <span class="keyword">if</span> (<span class="keyword">this</span>.touched) &#123;</span><br><span class="line">        <span class="keyword">var</span> radius = <span class="keyword">this</span>.controller.controllerRadius;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">var</span> tx = (e.touches[<span class="number">0</span>].clientX - <span class="number">30</span> - radius) / radius;</span><br><span class="line">        <span class="keyword">var</span> ty = (HEIGHT-e.touches[<span class="number">0</span>].clientY - <span class="number">20</span> - radius) / radius;</span><br><span class="line">        </span><br><span class="line">        <span class="keyword">if</span> (<span class="keyword">this</span>.checkIsFingerOnController(tx, ty))&#123;</span><br><span class="line">          <span class="keyword">this</span>.mousePos = &#123; <span class="attr">x</span>: tx, <span class="attr">y</span>: ty &#125;;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">else</span>&#123;</span><br><span class="line">          <span class="keyword">let</span> k = ty/tx;</span><br><span class="line">          <span class="keyword">if</span> (tx &gt; <span class="number">0</span> &amp;&amp; ty &gt; <span class="number">0</span>) &#123;tx = <span class="number">1</span> / <span class="built_in">Math</span>.sqrt(k * k + <span class="number">1</span>);ty = k * tx;&#125;</span><br><span class="line">          <span class="keyword">else</span> <span class="keyword">if</span> (tx &lt; <span class="number">0</span> &amp;&amp; ty &gt; <span class="number">0</span>) &#123; tx = <span class="number">-1</span> / <span class="built_in">Math</span>.sqrt(k * k + <span class="number">1</span>); ty = k * tx; &#125;</span><br><span class="line">          <span class="keyword">else</span> <span class="keyword">if</span> (tx &gt; <span class="number">0</span> &amp;&amp; ty &lt; <span class="number">0</span>) &#123; tx = <span class="number">1</span> / <span class="built_in">Math</span>.sqrt(k * k + <span class="number">1</span>); ty = k * tx; &#125;</span><br><span class="line">          <span class="keyword">else</span> &#123; tx = <span class="number">-1</span> / <span class="built_in">Math</span>.sqrt(k * k + <span class="number">1</span>); ty = k * tx; &#125;</span><br><span class="line">          <span class="keyword">this</span>.mousePos = &#123; <span class="attr">x</span>: tx, <span class="attr">y</span>: ty &#125;;</span><br><span class="line">        &#125;</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;).bind(<span class="keyword">this</span>))</span><br><span class="line"></span><br><span class="line">    canvas.addEventListener(<span class="string">'touchend'</span>, (<span class="function">(<span class="params">e</span>) =&gt;</span> &#123;</span><br><span class="line">      e.preventDefault()</span><br><span class="line">      <span class="keyword">this</span>.touched = <span class="literal">false</span>;</span><br><span class="line">      <span class="keyword">this</span>.controller.mesh.children[<span class="number">2</span>].children[<span class="number">1</span>].material.opacity = <span class="number">0.1</span>;</span><br><span class="line">      <span class="keyword">this</span>.mousePos = &#123; <span class="attr">x</span>: <span class="number">0</span>, <span class="attr">y</span>: <span class="number">0</span> &#125;;</span><br><span class="line">    &#125;).bind(<span class="keyword">this</span>))</span><br><span class="line">  &#125;</span><br><span class="line">  </span><br><span class="line">checkIsFingerOnController(x, y) &#123;</span><br><span class="line">    <span class="keyword">return</span> x*x+y*y&lt;<span class="number">1</span>;</span><br><span class="line">  &#125;</span><br></pre></td></tr></table></figure><p>添加 updatePosition() ，更新当前轮盘位置</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line">updatePosition() &#123;</span><br><span class="line">    <span class="keyword">var</span> radius = <span class="keyword">this</span>.controller.controllerRadius;</span><br><span class="line">    <span class="comment">// 在x轴上-radius至radius之间移动点标</span></span><br><span class="line">    <span class="comment">// 根据鼠标的位置在-1与1之间的范围，使用 normalize 函数实现（如下）</span></span><br><span class="line">    <span class="keyword">var</span> targetX = <span class="keyword">this</span>.normalize(<span class="keyword">this</span>.mousePos.x, <span class="number">-1</span>, <span class="number">1</span>, (<span class="number">-1</span> + <span class="number">0.33</span>) * radius, (<span class="number">1</span> - <span class="number">0.33</span>)*radius);</span><br><span class="line">    <span class="keyword">var</span> targetY = <span class="keyword">this</span>.normalize(<span class="keyword">this</span>.mousePos.y, <span class="number">-1</span>, <span class="number">1</span>, (<span class="number">-1</span> + <span class="number">0.33</span>) * radius, (<span class="number">1</span> - <span class="number">0.33</span>)*radius);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 在每帧通过添加剩余距离的一小部分的值移动点标</span></span><br><span class="line">    <span class="keyword">this</span>.controller.mesh.children[<span class="number">2</span>].position.x += (targetX - <span class="keyword">this</span>.controller.mesh.children[<span class="number">2</span>].position.x) * <span class="number">0.25</span>;</span><br><span class="line">    <span class="keyword">this</span>.controller.mesh.children[<span class="number">2</span>].position.y += (targetY - <span class="keyword">this</span>.controller.mesh.children[<span class="number">2</span>].position.y) * <span class="number">0.25</span>;</span><br><span class="line">  &#125;</span><br><span class="line">normalize(v, vmin, vmax, tmin, tmax) &#123;</span><br><span class="line">    <span class="keyword">var</span> nv = <span class="built_in">Math</span>.max(<span class="built_in">Math</span>.min(v, vmax), vmin);</span><br><span class="line">    <span class="keyword">var</span> dv = vmax - vmin;</span><br><span class="line">    <span class="keyword">var</span> pc = (nv - vmin) / dv;</span><br><span class="line">    <span class="keyword">var</span> dt = tmax - tmin;</span><br><span class="line">    <span class="keyword">var</span> tv = tmin + (pc * dt);</span><br><span class="line">    <span class="keyword">return</span> tv;</span><br><span class="line">  &#125;</span><br></pre></td></tr></table></figure><p>修改 updatePlane() ，更新当前飞机位置</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line">updatePlane() &#123;</span><br><span class="line">    <span class="comment">// 在x轴上-140至140之间和y轴25至175之间移动飞机</span></span><br><span class="line">    <span class="comment">// 根据鼠标的位置在-1与1之间的范围，使用 normalize 函数实现（如下）</span></span><br><span class="line"></span><br><span class="line">    <span class="keyword">var</span> targetX = <span class="keyword">this</span>.normalize(<span class="keyword">this</span>.mousePos.x, <span class="number">-1</span>, <span class="number">1</span>, <span class="number">-140</span>, <span class="number">140</span>);</span><br><span class="line">    <span class="keyword">var</span> targetY = <span class="keyword">this</span>.normalize(<span class="keyword">this</span>.mousePos.y, <span class="number">-1</span>, <span class="number">1</span>, <span class="number">25</span>, <span class="number">175</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 更新飞机的位置</span></span><br><span class="line">    <span class="comment">//this.airplane.mesh.position.x = targetX;</span></span><br><span class="line"></span><br><span class="line">    <span class="comment">// 在每帧通过添加剩余距离的一小部分的值移动飞机</span></span><br><span class="line">    <span class="keyword">this</span>.airplane.mesh.position.y += (targetY - <span class="keyword">this</span>.airplane.mesh.position.y) * <span class="number">0.1</span>;</span><br><span class="line">    <span class="keyword">this</span>.airplane.mesh.position.x += (targetX - <span class="keyword">this</span>.airplane.mesh.position.x) * <span class="number">0.05</span>;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 剩余的距离按比例转动飞机</span></span><br><span class="line">    <span class="keyword">this</span>.airplane.mesh.rotation.z = (targetY - <span class="keyword">this</span>.airplane.mesh.position.y) * <span class="number">0.0128</span>;</span><br><span class="line">    <span class="keyword">this</span>.airplane.mesh.rotation.x = (<span class="keyword">this</span>.airplane.mesh.position.y - targetY) * <span class="number">0.0064</span>;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">this</span>.airplane.propeller.rotation.x += <span class="number">0.3</span>;</span><br><span class="line">    <span class="keyword">this</span>.airplane.pilot.updateHairs();</span><br><span class="line">  &#125;</span><br></pre></td></tr></table></figure><p><img src="https://img-blog.csdnimg.cn/20191111131456936.gif" alt="在这里插入图片描述"><br>代码主体部分：</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 引入three</span></span><br><span class="line"><span class="keyword">import</span> * <span class="keyword">as</span> THREE <span class="keyword">from</span> <span class="string">'libs/three.js'</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 一些全局变量</span></span><br><span class="line"><span class="keyword">var</span> Colors = &#123; ... &#125;</span><br><span class="line"><span class="keyword">var</span> WIDTH = <span class="built_in">window</span>.innerWidth;</span><br><span class="line"><span class="keyword">var</span> HEIGHT = <span class="built_in">window</span>.innerHeight;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> Sea = <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123; ... &#125;</span><br><span class="line">Sea.prototype.moveWaves = <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123; ... &#125;</span><br><span class="line"><span class="keyword">var</span> Cloud = <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123; ... &#125;</span><br><span class="line"><span class="keyword">var</span> Sky = <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123; ... &#125;</span><br><span class="line"><span class="keyword">var</span> AirPlane = <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123; ... &#125;</span><br><span class="line"><span class="keyword">var</span> Pilot = <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123; ... &#125;</span><br><span class="line">Pilot.prototype.updateHairs = <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123; ... &#125;</span><br><span class="line"><span class="keyword">var</span> UI = <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123; ... &#125;</span><br><span class="line">UI.prototype.add = <span class="function"><span class="keyword">function</span> (<span class="params">obj</span>) </span>&#123; ... &#125;</span><br><span class="line">UI.prototype.render = <span class="function"><span class="keyword">function</span> (<span class="params">renderer</span>) </span>&#123; ... &#125;</span><br><span class="line"><span class="keyword">var</span> Controller = <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123; ... &#125;</span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 游戏主函数</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> <span class="class"><span class="keyword">class</span> <span class="title">Main</span> </span>&#123;</span><br><span class="line">  <span class="keyword">constructor</span>() &#123;</span><br><span class="line">    <span class="comment">// 创建场景，相机和渲染器</span></span><br><span class="line">    <span class="keyword">this</span>.createScene();</span><br><span class="line">    <span class="comment">// 添加光源</span></span><br><span class="line">    <span class="keyword">this</span>.createLights();</span><br><span class="line">    <span class="keyword">this</span>.start()</span><br><span class="line">  &#125;</span><br><span class="line">  createScene() &#123; ... &#125;</span><br><span class="line">  createLights() &#123; ... &#125;</span><br><span class="line">  createPlane() &#123; ... &#125;</span><br><span class="line">  createSea() &#123; ... &#125;</span><br><span class="line">  createSky() &#123; ... &#125;</span><br><span class="line">  </span><br><span class="line">  createUI() &#123; ... &#125;</span><br><span class="line">  updatePlane() &#123; ... &#125;</span><br><span class="line">  touchEvent() &#123; ... &#125;</span><br><span class="line">  checkIsFingerOnController(x, y) &#123; ... &#125;</span><br><span class="line">  updatePosition() &#123; ... &#125;</span><br><span class="line">  normalize(v, vmin, vmax, tmin, tmax) &#123; ... &#125;</span><br><span class="line"></span><br><span class="line">  start() &#123;</span><br><span class="line">    <span class="comment">// 添加对象 </span></span><br><span class="line">    <span class="keyword">this</span>.createPlane();</span><br><span class="line">    <span class="keyword">this</span>.createSea();</span><br><span class="line">    <span class="keyword">this</span>.createSky();</span><br><span class="line">    </span><br><span class="line">    <span class="keyword">this</span>.createUI();</span><br><span class="line">    </span><br><span class="line">    <span class="keyword">this</span>.mousePos = &#123; <span class="attr">x</span>: <span class="number">0</span>, <span class="attr">y</span>: <span class="number">0</span> &#125;;</span><br><span class="line">    <span class="comment">// 初始化事件监听</span></span><br><span class="line">    <span class="keyword">this</span>.touchEvent();</span><br><span class="line"></span><br><span class="line">    <span class="built_in">window</span>.requestAnimationFrame(<span class="keyword">this</span>.loop.bind(<span class="keyword">this</span>), canvas);</span><br><span class="line">  &#125;</span><br><span class="line">  update() &#123;</span><br><span class="line">    <span class="comment">// 转动大海和云</span></span><br><span class="line">    <span class="keyword">this</span>.sea.mesh.rotation.z += <span class="number">.005</span>;</span><br><span class="line">    <span class="keyword">this</span>.sky.rotation.z += <span class="number">.01</span>;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 更新每帧的飞机</span></span><br><span class="line">    <span class="keyword">this</span>.updatePlane();</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 更新每帧的海浪</span></span><br><span class="line">    <span class="keyword">this</span>.sea.moveWaves();</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 更新每帧的鼠标位置</span></span><br><span class="line">    <span class="keyword">this</span>.updatePosition();</span><br><span class="line">  &#125;</span><br><span class="line">  loop() &#123;</span><br><span class="line">    <span class="keyword">this</span>.update()</span><br><span class="line">    <span class="keyword">this</span>.renderer.render(<span class="keyword">this</span>.scene, <span class="keyword">this</span>.camera);</span><br><span class="line">    <span class="built_in">window</span>.requestAnimationFrame(<span class="keyword">this</span>.loop.bind(<span class="keyword">this</span>), canvas);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>相关链接：<br><a href="https://github.com/zj19941113/wegame3D" target="_blank" rel="noopener">Github项目地址</a><br><a href="https://threejs.org/docs/index.html#manual/en/introduction/Creating-a-scene" target="_blank" rel="noopener">three.js官方文档</a><br><a href="https://tympanus.net/codrops/2016/04/26/the-aviator-animating-basic-3d-scene-threejs/?utm_source=tuicool" target="_blank" rel="noopener">The Making of “The Aviator”: Animating a Basic 3D Scene with Three.js</a> <a href="https://www.jianshu.com/p/92771817c73f" target="_blank" rel="noopener">翻译</a></p>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;&lt;img src=&quot;https://img-blog.csdnimg.cn/20191111131456936.gif&quot; alt=&quot;在这里插入图片描述&quot;&gt;&lt;/p&gt;
&lt;h1 id=&quot;一、场景构造&quot;&gt;&lt;a href=&quot;#一、场景构造&quot; class=&quot;headerlink&quot; title=&quot;一、场景构造&quot;&gt;&lt;/a&gt;一、场景构造&lt;/h1&gt;&lt;h2 id=&quot;three-js基础&quot;&gt;&lt;a href=&quot;#three-js基础&quot; class=&quot;headerlink&quot; title=&quot;three.js基础&quot;&gt;&lt;/a&gt;three.js基础&lt;/h2&gt;&lt;p&gt;如果是刚接触3D引擎，关于three.js的基础知识可以参考之前的博客&lt;a href=&quot;https://blog.csdn.net/ffcjjhv/article/details/86632320&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Three.js+tween.js 基础(一)&lt;/a&gt; 中的基本概念篇部分。（场景 、相机 、渲染器 、添加对象）&lt;/p&gt;
&lt;h2 id=&quot;微信小游戏中使用three&quot;&gt;&lt;a href=&quot;#微信小游戏中使用three&quot; class=&quot;headerlink&quot; title=&quot;微信小游戏中使用three&quot;&gt;&lt;/a&gt;微信小游戏中使用three&lt;/h2&gt;&lt;p&gt;使用&lt;strong&gt;微信开发者工具&lt;/strong&gt;创建新的小游戏模板，AppID选择测试号，得到的是飞机大战的源文件，在这个基础上进行修改。&lt;/p&gt;
    
    </summary>
    
      <category term="前端" scheme="http://yoursite.com/categories/%E5%89%8D%E7%AB%AF/"/>
    
      <category term="THREE" scheme="http://yoursite.com/categories/THREE/"/>
    
      <category term="后台开发" scheme="http://yoursite.com/categories/%E5%90%8E%E5%8F%B0%E5%BC%80%E5%8F%91/"/>
    
    
      <category term="Three.js" scheme="http://yoursite.com/tags/Three-js/"/>
    
      <category term="3D微信小游戏" scheme="http://yoursite.com/tags/3D%E5%BE%AE%E4%BF%A1%E5%B0%8F%E6%B8%B8%E6%88%8F/"/>
    
      <category term="轮盘控制" scheme="http://yoursite.com/tags/%E8%BD%AE%E7%9B%98%E6%8E%A7%E5%88%B6/"/>
    
  </entry>
  
  <entry>
    <title>C++后台开发知识总结（四）操作系统/Linux 内核</title>
    <link href="http://yoursite.com/2019/11/08/29/"/>
    <id>http://yoursite.com/2019/11/08/29/</id>
    <published>2019-11-08T08:23:39.000Z</published>
    <updated>2019-12-18T04:22:25.834Z</updated>
    
    <content type="html"><![CDATA[<p>相关：<br><a href="https://blog.csdn.net/ffcjjhv/article/details/101433113" target="_blank" rel="noopener">C++后台开发知识总结（一）C++基础</a><br><a href="https://blog.csdn.net/ffcjjhv/article/details/101481241" target="_blank" rel="noopener">C++后台开发知识总结（二）数据库</a><br><a href="https://blog.csdn.net/ffcjjhv/article/details/101486572" target="_blank" rel="noopener">C++后台开发知识总结（三）计算机网络</a><br><a href="https://blog.csdn.net/ffcjjhv/article/details/101546677" target="_blank" rel="noopener">C++后台开发知识总结（四）操作系统/Linux 内核</a></p><h1 id="中断"><a href="#中断" class="headerlink" title="中断"></a>中断</h1><p>为什么需要中断：提高CPU运行效率<br>中断是指CPU对系统发生的某个事件做出的一种反应，CPU暂停正在执行的程序，保存现场后自动去执行相应的处理程序，处理完该事件后再返回中断处继续执行原来的程序。</p><a id="more"></a><p>中断一般三类：<br>1.由CPU外部引起的，如I/O中断、时钟中断<br>2.来自CPU内部事件或程序执行中引起的中断，例如程序非法操作，地址越界、浮点溢出<br>3.在程序中使用了系统调用引起的。</p><p><strong>中断处理机制</strong><br>为保证系统实时性，中断服务程序必须足够简短，但实际应用中某些时候发生中断时必须处理大量的事物，这时候如果都在中断服务程序中完成，则会严重降低中断的实时性，基于这个原因，linux系统提出了一个概念：把中断服务程序分为两部分-顶半部-底半部 。</p><p><strong>顶半部</strong><br>中断处理程序，功能是”登记中断”，当一个中断发生时，它进行相应地硬件读写后就把中断例程的下半部挂到该设备的下半部执行队列中去。<br>特点：响应速度快 ，不可中断</p><p>request_irq用于实现中断的注册功能:<br>int request_irq(unsigned int irq, void (*handler)(int, void*, struct pt_regs *), unsigned long flags, const char *devname, void *dev_id)<br>返回0表示成功,或者返回一个错误码<br>功能：向内核注册一个中断服务函数，发生中断号为irq的中断的时候，会执行handle指针函数。<br>  中断注册(参数)<br>    1）unsigned int irq 中断号。<br>    2）void (*handler)(int,void *,struct pt_regs *) 中断处理函数。<br>3）unsigned long flags 与中断管理有关的各种选项，如快速中断，共享中断<br>    IRQF_DISABLED(SA_INTERRUPT) 如果设置该位,表示是一个“快速”中断处理程序，保证中断处理的原子性(不被打断)，在服务该中断时,不会被其他类型的中断打断<br>IRQF_SHARED(SA_SHIRQ) 表明中断可以在设备间共享。共享中断就是将不同的设备挂到同一个中断信号线上。Linux对共享的支持主要是为PCI设备（如声卡、网卡、MODEM等）服务。<br>    4）const char * devname 设备名<br>5）void *dev_id 共享中断时使用。<br>void free_irq(unsigned int irq, void *dev_id) 释放中断</p><p><strong>底半部</strong><br>中断处理的大部分工作都在底半部，它几乎做了中断处理程序的所有事情。<br>特点：处理与中断有相关性但是可以延后执行的任务，可中断，而且可以被新的中断打断<br>底半部机制主要有：<strong>tasklet、工作队列和软中断</strong><br><strong>软中断：</strong><br>软中断作为下半部机制的代表，是随着SMP（share memory processor）的出现应运而生的，也是tasklet实现的基础。它的出现就是因为要满足上面所提出的上半部和下半部的区别，使得对时间不敏感的任务延后执行，产生后并不是马上可以执行，必须要等待内核的调度才能执行。而且可以在多个CPU上并行执行，使得总的系统效率可以更高。<br><strong>tasklet：</strong><br>由于软中断允许多个CPU同时操作，这就导致设计上的复杂度变高，如果某种应用并不需要在多个CPU上并行执行，那么软中断其实是没有必要的。因此诞生了弥补以上两个要求的tasklet。它具有以下特性：<br>a）一种特定类型的tasklet只能运行在一个CPU上，不能并行，只能串行执行。<br>b）多个不同类型的tasklet可以并行在多个CPU上。<br>c）软中断是静态分配的，在内核编译好之后，就不能改变。但tasklet就灵活许多，可以在运行时改变（比如添加模块时）。<br>如果不需要软中断的并行特性，tasklet就是最好的选择。<br><strong>工作队列：</strong><br>1、由内核线程去执行，换句话说总在进程上下文执行。<br>2、可以睡眠，阻塞。</p><h1 id="信号"><a href="#信号" class="headerlink" title="信号"></a>信号</h1><p>信号：对于 Linux来说，实际信号是软中断，用来通知进程发生了异步事件。一个进程收到一个信号类似与处理器收到一个中断请求。信号为 Linux 提供了一种处理异步事件的方法。比如，终端用户输入了 ctrl+c（会产生SIGINT信号，对该信号的默认反应就是进程终止） 来中断程序，会通过信号机制停止一个程序。</p><p>信号的名字和编号：<br>每个信号都有一个名字和编号，这些名字都以“SIG”开头，例如“SIGIO ”、“SIGCHLD”等等。<br>信号定义在signal.h头文件中，信号名都定义为正整数。<br><img src="https://img-blog.csdnimg.cn/20191107143212217.png" alt="在这里插入图片描述"><br>具体的信号名称可以使用kill -l来查看信号的名字以及序号，信号是从1开始编号的，不存在0号信号。kill对于信号0又特殊的应用。</p><p>信号的处理有三种方法，分别是：忽略、捕捉和默认动作<br>忽略信号，大多数信号可以使用这个方式来处理，但是有两种信号不能被忽略（分别是 SIGKILL和SIGSTOP）<br>捕捉信号：当该信号产生时，由内核来调用用户自定义的函数，以此来实现某种信号的处理。<br>系统默认动作，对于每个信号来说，系统都对应由默认的处理动作，当发生了该信号，系统会自动执行。不过，对系统来说，大部分的处理方式都比较粗暴，就是直接杀死该进程。<br>信号的使用：<br>常用的 kill 命令就是一个发送信号的工具，kill 9 PID来杀死进程。比如，我在后台运行了一个 top 工具，通过 ps 命令可以查看他的 PID（进程标志号），通过 kill 9 来发送了一个终止进程的信号来结束了 top 进程。<br><img src="https://img-blog.csdnimg.cn/20191107143430300.png" alt="在这里插入图片描述"><br> 如果查看信号编号和名称，可以发现9对应的是 9) SIGKILL，正是杀死该进程的信号。而以下的执行过程实际也就是执行了9号信号的默认动作——杀死进程。</p><p>信号的种类<br><strong>可靠信号与不可靠信号</strong><br>不可靠信号：Linux的信号继承自早期的Unix信号，信号值小于SIGRTMIN（34）的信号都是不可靠信号。这就是”不可靠信号”的来源。它的主要问题是信号可能丢失。1-31  都是不可靠的。<br>可靠信号：34-64重新设计的一套信号集合，不会出现信号丢失，支持排队<br><strong>实时信号与非实时信号</strong><br>实时信号 ： 就是可靠信号 ；非实时信号：不可靠信号</p><p>SIGCHLD信号：在一个进程终止或者停止时，将SIGCHLD信号发送给其父进程，按系统默认将忽略此信号，如果父进程希望被告知其子系统的这种状态，则应捕捉此信号。<br>子进程退出时向父进程发送SIGCHILD信号，父进程处理SIGCHILD信号。在信号处理函数中调用wait进行处理僵尸进程。<br>SIGCLD信号：<br>对于SIGCLD的早期处理方式如下:如果进程特地设置该信号的配置为SIG_IGN,则子进程状态信息会被丢弃，将不产生僵死进程。</p><h1 id="进程与线程"><a href="#进程与线程" class="headerlink" title="进程与线程"></a>进程与线程</h1><p>进程是系统进行资源调度和分配的的基本单位，实现了操作系统的并发；<br>线程是CPU调度和分派的基本单位，用于保证程序的实时性，实现进程内部的并发；<br>线程是操作系统可识别的最小执行和调度单位。每个线程都独自占用一个虚拟处理器：独自的寄存器组，指令计数器和处理器状态。每个线程完成不同的任务，但是共享同一地址空间（也就是同样的动态内存，映射文件，目标代码等等），打开的文件队列和其他内核资源。</p><p><strong>进程和线程的区别：</strong><br>1、一个线程只能属于一个进程，而一个进程可以有多个线程，但至少有一个线程。线程依赖于进程而存在。<br>2、进程在执行过程中拥有独立的内存单元，而多个线程共享进程的内存。（资源分配给进程，同一进程的所有线程共享该进程的所有资源。同一进程中的多个线程共享代码段（代码和常量），数据段（全局变量和静态变量），扩展段（堆存储）。但是每个线程拥有自己的栈段，栈段又叫运行时段，用来存放所有局部变量和临时变量。）<br>3、进程是资源分配的最小单位，线程是CPU调度的最小单位。<br>4、进程创建/撤消或切换的开销大于线程。由于在创建或撤消进程时，系统都要为之分配或回收资源，如内存空间、I／o设备等。因此，操作系统所付出的开销将显著地大于在创建或撤消线程时的开销。类似地，在进行进程切换时，涉及到整个当前进程CPU环境的保存以及新被调度运行的进程的CPU环境的设置。而线程切换只须保存和设置少量寄存器的内容，并不涉及存储器管理方面的操作。<br>5、通信：由于同一进程中的多个线程具有相同的地址空间，致使它们之间的同步和通信的实现，也变得比较容易。进程间通信IPC，线程间可以直接读写进程数据段（如全局变量）来进行通信——需要进程同步和互斥手段的辅助，以保证数据的一致性。<br>6、进程编程调试简单可靠性高，但是创建销毁开销大；线程正相反，开销小，切换速度快，但是编程调试相对复杂。<br>7、一个进程崩溃，不会对其他进程产生影响；而一个线程崩溃，会让同一进程内的其他线程也死掉。<br>8、进程适应于多核、多机分布；线程适用于多核。<br>游戏服务器应该为每个用户开辟一个进程。因为同一进程间的线程会相互影响，一个线程死掉会影响其他线程，从而导致进程崩溃。因此为了保证不同用户之间不会相互影响，应该为每个用户开辟一个进程</p><p>多线程和多进程的不同<br>进程是资源分配的最小单位，而线程时CPU调度的最小单位。多线程之间共享同一个进程的地址空间，线程间通信简单，同步复杂，线程创建、销毁和切换简单，速度快，占用内存少，适用于多核分布式系统，但是线程间会相互影响，一个线程意外终止会导致同一个进程的其他线程也终止，程序可靠性弱。而多进程间拥有各自独立的运行地址空间，进程间不会相互影响，程序可靠性强，但是进程创建、销毁和切换复杂，速度慢，占用内存多，进程间通信复杂，但是同步简单，适用于多核、多机分布。<br>多进程和多线程的使用场景：<br>多进程，适用于CPU密集型，多线程，适用于I/O密集型的工作场景。多进程适用于多机分布式场景中，易于多机扩展，多线程适用于单机多核分布式场景。</p><p>如何设计server，使得能够接收多个客户端的请求:多线程，线程池，io复用<br>线程产生的原因：<br>进程可以使多个程序能并发执行，以提高资源的利用率和系统的吞吐量；但是其具有一些缺点：进程在同一时间只能干一件事，进程在执行的过程中如果阻塞，整个进程就会挂起，即使进程中有些工作不依赖于等待的资源，仍然不会执行。因此，操作系统引入了比进程粒度更小的线程，作为并发执行的基本单位，从而减少程序在并发执行时所付出的时空开销，提高并发性。和进程相比，线程的优势如下：<br>1、从资源上来讲，线程是一种非常”节俭”的多任务操作方式。在linux系统下，启动一个新的进程必须分配给它独立的地址空间，建立众多的数据表来维护它的代码段、堆栈段和数据段，这是一种”昂贵”的多任务工作方式。<br>2、从切换效率上来讲，运行于一个进程中的多个线程，它们之间使用相同的地址空间，而且线程间彼此切换所需时间也远远小于进程间切换所需要的时间。据统计，一个进程的开销大约是一个线程开销的30倍左右。（<br>3、从通信机制上来讲，线程间方便的通信机制。对不同进程来说，它们具有独立的数据空间，要进行数据的传递只能通过进程间通信的方式进行，这种方式不仅费时，而且很不方便。线程则不然，由于同一进程下的线程之间共享数据空间，所以一个线程的数据可以直接为其他线程所用，这不仅快捷，而且方便。<br>除以上优点外，多线程程序作为一种多任务、并发的工作方式，还有如下优点：<br>1、使多CPU系统更加有效。操作系统会保证当线程数不大于CPU数目时，不同的线程运行于不同的CPU上。<br>2、改善程序结构。一个既长又复杂的进程可以考虑分为多个线程，成为几个独立或半独立的运行部分，这样的程序才会利于理解和修改。</p><h1 id="进程间通信"><a href="#进程间通信" class="headerlink" title="进程间通信"></a>进程间通信</h1><p>进程用户空间是相互独立的，一般而言是不能相互访问的。但很多情况下进程间需要互相通信，来完成系统的某项功能。进程通过与内核及其它进程之间的互相通信来协调它们的行为。<br>进程通信的应用场景：<br>数据传输：一个进程需要将它的数据发送给另一个进程，发送的数据量在一个字节到几兆字节之间。<br>共享数据：多个进程想要操作共享数据，一个进程对共享数据的修改，别的进程应该立刻看到。<br>通知事件：一个进程需要向另一个或一组进程发送消息，通知它（它们）发生了某种事件（如进程终止时要通知父进程）。<br>资源共享：多个进程之间共享同样的资源。为了作到这一点，需要内核提供锁和同步机制。<br>进程控制：有些进程希望完全控制另一个进程的执行（如Debug进程），此时控制进程希望能够拦截另一个进程的所有陷入和异常，并能够及时知道它的状态改变。</p><p>进程间通信主要包括：<strong>管道、消息队列、信号量、信号、共享内存、以及套接字socket</strong>。<strong>管道( pipe )</strong><br>主要包括无名管道和命名管道<br>管道可用于具有亲缘关系的父子进程间的通信，有名管道除了具有管道所具有的功能外，它还允许无亲缘关系进程间的通信<br><strong>消息队列</strong><br>是消息的链接表，存放在内核中。一个消息队列由一个标识符（即队列ID）来标记。消息队列克服了信号传递信息少，管道只能承载无格式字节流以及缓冲区大小受限等特点。具有写权限得进程可以按照一定得规则向消息队列中添加新信息；对消息队列有读权限得进程则可以从消息队列中读取信息；<br>特点：<br>1)消息队列是面向记录的，其中的消息具有特定的格式以及特定的优先级。<br>2)消息队列独立于发送与接收进程。进程终止时，消息队列及其内容并不会被删除。<br>3)消息队列可以实现消息的随机查询,消息不一定要以先进先出的次序读取,也可以按消息的类型读取。<br><strong>信号量( semophore )</strong><br>是一个计数器，可以用来控制多个进程对共享资源的访问。信号量用于实现进程间的互斥与同步，而不用于存储进程间通信数据。<br>特点：<br>1)信号量用于进程间同步，若要在进程间传递数据需要结合共享内存。<br>2)信号量基于操作系统的 PV 操作，程序对信号量的操作都是原子操作。<br>3)每次对信号量的 PV 操作不仅限于对信号量值加 1 或减 1，而且可以加减任意正整数。<br>4)支持信号量组。<br><strong>信号( sinal )</strong><br>是一种比较复杂的通信方式，用于通知接收进程某个事件已经发生。<br><strong>共享内存( shared memory )</strong><br>它使得多个进程可以访问同一块内存空间，不同进程可以及时看到对方进程中对共享内存中数据得更新。这种方式需要依靠某种同步操作，如互斥锁和信号量等<br>特点：<br>1)共享内存是最快的一种IPC，因为进程是直接对内存进行存取<br>2)因为多个进程可以同时操作，所以需要进行同步<br>3)信号量+共享内存通常结合在一起使用，信号量用来同步对共享内存的访问<br>Linux内存共享有多种，如mmap()、Posix共享内存、System V 共享内存。<br><strong>套接字( socket )</strong><br>可用于不同主机之间的进程通信。</p><h1 id="线程间通信"><a href="#线程间通信" class="headerlink" title="线程间通信"></a>线程间通信</h1><p>Posix实现的线程，需使用 -lpthread 库编译 :</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ g++ test.cpp -lpthread -o test</span><br></pre></td></tr></table></figure><p><strong>1、    临界区</strong><br>通过多线程的串行化来访问公共资源或一段代码，速度快，适合控制数据访问；<br>确保在某一时刻只有一个线程能访问数据的简便办法。在任意时刻只允许一个线程对共享资源进行访问。假如有多个线程试图同时访问临界区，那么在有一个线程进入后其他任何试图访问此临界区的线程将被挂起，并一直持续到进入临界区的线程离开。临界区在被释放后，其他线程能够继续抢占，并以此达到用原子方式操作共享资源的目的。<br><strong>2、    互斥量</strong><br>为协调一起对一个共享资源的单独访问而设计的<br>对资源加锁能阻塞其他线程的访问</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;pthread.h&gt;</span></span></span><br><span class="line"><span class="keyword">pthread_mutex_t</span> sum_mutex; <span class="comment">//互斥锁</span></span><br><span class="line">pthread_mutex_init( &amp;sum_mutex, <span class="literal">NULL</span> ); <span class="comment">//对锁进行初始化</span></span><br><span class="line">pthread_mutex_lock( &amp;sum_mutex ); <span class="comment">//加锁</span></span><br><span class="line">pthread_mutex_unlock( &amp;sum_mutex ); <span class="comment">//释放锁，供其他线程使用</span></span><br><span class="line">pthread_mutex_destroy( &amp;sum_mutex ); <span class="comment">//注销锁</span></span><br></pre></td></tr></table></figure><p><strong>3、信号量</strong><br>它允许多个线程在同一时刻访问同一资源，但是需要限制在同一时刻访问此资源的最大线程数目</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">pthread_mutex_t</span> tasks_mutex; <span class="comment">//互斥锁</span></span><br><span class="line"><span class="keyword">pthread_cond_t</span> tasks_cond; <span class="comment">//条件信号量</span></span><br><span class="line">pthread_cond_init( &amp;tasks_cond, <span class="literal">NULL</span> ); <span class="comment">//初始化条件信号量</span></span><br><span class="line">pthread_cond_signal( &amp;tasks_cond ); <span class="comment">//signal:向hello1发送信号</span></span><br><span class="line">pthread_cond_wait( &amp;tasks_cond, &amp;tasks_mutex ); <span class="comment">//wait:等待信号量生效，接收到信号，向hello2发出信号，跳出wait,执行后续</span></span><br><span class="line">pthread_cond_destroy( &amp;tasks_cond ); <span class="comment">//销毁条件变量</span></span><br></pre></td></tr></table></figure><p><strong>4、事件</strong><br>用来通知线程有一些事件已发生，从而启动后继任务的开始</p><p>内核线程：内核线程需要系统内核支持，同时系统内核支持内核线程，内核线程只运行在内核态，不受用户态上下文的拖累，内核线程只能由系统内核管理，像普通进程一样被调度。内核线程的使用是廉价的，唯一使用的资源就是内核栈和上下文切换时保存寄存器的空间。<br>轻量级进程： LWP， Light-Weight Process也是一种用户线程，运行在用户态，是建立在系统内核上的，由系统内核支持的用户线程。它是内核线程的高度抽象，所以轻量级进程需要系统内核支持，同时系统内核支持内核线程。每个轻量级进程都与一个内核线程关联，轻量级进程与内核线程一对一关联。<br>用户级线程：完全建立在用户态空间的线程，用户线程的创建、调度、同步和销毁全部在用户态空间中完成，不需要系统内核支持，也不需要系统内核支持内核线程。<br>Linux使用的线程库采用的是一对一关联，一个用户线程对应一个轻量级进程，一个轻量级进程对应一个内核线程。</p><h1 id="协程"><a href="#协程" class="headerlink" title="协程"></a>协程</h1><p>协程看上去也是子程序，但执行过程中，在子程序内部可中断，然后转而执行别的子程序，在适当的时候再返回来接着执行。<br>协程拥有自己的寄存器上下文和栈。协程调度切换时，将寄存器上下文和栈保存到其他地方，在切回来的时候，恢复先前保存的寄存器上下文和栈，直接操作栈则基本没有内核切换的开销，可以不加锁的访问全局变量，所以上下文的切换非常快。<br><strong>协程和线程区别</strong><br>那和多线程比，协程最大的优势就是协程极高的执行效率。因为子程序切换不是线程切换，而是由程序自身控制，因此，没有线程切换的开销，和多线程比，线程数量越多，协程的性能优势就越明显。<br>第二大优势就是不需要多线程的锁机制，因为只有一个线程，也不存在同时写变量冲突，在协程中控制共享资源不加锁，只需要判断状态就好了，所以执行效率比多线程高很多。</p><h1 id="微内核与宏内核"><a href="#微内核与宏内核" class="headerlink" title="微内核与宏内核"></a>微内核与宏内核</h1><p>宏内核：除了最基本的进程、线程管理、内存管理外，将文件系统，驱动，网络协议等等都集成在内核里面，例如linux内核。<br>优点：效率高。<br>缺点：稳定性差，开发过程中的bug经常会导致整个系统挂掉。</p><p>微内核：内核中只有最基本的调度、内存管理。驱动、文件系统等都是用户态的守护进程去实现的。<br>优点：稳定，驱动等的错误只会导致相应进程死掉，不会导致整个系统都崩溃<br>缺点：效率低。典型代表QNX，QNX的文件系统是跑在用户态的进程，称为resmgr的东西，是订阅发布机制，文件系统的错误只会导致这个守护进程挂掉。不过数据吞吐量就比较不乐观了。</p><h1 id="用户态和内核态区别"><a href="#用户态和内核态区别" class="headerlink" title="用户态和内核态区别"></a>用户态和内核态区别</h1><p>用户态和内核态是操作系统的两种运行级别，两者最大的区别就是特权级不同。用户态拥有最低的特权级，内核态拥有较高的特权级。运行在用户态的程序不能直接访问操作系统内核数据结构和程序。内核态和用户态之间的转换方式主要包括：系统调用，异常和中断。</p><p>用户态到内核态的转化原理:<br><strong>1、系统调用</strong><br>这是用户进程主动要求切换到内核态的一种方式，用户进程通过系统调用申请操作系统提供的服务程序完成工作。<br><strong>2、异常</strong><br>当CPU在执行运行在用户态的程序时，发现了某些事件不可知的异常，这是会触发由当前运行进程切换到处理此异常的内核相关程序中，也就到了内核态，比如缺页异常。<br><strong>3、外围设备的中断</strong><br>当外围设备完成用户请求的操作之后，会向CPU发出相应的中断信号，这时CPU会暂停执行下一条将要执行的指令，转而去执行中断信号的处理程序，如果先执行的指令是用户态下的程序，那么这个转换的过程自然也就发生了有用户态到内核态的切换。比如硬盘读写操作完成，系统会切换到硬盘读写的中断处理程序中执行后续操作等。<br>从出发方式看，可以在认为存在前述3种不同的类型，但是从最终实际完成由用户态到内核态的切换操作上来说，涉及的关键步骤是完全一样的，没有任何区别，都相当于执行了一个中断响应的过程，因为系统调用实际上最终是中断机制实现的，而异常和中断处理机制基本上是一样的，用户态切换到内核态的步骤主要包括：<br>1、从当前进程的描述符中提取其内核栈的ss0及esp0信息。<br>2、使用ss0和esp0指向的内核栈将当前进程的cs,eip，eflags，ss,esp信息保存起来，这个过程也完成了由用户栈找到内核栈的切换过程，同时保存了被暂停执行的程序的下一条指令<br>3、将先前由中断向量检索得到的中断处理程序的cs，eip信息装入相应的寄存器，开始执行中断处理程序，这时就转到了内核态的程序执行了。</p><h1 id="线程需要保存哪些上下文，SP、PC、EAX这些寄存器是干嘛用的"><a href="#线程需要保存哪些上下文，SP、PC、EAX这些寄存器是干嘛用的" class="headerlink" title="线程需要保存哪些上下文，SP、PC、EAX这些寄存器是干嘛用的"></a>线程需要保存哪些上下文，SP、PC、EAX这些寄存器是干嘛用的</h1><p>线程在切换的过程中需要保存当前线程Id、线程状态、堆栈、寄存器状态等信息。<br>其中寄存器主要包括SP PC EAX等寄存器，其主要功能如下：<br>SP:堆栈指针，指向当前栈的栈顶地址<br>PC:程序计数器，存储下一条将要执行的指令<br>EAX:累加寄存器，用于加法乘法的缺省寄存器</p><h1 id="实现多线程"><a href="#实现多线程" class="headerlink" title="实现多线程"></a>实现多线程</h1><p>Win:</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;iostream&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;thread&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> <span class="built_in">std</span>;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">thread01</span><span class="params">()</span> </span>&#123;</span><br><span class="line">  <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; <span class="number">5</span>; i++) <span class="built_in">cout</span> &lt;&lt; <span class="string">"Thread 01 is working ！"</span> &lt;&lt; <span class="built_in">endl</span>;</span><br><span class="line">&#125;</span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">thread02</span><span class="params">()</span> </span>&#123;</span><br><span class="line">  <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; <span class="number">5</span>; i++) <span class="built_in">cout</span> &lt;&lt; <span class="string">"Thread 02 is working ！"</span> &lt;&lt; <span class="built_in">endl</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">  <span class="function">thread <span class="title">task01</span><span class="params">(thread01)</span></span>;</span><br><span class="line">  <span class="function">thread <span class="title">task02</span><span class="params">(thread02)</span></span>;</span><br><span class="line">  task01.join();</span><br><span class="line">  task02.join();</span><br><span class="line"></span><br><span class="line">  <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; <span class="number">5</span>; i++)  </span><br><span class="line"><span class="built_in">cout</span> &lt;&lt; <span class="string">"Main thread is working ！"</span> &lt;&lt; <span class="built_in">endl</span>;</span><br><span class="line">  <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p><img src="https://img-blog.csdnimg.cn/201911071525305.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZmY2pqaHY=,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"><br>阻塞主流程:<br>两个子线程并行执行，join函数会阻塞主流程，所以子线程执行完成后才继续执行主线程。</p><p>从主流程中分离:<br>可以使用detach将子线程从主流程中分离，独立运行，不会阻塞主线程：</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="function">thread <span class="title">task01</span><span class="params">(thread01)</span></span>;</span><br><span class="line"><span class="function">thread <span class="title">task02</span><span class="params">(thread02)</span></span>;</span><br><span class="line">task01.detach();</span><br><span class="line">task02.detach();</span><br></pre></td></tr></table></figure><p><img src="https://img-blog.csdnimg.cn/20191107152549894.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZmY2pqaHY=,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"><br>带参数线程：</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">thread01</span><span class="params">(<span class="keyword">int</span> n)</span> </span>&#123;</span><br><span class="line">  <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; n; i++) <span class="built_in">cout</span> &lt;&lt; <span class="string">"Thread 01 is working ！"</span> &lt;&lt; <span class="built_in">endl</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="function">thread <span class="title">task01</span><span class="params">(thread01,<span class="number">5</span>)</span></span>;</span><br></pre></td></tr></table></figure><p>多线程数据竞争:<br>使用线程互斥对象mutex保持数据同步。mutex类的使用需要包含头文件mutex。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;mutex&gt;</span></span></span><br><span class="line">mutex mu;  <span class="comment">//线程互斥对象</span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">thread01</span><span class="params">()</span> </span>&#123;</span><br><span class="line">  <span class="keyword">while</span> (totalNum &gt; <span class="number">0</span>)&#123;</span><br><span class="line">    mu.lock(); <span class="comment">//同步数据锁</span></span><br><span class="line">    <span class="built_in">cout</span> &lt;&lt; totalNum &lt;&lt; <span class="built_in">endl</span>;</span><br><span class="line">    totalNum--;</span><br><span class="line">    mu.unlock();  <span class="comment">//解除锁定</span></span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">thread02</span><span class="params">()</span> </span>&#123;</span><br><span class="line">  <span class="keyword">while</span> (totalNum &gt; <span class="number">0</span>)&#123;</span><br><span class="line">    mu.lock();</span><br><span class="line">    <span class="built_in">cout</span> &lt;&lt; totalNum &lt;&lt; <span class="built_in">endl</span>;</span><br><span class="line">    totalNum--;</span><br><span class="line">    mu.unlock();</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>Linux:</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;iostream&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;pthread.h&gt;</span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> <span class="built_in">std</span>;</span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> NUM_THREADS 5</span></span><br><span class="line"><span class="comment">// 线程的运行函数,函数返回的是函数指针，便于后面作为参数  </span></span><br><span class="line"><span class="function"><span class="keyword">void</span>* <span class="title">say_hello</span><span class="params">(<span class="keyword">void</span>* args)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="built_in">cout</span> &lt;&lt; <span class="string">"Hello Runoob！"</span> &lt;&lt; <span class="built_in">endl</span>;</span><br><span class="line">&#125;</span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="comment">// 定义线程的 id 变量，多个变量使用数组</span></span><br><span class="line">    <span class="keyword">pthread_t</span> tids[NUM_THREADS];</span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; NUM_THREADS; ++i)</span><br><span class="line">    &#123;</span><br><span class="line">        <span class="comment">//参数依次是：创建的线程id，线程参数，调用的函数，传入的函数参数</span></span><br><span class="line">        <span class="keyword">int</span> ret = pthread_create(&amp;tids[i], <span class="literal">NULL</span>, say_hello, <span class="literal">NULL</span>);</span><br><span class="line">        <span class="keyword">if</span> (ret != <span class="number">0</span>)</span><br><span class="line">        &#123;</span><br><span class="line">           <span class="built_in">cout</span> &lt;&lt; <span class="string">"pthread_create error: error_code="</span> &lt;&lt; ret &lt;&lt; <span class="built_in">endl</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    pthread_exit(<span class="literal">NULL</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>使用 -lpthread 库编译 :</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ g++ test.cpp -lpthread -o test.o</span><br></pre></td></tr></table></figure><p>传递参数：</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">void</span> *<span class="title">PrintHello</span><span class="params">(<span class="keyword">void</span> *threadid)</span></span></span><br><span class="line"><span class="function"></span>&#123;  </span><br><span class="line">   <span class="comment">// 对传入的参数进行强制类型转换，由无类型指针变为整形数指针，然后再读取</span></span><br><span class="line">   <span class="keyword">int</span> tid = *((<span class="keyword">int</span>*)threadid);</span><br><span class="line">   <span class="built_in">cout</span> &lt;&lt; <span class="string">"Hello Runoob! 线程 ID, "</span> &lt;&lt; tid &lt;&lt; <span class="built_in">endl</span>;</span><br><span class="line">   pthread_exit(<span class="literal">NULL</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">rc = pthread_create(&amp;threads[i], <span class="literal">NULL</span>,PrintHello, (<span class="keyword">void</span> *)&amp;(indexes[i]));</span><br></pre></td></tr></table></figure><p>通过结构传递多个参数</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;iostream&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;cstdlib&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;pthread.h&gt;</span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> <span class="built_in">std</span>;</span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> NUM_THREADS     5</span></span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">thread_data</span>&#123;</span></span><br><span class="line">   <span class="keyword">int</span>  thread_id;</span><br><span class="line">   <span class="keyword">char</span> *message;</span><br><span class="line">&#125;;</span><br><span class="line"><span class="function"><span class="keyword">void</span> *<span class="title">PrintHello</span><span class="params">(<span class="keyword">void</span> *threadarg)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">   <span class="class"><span class="keyword">struct</span> <span class="title">thread_data</span> *<span class="title">my_data</span>;</span></span><br><span class="line">   my_data = (struct thread_data *) threadarg;</span><br><span class="line">   <span class="built_in">cout</span> &lt;&lt; <span class="string">"Thread ID : "</span> &lt;&lt; my_data-&gt;thread_id ;</span><br><span class="line">   <span class="built_in">cout</span> &lt;&lt; <span class="string">" Message : "</span> &lt;&lt; my_data-&gt;message &lt;&lt; <span class="built_in">endl</span>;</span><br><span class="line">   pthread_exit(<span class="literal">NULL</span>);</span><br><span class="line">&#125;</span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span> <span class="params">()</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">   <span class="keyword">pthread_t</span> threads[NUM_THREADS];</span><br><span class="line">   <span class="class"><span class="keyword">struct</span> <span class="title">thread_data</span> <span class="title">td</span>[<span class="title">NUM_THREADS</span>];</span></span><br><span class="line">   <span class="keyword">int</span> rc;</span><br><span class="line">   <span class="keyword">int</span> i;</span><br><span class="line">   <span class="keyword">for</span>( i=<span class="number">0</span>; i &lt; NUM_THREADS; i++ )&#123;</span><br><span class="line">      <span class="built_in">cout</span> &lt;&lt;<span class="string">"main() : creating thread, "</span> &lt;&lt; i &lt;&lt; <span class="built_in">endl</span>;</span><br><span class="line">      td[i].thread_id = i;</span><br><span class="line">      td[i].message = <span class="string">"This is message"</span>;</span><br><span class="line">      rc = pthread_create(&amp;threads[i], <span class="literal">NULL</span>, PrintHello, (<span class="keyword">void</span> *)&amp;td[i]); <span class="comment">//传入到参数必须强转为void*类型，即无类型指针</span></span><br><span class="line">      <span class="keyword">if</span> (rc)&#123;</span><br><span class="line">         <span class="built_in">cout</span> &lt;&lt; <span class="string">"Error:unable to create thread,"</span> &lt;&lt; rc &lt;&lt; <span class="built_in">endl</span>;</span><br><span class="line">         <span class="built_in">exit</span>(<span class="number">-1</span>);</span><br><span class="line">      &#125;</span><br><span class="line">   &#125;</span><br><span class="line">   pthread_exit(<span class="literal">NULL</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;iostream&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;cstdlib&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;pthread.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;unistd.h&gt;</span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> <span class="built_in">std</span>;</span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> NUM_THREADS     5</span></span><br><span class="line"><span class="function"><span class="keyword">void</span> *<span class="title">wait</span><span class="params">(<span class="keyword">void</span> *t)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">   <span class="keyword">int</span> i;</span><br><span class="line">   <span class="keyword">long</span> tid;</span><br><span class="line">   tid = (<span class="keyword">long</span>)t;</span><br><span class="line">   sleep(<span class="number">1</span>);</span><br><span class="line">   <span class="built_in">cout</span> &lt;&lt; <span class="string">"Sleeping in thread "</span> &lt;&lt; <span class="built_in">endl</span>;</span><br><span class="line">   <span class="built_in">cout</span> &lt;&lt; <span class="string">"Thread with id : "</span> &lt;&lt; tid &lt;&lt; <span class="string">"  ...exiting "</span> &lt;&lt; <span class="built_in">endl</span>;</span><br><span class="line">   pthread_exit(<span class="literal">NULL</span>);</span><br><span class="line">&#125;</span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span> <span class="params">()</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">   <span class="keyword">int</span> rc;</span><br><span class="line">   <span class="keyword">int</span> i;</span><br><span class="line">   <span class="keyword">pthread_t</span> threads[NUM_THREADS];</span><br><span class="line">   <span class="keyword">pthread_attr_t</span> attr;</span><br><span class="line">   <span class="keyword">void</span> *status;</span><br><span class="line">   <span class="comment">// 初始化并设置线程为可连接的（joinable）</span></span><br><span class="line">   pthread_attr_init(&amp;attr);</span><br><span class="line">   pthread_attr_setdetachstate(&amp;attr, PTHREAD_CREATE_JOINABLE);</span><br><span class="line">   <span class="keyword">for</span>( i=<span class="number">0</span>; i &lt; NUM_THREADS; i++ )&#123;</span><br><span class="line">      <span class="built_in">cout</span> &lt;&lt; <span class="string">"main() : creating thread, "</span> &lt;&lt; i &lt;&lt; <span class="built_in">endl</span>;</span><br><span class="line">      rc = pthread_create(&amp;threads[i], <span class="literal">NULL</span>, wait, (<span class="keyword">void</span> *)i );</span><br><span class="line">      <span class="keyword">if</span> (rc)&#123;</span><br><span class="line">         <span class="built_in">cout</span> &lt;&lt; <span class="string">"Error:unable to create thread,"</span> &lt;&lt; rc &lt;&lt; <span class="built_in">endl</span>;</span><br><span class="line">         <span class="built_in">exit</span>(<span class="number">-1</span>);</span><br><span class="line">      &#125;</span><br><span class="line">   &#125;</span><br><span class="line">   <span class="comment">// 删除属性，并等待其他线程</span></span><br><span class="line">   pthread_attr_destroy(&amp;attr);</span><br><span class="line">   <span class="keyword">for</span>( i=<span class="number">0</span>; i &lt; NUM_THREADS; i++ )&#123;</span><br><span class="line">      rc = pthread_join(threads[i], &amp;status);</span><br><span class="line">      <span class="keyword">if</span> (rc)&#123;</span><br><span class="line">         <span class="built_in">cout</span> &lt;&lt; <span class="string">"Error:unable to join,"</span> &lt;&lt; rc &lt;&lt; <span class="built_in">endl</span>;</span><br><span class="line">         <span class="built_in">exit</span>(<span class="number">-1</span>);</span><br><span class="line">      &#125;</span><br><span class="line">      <span class="built_in">cout</span> &lt;&lt; <span class="string">"Main: completed thread id :"</span> &lt;&lt; i ;</span><br><span class="line">      <span class="built_in">cout</span> &lt;&lt; <span class="string">"  exiting with status :"</span> &lt;&lt; status &lt;&lt; <span class="built_in">endl</span>;</span><br><span class="line">   &#125;</span><br><span class="line">   <span class="built_in">cout</span> &lt;&lt; <span class="string">"Main: program exiting."</span> &lt;&lt; <span class="built_in">endl</span>;</span><br><span class="line">   pthread_exit(<span class="literal">NULL</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h1 id="并发-concurrency-和并行-parallelism"><a href="#并发-concurrency-和并行-parallelism" class="headerlink" title="并发(concurrency)和并行(parallelism)"></a>并发(concurrency)和并行(parallelism)</h1><p>并发（concurrency）：指宏观上看起来两个程序在同时运行，比如说在单核cpu上的多任务。但是从微观上看两个程序的指令是交织着运行的，你的指令之间穿插着我的指令，我的指令之间穿插着你的，在单个周期内只运行了一个指令。这种并发并不能提高计算机的性能，只能提高效率。<br>并行（parallelism）：指严格物理意义上的同时运行，比如多核cpu，两个程序分别运行在两个核上，两者之间互不影响，单个周期内每个程序都运行了自己的指令，也就是运行了两条指令。这样说来并行的确提高了计算机的效率。所以现在的cpu都是往多核方面发展。</p><h1 id="系统调用"><a href="#系统调用" class="headerlink" title="系统调用"></a>系统调用</h1><p>系统调用提供了用户程序与操作系统之间的接口（即系统调用是用户程序和内核交互的接口）。用户程序只在用户态下运行，有时需要访问系统核心功能，这时通过系统调用接口使用系统调用。危险的指令被包装成系统调用，用户程序只能调用而无权自己运行那些危险的指令。<br>系统调用举例：<br>对文件进行写操作，open和write都是系统调用。<br>创建进程fork，vfork等都是系统调用。</p><h1 id="Linux虚拟内存"><a href="#Linux虚拟内存" class="headerlink" title="Linux虚拟内存"></a>Linux虚拟内存</h1><p>为了防止不同进程同一时刻在物理内存中运行而对物理内存的争夺和践踏，采用了虚拟内存。<br>1 每个进程有独立的虚拟地址空间，进程访问的虚拟地址并不是真正的物理地址<br>2 虚拟地址可通过每个进程上页表与物理地址进行映射，获得真正物理地址<br>3 如果虚拟地址对应物理地址不在物理内存中，则产生缺页中断，真正分配物理地址，同时更新进程的页表；如果此时物理内存已耗尽，则根据内存替换算法淘汰部分页面至物理磁盘中。</p><p>虚拟内存技术使得不同进程在运行过程中，它所看到的是自己独自占有了当前系统的4G内存。所有进程共享同一物理内存，每个进程只把自己目前需要的虚拟内存空间映射并存储到物理内存上。 事实上，在每个进程创建加载时，内核只是为进程“创建”了虚拟内存的布局，具体就是初始化进程控制表中内存相关的链表，实际上并不立即就把虚拟内存对应位置的程序数据和代码（比如.text .data段）拷贝到物理内存中，只是建立好虚拟内存和磁盘文件之间的映射就好（叫做存储器映射），等到运行到对应的程序时，才会通过缺页异常，来拷贝数据。还有进程运行过程中，要动态分配内存，比如malloc时，也只是分配了虚拟内存，即为这块虚拟内存对应的页表项做相应设置，当进程真正访问到此数据时，才引发缺页异常。</p><p>优点：<br>1.既然每个进程的内存空间都是一致而且固定的，所以链接器在链接可执行文件时，可以设定内存地址，而不用去管这些数据最终实际的内存地址，这是有独立内存空间的好处<br>2.当不同的进程使用同样的代码时，比如库文件中的代码，物理内存中可以只存储一份这样的代码，不同的进程只需要把自己的虚拟内存映射过去就可以了，节省内存<br>3.在程序需要分配连续的内存空间的时候，只需要在虚拟内存空间分配连续空间，而不需要实际物理内存的连续空间，可以利用碎片</p><ol start="4"><li>内存保护：每个进程运行在各自的虚拟内存地址空间，互相不能干扰对方。<br>虚拟内存的代价：</li><li>虚存的管理需要建立很多数据结构，这些数据结构要占用额外的内存</li><li>虚拟地址到物理地址的转换，增加了指令的执行时间。</li><li>页面的换入换出需要磁盘I/O，这是很耗时的</li><li>如果一页中只有一部分数据，会浪费内存。<h1 id="操作系统中的页表寻址"><a href="#操作系统中的页表寻址" class="headerlink" title="操作系统中的页表寻址"></a>操作系统中的页表寻址</h1>页式内存管理，内存分成固定长度的一个个页片。操作系统为每一个进程维护了一个从虚拟地址到物理地址的映射关系的数据结构，叫页表，页表的内容就是该进程的虚拟地址到物理地址的一个映射。页表中的每一项都记录了这个页的基地址。通过页表，由逻辑地址的高位部分先找到逻辑地址对应的页基地址，再由页基地址偏移一定长度就得到最后的物理地址，偏移的长度由逻辑地址的低位部分决定。一般情况下，这个过程都可以由硬件完成，所以效率还是比较高的。页式内存管理的优点就是比较灵活，内存管理以较小的页为单位，方便内存换入换出和扩充地址空间。<h1 id="缺页中断"><a href="#缺页中断" class="headerlink" title="缺页中断"></a>缺页中断</h1>malloc()和mmap()等内存分配函数，在分配时只是建立了进程虚拟地址空间，并没有分配虚拟内存对应的物理内存。当进程访问这些没有建立映射关系的虚拟内存时，处理器自动触发一个缺页异常。<br>缺页中断：在请求分页系统中，可以通过查询页表中的状态位来确定所要访问的页面是否存在于内存中。每当所要访问的页面不在内存时，会产生一次缺页中断，此时操作系统会根据页表中的外存地址在外存中找到所缺的一页，将其调入内存。<br>缺页本身是一种中断，与一般的中断一样，需要经过4个处理步骤：<br>1、保护CPU现场<br>2、分析中断原因<br>3、转入缺页中断处理程序进行处理<br>4、恢复CPU现场，继续执行<br>但是缺页中断是由于所要访问的页面不存在于内存时，由硬件所产生的一种特殊的中断，因此，与一般的中断存在区别：<br>1、在指令执行期间产生和处理缺页中断信号<br>2、一条指令在执行期间，可能产生多次缺页中断<br>3、缺页中断返回是，执行产生中断的一条指令，而一般的中断返回是，执行下一条指令。</li></ol><h1 id="malloc-的内存都有相应的-free-，就不会出现内存泄露了吗"><a href="#malloc-的内存都有相应的-free-，就不会出现内存泄露了吗" class="headerlink" title="malloc 的内存都有相应的 free ，就不会出现内存泄露了吗"></a>malloc 的内存都有相应的 free ，就不会出现内存泄露了吗</h1><p>free 的内存:<br>1 malloc 使用 mmap 分配的内存 ( 大于 128k) ， free 会调用 unmmap 系统调用马上还给 OS ，实现真正释放。<br>2 堆内的内存，只有释放堆顶的空间，同时堆顶总连续空闲空间大于 128k 才使用 sbrk(-SIZE) 回收内存，真正归还 OS 。<br>3 堆内的空闲空间，是不会归还给 OS 的。</p><p>狭义上的内存泄露是指 malloc 的内存，没有 free ，导致内存浪费，直到程序结束。而广义上的内存泄露就是进程使用内存量不断增加，或大大超出系统原设计的上限。free 了的堆空闲空间并不会马上归还 OS ，并且堆内的空洞（碎片）更是很难真正释放，除非空洞成为了新的堆顶。<br>因此，随着系统频繁地 malloc 和 free ，尤其对于小块内存，堆内将产生越来越多不可用的碎片，导致“内存泄露”。而这种“泄露”现象使用 valgrind 是无法检测出来的。<br>因此，当我们写程序时，不能完全依赖 glibc 的 malloc 和 free 的实现。更好方式是建立属于进程的内存池，即一次分配 (malloc) 大块内存，小内存从内存池中获得，当进程结束或该块内存不可用时，一次释放 (free) ，可大大减少碎片的产生。</p><h1 id="操作系统中的结构体对齐，字节对齐"><a href="#操作系统中的结构体对齐，字节对齐" class="headerlink" title="操作系统中的结构体对齐，字节对齐"></a>操作系统中的结构体对齐，字节对齐</h1><p>1、原因：<br>1）平台原因（移植原因）：不是所有的硬件平台都能访问任意地址上的任意数据的；某些硬件平台只能在某些地址处取某些特定类型的数据，否则抛出硬件异常。<br>2）性能原因：数据结构（尤其是栈）应该尽可能地在自然边界上对齐。原因在于，为了访问未对齐的内存，处理器需要作两次内存访问；而对齐的内存访问仅需要一次访问。<br><strong>2、规则</strong><br>1）数据成员对齐规则：结构(struct)(或联合(union))的数据成员，第一个数据成员放在offset为0的地方，以后每个数据成员的对齐按照#pragma pack指定的数值和这个数据成员自身长度中，比较小的那个进行。<br>2）结构(或联合)的整体对齐规则：在数据成员完成各自对齐之后，结构(或联合)本身也要进行对齐，对齐将按照#pragma pack指定的数值和结构(或联合)最大数据成员长度中，比较小的那个进行。<br>3）结构体作为成员：如果一个结构里有某些结构体成员，则结构体成员要从其内部最大元素大小的整数倍地址开始存储。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 字节对齐</span></span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">SByte1</span>   </span></span><br><span class="line"><span class="class">&#123;</span>   </span><br><span class="line">    <span class="keyword">double</span> d;    <span class="comment">// 长度8，偏移量为0；存放位置区间[0,7]</span></span><br><span class="line">    <span class="keyword">char</span> j;      <span class="comment">// 长度1，偏移量为8；存放位置区间[8]</span></span><br><span class="line">    <span class="keyword">int</span> a;       <span class="comment">// 长度4，偏移量12；存放位置区间[12，15] </span></span><br><span class="line">&#125;;    </span><br><span class="line"><span class="keyword">sizeof</span>(SByte1);  <span class="comment">// = 16   </span></span><br><span class="line">  </span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">SByte2</span>   </span></span><br><span class="line"><span class="class">&#123;</span>         </span><br><span class="line">    <span class="keyword">char</span> j;      <span class="comment">// 长度1，偏移量为0；存放位置区间[0,1]</span></span><br><span class="line">    <span class="keyword">double</span> d;    <span class="comment">// 长度8，偏移量8；存放位置区间[8,15]  </span></span><br><span class="line">    <span class="keyword">int</span> a;       <span class="comment">// 长度4，偏移量16；存放位置区间[16,19]</span></span><br><span class="line">&#125;;    </span><br><span class="line"><span class="keyword">sizeof</span>(SByte2);  <span class="comment">// = 24，为了凑成8的倍数，填充20~23  </span></span><br><span class="line"></span><br><span class="line"><span class="comment">//可以通过#pragma pack(n)来设定变量以n字节对齐方式，n=1,2,4,8,16</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">pragma</span> pack(push) <span class="comment">//保存对齐状态   </span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">pragma</span> pack(4)    <span class="comment">//设定为4字节对齐   </span></span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">CByte</span>   </span></span><br><span class="line"><span class="class">&#123;</span>   </span><br><span class="line"><span class="keyword">char</span> c;       <span class="comment">//长度1 &lt; 4 按1对齐；偏移量为0；存放位置区间[0,1]</span></span><br><span class="line"><span class="keyword">double</span> d;     <span class="comment">//长度8 &gt; 4 按4对齐；偏移量为4；存放位置区间[4,11] </span></span><br><span class="line"><span class="keyword">int</span> i;        <span class="comment">//长度4 = 4 按4对齐；偏移量为12；存放位置区间[12,15]</span></span><br><span class="line">&#125;;   </span><br><span class="line"><span class="meta">#<span class="meta-keyword">pragma</span> pack(pop)  <span class="comment">//恢复对齐状态   </span></span></span><br><span class="line"><span class="keyword">sizeof</span>(CByte); <span class="comment">// = 16  </span></span><br><span class="line"></span><br><span class="line"><span class="meta">#<span class="meta-keyword">pragma</span> pack(2)</span></span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">AA</span> &#123;</span></span><br><span class="line"><span class="keyword">int</span> a; <span class="comment">//长度4 &gt; 2 按2对齐；偏移量为0；存放位置区间[0,3]</span></span><br><span class="line"><span class="keyword">char</span> b; <span class="comment">//长度1 &lt; 2 按1对齐；偏移量为4；存放位置区间[4]</span></span><br><span class="line"><span class="keyword">short</span> c; <span class="comment">//长度2 = 2 按2对齐；偏移量要提升到2的倍数6；存放位置区间[6,7]</span></span><br><span class="line"><span class="keyword">char</span> d; <span class="comment">//长度1 &lt; 2 按1对齐；偏移量为7；存放位置区间[8]；共九个字节</span></span><br><span class="line">&#125;;</span><br><span class="line"><span class="meta">#<span class="meta-keyword">pragma</span> pack()</span></span><br></pre></td></tr></table></figure><h1 id="软链接和硬链接区别"><a href="#软链接和硬链接区别" class="headerlink" title="软链接和硬链接区别"></a>软链接和硬链接区别</h1><p>为了解决文件共享问题，Linux引入了软链接和硬链接。除了为Linux解决文件共享使用，还带来了隐藏文件路径、增加权限安全及节省存储等好处。<br>硬链接：若1个inode号对应多个文件名<br>软连接：若文件用户数据块中存放的内容是另一个文件的路径名指向<br>1，软链接可以理解成快捷方式。它和windows下的快捷方式的作用是一样的。<br>2，硬链接等于cp -p 加 同步更新。<br>对文件jys建立软链接和硬链接：<br> <img src="https://img-blog.csdnimg.cn/20191107160021520.png" alt="在这里插入图片描述"><br>软链接：ln -s 源文件 目标文件<br>硬链接：ln 源文件 目标文件<br><strong>区别:</strong><br>软链接文件的大小和创建时间和源文件不同。硬链接文件和源文件的大小和创建时间一样。<br>删除源文件多软链接和硬链接的影响：查看软链接文件，查看的文件不存在。但是删除源文件，硬链接文件还可以查看。<br>i节点是文件和目录的唯一标识，删除了jys,只是删除了从920586到jys的映射关系，不影响它和jys.hard的映射关系。此图也解释了硬链接的同步更新，对源文件修改，操作系统只认i节点，于是操作系统就将修改内容写进所有i节点相同名字不同的文件。<br> <img src="https://img-blog.csdnimg.cn/20191107160816996.png" alt="在这里插入图片描述"></p><h1 id="什么是大端小端以及如何判断大端小端"><a href="#什么是大端小端以及如何判断大端小端" class="headerlink" title="什么是大端小端以及如何判断大端小端"></a>什么是大端小端以及如何判断大端小端</h1><p>小端就是低位字节放在内存的低地址端, 大端就是低位字节放在内存的高地址端</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">JudgeSystem</span><span class="params">(<span class="keyword">void</span>)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line"><span class="keyword">int</span> a = <span class="number">1</span>;</span><br><span class="line"><span class="keyword">char</span> * p = (<span class="keyword">char</span> *)&amp;a;</span><br><span class="line"> </span><br><span class="line"><span class="comment">//如果是小端则返回1，如果是大端则返回0</span></span><br><span class="line"><span class="keyword">return</span> *p;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>或者根据联合体来判断该系统是大端还是小端。因为联合体变量总是从低地址存储。<br><img src="https://img-blog.csdnimg.cn/20191107161444522.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZmY2pqaHY=,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"></p><h1 id="Linux-常用命令"><a href="#Linux-常用命令" class="headerlink" title="Linux 常用命令"></a>Linux 常用命令</h1><p><strong>ls命令</strong><br>ls –l  # 以详情模式(long listing fashion)列出文件夹的内容。<br>ls –a  # 列出文件夹里的所有内容，包括以”.”开头的隐藏文件。<br><strong>mkdir命令</strong><br>“mkdir”(Make directory)命令在命名路径下创建新的目录。然而如果目录已经存在了，那么它就会返回一个错误信息”不能创建文件夹，文件夹已经存在了”(“cannot create folder, folder already exists”)<br><strong>grep命令</strong><br>通常用于对一些命令的输出进行筛选加工<br>grep [-acinv] [–color=auto] ‘查找字符串’ filename<br>ls -l | grep -i file  # 把ls -l的输出中包含字母file（不区分大小写）的内容输出<br><strong>cp命令</strong><br>cp -a file1 file2 #连同文件的所有特性把文件file1复制成文件file2<br>cp file1 file2 file3 dir #把文件file1、file2、file3复制到目录dir中<br><strong>mv命令</strong><br>mv file1 file2 file3 dir # 把文件file1、file2、file3移动到目录dir中<br>mv file1 file2 # 把文件file1重命名为file2<br><strong>rm命令</strong><br>rm -i file # 删除文件file，在删除之前会询问是否进行该操作<br>rm -fr dir # 强制删除目录dir中的所有文件<br><strong>ps命令</strong><br>ps aux # 查看系统所有的进程数据<br><strong>vim命令</strong><br>用于文本编辑<br>输入 i ，退出命令模式，进入INSERT模式<br>开始修改内容……<br>按 esc 键，退出INSERT模式，进入命令模式<br>再输入 :wq，保存文件，退出vi编辑器<br><strong>time命令</strong><br>$ time date<br>Sun Mar 26 22:45:34 GMT-8 2006  # 命令”date”的执行结果<br>real    0m0.136s  # 实际时间<br>user    0m0.010s  # 用户CPU时间<br>sys     0m0.070s  # 系统CPU时间<br><strong>touch 命令</strong><br>“touch”命令代表了将文件的访问和修改时间更新为当前时间。touch命令只会在文件不存在的时候才会创建它。如果文件已经存在了，它会更新时间戳，但是并不会改变文件的内容。<br><strong>chmod 命令</strong><br>chmod 777 abc.sh  # 为拥有者，用户所在组和其它用户提供读，写，执行权限。<br><strong>tar命令</strong><br>tar -zxvf abc.tar.gz   # (记住’z’代表了.tar.gz)<br>tar -jxvf abc.tar.bz2  # (记住’j’代表了.tar.bz2) 压缩的更好但是也更慢</p><h1 id="awk的使用"><a href="#awk的使用" class="headerlink" title="awk的使用"></a>awk的使用</h1><p>awk [-F  field-separator]  ‘commands’  input-file(s)<br>1、找到当前文件夹下所有的文件和子文件夹,并显示文件大小<br><img src="https://img-blog.csdnimg.cn/20191107162441362.png" alt="在这里插入图片描述"><br>$ ls –l | awk ‘{print $5 “\t” $9}’</p><p>2、找到当前文件夹下所有的文件和子文件夹，并显示文件大小，并显示排序<br>&gt; ls -l | awk ‘BEGIN {COUNT = -1; print “BEGIN COUNT”}<br>{COUNT = COUNT + 1; print COUNT”\t”$5”\t”$9}<br>END {print “END, COUNT = “COUNT}’</p><p>3、找到当前文件夹下所有的子文件夹,并显示排序<br>&gt; ls -l | awk ‘BEGIN {print “BEGIN COUNT”} /4096/{print NR”\t”$5”\t”$9}<br>END {print “END”}’</p><h1 id="Linux下怎么得到一个文件的100到200行"><a href="#Linux下怎么得到一个文件的100到200行" class="headerlink" title="Linux下怎么得到一个文件的100到200行"></a>Linux下怎么得到一个文件的100到200行</h1><p>sed -n ‘100,200p’ inputfile<br>awk ‘NR&gt;=100&amp;&amp;NR&lt;=200{print}’ inputfile<br>head -200 inputfile|tail -100</p><h1 id="OS缺页置换算法"><a href="#OS缺页置换算法" class="headerlink" title="OS缺页置换算法"></a>OS缺页置换算法</h1><p>当访问一个内存中不存在的页，并且内存已满，则需要从内存中调出一个页或将数据送至磁盘对换区，替换一个页，这种现象叫做缺页置换。当前操作系统最常采用的缺页置换算法如下：<br><strong>先进先出(FIFO)算法：</strong>置换最先调入内存的页面，即置换在内存中驻留时间最久的页面。按照进入内存的先后次序排列成队列，从队尾进入，从队首删除。<br><strong>最近最少使用（LRU）算法:</strong> 置换最近一段时间以来最长时间未访问过的页面。根据程序局部性原理，刚被访问的页面，可能马上又要被访问；而较长时间内没有被访问的页面，可能最近不会被访问。<br>当前最常采用的就是LRU算法。</p><h1 id="虚拟内存置换的方式"><a href="#虚拟内存置换的方式" class="headerlink" title="虚拟内存置换的方式"></a>虚拟内存置换的方式</h1><p>比较常见的内存替换算法有：FIFO，LRU，LFU，LRU-K，2Q。<br>1、FIFO（先进先出淘汰算法）<br>思想：最近刚访问的，将来访问的可能性比较大。<br>实现：使用一个队列，新加入的页面放入队尾，每次淘汰队首的页面，即最先进入的数据，最先被淘汰。<br>弊端：无法体现页面冷热信息<br>2、LFU（最不经常访问淘汰算法）<br>思想：如果数据过去被访问多次，那么将来被访问的频率也更高。<br>实现：每个数据块一个引用计数，所有数据块按照引用计数排序，具有相同引用计数的数据块则按照时间排序。每次淘汰队尾数据块。<br>开销：排序开销。<br>弊端：缓存颠簸。<br>3、LRU（最近最少使用替换算法）<br>思想：如果数据最近被访问过，那么将来被访问的几率也更高。<br>实现：使用一个栈，新页面或者命中的页面则将该页面移动到栈底，每次替换栈顶的缓存页面。<br>优点：LRU算法对热点数据命中率是很高的。<br>缺陷：<br>1）缓存颠簸，当缓存（1，2，3）满了，之后数据访问（0，3，2，1，0，3，2，1。。。）。<br>2）缓存污染，突然大量偶发性的数据访问，会让内存中存放大量冷数据。<br>4、LRU-K（LRU-2、LRU-3）<br>思想：最久未使用K次淘汰算法。<br>LRU-K中的K代表最近使用的次数，因此LRU可以认为是LRU-1。LRU-K的主要目的是为了解决LRU算法“缓存污染”的问题，其核心思想是将“最近使用过1次”的判断标准扩展为“最近使用过K次”。<br>相比LRU，LRU-K需要多维护一个队列，用于记录所有缓存数据被访问的历史。只有当数据的访问次数达到K次的时候，才将数据放入缓存。当需要淘汰数据时，LRU-K会淘汰第K次访问时间距当前时间最大的数据。<br>实现：<br>1）数据第一次被访问，加入到访问历史列表；<br>2）如果数据在访问历史列表里后没有达到K次访问，则按照一定规则（FIFO，LRU）淘汰；<br>3）当访问历史队列中的数据访问次数达到K次后，将数据索引从历史队列删除，将数据移到缓存队列中，并缓存此数据，缓存队列重新按照时间排序；<br>4）缓存数据队列中被再次访问后，重新排序；<br>5）需要淘汰数据时，淘汰缓存队列中排在末尾的数据，即：淘汰“倒数第K次访问离现在最久”的数据。<br>针对问题：<br>LRU-K的主要目的是为了解决LRU算法“缓存污染”的问题，其核心思想是将“最近使用过1次”的判断标准扩展为“最近使用过K次”。<br>5、2Q<br>类似LRU-2。使用一个FIFO队列和一个LRU队列。<br>实现<br>1）新访问的数据插入到FIFO队列；<br>2）如果数据在FIFO队列中一直没有被再次访问，则最终按照FIFO规则淘汰；<br>3）如果数据在FIFO队列中被再次访问，则将数据移到LRU队列头部；<br>4）如果数据在LRU队列再次被访问，则将数据移到LRU队列头部；<br>5）LRU队列淘汰末尾的数据。<br>针对问题：LRU的缓存污染<br>弊端：<br>当FIFO容量为2时，访问负载是：ABCABCABC会退化为FIFO，用不到LRU。</p><h1 id="linux常见的调度算法"><a href="#linux常见的调度算法" class="headerlink" title="linux常见的调度算法"></a>linux常见的调度算法</h1><p>调度算法：根据系统的资源分配策略所规定的资源分配算法。调度，当有多个进程(或多个进程发出的请求)要使用这些资源时，因为资源的有限性，必须按照一定的原则选择进程(请求)来占用资源。<br>1、先来先去服务（队列）<br>如果早就绪的进程排在就绪队列的前面，迟就绪的进程排在就绪队列的后面，那么先来先服务(FCFS: first come first service)总是把当前处于就绪队列之首的那个进程调度到运行状态。也就说，它只考虑进程进入就绪队列的先后，而不考虑它的下一个CPU周期的长短及其他因素。<br>有利于长作业以及CPU繁忙的作业，不利于短作业以及I/O繁忙的作业<br>2、最短优先（优先队列）<br>对预计执行时间短的作业（进程）优先分派处理机.通常后来的短作业不抢先正在执行的作业.<br>比FCFS缩短作业的等待时间；长作业的运行得不到保证。<br>3、轮转法(RoundRobin)<br>将系统中所有的就绪进程按照FCFS原则，排成一个队列。每次调度时将CPU分派给队首进程，让其执行一个时间片。时间片的长度从几个ms到几百ms。当进程用完分给它的时间片后，调度程序便停止该进程的运行，并把它放入就绪队列的末尾。<br>让每个进程在就绪队列中的等待时间与享受服务的时间成正比例。<br>4、多级反馈队列算法<br>设置多个就绪队列，分别赋予不同的优先级。新进程进入内存后，先投入队列1的末尾，按FCFS算法调度;若按队列1一个时间片未能执行完，则降低投入到队列2的末尾，同样按FCFS算法调度;如此下去，降低到最后的队列，则按”时间片轮转”算法调度直到完成。仅当较高优先级的队列为空，才调度较低优先级的队列中的进程执行。如果进程执行时有新进程进入较高优先级的队列，则抢先执行新进程，并把被抢先的进程投入原队列的末尾。<br>优点：<br>为提高系统吞吐量和缩短平均周转时间而照顾短进程。<br>为获得较好的I/O设备利用率和缩短响应时间而照顾I/O型进程。<br>不必估计进程的执行时间，动态调节。</p><h1 id="linux文件系统"><a href="#linux文件系统" class="headerlink" title="linux文件系统"></a>linux文件系统</h1><p>Linux ext2, ext3, ext4 文件系统：<br>Ext，全称extended file system, extfs，即扩展文件系统，Ext2就代表第二代文件扩展系统，<br>Linux ext2/ext3文件系统使用索引节点来记录文件信息，作用像windows的文件分配表。索引节点是一个结构，它包含了一个文件的长度、创建及修改时间、权限、所属关系、磁盘中的位置等信息。一个文件系统维护了一个索引节点的数组，每个文件或目录都与索引节点数组中的唯一一个元素对应。<br>Ext3/Ext4，是Ext2的升级版，只不过为了快速恢复文件系统，减少一致性检查的时间，增加了日志功能，所以Ext2被称为索引式文件系统，而Ext3/Ext4被称为日志式文件系统。</p><p>Ext家族是Linux支持度最广、最完整的文件系统，当我们格式化磁盘后，就已经为我们规划好了所有的inode/block/metadate等数据，这样系统可以直接使用，不需要再进行动态的配置，这也是它最优秀的特点，不过这也是它最显著的缺点，磁盘容量越大，格式化越慢，centos7.x已经选用xfs作为默认文件系统，xfs是一种适合大容量磁盘和处理巨型文件的文件系统。<br><img src="https://img-blog.csdnimg.cn/2019110717050610.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZmY2pqaHY=,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"><br>虚拟文件系统（Virtual File System, 简称 VFS）， 是 Linux 内核中的一个软件层，用于给用户空间的程序提供文件系统接口。正是由于在内核中引入了VFS，跨文件系统的文件操作才能实现，“一切皆是文件” 的口号才能承诺。</p><table><thead><tr><th>目录</th><th>描述</th></tr></thead><tbody><tr><td>/ (root 文件系统)</td><td>root 文件系统是文件系统的顶级目录。</td></tr><tr><td>/bin</td><td>/bin 目录包含用户的可执行文件。</td></tr><tr><td>/boot</td><td>包含启动 Linux 系统所需要的静态引导程序和内核可执行文件以及配置文件。</td></tr><tr><td>/dev</td><td>该目录包含每一个连接到系统的硬件设备的设备文件。这些文件不是设备驱动，而是代表计算机上的每一个计算机能够访问的设备。</td></tr><tr><td>/etc</td><td>包含主机计算机的本地系统配置文件。</td></tr><tr><td>/home</td><td>主目录存储用户文件，每一个用户都有一个位于 /home 目录中的子目录（作为其主目录）。</td></tr><tr><td>/lib</td><td>包含启动系统所需要的共享库文件。</td></tr><tr><td>/media</td><td>一个挂载外部可移动设备的地方，比如主机可能连接了一个 USB 驱动器。</td></tr><tr><td>/mnt</td><td>一个普通文件系统的临时挂载点（如不可移动的介质），当管理员对一个文件系统进行修复或在其上工作时可以使用。</td></tr><tr><td>/opt</td><td>可选文件，比如供应商提供的应用程序应该安装在这儿。</td></tr><tr><td>/root</td><td>这不是 root（/）文件系统。它是 root 用户的主目录。</td></tr><tr><td>/sbin</td><td>系统二进制文件。这些是用于系统管理的可执行文件。</td></tr><tr><td>/tmp</td><td>临时目录。被操作系统和许多程序用来存储临时文件。用户也可能临时在这儿存储文件。注意，存储在这儿的文件可能在任何时候在没有通知的情况下被删除。</td></tr><tr><td>/usr</td><td>该目录里面包含可共享的、只读的文件，包括可执行二进制文件和库、man 文件以及其他类型的文档。</td></tr><tr><td>/var</td><td>可变数据文件存储在这儿。这些文件包括日志文件、MySQL 和其他数据库的文件、Web 服务器的数据文件、邮件以及更多。</td></tr></tbody></table><p>《深入理解linux内核》第12章：虚拟文件系统 以及 第18章：Ext2和Ext3文件系统 以及 第16章：访问文件，可以让你深入了解linux文件系统</p><h1 id="如何修改文件最大句柄数"><a href="#如何修改文件最大句柄数" class="headerlink" title="如何修改文件最大句柄数"></a>如何修改文件最大句柄数</h1><p>linux默认最大文件句柄数是1024个，在linux服务器文件并发量比较大的情况下，系统会报”too many open files”的错误。故在linux服务器高并发调优时，往往需要预先调优Linux参数，修改Linux最大文件句柄数。<br>有两种方法：</p><ol><li>ulimit -n &lt;可以同时打开的文件数&gt;，将当前进程的最大句柄数修改为指定的参数（注：该方法只针对当前进程有效，重新打开一个shell或者重新开启一个进程，参数还是之前的值）<br>首先用<code>ulimit -a</code>查询Linux相关的参数，如下所示：<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="function">max locked <span class="title">memory</span>       <span class="params">(kbytes, -l)</span> 64</span></span><br><span class="line"><span class="function">max memory <span class="title">size</span>         <span class="params">(kbytes, -m)</span> unlimited</span></span><br><span class="line"><span class="function">open <span class="title">files</span>                      <span class="params">(-n)</span> 1024</span></span><br></pre></td></tr></table></figure></li></ol><p>其中，open files就是最大文件句柄数，默认是1024个。<br>修改Linux最大文件句柄数：  <code>ulimit -n 2048</code>， 将最大句柄数修改为 2048个。</p><ol start="2"><li>对所有进程都有效的方法，修改Linux系统参数<br>vi /etc/security/limits.conf 添加</li></ol><p>*　　soft　　nofile　　65536<br>*　　hard　　nofile　　65536<br>将最大句柄数改为65536<br>修改以后保存，注销当前用户，重新登录，修改后的参数就生效了</p><h1 id="System-V、Posix-IPC"><a href="#System-V、Posix-IPC" class="headerlink" title="System V、Posix IPC"></a>System V、Posix IPC</h1><p>Posix是“可移植操作系统接口（Portable Operating System Interface ）的首字母简写，但它并不是一个单一的标准，而是IEEE开发的一系列标准，System v是Unix操作系统众多版本的一个分支。将这两个名词放在一起讨论的一般是在Linux的进程间通信中，如在信号量编程中，有Posix信号量和System V信号量。<br>Posix信号量是基于内存的，即信号量值是放在共享内存中的。而System v信号量测试基于内核的，它放在内核里面，相同点都是它们都可以用于进程或者线程间的同步。<br>“Posix 信号量”，指的是单个计数信号量；“System v信号量”时，所指的是计数信号量集。</p><h1 id="死锁产生的四个必要条件及如何预防"><a href="#死锁产生的四个必要条件及如何预防" class="headerlink" title="死锁产生的四个必要条件及如何预防"></a>死锁产生的四个必要条件及如何预防</h1><p>死锁是指两个或两个以上进程在执行过程中，因争夺资源而造成的下相互等待的现象。<br><strong>死锁发生的四个必要条件：</strong><br>互斥：一个资源每次只能被一个进程使用。<br>请求与保持：一个进程因请求资源而阻塞时，对已获得的资源保持不放。<br>不可剥夺: 进程已获得的资源，在末使用完之前，不能强行剥夺，只能在使用后自己释放<br>循环等待: 若干进程之间形成一种头尾相接的循环等待资源关系。</p><p>通过破坏死锁产生的4个必要条件来预防死锁，由于资源互斥是资源使用的固有特性是无法改变的。<br>破坏”请求与保持条件“：<br>第一种方法静态分配：每个进程在开始执行时就申请他所需要的全部资源。<br>第二种是动态分配：每个进程在申请所需要的资源时他本身不占用系统资源。<br>破坏“不可剥夺”条件：<br>一个进程不能获得所需要的全部资源时便处于等待状态，等待期间他占有的资源将被隐式的释放重新加入到系统的资源列表中，可以被其他的进程使用。<br>破坏“循环等待”条件：<br>采用资源有序分配，将系统中的所有资源顺序编号，将紧缺的，稀少的采用较大的编号，每个进程按编号递增的请求资源，释放则相反</p><h1 id="Linux的4种锁机制"><a href="#Linux的4种锁机制" class="headerlink" title="Linux的4种锁机制"></a>Linux的4种锁机制</h1><p>互斥锁：mutex，用于保证在任何时刻，都只能有一个线程访问该对象。当获取锁操作失败时，线程会进入睡眠，等待锁释放时被唤醒<br>读写锁：rwlock，分为读锁和写锁。处于读操作时，可以允许多个线程同时获得读操作。但是同一时刻只能有一个线程可以获得写锁。其它获取写锁失败的线程都会进入睡眠状态，直到写锁释放时被唤醒。 注意：写锁会阻塞其它读写锁。当有一个线程获得写锁在写时，读锁也不能被其它线程获取；写者优先于读者（一旦有写者，则后续读者必须等待，唤醒时优先考虑写者）。适用于读取数据的频率远远大于写数据的频率的场合。<br>自旋锁：spinlock，在任何时刻同样只能有一个线程访问对象。但是当获取锁操作失败时，不会进入睡眠，而是会在原地自旋，直到锁被释放。这样节省了线程从睡眠状态到被唤醒期间的消耗，在加锁时间短暂的环境下会极大的提高效率。但如果加锁时间过长，则会非常浪费CPU资源。<br>RCU：即read-copy-update，在修改数据时，首先需要读取数据，然后生成一个副本，对副本进行修改。修改完成后，再将老数据update成新的数据。使用RCU时，读者几乎不需要同步开销，既不需要获得锁，也不使用原子指令，不会导致锁竞争，因此就不用考虑死锁问题了。而对于写者的同步开销较大，它需要复制被修改的数据，还必须使用锁机制同步并行其它写者的修改操作。在有大量读操作，少量写操作的情况下效率非常高。<br>互斥锁和读写锁的区别：<br>1）读写锁区分读者和写者，而互斥锁不区分<br>2）互斥锁同一时间只允许一个线程访问该对象，无论读写；读写锁同一时间内只允许一个写者，但是允许多个读者同时读对象。</p><h1 id="怎么实现线程池"><a href="#怎么实现线程池" class="headerlink" title="怎么实现线程池"></a>怎么实现线程池</h1><p>1.设置一个生产者消费者队列，作为临界资源<br>2.初始化n个线程，并让其运行起来，加锁去队列取任务运行<br>3.当任务队列为空的时候，所有线程阻塞<br>4.当生产者队列来了一个任务后，先对队列加锁，把任务挂在到队列上，然后使用条件变量去通知阻塞中的一个线程</p><h1 id="如何实现linux的高并发，线程池的思想"><a href="#如何实现linux的高并发，线程池的思想" class="headerlink" title="如何实现linux的高并发，线程池的思想"></a>如何实现linux的高并发，线程池的思想</h1><p>线程池：<br>线程的开启和回收是要消耗系统性能的，对于大量使用线程的场景，使用线程池来进行管理，实现单个线程的复用，提高并发效率。<br>线程池里面的线程都是现成的而且能够重复使用，我们不需要临时创建大量线程，然后在任务结束时又销毁大量线程。一个理想的线程池能够合理地动态调节池内线程数量，既不会因为线程过少而导致大量任务堆积，也不会因为线程过多了而增加额外的系统开销。</p><p><strong>线程池的处理流程如下：</strong><br>1、判断线程池里的工作线程（线程池中实际执行任务的线程）是否都在执行任务，如果不是（工作线程空闲或者还有工作线程没有被创建）则创建一个新的工作线程来执行任务。如果核心线程都在执行任务，则进入下个流程。<br>2、线程池判断工作队列（用来存放没有处理的任务，提供一种缓冲机制）是否已满，如果工作队列没有满，则将新提交的任务存储在这个工作队列里。如果工作队列满了，则进入下个流程。<br>3、判断线程池里的线程是否都处于工作状态（线程的闲与忙的状态是通过互斥量实现的），如果没有，则创建一个新的工作线程来执行任务。如果已经满了，则交给饱和策略来处理这个任务。<br>因为这里涉及到多个线程同时访问一个队列的问题，所以我们需要互斥锁来保护队列</p><h1 id="生产者消费者并发程序"><a href="#生产者消费者并发程序" class="headerlink" title="生产者消费者并发程序"></a>生产者消费者并发程序</h1><p>死循环+来连接时新建线程的方法效率有点低，怎么改进？<br>提前创建好一个线程池，用生产者消费者模型，创建一个任务队列，队列作为临界资源，有了新连接，就挂在到任务队列上，队列为空所有线程睡眠。改进死循环：使用select epoll这样的技术。<br><strong>生产者消费者并发程序要求能够写得出来</strong><br>生产者（producer）和消费者（consumer）问题是并发处理中最常见的一类问题，是一个多线程同步问题的经典案例。<br>有一个或者多个生产者产生某种类型的数据，并放置在固定大小的缓冲区中，一个消费者从缓冲区中取数据，每次取一项。任何时候，只有一个生产者或者消费者可以访问缓冲区；同时，消费者只能在缓冲区不为空的时候从缓冲区中读数据，生产者只能在缓冲区不为满的时候向缓冲区写入数据。<br>第一是缓冲区的互斥访问问题，任意时刻最多只能有一个线程访问缓冲区，Linux下可以使用互斥量pthread_mutex_t mutex对访问缓冲区的临界区代码进行保护。<br>第二是生产者和消费者对缓冲区访问的同步问题，生产者在缓冲区满时不能向缓冲区中写入数据，同时消费者在缓冲区空时不能读取数据，这里采用两个信号量sem_t room_sem（表示缓冲区有可用空间）和sem_t product_sem（表示缓冲区有可用产品）来对缓冲区进行同步。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string">&lt;stdio.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string">&lt;stdlib.h&gt; </span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string">&lt;unistd.h&gt; // POSIX 操作系统 API 的访问功能</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string">&lt;pthread.h&gt; //线程</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string">&lt;semaphore.h&gt; //信号量</span></span></span><br><span class="line"> </span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> PRODUCER_NUM 5 <span class="comment">//生产者数目</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> CONSUMER_NUM 5 <span class="comment">//消费者数目</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> POOL_SIZE  11  <span class="comment">//缓冲池大小</span></span></span><br><span class="line"><span class="keyword">int</span> pool[POOL_SIZE];  <span class="comment">//缓冲区</span></span><br><span class="line"><span class="keyword">int</span> head=<span class="number">0</span>; <span class="comment">//缓冲池读取指针</span></span><br><span class="line"><span class="keyword">int</span> rear=<span class="number">0</span>; <span class="comment">//缓冲池写入指针</span></span><br><span class="line"><span class="keyword">sem_t</span> room_sem;   <span class="comment">//同步信号量，表示缓冲区有可用空间</span></span><br><span class="line"><span class="keyword">sem_t</span> product_sem;    <span class="comment">//同步信号量，表示缓冲区有可用产品</span></span><br><span class="line"><span class="keyword">pthread_mutex_t</span> mutex; <span class="comment">//互斥量</span></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">producer_fun</span><span class="params">(<span class="keyword">void</span> *arg)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">  <span class="keyword">while</span> (<span class="number">1</span>)</span><br><span class="line">  &#123;</span><br><span class="line">    sleep(<span class="number">1</span>);</span><br><span class="line">    sem_wait(&amp;room_sem);</span><br><span class="line">    pthread_mutex_lock(&amp;mutex);</span><br><span class="line">    <span class="comment">//生产者往缓冲池中写入数据</span></span><br><span class="line">    pool[rear] = <span class="number">1</span>;</span><br><span class="line">    rear = (rear + <span class="number">1</span>) % POOL_SIZE;</span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">"producer %d write to pool\n"</span>, (<span class="keyword">int</span>)arg);</span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">"pool size is %d\n"</span>,(rear-head+POOL_SIZE)%POOL_SIZE);</span><br><span class="line">    pthread_mutex_unlock(&amp;mutex);</span><br><span class="line">    sem_post(&amp;product_sem);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"> </span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">consumer_fun</span><span class="params">(<span class="keyword">void</span> *arg)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">  <span class="keyword">while</span> (<span class="number">1</span>)</span><br><span class="line">  &#123;</span><br><span class="line">    <span class="keyword">int</span> data;</span><br><span class="line">    sleep(<span class="number">10</span>);</span><br><span class="line">    sem_wait(&amp;product_sem);</span><br><span class="line">pthread_mutex_lock(&amp;mutex);</span><br><span class="line">    <span class="comment">//消费者从缓冲池读取数据</span></span><br><span class="line">    data = pool[head];</span><br><span class="line">    head = (head + <span class="number">1</span>) % POOL_SIZE;</span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">"consumer %d read from pool\n"</span>, (<span class="keyword">int</span>)arg);</span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">"pool size is %d\n"</span>,(rear-head+POOL_SIZE)%POOL_SIZE);</span><br><span class="line">    pthread_mutex_unlock(&amp;mutex);</span><br><span class="line">    sem_post(&amp;room_sem);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"> </span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">  <span class="keyword">pthread_t</span> producer_id[PRODUCER_NUM];</span><br><span class="line">  <span class="keyword">pthread_t</span> consumer_id[CONSUMER_NUM];</span><br><span class="line">  pthread_mutex_init(&amp;mutex, <span class="literal">NULL</span>); <span class="comment">//初始化互斥量</span></span><br><span class="line">  <span class="keyword">int</span> ret = sem_init(&amp;room_sem, <span class="number">0</span>, POOL_SIZE<span class="number">-1</span>);  <span class="comment">//初始化信号量room_sem为缓冲池大小</span></span><br><span class="line">  <span class="keyword">if</span> (ret != <span class="number">0</span>)</span><br><span class="line">  &#123;</span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">"sem_init error"</span>);</span><br><span class="line">    <span class="built_in">exit</span>(<span class="number">0</span>);</span><br><span class="line">  &#125;</span><br><span class="line">  ret = sem_init(&amp;product_sem, <span class="number">0</span>, <span class="number">0</span>); <span class="comment">//初始化信号量product_sem为0，开始时缓冲池中没有数据</span></span><br><span class="line">  <span class="keyword">if</span> (ret != <span class="number">0</span>)</span><br><span class="line">  &#123;</span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">"sem_init error"</span>);</span><br><span class="line">    <span class="built_in">exit</span>(<span class="number">0</span>);</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; PRODUCER_NUM; i++)</span><br><span class="line">  &#123;</span><br><span class="line">    <span class="comment">//创建生产者线程</span></span><br><span class="line">    ret =pthread_create(&amp;producer_id[i], <span class="literal">NULL</span>, producer_fun, (<span class="keyword">void</span>*)i);</span><br><span class="line">    <span class="keyword">if</span> (ret != <span class="number">0</span>)</span><br><span class="line">    &#123;</span><br><span class="line">      <span class="built_in">printf</span>(<span class="string">"producer_id error"</span>);</span><br><span class="line">      <span class="built_in">exit</span>(<span class="number">0</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">//创建消费者线程</span></span><br><span class="line">    ret = pthread_create(&amp;consumer_id[i], <span class="literal">NULL</span>, consumer_fun, (<span class="keyword">void</span>*)i);</span><br><span class="line">    <span class="keyword">if</span> (ret != <span class="number">0</span>)</span><br><span class="line">    &#123;</span><br><span class="line">      <span class="built_in">printf</span>(<span class="string">"consumer_id error"</span>);</span><br><span class="line">      <span class="built_in">exit</span>(<span class="number">0</span>);</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;PRODUCER_NUM;i++)</span><br><span class="line">  &#123;</span><br><span class="line">    pthread_join(producer_id[i],<span class="literal">NULL</span>);</span><br><span class="line">    pthread_join(consumer_id[i],<span class="literal">NULL</span>);</span><br><span class="line">  &#125;</span><br><span class="line"> </span><br><span class="line">  <span class="built_in">exit</span>(<span class="number">0</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p> <img src="https://img-blog.csdnimg.cn/20191108152416604.png" alt="在这里插入图片描述"></p><h1 id="惊群效应"><a href="#惊群效应" class="headerlink" title="惊群效应"></a>惊群效应</h1><p>惊群是指多个进程/线程在等待同一资源时，每当资源可用，所有的进程/线程都来竞争资源的现象。<br>春天来了, 公园出现了很多麻雀. 而你恰巧有一个玉米粒. 扔出去，立马无数麻雀过来争抢.而最终只有一只麻雀得到了.而那些没有抢到的麻雀很累…….<br>对于操作系统来说，多个进程/线程在等待同一资源是，也会产生类似的效果，其结果就是每当资源可用，所有的进程/线程都来竞争资源，造成的后果：<br>1）系统对用户进程/线程频繁的做无效的调度、上下文切换，系统系能大打折扣。<br>2）为了确保只有一个线程得到资源，用户必须对资源操作进行加锁保护，进一步加大了系统开销。<br><strong>accept惊群</strong><br>多线程或多进程调用accept就会出现如下情况，当前多个进程阻塞在accept中，此时有客户端连接时，内核就会通知阻塞在accept的所有进程，这时就会造成惊群现象，也就是所有accept都会返回 但是只有一个能拿到有效的文件描述符，其他进程最后都会返回无效描述符。但在linux kernel 版本2.6 以上时，accept惊群的问题已经解决，大致方案就是选一个阻塞在accept的进程返回。<br><strong>epoll惊群</strong><br>但是在IO复用中， select/poll/epoll 还是存在这种现象，其原因就是这些阻塞函数造成了以上同样的问题。<br>如果多个进程/线程阻塞在监听同一个监听socket fd的epoll_wait上，当有一个新的连接到来时，所有的进程都会被唤醒。<br>避免惊群：Nginx采用互斥锁</p><h1 id="fork、vfork、clone的区别"><a href="#fork、vfork、clone的区别" class="headerlink" title="fork、vfork、clone的区别"></a>fork、vfork、clone的区别</h1><p>fork,vfork,clone都是linux的系统调用，主要用来linux创建新的子进程或线程（vfork创造出来的是线程）。<br><strong>fork</strong><br>fork:创建一个和当前进程映像一样的进程可以通过fork( )系统调用：</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;sys/types.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;unistd.h&gt;</span></span></span><br><span class="line"><span class="keyword">pid_t</span> fork(<span class="keyword">void</span>);</span><br></pre></td></tr></table></figure><p>由于fork()后会产生一个和父进程完全相同的子进程，fork函数调用一次返回两次，子进程返回值为0，父进程返回子进程的进程ID，返回类型为pid_t。但子进程在此后多会exec系统调用，出于效率考虑，linux中引入了“写时复制技术-Copy-On-Write”。<br><strong>写时复制</strong> fork子进程完全复制父进程的栈空间，也复制了页表，但没有复制物理页面，所以这时虚拟地址相同，物理地址也相同，但是会把父子共享的页面标记为“只读”，如果父子进程一直对这个页面是同一个页面，直到其中任何一个进程要对共享的页面“写操作”，这时内核会复制一个物理页面给这个进程使用，同时修改页表。而把原来的只读页面标记为“可写”，留给另外一个进程使用。<br>fork之后内核一般会通过将子进程放在队列的前面，以让子进程先执行，因为很多情况下子进程要马上执行exec，会清空栈、堆，这些和父进程共享的空间，加载新的代码段。exec将新程序代码加载（拷贝）到子进程的内存空间，替换掉原有的与父进程一模一样的代码和数据，让子进程空间运行全新的程序。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string">&lt;sys/types.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string">&lt;unistd.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string">&lt;stdio.h&gt;</span></span></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="keyword">pid_t</span> pid;</span><br><span class="line">    pid = fork();</span><br><span class="line">    <span class="keyword">if</span>(pid&lt;<span class="number">0</span>)</span><br><span class="line">        <span class="built_in">printf</span>(<span class="string">"error in fork!\n"</span>);</span><br><span class="line">    <span class="keyword">else</span> <span class="keyword">if</span>(pid == <span class="number">0</span>)</span><br><span class="line">        <span class="built_in">printf</span>(<span class="string">"I am the child process,ID is %d\n"</span>,getpid());</span><br><span class="line">    <span class="keyword">else</span> </span><br><span class="line">        <span class="built_in">printf</span>(<span class="string">"I am the parent process,ID is %d\n"</span>,getpid());</span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>Wait():我们用fork启动一个进程时，子进程就有了自己的生命，并将独立地运行。有时，我们需要知道某个子进程是否已经结束了，我们可以通过wait函数安排父进程在子进程之后结束。wait系统调用会使父进程暂停执行，直到它的一个子进程结束为止。返回的是子进程的PID<br><strong>Vfork</strong><br>在实现写时复制之前，Unix的设计者们就一直很关注在fork后立刻执行exec所造成的地址空间的浪费。BSD的开发者们在3.0的BSD系统中引入了vfork( )系统调用。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;sys/types.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;unistd.h&gt;</span></span></span><br><span class="line"><span class="keyword">pid_t</span> vfork(<span class="keyword">void</span>);</span><br></pre></td></tr></table></figure><p>vfork创建出的子进程（线程）共享了父进程的变量，内存资源不独立，这一次是指针复制，2者的指针指向了同一个内存，所以子进程修改了变量，父进程的变量同样受到了影响。另外由vfork创造出来的子进程还会导致父进程挂起，除非子进程exit或者exec才会唤起父进程。<br>fork和vfork的区别：<br>1.fork( )的子进程拷贝父进程的数据段和代码段；vfork( )的子进程与父进程共享数据段</p><ol start="2"><li>fork( )的父子进程的执行次序不确定；vfork( )保证子进程先运行，在调用exec或exit之前与父进程数据是共享的，在它调用exec或exit之后父进程才可能被调度运行。</li><li>vfork( )保证子进程先运行，在它调用exec或exit之后父进程才可能被调度运行。如果在调用这两个函数之前子进程依赖于父进程的进一步动作，则会导致死锁。</li><li>fork( )当需要改变共享数据段中变量的值，则拷贝父进程。</li></ol><p><strong>clone</strong><br>clone函数功能强大，带了众多参数，因此由他创建的进程要比前面2种方法要复杂。clone可以让你有选择性的继承父进程的资源，你可以选择想vfork一样和父进程共享一个虚存空间，从而使创造的是线程，你也可以不和父进程共享，你甚至可以选择创造出来的进程和父进程不再是父子关系，而是兄弟关系。<br>int clone(int (*fn)(void *), void *child_stack, int flags, void *arg);<br>fn是函数指针，指向程序的指针，child_stack是为子进程分配系统堆栈空间，flags是标志用来描述你需要从父进程继承那些资源，arg就是传给子进程的参数<br>CLONE_VFORK     父进程被挂起，直至子进程释放虚拟内存资源<br>CLONE_VM        子进程与父进程运行于相同的内存空间</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">int</span> FIBER_STACK = <span class="number">8192</span>;</span><br><span class="line"><span class="keyword">void</span> * <span class="built_in">stack</span> = <span class="built_in">malloc</span>(FIBER_STACK);<span class="comment">//为子进程申请系统堆栈</span></span><br><span class="line">clone(&amp;do_something, (<span class="keyword">char</span> *)<span class="built_in">stack</span> + FIBER_STACK, CLONE_VM|CLONE_VFORK, <span class="number">0</span>);</span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">do_something</span><span class="params">()</span></span>&#123;&#125;</span><br></pre></td></tr></table></figure><h1 id="僵尸进程"><a href="#僵尸进程" class="headerlink" title="僵尸进程"></a>僵尸进程</h1><p><strong>1）正常进程</strong><br>正常情况下，子进程是通过父进程创建的，子进程再创建新的进程。子进程的结束和父进程的运行是一个异步过程，即父进程永远无法预测子进程到底什么时候结束。当一个进程完成它的工作终止之后，它的父进程需要调用wait()或者waitpid()系统调用取得子进程的终止状态。<br><strong>waitt和waitpid区别和联系</strong> 在一个子进程终止前， wait 使其调用者阻塞，而waitpid 有一选择项，可使调用者不阻塞。waitpid并不等待第一个终止的子进程—它有若干个选择项，可以控制它所等待的特定进程。实际上wait函数是waitpid函数的一个特例。<br>unix提供了一种机制可以保证只要父进程想知道子进程结束时的状态信息，就可以得到：在每个进程退出的时候，内核释放该进程所有的资源，包括打开的文件，占用的内存等。 但是仍然为其保留一定的信息，直到父进程通过wait / waitpid来取时才释放。保存信息包括：<br>1进程号the process ID<br>2退出状态the termination status of the process<br>3运行时间the amount of CPU time taken by the process等<br><strong>2）孤儿进程</strong><br>一个父进程退出，而它的一个或多个子进程还在运行，那么那些子进程将成为孤儿进程。孤儿进程将被init进程(进程号为1)所收养，并由init进程对它们完成状态收集工作。<br><strong>3）僵尸进程</strong><br>一个进程使用fork创建子进程，如果子进程退出，而父进程并没有调用wait或waitpid获取子进程的状态信息，那么子进程的进程描述符仍然保存在系统中。这种进程称之为僵尸进程。<br>僵尸进程是一个进程必然会经过的过程：这是每个子进程在结束时都要经过的阶段。<br>如果子进程在exit()之后，父进程没有来得及处理，这时用ps命令就能看到子进程的状态是“Z”。如果父进程能及时处理，可能用ps命令就来不及看到子进程的僵尸状态，但这并不等于子进程不经过僵尸状态。<br>如果父进程在子进程结束之前退出，则子进程将由init接管。init将会以父进程的身份对僵尸状态的子进程进行处理。<br>危害：<br>如果进程不调用wait / waitpid的话， 那么保留的那段信息就不会释放，其进程号就会一直被占用，但是系统所能使用的进程号是有限的，如果大量的产生僵死进程，将因为没有可用的进程号而导致系统不能产生新的进程。<br>外部消灭：<br>通过kill发送SIGTERM或者SIGKILL信号消灭产生僵尸进程的进程，它产生的僵死进程就变成了孤儿进程，这些孤儿进程会被init进程接管，init进程会wait()这些孤儿进程，释放它们占用的系统进程表中的资源<br>内部解决：<br>1、子进程退出时向父进程发送SIGCHILD信号，父进程处理SIGCHILD信号。在信号处理函数中调用wait进行处理僵尸进程。<br>2、fork两次，原理是将子进程成为孤儿进程，从而其的父进程变为init进程，通过init进程可以处理僵尸进程。</p><p><strong>杀死僵死进程：</strong></p><figure class="highlight"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ kill -HUP `ps -A -ostat,ppid,pid |grep -e '^[Zz]' | awk'&#123;print $2&#125;'`</span><br></pre></td></tr></table></figure><p>(1) 检查当前僵尸进程信息： </p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ ps -ef | grep defunct | grep -v grep | wc -l</span><br></pre></td></tr></table></figure><p>1</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ top | head <span class="number">-2</span></span><br></pre></td></tr></table></figure><p><img src="https://img-blog.csdnimg.cn/20191108154350691.png" alt="在这里插入图片描述"><br>(2) 获得杀僵尸进程语句</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">$ ps -ef | grep defunct | grep -v grep | awk '&#123;print "kill -9 " $2,$3&#125;'  </span><br><span class="line"><span class="comment">//僵尸进程数会大大减少</span></span><br></pre></td></tr></table></figure><p>(3）过一会儿检查当前僵尸进程信息</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ ps -ef | grep defunct | grep -v grep | wc -l</span><br></pre></td></tr></table></figure><p>(4) 再次获得杀僵尸进程语句</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">$ ps -ef | grep defunct | grep -v grep | awk '&#123;print "kill -18 " $3&#125;'</span><br><span class="line"><span class="comment">//使用信号量18杀其父进程, 僵尸进程应该会全部消失</span></span><br></pre></td></tr></table></figure><p>清除ZOMBIE(僵尸)进程原理:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ kill -18 PPID</span><br></pre></td></tr></table></figure><p>PPID是其父进程, 这个信号是告诉父进程, 该子进程已经死亡了, 请收回分配给他的资源.如果还不行则看先看其父进程又无其他子进程, 如果有, 可能需要先kill其他子进程, 也就是兄弟进程.方法是:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">$ kill -15 PID1 PID2   //PID1,PID2是僵尸进程的父进程的其它子进程.:</span><br><span class="line">$ kill -15 PPID    //再kill父进程</span><br></pre></td></tr></table></figure><p>杀死进程：<br>Kill 234   //杀死pid 为234的进程<br>kill -TERM 234   //杀死进程和子进程  -15<br>kill -9 323   //彻底杀死进程<br>kill -HUP 456   //重跑 (restart) 进程<br>killall python   //通过进程名字结束进程</p><h1 id="5种IO模型"><a href="#5种IO模型" class="headerlink" title="5种IO模型"></a>5种IO模型</h1><p>1.阻塞IO:<br>调用者调用了某个函数，等待这个函数返回，期间什么也不做，不停的去检查这个函数有没有返回，必须等这个函数返回才能进行下一步动作<br>2.非阻塞IO:<br>非阻塞等待，每隔一段时间就去检测IO事件是否就绪。没有就绪就可以做其他事。<br>3.信号驱动IO:<br>linux用套接口进行信号驱动IO，安装一个信号处理函数，进程继续运行并不阻塞，当IO时间就绪，进程收到SIGIO信号。然后处理IO事件。<br>4.IO复用/多路转接IO:<br>linux用select/poll函数实现IO复用模型，这两个函数也会使进程阻塞，但是和阻塞IO所不同的是这两个函数可以同时阻塞多个IO操作。而且可以同时对多个读操作、写操作的IO函数进行检测。知道有数据可读或可写时，才真正调用IO操作函数<br>5.异步IO:<br>linux中，可以调用aio_read函数告诉内核描述字缓冲区指针和缓冲区的大小、文件偏移及通知的方式，然后立即返回，当内核将数据拷贝到缓冲区后，再通知应用程序。</p><h1 id="阻塞，非阻塞，同步，异步"><a href="#阻塞，非阻塞，同步，异步" class="headerlink" title="阻塞，非阻塞，同步，异步"></a>阻塞，非阻塞，同步，异步</h1><p>阻塞和非阻塞：调用者在事件没有发生的时候，一直在等待事件发生，不能去处理别的任务这是阻塞。调用者在事件没有发生的时候，可以去处理别的任务这是非阻塞。<br>同步和异步：调用者必须循环自己去查看事件有没有发生，这种情况是同步。调用者不用自己去查看事件有没有发生，而是等待着注册在事件上的回调函数通知自己，这种情况是异步</p><h1 id="异步编程的事件循环"><a href="#异步编程的事件循环" class="headerlink" title="异步编程的事件循环"></a>异步编程的事件循环</h1><p>事件循环就是不停循环等待事件的发生，然后将这个事件的所有处理器，以及他们订阅这个事件的时间顺序依次依次执行。当这个事件的所有处理器都被执行完毕之后，事件循环就会开始继续等待下一个事件的触发，不断往复。当同时并发地处理多个请求时，以上的概念也是正确的，可以这样理解：在单个的线程中，事件处理器是一个一个按顺序执行的。即如果某个事件绑定了两个处理器，那么第二个处理器会在第一个处理器执行完毕后，才开始执行。在这个事件的所有处理器都执行完毕之前，事件循环不会去检查是否有新的事件触发。在单个线程中，一切都是有顺序地一个一个地执行的！</p><h1 id="page-cache"><a href="#page-cache" class="headerlink" title="page cache"></a>page cache</h1><p>加快从磁盘读取文件的速率。page cache中有一部分磁盘文件的缓存，因为从磁盘中读取文件比较慢，所以读取文件先去page cache中去查找，如果命中，则不需要去磁盘中读取，大大加快读取速度。在 Linux 内核中，文件的每个数据块最多只能对应一个 Page Cache 项，它通过两个数据结构来管理这些 Cache项，一个是radix tree，另一个是双向链表。Radix tree 是一种搜索树，Linux内核利用这个数据结构来通过文件内偏移快速定位Cache 项</p><h1 id="select、poll、epoll的区别"><a href="#select、poll、epoll的区别" class="headerlink" title="select、poll、epoll的区别"></a>select、poll、epoll的区别</h1><p>IO多路复用：一个进程可以监视多个描述符，一旦某个描述符就绪（一般是读就绪或者写就绪），能够通知程序进行相应的读写操作。Linux中的 select，poll，epoll 都是IO多路复用的机制。<br>epoll跟select都能提供多路I/O复用的解决方案。在现在的Linux内核里有都能够支持，其中epoll是Linux所特有，而select则应该是POSIX所规定，一般操作系统均有实现。</p><p><strong>select</strong> 时间复杂度O(n)<br>select本质上是通过设置或者检查存放fd标志位的数据结构来进行下一步处理。<br>缺点：单个进程可监视的fd数量被限制；线性扫描，即采用轮询的方法，效率较低；需要维护一个用来存放大量fd的数据结构，用户空间和内核空间在传递该结构时复制开销大。<br>它仅仅知道了，有I/O事件发生了，却并不知道是哪那几个流，只能无差别轮询所有流，找出能读出数据，或者写入数据的流，对他们进行操作。</p><p><strong>poll</strong> 时间复杂度O(n)<br>poll本质上和select没有区别，它将用户传入的数组拷贝到内核空间，然后查询每个fd对应的设备状态，但是它没有最大连接数的限制，原因是它是基于链表来存储的。<br>poll还有一个特点是“水平触发”，如果报告了fd后，没有被处理，那么下次poll时会再次报告该fd。</p><p><strong>epoll</strong> 时间复杂度O(1)<br>epoll可以理解为event poll，epoll会把哪个流发生了怎样的I/O事件通知我们。<br> epoll支持水平触发和边缘触发，最大的特点在于边缘触发，它只告诉进程哪些fd刚刚变为就需态，并且只会通知一次。<br>水平触发——只要满足条件，就触发一个事件(只要有数据没有被获取，内核就不断通知你)；<br>边缘触发——每当状态变化时，触发一个事件。<br>epoll的优点：<br>1、没有最大并发连接的限制，能打开的FD的上限远大于1024（1G的内存上能监听约10万个端口）；<br>2、效率提升，不是轮询的方式，不会随着FD数目的增加效率下降。只有活跃可用的FD才会调用callback函数；即Epoll最大的优点就在于它只管你“活跃”的连接，而跟连接总数无关，因此在实际的网络环境中，Epoll的效率就会远远高于select和poll。<br>3、epoll使用mmap减少复制开销。</p><p><strong>select、poll、epoll区别</strong><br>| 区别 |     select|     poll    | epoll|<br>|–|–|–|–|<br>| 支持一个进程所能打开的最大连接数|     单个进程所能打开的最大连接数有FD_SETSIZE宏定义，其大小是32个整数的大小（在32位的机器上，大小就是32*32）|     poll本质上和select没有区别，但是它没有最大连接数的限制，原因是它是基于链表来存储的    | 虽然连接数有上限，但是很大，1G内存的机器上可以打开10万左右的连接|<br>| FD剧增后带来的IO效率问题|     因为每次调用时都会对连接进行线性遍历，所以随着FD的增加会造成遍历速度慢的“线性下降性能问题”。|     同左    | 因为epoll内核中实现是根据每个fd上的callback函数来实现的，只有活跃的socket才会主动调用callback，所以在活跃socket较少的情况下，使用epoll没有前面两者的线性下降的性能问题，但是所有socket都很活跃的情况下，可能会有性能问题。|<br>| 消息传递方式    | 内核需要将消息传递到用户空间，都需要内核拷贝动作    | 同左    | epoll通过内核和用户空间共享一块内存来实现的。| </p><h1 id="epoll怎么实现的"><a href="#epoll怎么实现的" class="headerlink" title="epoll怎么实现的"></a>epoll怎么实现的</h1><p>Linux epoll机制是通过红黑树和双向链表实现的。3个epoll系统调用:</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">epoll_create</span><span class="params">(<span class="keyword">int</span> size)</span></span>;</span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">epoll_ctl</span><span class="params">(<span class="keyword">int</span> epfd, <span class="keyword">int</span> op, <span class="keyword">int</span> fd, struct epoll_event *event)</span></span>;</span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">epoll_wait</span><span class="params">(<span class="keyword">int</span> epfd, struct epoll_event *events,<span class="keyword">int</span> maxevents, <span class="keyword">int</span> timeout)</span></span>;</span><br></pre></td></tr></table></figure><p>Linux epoll机制是通过红黑树和双向链表实现的。 首先通过epoll_create()系统调用在内核中创建一个eventpoll类型的句柄，其中包括红黑树根节点和双向链表头节点。然后通过epoll_ctl()系统调用，向epoll对象的红黑树结构中添加、删除、修改感兴趣的事件，返回0标识成功，返回-1表示失败。最后通过epoll_wait()系统调用判断双向链表是否为空，如果为空则阻塞。当文件描述符状态改变，fd上的回调函数被调用，该函数将fd加入到双向链表中，此时epoll_wait函数被唤醒，返回就绪好的事件。</p><h1 id="进程状态转换图，动态就绪，静态就绪，动态阻塞，静态阻塞"><a href="#进程状态转换图，动态就绪，静态就绪，动态阻塞，静态阻塞" class="headerlink" title="进程状态转换图，动态就绪，静态就绪，动态阻塞，静态阻塞"></a>进程状态转换图，动态就绪，静态就绪，动态阻塞，静态阻塞</h1><p>1、进程的五种基本状态：<br> <img src="https://img-blog.csdnimg.cn/20191108161411814.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZmY2pqaHY=,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"><br>创建状态：进程正在被创建<br>就绪状态：进程被加入到就绪队列中等待CPU调度运行<br>执行状态：进程正在被运行<br>等待阻塞状态：进程因为某种原因，比如等待I/O，等待设备，而暂时不能运行。<br>终止状态：进程运行完毕<br>2、交换技术<br>当多个进程竞争内存资源时，会造成内存资源紧张，并且，如果此时没有就绪进程，处理机会空闲，I/0速度比处理机速度慢得多，可能出现全部进程阻塞等待I/O。<br>针对以上问题，提出了两种解决方法：<br>1）交换技术：换出一部分进程到外存，腾出内存空间。<br>2）虚拟存储技术：每个进程只能装入一部分程序和数据。<br>在交换技术上，将内存暂时不能运行的进程，或者暂时不用的数据和程序，换出到外存，来腾出足够的内存空间，把已经具备运行条件的进程，或进程所需的数据和程序换入到内存。<br>从而出现了进程的挂起状态：进程被交换到外存，进程状态就成为了挂起状态。<br>3、活动阻塞，静止阻塞，活动就绪，静止就绪<br>1）活动阻塞：进程在内存，但是由于某种原因被阻塞了。<br>2）静止阻塞：进程在外存，同时被某种原因阻塞了。<br>3）活动就绪：进程在内存，处于就绪状态，只要给CPU和调度就可以直接运行。<br>4）静止就绪：进程在外存，处于就绪状态，只要调度到内存，给CPU和调度就可以运行。<br>从而出现了：<br>活动就绪 ——  静止就绪        （内存不够，调到外存）<br>活动阻塞 ——  静止阻塞        （内存不够，调到外存）<br>执行     ——  静止就绪         （时间片用完）</p><h1 id="伙伴系统、slab缓存"><a href="#伙伴系统、slab缓存" class="headerlink" title="伙伴系统、slab缓存"></a>伙伴系统、slab缓存</h1><p>伙伴系统、slab缓存是linux系统物理内存分配时所用到的技术。Linux内核内存管理的一项重要工作就是如何在频繁申请释放内存的情况下，避免碎片的产生。Linux采用伙伴系统解决外部碎片的问题，采用slab解决内部碎片的问题。<br><strong>伙伴系统</strong> （分配的大小由一个页框4k到1024个页框4M）<br>使用场景：内核中很多时候要求分配连续页，为快速检测内存中的连续区域采用的一种技术。<br>Linux内核引入了伙伴系统，把所有的空闲页框分组为11个块链表，每个块链表分别包含大小为1、2、4、8、16、32、64、128、256、512和1024个连续页框的页框块。最大可以申请1024个连续页框，也即4MB大小的连续空间。<br>假设要申请一个256个页框的块，先从256个页框的链表中查找空闲块，如果没有，就去512个页框的链表中找，找到了即将页框分为两个256个页框的块，一个分配给应用，另外一个移到256个页框的链表中。如果512个页框的链表中仍没有空闲块，继续向1024个页框的链表查找，如果仍然没有，则返回错误。<br>页框块在释放时，会主动将两个连续的页框块合并成一个较大的页框块。<br><strong>slab缓存</strong><br>适用场景：内核本身经常需要比完整页帧小的多的内存块。<br>slab的目的在于避免内部碎片。从buddy系统获取的内存至少是一个页，也就是4K，如果仅仅需要8字节的内存，显然巨大的内部碎片无法容忍。<br>slab从buddy系统申请空间，将较大的连续内存拆分成一系列较小的内存块。申请空间时从slab中获取大小最相近的小块内存，这样可以有效减少内部碎片。在slab最大的块为8K，slab中所有块在物理上也是连续的。<br>slab分配器是基于对象进行管理的，相同类型的对象归为一类(如进程描述符就是一类)，每当要申请这样一个对象，slab分配器就从一个slab列表中分配一个这样大小的单元出去，而当要释放时，将其重新保存在该列表中，而不是直接返回给伙伴系统，从而避免这些内碎片。</p><p>在内核中想要分配一段连续的内存，首先向slab系统申请，如果不满足（超过两个页面，也就是8K），直接向buddy系统申请。如果还不满足（超过4M，也就是1024个页面），将无法获取到连续的物理地址。可以通过vmalloc获取虚拟地址空间连续，但物理地址不连续的更大的内存空间。</p><h1 id="linux内核中的Timer-定时器机制"><a href="#linux内核中的Timer-定时器机制" class="headerlink" title="linux内核中的Timer 定时器机制"></a>linux内核中的Timer 定时器机制</h1><p>hrtimer采用红黑树进行高精度定时器的管理，而不是时间轮；</p><p>高精度时钟定时器不在依赖系统的tick中断，而是基于事件触发。<br>旧内核的定时器实现依赖于系统定时器硬件定期的tick，基于该tick，内核会扫描timer wheel处理超时事件，会更新jiffies，wall time(墙上时间，现实时间)，process的使用时间等等工作。<br>新的内核不再会直接支持周期性的tick，新内核定时器框架采用了基于事件触发，而不是以前的周期性触发。新内核实现了hrtimer(high resolution timer)：于事件触发。<br>hrtimer的工作原理：<br>通过将高精度时钟硬件的下次中断触发时间设置为红黑树中最早到期的Timer 的时间，时钟到期后从红黑树中得到下一个 Timer 的到期时间，并设置硬件，如此循环反复。</p><h1 id="docker"><a href="#docker" class="headerlink" title="docker"></a>docker</h1><p>下次单独出篇博客总结。。。。。</p>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;相关：&lt;br&gt;&lt;a href=&quot;https://blog.csdn.net/ffcjjhv/article/details/101433113&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;C++后台开发知识总结（一）C++基础&lt;/a&gt;&lt;br&gt;&lt;a href=&quot;https://blog.csdn.net/ffcjjhv/article/details/101481241&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;C++后台开发知识总结（二）数据库&lt;/a&gt;&lt;br&gt;&lt;a href=&quot;https://blog.csdn.net/ffcjjhv/article/details/101486572&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;C++后台开发知识总结（三）计算机网络&lt;/a&gt;&lt;br&gt;&lt;a href=&quot;https://blog.csdn.net/ffcjjhv/article/details/101546677&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;C++后台开发知识总结（四）操作系统/Linux 内核&lt;/a&gt;&lt;/p&gt;
&lt;h1 id=&quot;中断&quot;&gt;&lt;a href=&quot;#中断&quot; class=&quot;headerlink&quot; title=&quot;中断&quot;&gt;&lt;/a&gt;中断&lt;/h1&gt;&lt;p&gt;为什么需要中断：提高CPU运行效率&lt;br&gt;中断是指CPU对系统发生的某个事件做出的一种反应，CPU暂停正在执行的程序，保存现场后自动去执行相应的处理程序，处理完该事件后再返回中断处继续执行原来的程序。&lt;/p&gt;
    
    </summary>
    
      <category term="C++" scheme="http://yoursite.com/categories/C/"/>
    
      <category term="后台开发" scheme="http://yoursite.com/categories/%E5%90%8E%E5%8F%B0%E5%BC%80%E5%8F%91/"/>
    
    
      <category term="后台开发" scheme="http://yoursite.com/tags/%E5%90%8E%E5%8F%B0%E5%BC%80%E5%8F%91/"/>
    
      <category term="操作系统" scheme="http://yoursite.com/tags/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/"/>
    
      <category term="Linux 内核" scheme="http://yoursite.com/tags/Linux-%E5%86%85%E6%A0%B8/"/>
    
  </entry>
  
  <entry>
    <title>C++后台开发知识总结（三）计算机网络</title>
    <link href="http://yoursite.com/2019/09/27/28/"/>
    <id>http://yoursite.com/2019/09/27/28/</id>
    <published>2019-09-26T17:01:31.000Z</published>
    <updated>2019-12-18T04:21:50.877Z</updated>
    
    <content type="html"><![CDATA[<p>相关：<br><a href="https://blog.csdn.net/ffcjjhv/article/details/101433113" target="_blank" rel="noopener">C++后台开发知识总结（一）C++基础</a><br><a href="https://blog.csdn.net/ffcjjhv/article/details/101481241" target="_blank" rel="noopener">C++后台开发知识总结（二）数据库</a><br><a href="https://blog.csdn.net/ffcjjhv/article/details/101486572" target="_blank" rel="noopener">C++后台开发知识总结（三）计算机网络</a><br><a href="https://blog.csdn.net/ffcjjhv/article/details/101546677" target="_blank" rel="noopener">C++后台开发知识总结（四）操作系统/Linux 内核</a></p><h1 id="OSI与TCP-IP各层的结构与功能，都有哪些协议"><a href="#OSI与TCP-IP各层的结构与功能，都有哪些协议" class="headerlink" title="OSI与TCP/IP各层的结构与功能，都有哪些协议"></a>OSI与TCP/IP各层的结构与功能，都有哪些协议</h1><p>  <img src="https://img-blog.csdnimg.cn/20190927001422658.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZmY2pqaHY=,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"><br><img src="https://img-blog.csdnimg.cn/20190927001554677.png" alt="在这里插入图片描述"><br>OSI七层模型及其包含的协议如下:<br><strong>物理层：</strong><br>在物理媒体上传输原始的数据比特流,传输单位为bit，主要包括的协议为：IEE802.3 CLOCK RJ45</p><a id="more"></a><p><strong>数据链路层：</strong><br>将数据分成一个个数据帧，以数据帧为单位传输。有应有答，遇错重发。传输单位为帧,主要包括的协议为MAC VLAN PPP<br><strong>网络层：</strong><br>负责数据包从源到宿的传递和网际互连，传输单位为包,主要包括的协议为IP ARP ICMP<br><strong>传输层：</strong><br>提供端到端的可靠报文传递和错误恢复，传输单位为报文,主要包括的协议为TCP UDP</p><p><strong>会话层：</strong> 建立、管理和终止会话，传输单位为SPDU，主要包括的协议为RPC NFS<br><strong>表示层：</strong> 对数据进行翻译、加密和压缩,传输单位为PPDU，主要包括的协议为JPEG ASII<br><strong>应用层：</strong> 允许访问OSI环境的手段,传输单位为APDU，主要包括的协议为FTP HTTP DNS</p><p><strong>TCP/IP 4层模型包括：</strong><br>网络接口层：MAC VLAN<br>网络层:IP ARP ICMP<br>传输层:TCP UDP<br>应用层:HTTP DNS SMTP</p><h1 id="TCP-IP-数据链路层的交互过程"><a href="#TCP-IP-数据链路层的交互过程" class="headerlink" title="TCP/IP/数据链路层的交互过程"></a>TCP/IP/数据链路层的交互过程</h1><p>网络层等到数据链层用mac地址作为通信目标，数据包到达网络等准备往数据链层发送的时候，首先会去自己的arp缓存表(存着ip-mac对应关系)去查找改目标ip的mac地址，如果查到了，就讲目标ip的mac地址封装到链路层数据包的包头。如果缓存中没有找到，会发起一个广播：who is ip XXX tell ip XXX,所有收到的广播的机器看这个ip是不是自己的，如果是自己的，则以单拨的形式将自己的mac地址回复给请求的机器</p><h1 id="传递到IP层怎么知道报文该给哪个应用程序，它怎么区分UDP报文还是TCP报文"><a href="#传递到IP层怎么知道报文该给哪个应用程序，它怎么区分UDP报文还是TCP报文" class="headerlink" title="传递到IP层怎么知道报文该给哪个应用程序，它怎么区分UDP报文还是TCP报文"></a>传递到IP层怎么知道报文该给哪个应用程序，它怎么区分UDP报文还是TCP报文</h1><p>根据端口区分；<br>看ip头中的协议标识字段，17是udp，6是tcp</p><h1 id="输入网址后发生了什么，用到哪些协议"><a href="#输入网址后发生了什么，用到哪些协议" class="headerlink" title="输入网址后发生了什么，用到哪些协议"></a>输入网址后发生了什么，用到哪些协议</h1><p> <img src="https://img-blog.csdnimg.cn/20190927001847419.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZmY2pqaHY=,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"><br>http、dns、tcp、ip、arp地址解析协议、OSPF链路状态路由协议 </p><p>1、首先，在浏览器地址栏中输入url<br>2、查看浏览器缓存-系统缓存-路由器缓存，如果缓存中有，会直接在屏幕中显示页面内容。若没有，则跳到第三步操作。<br>3、在发送http请求前，需要域名解析(DNS解析)解析获取相应的IP地址。<br>4、浏览器向服务器发起tcp连接，与浏览器建立tcp三次握手。<br>5、握手成功后，浏览器向服务器发送http请求，请求数据包。<br>6、服务器处理收到的请求，将数据返回至浏览器<br>7、浏览器收到HTTP响应<br>8、读取页面内容，浏览器渲染，解析html源码<br>9、生成Dom树、解析css样式、js交互<br>10、客户端和服务器交互<br>11、ajax查询</p><h1 id="TCP三次握手和四次挥手"><a href="#TCP三次握手和四次挥手" class="headerlink" title="TCP三次握手和四次挥手"></a>TCP三次握手和四次挥手</h1><p> <img src="https://img-blog.csdnimg.cn/20190927002212798.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZmY2pqaHY=,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"><br>两个序号和三个标志位：<br>（1）序号：seq序号，占32位，用来标识从TCP源端向目的端发送的字节流，发起方发送数据时对此进行标记。<br>（2）确认序号：ack序号，只有ACK标志位为1时，确认序号字段才有效，ack=seq+1<br>（3）标志位：共6个，即URG、ACK、PSH、RST、SYN、FIN等，具体含义如下：<br>ACK：确认序号有效； SYN：发起一个新连接； FIN：释放一个连接<br> <img src="https://img-blog.csdnimg.cn/2019092700230883.png" alt="在这里插入图片描述"><br>客户端–发送带有SYN标志的数据包–一次握手–服务端<br>服务端–发送带有SYN/ACK标志的数据包–二次握手–客户端<br>客户端–发送带有带有ACK标志的数据包–三次握手–服务端<br><img src="https://img-blog.csdnimg.cn/20190927002321269.png" alt="在这里插入图片描述"><br>客户端-发送一个FIN，用来关闭客户端到服务器的数据传送<br>服务器-收到这个FIN，它发回一个ACK，确认序号为收到的序号加1 。<br>服务器-关闭与客户端的连接，发送一个FIN给客户端<br>客户端-发回ACK报文确认，并将确认序号设置为收到序号加1<br><strong>为什么要四次挥手？</strong><br>任何一方都可以在数据传送结束后发出连接释放的通知，待对方确认后进入半关闭状态。当另一方也没有数据再发送的时候，则发出连接释放通知，对方确认后就完全关闭了TCP连接。</p><h1 id="TIME-WAIT：作用以及如何避免"><a href="#TIME-WAIT：作用以及如何避免" class="headerlink" title="TIME_WAIT：作用以及如何避免"></a>TIME_WAIT：作用以及如何避免</h1><p><img src="https://img-blog.csdnimg.cn/20190927002355750.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZmY2pqaHY=,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"><br><img src="https://img-blog.csdnimg.cn/20190927002406993.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZmY2pqaHY=,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"><br>1：主机1发送FIN；此时，主机1进入FIN_WAIT_1状态；<br>2：主机2收到FIN，向主机1回一个ACK报文段；主机1进入FIN_WAIT_2状态；<br>3：主机2发送FIN，请求关闭连接，同时主机2进入LAST_ACK状态；<br>4：主机1收到主机2发送的FIN报文段，向主机2发送ACK报文段，然后主机1进入TIME_WAIT状态；主机2收到主机1的ACK报文段以后就关闭连接；此时，主机1等待2MSL后依然没有收到回复，则证明Server端已正常关闭，那好，主机1也可以关闭连接了。<br><strong>MSL</strong>是指数据包在网络中的最大生存时间</p><p><strong>为什么要有TIME_WAIT这个状态：</strong><br>（1）TCP实现必须可靠地终止连接的两个方向(全双工关闭)，主机1必须进入 TIME_WAIT 状态，因为主机1可能面临<strong>重发最终ACK</strong>的情形。假设最终的ACK丢失，主机2将重发FIN，主机1必须维护TCP状态信息以便可以重发最终的ACK，否则会发送RST，结果主机2认为发生错误。<br>（2）避免上一个连接延迟到达的数据包被<strong>下一个连接错误接收</strong>。如果在被推迟的报文未抵达前接收方断开了连接，随后又建立了一个与之前相同IP、Port的连接，而之前被推迟的报文在这时恰好到达，而此时此新连接非彼连接，从而会发生数据错乱。</p><p><strong>出现太多TIME_WAIT可能导致的后果：</strong><br>在<strong>高并发短连接</strong>的TCP服务器上，当服务器处理完请求后立刻按照主动正常关闭连接。这个场景下，会出现大量socket处于TIMEWAIT状态。如果客户端的并发量持续很高，此时部分客户端就会显示连接不上。高并发可以让服务器在短时间范围内同时占用大量端口。短连接比如，取一个web页面，1秒钟的http短连接处理完业务，在关闭连接之后，这个业务用过的端口会停留在TIMEWAIT状态几分钟，而这几分钟，其他HTTP请求来临的时候是无法占用此端口的。服务器干正经事的时间和端口（资源）被挂着无法被使用的时间的比例是 1：几百，服务器资源严重浪费。</p><p><strong>linux 大量的TIME_WAIT解决办法：</strong><br>通过调整内核参数解决<br><code>vi /etc/sysctl.conf</code><br>编辑文件，加入以下内容：<br>net.ipv4.tcp_syncookies = 1<br>net.ipv4.tcp_tw_reuse = 1<br>net.ipv4.tcp_tw_recycle = 1<br>net.ipv4.tcp_fin_timeout = 30</p><p>net.ipv4.tcp_syncookies = 1表示开启SYN Cookies。当出现SYN等待队列溢出时，启用cookies来处理，可防范少量SYN攻击，默认为0，表示关闭；<br>net.ipv4.tcp_tw_reuse = 1表示开启重用。允许将TIME-WAIT sockets重新用于新的TCP连接，默认为0，表示关闭；<br>net.ipv4.tcp_tw_recycle = 1表示开启TCP连接中TIME-WAIT sockets的快速回收，默认为0，表示关闭。<br>net.ipv4.tcp_fin_timeout修改系統默认的TIMEOUT时间</p><h1 id="TCP、UDP协议的区别"><a href="#TCP、UDP协议的区别" class="headerlink" title="TCP、UDP协议的区别"></a>TCP、UDP协议的区别</h1><p> <img src="https://img-blog.csdnimg.cn/20190927002750406.png" alt="在这里插入图片描述"><br>UDP在传送数据之前不需要先建立连接，远地主机在收到UDP报文后，不需要给出任何确认。虽然UDP不提供可靠交付，但在某些情况下UDP确是一种最有效的工作方式（一般用于即时通信），比如： QQ语音 QQ视频 、直播等等<br>TCP提供面向连接的服务。在传送数据之前必须先建立连接，数据传送结束后要释放连接。TCP不提供广播或多播服务。由于TCP要提供可靠的，面向连接的运输服务（TCP的可靠体现在TCP在传递数据之前，会有三次握手来建立连接，而且在数据传递时，有确认、窗口、重传、拥塞控制机制，在数据传完后，还会断开连接用来节约系统资源），这一难以避免增加了许多开销，如确认，流量控制，计时器以及连接管理等。这不仅使协议数据单元的首部增大很多，还要占用许多处理机资源。TCP一般用于文件传输、发送和接收</p><h1 id="TCP怎么保证可靠性"><a href="#TCP怎么保证可靠性" class="headerlink" title="TCP怎么保证可靠性"></a>TCP怎么保证可靠性</h1><p>TCP保证可靠性：<br><strong>（1）序列号、确认应答、超时重传</strong><br>数据到达接收方，接收方需要发出一个确认应答，表示已经收到该数据段，并且确认序号会说明了它下一次需要接收的数据序列号。如果发送发迟迟未收到确认应答，那么可能是发送的数据丢失，也可能是确认应答丢失，这时发送方在等待一定时间后会进行重传。<br><strong>（2）窗口控制与高速重发控制/快速重传（重复确认应答）</strong><br>TCP会利用窗口控制来提高传输速度，意思是在一个窗口大小内，不用一定要等到应答才能发送下一段数据，窗口大小就是无需等待确认而可以继续发送数据的最大值。如果不使用窗口控制，每一个没收到确认应答的数据都要重发。<br>使用窗口控制，如果数据段1001-2000丢失，后面数据每次传输，确认应答都会不停地发送序号为1001的应答，表示我要接收1001开始的数据，发送端如果收到3次相同应答，就会立刻进行重发；但还有种情况有可能是数据都收到了，但是有的应答丢失了，这种情况不会进行重发，因为发送端知道，如果是数据段丢失，接收端不会放过它的，会疯狂向它提醒……<br><strong>（3）拥塞控制</strong><br>如果把窗口定的很大，发送端连续发送大量的数据，可能会造成网络的拥堵（大家都在用网，你在这狂发，吞吐量就那么大，当然会堵），甚至造成网络的瘫痪。所以TCP在为了防止这种情况而进行了拥塞控制。<br><strong>慢启动</strong>：定义拥塞窗口，一开始将该窗口大小设为1，之后每次收到确认应答（经过一个rtt），将拥塞窗口大小<em>2。<br>*</em>拥塞避免<strong>：设置慢启动阈值，一般开始都设为65536。拥塞避免是指当拥塞窗口大小达到这个阈值，拥塞窗口的值不再指数上升，而是加法增加（每次确认应答/每个rtt，拥塞窗口大小+1），以此来避免拥塞。<br>将报文段的超时重传看做拥塞，则一旦发生超时重传，我们需要先将阈值设为当前窗口大小的一半，并且将窗口大小设为初值1，然后重新进入慢启动过程。<br>**快速重传</strong>：在遇到3次重复确认应答（高速重发控制）时，代表收到了3个报文段，但是这之前的1个段丢失了，便对它进行立即重传。<br>然后，先将阈值设为当前窗口大小的一半，然后将拥塞窗口大小设为慢启动阈值+3的大小。<br>这样可以达到：在TCP通信时，网络吞吐量呈现逐渐的上升，并且随着拥堵来降低吞吐量，再进入慢慢上升的过程，网络不会轻易的发生瘫痪。</p><h1 id="GET-和-POST-的本质区别"><a href="#GET-和-POST-的本质区别" class="headerlink" title="GET 和 POST 的本质区别"></a>GET 和 POST 的本质区别</h1><table><thead><tr><th></th><th>GET</th><th>POST</th></tr></thead><tbody><tr><td>书签</td><td>可收藏为书签</td><td>不可收藏为书签</td></tr><tr><td>缓存</td><td>能被缓存</td><td>不能缓存</td></tr><tr><td>历史</td><td>参数保留在浏览器历史中</td><td>参数不会保存在浏览器历史中</td></tr><tr><td>对数据长度的限制</td><td>GET请求的参数是放在URL里的； URL 的最大长度是 2048 个字符</td><td>POST请求参数是放在请求body里的，无限制</td></tr><tr><td>对数据类型的限制</td><td>只允许 ASCII字符</td><td>没有限制。也允许二进制数据</td></tr><tr><td>安全性</td><td>GET的安全性较差，因为所发送的数据是URL的一部分</td><td>POST 比GET 更安全，因为参数不会被保存在浏览器历史或web服务器日志中</td></tr><tr><td>可见性</td><td>数据在URL中对所有人都是可见的</td><td>数据不会显示在 URL 中</td></tr></tbody></table><p><strong>本质区别</strong>:GET产生一个TCP数据包；POST产生两个TCP数据包。<br>对于GET方式的请求，浏览器会把http header和data一并发送出去，服务器响应200（返回数据）； 而对于POST，浏览器先发送header，服务器响应100 continue，浏览器再发送data，服务器响应200 ok（返回数据）。</p><h1 id="HTTP状态码"><a href="#HTTP状态码" class="headerlink" title="HTTP状态码"></a>HTTP状态码</h1><table><thead><tr><th></th><th>类别</th><th>原因短语</th></tr></thead><tbody><tr><td>1XX</td><td>Informational（信息性状态码）</td><td>接收的请求正在处理</td></tr><tr><td>2XX</td><td>Success     （成功状态码）</td><td>请求正常处理完毕</td></tr><tr><td>3XX</td><td>Redirection  （重定向状态码）</td><td>需要进行附加操作以完成请求</td></tr><tr><td>4XX</td><td>Client Error  （客户端错误状态码）</td><td>服务器无法处理请求</td></tr><tr><td>5XX</td><td>Server Error  （服务器错误状态码）</td><td>服务器处理请求出错</td></tr><tr><td>常见状态代码、状态描述的详细说明如下。</td><td></td><td></td></tr><tr><td>200 OK：客户端请求成功。</td><td></td><td></td></tr><tr><td>206 partial content服务器已经正确处理部分GET请求，实现断点续传或同时分片下载，该请求必须包含Range请求头来指示客户端期望得到的范围</td><td></td><td></td></tr><tr><td>300 multiple choices（可选重定向）:被请求的资源有一系列可供选择的反馈信息，由浏览器/用户自行选择其中一个。</td><td></td><td></td></tr><tr><td>301 moved permanently（永久重定向）：该资源已被永久移动到新位置，将来任何对该资源的访问都要使用本响应返回的若干个URI之一。</td><td></td><td></td></tr><tr><td>302 move temporarily(临时重定向)：请求的资源现在临时从不同的URI中获得，</td><td></td><td></td></tr><tr><td>304 not modified :如果客户端发送一个待条件的GET请求并且该请求以经被允许，而文档内容未被改变，则返回304,该响应不包含包体（即可直接使用缓存）。</td><td></td><td></td></tr><tr><td>403 Forbidden：服务器收到请求，但是拒绝提供服务。</td><td></td><td></td></tr><tr><td>404 not Found：请求资源不存在，举个例子：输入了错误的URL。</td><td></td><td></td></tr></tbody></table><h1 id="HTTP长连接、短连接"><a href="#HTTP长连接、短连接" class="headerlink" title="HTTP长连接、短连接"></a>HTTP长连接、短连接</h1><p>在HTTP/1.0中默认使用短连接。也就是说，客户端和服务器每进行一次HTTP操作，就建立一次连接，任务结束就中断连接。当客户端浏览器访问的某个HTML或其他类型的Web页中包含有其他的Web资源（如JavaScript文件、图像文件、CSS文件等），每遇到这样一个Web资源，浏览器就会重新建立一个HTTP会话。<br>而从HTTP/1.1起，默认使用长连接，用以保持连接特性。使用长连接的HTTP协议，会在响应头加入这行代码：<code>Connection:keep-alive</code><br>复制代码在使用长连接的情况下，当一个网页打开完成后，客户端和服务器之间用于传输HTTP数据的TCP连接不会关闭，客户端再次访问这个服务器时，会继续使用这一条已经建立的连接。Keep-Alive不会永久保持连接，它有一个保持时间，可以在不同的服务器软件（如Apache）中设定这个时间。实现长连接需要客户端和服务端都支持长连接。</p><h1 id="HTTP和HTTPS的区别"><a href="#HTTP和HTTPS的区别" class="headerlink" title="HTTP和HTTPS的区别"></a>HTTP和HTTPS的区别</h1><p>HTTPS即加密的HTTP，HTTPS并不是一个新协议，而是HTTP+SSL（TLS）。原本HTTP先和TCP（假定传输层是TCP协议）直接通信，所有传输的内容都是明文，客户端和服务器端都无法验证对方的身份。<br>而加了SSL后，就变成HTTP先和SSL通信，再由SSL和TCP通信，相当于SSL被嵌在了HTTP和TCP之间，所有传输的内容都经过加密，加密采用对称加密，但对称加密的密钥用服务器方的证书进行了非对称加密。此外客户端可以验证服务器端的身份，如果配置了客户端验证，服务器方也可以验证客户端的身份.</p><p>HTTPS协议需要服务端申请证书，浏览器端安装对应的根证书<br>HTTP协议端口是80，HTTPS协议端口是443</p><p><strong>HTTPS优点：</strong><br>HTTPS传输数据过程中使用密钥进行加密，所以安全性更高<br>HTTPS协议可以认证用户和服务器，确保数据发送到正确的用户和服务器<br><strong>HTTPS缺点：</strong><br>HTTPS握手阶段延时较高：由于在进行HTTP会话之前还需要进行SSL握手，因此HTTPS协议握手阶段延时增加<br>HTTPS部署成本高：一方面HTTPS协议需要使用证书来验证自身的安全性，所以需要购买CA证书；另一方面由于采用HTTPS协议需要进行加解密的计算，占用CPU资源较多，需要的服务器配置或数目高</p><h1 id="数字证书是什么，里面都包含那些内容"><a href="#数字证书是什么，里面都包含那些内容" class="headerlink" title="数字证书是什么，里面都包含那些内容"></a>数字证书是什么，里面都包含那些内容</h1><p>数字证书是在一个身份和该身份的持有者所拥有的公/私钥对之间建立了一种联系，由认证中心（CA）或者认证中心的下级认证中心颁发的。<br>数字证书颁发过程如下：用户产生了自己的密钥对，并将公共密钥及部分个人身份信息传送给一家认证中心。认证中心在核实身份后，将执行一些必要的步骤，以确信请求确实由用户发送而来，然后，认证中心将发给用户一个数字证书，该证书内附了用户和他的密钥等信息，同时还附有对认证中心公共密钥加以确认的数字证书。当用户想证明其<strong>公开密钥的合法性</strong>时，就可以提供这一数字证书。</p><h1 id="各种协议与HTTP协议之间的关系"><a href="#各种协议与HTTP协议之间的关系" class="headerlink" title="各种协议与HTTP协议之间的关系"></a>各种协议与HTTP协议之间的关系</h1><p><img src="https://img-blog.csdnimg.cn/2019092700423149.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZmY2pqaHY=,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"></p><h1 id="IP地址作用，以及MAC地址作用"><a href="#IP地址作用，以及MAC地址作用" class="headerlink" title="IP地址作用，以及MAC地址作用"></a>IP地址作用，以及MAC地址作用</h1><p>MAC地址是一个硬件地址，用来定义网络设备的位置，主要由数据链路层负责。而IP地址是IP协议提供的一种统一的地址格式，为互联网上的每一个网络和每一台主机分配一个逻辑地址，以此来屏蔽物理地址的差异。</p><h1 id="流量控制"><a href="#流量控制" class="headerlink" title="流量控制"></a>流量控制</h1><p>流量控制：防止发送方发的太快，耗尽接收方的资源，从而使接收方来不及处理<br>依据：接收端缓冲区的大小<br>实现流量控制：<br>滑动窗口： 在确认应答策略中，对每一个发送的数据段，都要给一个ACK确认应答，收到ACK后再发送下一个数据段，这样做有一个比较大的缺点，就是性能比较差，尤其是数据往返的时间长的时候，使用滑动窗口，就可以一次发送多条数据，从而就提高了性能。<br>（1）接收端将自己可以接收的缓冲区大小放入TCP首部中的“窗口大小”字段，通过ACK来通知发送端<br>（2）窗口大小指的是不需要接收端的应答，可以一次连续的发送数据<br>（3）操作系统内核为了维护滑动窗口，需要开辟发送缓冲区，来记录当前还有那些数据没有应答，只有确认应答过的数据，才能从缓冲区删掉<br>（4）滑动窗口中的数据类型：发送了尚未确认的，没有发送，但是等待发送的。接收端窗口就是等待确认的数据序号组成。</p><h1 id="拥塞控制"><a href="#拥塞控制" class="headerlink" title="拥塞控制"></a>拥塞控制</h1><p>拥塞控制：防止发送方发的太快，使得网络来不及处理，从而导致网络拥塞<br>拥塞控制的表现：丢包、延时变长<br>拥塞控制是防止过多的数据注入网络，使得网络中的路由器或者链路过载。流量控制是点对点的通信量控制，而拥塞控制是全局的网络流量整体性的控制。发送双方都有一个拥塞窗口——cwnd。拥塞窗口的大小取决于网络的拥塞情况，并且是动态变化的，发送方一般让自己的发送窗口不大于拥塞窗口。<br>1、慢开始<br>TCP 连接开始，cwnd设置为1，字节未超过阈值ssthresh，接到确认呈指数型增长<br>2、拥塞避免<br>超过阈值变为线性增长。一旦发现网络拥塞，就把慢开始门限设为当前值的一半，并且重新设置cwnd为1，重新慢启动。<br>3、快重传<br>接收方每次收到一个失序的报文段后就立即发出重复确认，发送方只要连续收到三个重复确认就立即重传（尽早重传未被确认的报文段）。<br>4、快恢复<br>当发送方连续收到了三个重复确认（为什么是3个？因为1-2个重复ACK，很有可能是乱序，只有在3个及以上的时候才是有可能丢包了）时，把慢开始门限减半，由于发送方现在认为网络很可能没有发生拥塞，跳过指数增加，直接使拥塞窗口的线性增大。<br><img src="https://img-blog.csdnimg.cn/20190927004418957.png" alt="在这里插入图片描述"><br>采用快恢复算法时，慢开始只在建立连接和网络超时才使用。<br>采用慢开始和拥塞避免算法的时候<br>1.一旦cwnd&gt;慢开始门限，就采用拥塞避免算法，减慢增长速度<br>2.一旦出现丢包的情况，就重新进行慢开始，减慢增长速度<br>采用快恢复和快重传算法的时候<br>1.一旦cwnd&gt;慢开始门限，就采用拥塞避免算法，减慢增长速度<br>2.一旦发送方连续收到了三个重复确认，就采用拥塞避免算法，减慢增长速度<br><strong>流量控制和拥塞控制的区别</strong><br>相同点：<br>现象都是丢包；<br>实现机制都是让发送方发的慢一点，发的少一点<br>不同点：<br>（1）丢包位置：流量控制丢包位置是在接收端上、拥塞控制丢包位置是在路由器上<br>（2）作用的对象：流量控制的对象是接收方，怕发送方发的太快，使得接收方来不及处理<br>拥塞控制的对象是网络，怕发送发发的太快，造成网络拥塞，使得网络来不及处理</p><h1 id="Ddos"><a href="#Ddos" class="headerlink" title="Ddos"></a>Ddos</h1><p>Dos拒绝服务攻击攻击原理：DoS攻击就是利用合理的服务请求来占用过多的服务资源，从而使合法用户无法得到服务的响应。dos攻击与ddos攻击的区别就是，它是一对一的攻击，而ddos是分布式的攻击。<br>最常见的DoS攻击有对计算机网络的带宽攻击和连通性攻击。<br><strong>带宽攻击：</strong> 指以极大的通信量冲击网络，使得所有可用网络资源都被消耗殆尽，最后导致合法的用户请求无法通过。<br><strong>连通性攻击：</strong> 指用大量的连接请求冲击计算机，使得所有可用的操作系统资源都被消耗殆尽，最终计算机无法再处理合法用户的请求。<br>传统上，攻击者所面临的主要问题是网络带宽，由于较小的网络规模和较慢的网络速度的限制，攻击者无法发出过多的请求。大多数的DoS攻击还是需要相当大的带宽的，而以个人为单位的黑客们很难使用高带宽的资源。为了克服这个缺点，DoS攻击者开发了分布式的攻击。攻击者简单利用工具集合许多的网络带宽来同时对同一个目标发动大量的攻击请求，这就是DDoS攻击<br><strong>SYN泛洪：</strong><br>攻击主机C(地址伪装后为C)—–大量SYN包—-&gt;被攻击主机<br>       C&lt;——-SYN/ACK包—-被攻击主机<br>由于C地址不可达，被攻击主机等待超时。攻击主机通过发大量SYN包填满未连接队列，导致正常SYN包被拒绝服务。（防范：给每一个请求连接的IP地址分配一个Cookie）<br><strong>常见的dos攻击：</strong><br>死亡之ping：故意产生畸形的测试Ping包，声称自己的尺寸超过64KB上限，使未采取保护措施的网络系统出现内存分配错误，导致TCP/IP协议栈崩溃，最终接收方宕机。<br>泪滴：某些TCP/IP协议栈在收到含有重叠偏移的伪造分段时将崩溃。<br>UDP泛洪：伪造与某一主机的Chargen服务之间的一次的UDP连接，回复地址指向开着Echo服务的一台主机，通过将Chargen和Echo服务互指，来回传送毫无用处且占满带宽的垃圾数据<br><strong>常见的Ddos攻击：</strong><br>Smurf攻击：用一个伪造的源地址连续ping一个或多个计算机网络，这就导致所有计算机所响应的那个计算机并不是实际发送这个信息包的那个计算机。这个伪造的源地址，实际上就是攻击的目标，它将被极大数量的响应信息量所淹没。</p><h1 id="XSS和-CSRF"><a href="#XSS和-CSRF" class="headerlink" title="XSS和 CSRF"></a>XSS和 CSRF</h1><p><strong>XSS</strong><br>跨站脚本攻击，这些可执行的脚本由攻击者提供，最终为用户浏览器加载，不同于大多数攻击，有存储型和反射型。<br>防御方式:编码，过滤，解码<br><strong>CSRF</strong><br>跨站请求伪造（攻击者盗用你的身份，以你的身份发送恶意请求），一次CSRF攻击的步骤：<br>登录受信任的网站A，并在本地生成cookie<br>在不登出A的情况下，访问危险网站B<br>防御的方法：总的思想在客户端页面增加伪随机值<br>Cookie Hashing 所有的表单都包含一个伪随机值<br>验证码<br>不同的表单包含一个不同的伪随机值</p><h1 id="socket编程"><a href="#socket编程" class="headerlink" title="socket编程"></a>socket编程</h1><p><strong>什么是 socket</strong><br>socket 的原意是“插座”，在计算机通信领域，socket 被翻译为“套接字”，它是计算机之间进行通信的一种约定或一种方式。通过 socket 这种约定，一台计算机可以接收其他计算机的数据，也可以向其他计算机发送数据。<br><strong>UNIX/Linux 中的 socket</strong><br>在 UNIX/Linux 系统中，为了统一对各种硬件的操作，简化接口，不同的硬件设备也都被看成一个文件。对这些文件的操作，等同于对磁盘上普通文件的操作。为了表示和区分已经打开的文件，UNIX/Linux 会给每个文件分配一个 ID，这个 ID 就是一个整数，被称为文件描述符（File Descriptor）。</p><p>通过 socket() 函数来创建一个网络连接，或者说打开一个网络文件，socket() 的返回值就是文件描述符。有了文件描述符，我们就可以使用普通的文件操作函数来传输数据了，例如：<br>用 read() 读取从远程计算机传来的数据；<br>用 write() 向远程计算机写入数据。</p><p><strong>socket有哪些类型</strong><br>流格式套接字（SOCK_STREAM）<br>SOCK_STREAM 是一种可靠的、双向的通信数据流，数据可以准确无误地到达另一台计算机，如果损坏或丢失，可以重新发送。使用了 TCP 协议（The Transmission Control Protocol，传输控制协议）<br>应用场景：浏览器所使用的 http 协议就基于面向连接的套接字<br>数据报格式套接字（SOCK_DGRAM）<br>计算机只管传输数据，不作数据校验，如果数据在传输中损坏，或者没有到达另一台计算机，是没有办法补救的。也就是说，数据错了就错了，无法重传。因为数据报套接字所做的校验工作少，所以在传输效率方面比流格式套接字要高。使用 UDP 协议（User Datagram Protocol，用户数据报协议）。<br>应用场景：QQ 视频聊天和语音聊天</p><p><strong>常用函数：</strong></p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;sys/types.h&gt;       </span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;sys/socket.h&gt;</span></span></span><br></pre></td></tr></table></figure><p><strong>1、socket()描述字建立函数</strong></p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//int socket(int domain, int type, int protocol);</span></span><br><span class="line"><span class="keyword">int</span> serv_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);</span><br></pre></td></tr></table></figure><p><strong>domain</strong> 指明所使用的协议族，通常为AF_INET，表示互联网协议族（TCP/IP协议族）<br>AF_INET IPv4因特网域，AF_INET6 IPv6因特网域，AF_UNIX Unix域，AF_ROUTE 路由套接字，AF_KEY 密钥套接字，AF_UNSPEC 未指定<br><strong>type</strong> 指定socket的类型<br>SOCK_STREAM，SOCK_DGRAM，SOCK_RAW protocol<br><strong>protocol</strong> 通常赋值”0“。 0 选择type类型对应的默认协议，IPPROTO_TCP TCP传输协议，IPPROTO_UDP UDP传输协议，IPPROTO_SCTP SCTP传输协议，IPPROTO_TIPC TIPC传输协议</p><p><strong>2、bind()函数：IP号端口号与相应描述字赋值函数</strong></p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);</span></span><br><span class="line"><span class="comment">//将套接字和IP、端口绑定</span></span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">sockaddr_in</span> <span class="title">serv_addr</span>;</span></span><br><span class="line"><span class="built_in">memset</span>(&amp;serv_addr, <span class="number">0</span>, <span class="keyword">sizeof</span>(serv_addr));  <span class="comment">//每个字节都用0填充</span></span><br><span class="line">serv_addr.sin_family = AF_INET;  <span class="comment">//使用IPv4地址</span></span><br><span class="line">serv_addr.sin_addr.s_addr = inet_addr(<span class="string">"127.0.0.1"</span>);  <span class="comment">//具体的IP地址</span></span><br><span class="line">serv_addr.sin_port = htons(<span class="number">1234</span>);  <span class="comment">//端口</span></span><br><span class="line">bind(serv_sock, (struct sockaddr*)&amp;serv_addr, <span class="keyword">sizeof</span>(serv_addr));</span><br><span class="line"></span><br><span class="line"><span class="comment">//ipv4对应的是： </span></span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment">struct sockaddr&#123;</span></span><br><span class="line"><span class="comment">unisgned short  as_family;    // 协议族</span></span><br><span class="line"><span class="comment">char           sa_data[14];  // IP+端口</span></span><br><span class="line"><span class="comment">       &#125;;</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="comment">//同等替换：</span></span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment">struct sockaddr_in &#123;</span></span><br><span class="line"><span class="comment">    sa_family_t      sin_family;   // 协议族</span></span><br><span class="line"><span class="comment">    in_port_t        sin_port;   // 端口号</span></span><br><span class="line"><span class="comment">    struct  in_addr  sin_addr;   // IP地址结构体</span></span><br><span class="line"><span class="comment">    unsigned char    sin_zero[8];  // 填充   </span></span><br><span class="line"><span class="comment">&#125;;</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="comment">//两个结构是等同的可以先互转换，第一个结构将地址和端口绑定了，第二个结构将两者分开表示*/</span></span><br><span class="line"><span class="comment">//IP地址结构如下：为32位字 </span></span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment">struct in_addr &#123;</span></span><br><span class="line"><span class="comment">    uint32_t       s_addr;     </span></span><br><span class="line"><span class="comment">&#125;;</span></span><br><span class="line"><span class="comment">*/</span></span><br></pre></td></tr></table></figure><p><strong>3、listen()函数：监听设置函数</strong></p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//int listen(int sockfd, int backlog);</span></span><br><span class="line">listen(serv_sock, <span class="number">20</span>); <span class="comment">//请求队列中允许的最大请求数20</span></span><br></pre></td></tr></table></figure><p><strong>4、accept()函数：用于从已完成连接队列队头返回下一个已完成连接。如果已完成连接队列为空，那么进程被投入睡眠。</strong></p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);</span></span><br><span class="line"><span class="comment">//接收客户端请求</span></span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">sockaddr_in</span> <span class="title">clnt_addr</span>;</span></span><br><span class="line"><span class="keyword">socklen_t</span> clnt_addr_size = <span class="keyword">sizeof</span>(clnt_addr);</span><br><span class="line"><span class="keyword">int</span> clnt_sock = accept(serv_sock, (struct sockaddr*)&amp;clnt_addr, &amp;clnt_addr_size);</span><br></pre></td></tr></table></figure><p>5、connect()函数:客户机连接主机</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//int connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen);</span></span><br><span class="line">connect(sock, (struct sockaddr*)&amp;serv_addr, <span class="keyword">sizeof</span>(serv_addr));</span><br></pre></td></tr></table></figure><p><strong>基于TCP的socket：</strong><br>服务器端程序：<br>1创建一个socket，用函数socket()<br>2绑定IP地址、端口等信息到socket上，用函数bind()<br>3设置允许的最大连接数，用函数listen()<br>4接收客户端上来的连接，用函数accept()<br>5收发数据，用函数send()和recv()，或者read()和write()<br>6关闭网络连接</p><p>客户端程序：<br>1创建一个socket，用函数socket()<br>2设置要连接的对方的IP地址和端口等属性<br>3连接服务器，用函数connect()<br>4收发数据，用函数send()和recv()，或read()和write()<br>5关闭网络连接</p><h1 id="socket-编程1：读取一个字符串并打印出来。"><a href="#socket-编程1：读取一个字符串并打印出来。" class="headerlink" title="socket 编程1：读取一个字符串并打印出来。"></a>socket 编程1：读取一个字符串并打印出来。</h1><p>服务器端代码 server.cpp：</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;stdio.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;string.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;stdlib.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;unistd.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;arpa/inet.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;sys/socket.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;netinet/in.h&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    <span class="comment">//创建套接字</span></span><br><span class="line">    <span class="keyword">int</span> serv_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);</span><br><span class="line"></span><br><span class="line">    <span class="comment">//将套接字和IP、端口绑定</span></span><br><span class="line">    <span class="class"><span class="keyword">struct</span> <span class="title">sockaddr_in</span> <span class="title">serv_addr</span>;</span></span><br><span class="line">    <span class="built_in">memset</span>(&amp;serv_addr, <span class="number">0</span>, <span class="keyword">sizeof</span>(serv_addr));  <span class="comment">//每个字节都用0填充</span></span><br><span class="line">    serv_addr.sin_family = AF_INET;  <span class="comment">//使用IPv4地址</span></span><br><span class="line">    serv_addr.sin_addr.s_addr = inet_addr(<span class="string">"127.0.0.1"</span>);  <span class="comment">//具体的IP地址</span></span><br><span class="line">    serv_addr.sin_port = htons(<span class="number">1234</span>);  <span class="comment">//端口</span></span><br><span class="line">    bind(serv_sock, (struct sockaddr*)&amp;serv_addr, <span class="keyword">sizeof</span>(serv_addr));</span><br><span class="line"></span><br><span class="line">    <span class="comment">//进入监听状态，等待用户发起请求</span></span><br><span class="line">    listen(serv_sock, <span class="number">20</span>); <span class="comment">//请求队列中允许的最大请求数20</span></span><br><span class="line"></span><br><span class="line">    <span class="comment">//接收客户端请求</span></span><br><span class="line">    <span class="class"><span class="keyword">struct</span> <span class="title">sockaddr_in</span> <span class="title">clnt_addr</span>;</span></span><br><span class="line">    <span class="keyword">socklen_t</span> clnt_addr_size = <span class="keyword">sizeof</span>(clnt_addr);</span><br><span class="line">    <span class="keyword">int</span> clnt_sock = accept(serv_sock, (struct sockaddr*)&amp;clnt_addr, &amp;clnt_addr_size);</span><br><span class="line"></span><br><span class="line">    <span class="comment">//向客户端发送数据</span></span><br><span class="line">    <span class="keyword">char</span> str[] = <span class="string">"http://c.biancheng.net/socket/"</span>;</span><br><span class="line">    write(clnt_sock, str, <span class="keyword">sizeof</span>(str));</span><br><span class="line">   </span><br><span class="line">    <span class="comment">//关闭套接字</span></span><br><span class="line">    close(clnt_sock);</span><br><span class="line">    close(serv_sock);</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>客户端代码 client.cpp：</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;stdio.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;string.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;stdlib.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;unistd.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;arpa/inet.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;sys/socket.h&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    <span class="comment">//创建套接字</span></span><br><span class="line">    <span class="keyword">int</span> sock = socket(AF_INET, SOCK_STREAM, <span class="number">0</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">//向服务器（特定的IP和端口）发起请求</span></span><br><span class="line">    <span class="class"><span class="keyword">struct</span> <span class="title">sockaddr_in</span> <span class="title">serv_addr</span>;</span></span><br><span class="line">    <span class="built_in">memset</span>(&amp;serv_addr, <span class="number">0</span>, <span class="keyword">sizeof</span>(serv_addr));  <span class="comment">//每个字节都用0填充</span></span><br><span class="line">    serv_addr.sin_family = AF_INET;  <span class="comment">//使用IPv4地址</span></span><br><span class="line">    serv_addr.sin_addr.s_addr = inet_addr(<span class="string">"127.0.0.1"</span>);  <span class="comment">//具体的IP地址</span></span><br><span class="line">    serv_addr.sin_port = htons(<span class="number">1234</span>);  <span class="comment">//端口</span></span><br><span class="line">    connect(sock, (struct sockaddr*)&amp;serv_addr, <span class="keyword">sizeof</span>(serv_addr));</span><br><span class="line">   </span><br><span class="line">    <span class="comment">//读取服务器传回的数据</span></span><br><span class="line">    <span class="keyword">char</span> buffer[<span class="number">40</span>];</span><br><span class="line">    read(sock, buffer, <span class="keyword">sizeof</span>(buffer)<span class="number">-1</span>);</span><br><span class="line">   </span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">"Message form server: %s\n"</span>, buffer);</span><br><span class="line">   </span><br><span class="line">    <span class="comment">//关闭套接字</span></span><br><span class="line">    close(sock);</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>启动一个终端（Shell），先编译 server.cpp 并运行：<br>[admin@localhost ~]$ g++ server.cpp -o server<br>[admin@localhost ~]$ ./server  #等待请求的到来<br>正常情况下，程序运行到 accept() 函数就会被阻塞，等待客户端发起请求。<br>接下再启动一个终端，编译 client.cpp 并运行：<br>[admin@localhost ~]$ g++ client.cpp -o client<br>[admin@localhost ~]$ ./client<br>Message form server: <a href="http://c.biancheng.net/socket/" target="_blank" rel="noopener">http://c.biancheng.net/socket/</a><br>client 接收到从 server发送过来的字符串就运行结束了，同时，server 完成发送字符串的任务也运行结束了。</p><h1 id="socket-编程2：文件传输"><a href="#socket-编程2：文件传输" class="headerlink" title="socket 编程2：文件传输"></a>socket 编程2：文件传输</h1><p>Server端代码如下：</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string">&lt;netinet/in.h&gt;  // sockaddr_in</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string">&lt;sys/types.h&gt;   // socket</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string">&lt;sys/socket.h&gt;  // socket</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string">&lt;stdio.h&gt;       // printf</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string">&lt;stdlib.h&gt;      // exit</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string">&lt;string.h&gt;      // bzero</span></span></span><br><span class="line"></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> SERVER_PORT 8000</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> LENGTH_OF_LISTEN_QUEUE 20</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> BUFFER_SIZE 1024</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> FILE_NAME_MAX_SIZE 512</span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">(<span class="keyword">void</span>)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="comment">// 声明并初始化一个服务器端的socket地址结构</span></span><br><span class="line">    <span class="class"><span class="keyword">struct</span> <span class="title">sockaddr_in</span> <span class="title">server_addr</span>;</span></span><br><span class="line">    bzero(&amp;server_addr, <span class="keyword">sizeof</span>(server_addr));</span><br><span class="line">    server_addr.sin_family = AF_INET;</span><br><span class="line">    server_addr.sin_addr.s_addr = htons(INADDR_ANY);</span><br><span class="line">    server_addr.sin_port = htons(SERVER_PORT);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 创建socket，若成功，返回socket描述符</span></span><br><span class="line">    <span class="keyword">int</span> server_socket_fd = socket(PF_INET, SOCK_STREAM, <span class="number">0</span>);</span><br><span class="line">    <span class="keyword">if</span>(server_socket_fd &lt; <span class="number">0</span>)</span><br><span class="line">    &#123;</span><br><span class="line">        perror(<span class="string">"Create Socket Failed:"</span>);</span><br><span class="line">        <span class="built_in">exit</span>(<span class="number">1</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">int</span> opt = <span class="number">1</span>;</span><br><span class="line">    setsockopt(server_socket_fd, SOL_SOCKET, SO_REUSEADDR, &amp;opt, <span class="keyword">sizeof</span>(opt));</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 绑定socket和socket地址结构</span></span><br><span class="line">    <span class="keyword">if</span>(<span class="number">-1</span> == (bind(server_socket_fd, (struct sockaddr*)&amp;server_addr, <span class="keyword">sizeof</span>(server_addr))))</span><br><span class="line">    &#123;</span><br><span class="line">        perror(<span class="string">"Server Bind Failed:"</span>);</span><br><span class="line">        <span class="built_in">exit</span>(<span class="number">1</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="comment">// socket监听</span></span><br><span class="line">    <span class="keyword">if</span>(<span class="number">-1</span> == (listen(server_socket_fd, LENGTH_OF_LISTEN_QUEUE)))</span><br><span class="line">    &#123;</span><br><span class="line">        perror(<span class="string">"Server Listen Failed:"</span>);</span><br><span class="line">        <span class="built_in">exit</span>(<span class="number">1</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">while</span>(<span class="number">1</span>)</span><br><span class="line">    &#123;</span><br><span class="line">        <span class="comment">// 定义客户端的socket地址结构</span></span><br><span class="line">        <span class="class"><span class="keyword">struct</span> <span class="title">sockaddr_in</span> <span class="title">client_addr</span>;</span></span><br><span class="line">        <span class="keyword">socklen_t</span> client_addr_length = <span class="keyword">sizeof</span>(client_addr);</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 接受连接请求，返回一个新的socket(描述符)，这个新socket用于同连接的客户端通信</span></span><br><span class="line">        <span class="comment">// accept函数会把连接到的客户端信息写到client_addr中</span></span><br><span class="line">        <span class="keyword">int</span> new_server_socket_fd = accept(server_socket_fd, (struct sockaddr*)&amp;client_addr, &amp;client_addr_length);</span><br><span class="line">        <span class="keyword">if</span>(new_server_socket_fd &lt; <span class="number">0</span>)</span><br><span class="line">        &#123;</span><br><span class="line">            perror(<span class="string">"Server Accept Failed:"</span>);</span><br><span class="line">            <span class="keyword">break</span>;</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="comment">// recv函数接收数据到缓冲区buffer中</span></span><br><span class="line">        <span class="keyword">char</span> buffer[BUFFER_SIZE];</span><br><span class="line">        bzero(buffer, BUFFER_SIZE);</span><br><span class="line">        <span class="keyword">if</span>(recv(new_server_socket_fd, buffer, BUFFER_SIZE, <span class="number">0</span>) &lt; <span class="number">0</span>)</span><br><span class="line">        &#123;</span><br><span class="line">            perror(<span class="string">"Server Recieve Data Failed:"</span>);</span><br><span class="line">            <span class="keyword">break</span>;</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 然后从buffer(缓冲区)拷贝到file_name中</span></span><br><span class="line">        <span class="keyword">char</span> file_name[FILE_NAME_MAX_SIZE+<span class="number">1</span>];</span><br><span class="line">        bzero(file_name, FILE_NAME_MAX_SIZE+<span class="number">1</span>);</span><br><span class="line">        <span class="built_in">strncpy</span>(file_name, buffer, <span class="built_in">strlen</span>(buffer)&gt;FILE_NAME_MAX_SIZE?FILE_NAME_MAX_SIZE:<span class="built_in">strlen</span>(buffer));</span><br><span class="line">        <span class="built_in">printf</span>(<span class="string">"%s\n"</span>, file_name);</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 打开文件并读取文件数据</span></span><br><span class="line">        FILE *fp = fopen(file_name, <span class="string">"r"</span>);</span><br><span class="line">        <span class="keyword">if</span>(<span class="literal">NULL</span> == fp)</span><br><span class="line">        &#123;</span><br><span class="line">            <span class="built_in">printf</span>(<span class="string">"File:%s Not Found\n"</span>, file_name);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">else</span></span><br><span class="line">        &#123;</span><br><span class="line">            bzero(buffer, BUFFER_SIZE);</span><br><span class="line">            <span class="keyword">int</span> length = <span class="number">0</span>;</span><br><span class="line">            <span class="comment">// 每读取一段数据，便将其发送给客户端，循环直到文件读完为止</span></span><br><span class="line">            <span class="keyword">while</span>((length = fread(buffer, <span class="keyword">sizeof</span>(<span class="keyword">char</span>), BUFFER_SIZE, fp)) &gt; <span class="number">0</span>)</span><br><span class="line">            &#123;</span><br><span class="line">                <span class="keyword">if</span>(send(new_server_socket_fd, buffer, length, <span class="number">0</span>) &lt; <span class="number">0</span>)</span><br><span class="line">                &#123;</span><br><span class="line">                    <span class="built_in">printf</span>(<span class="string">"Send File:%s Failed./n"</span>, file_name);</span><br><span class="line">                    <span class="keyword">break</span>;</span><br><span class="line">                &#125;</span><br><span class="line">                bzero(buffer, BUFFER_SIZE);</span><br><span class="line">            &#125;</span><br><span class="line"></span><br><span class="line">            <span class="comment">// 关闭文件</span></span><br><span class="line">            fclose(fp);</span><br><span class="line">            <span class="built_in">printf</span>(<span class="string">"File:%s Transfer Successful!\n"</span>, file_name);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="comment">// 关闭与客户端的连接</span></span><br><span class="line">        close(new_server_socket_fd);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">// 关闭监听用的socket</span></span><br><span class="line">    close(server_socket_fd);</span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>客户端代码 client.cpp：</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string">&lt;netinet/in.h&gt;   // sockaddr_in</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string">&lt;sys/types.h&gt;    // socket</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string">&lt;sys/socket.h&gt;   // socket</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string">&lt;stdio.h&gt;        // printf</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string">&lt;stdlib.h&gt;       // exit</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string">&lt;string.h&gt;       // bzero</span></span></span><br><span class="line"> </span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> SERVER_PORT 8000</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> BUFFER_SIZE 1024</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> FILE_NAME_MAX_SIZE 512</span></span><br><span class="line"> </span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="comment">// 声明并初始化一个客户端的socket地址结构</span></span><br><span class="line">    <span class="class"><span class="keyword">struct</span> <span class="title">sockaddr_in</span> <span class="title">client_addr</span>;</span></span><br><span class="line">    bzero(&amp;client_addr, <span class="keyword">sizeof</span>(client_addr));</span><br><span class="line">    client_addr.sin_family = AF_INET;</span><br><span class="line">    client_addr.sin_addr.s_addr = htons(INADDR_ANY);</span><br><span class="line">    client_addr.sin_port = htons(<span class="number">0</span>);</span><br><span class="line"> </span><br><span class="line">    <span class="comment">// 创建socket，若成功，返回socket描述符</span></span><br><span class="line">    <span class="keyword">int</span> client_socket_fd = socket(AF_INET, SOCK_STREAM, <span class="number">0</span>);</span><br><span class="line">    <span class="keyword">if</span>(client_socket_fd &lt; <span class="number">0</span>)</span><br><span class="line">    &#123;</span><br><span class="line">        perror(<span class="string">"Create Socket Failed:"</span>);</span><br><span class="line">        <span class="built_in">exit</span>(<span class="number">1</span>);</span><br><span class="line">    &#125;</span><br><span class="line"> </span><br><span class="line">    <span class="comment">// 绑定客户端的socket和客户端的socket地址结构 非必需</span></span><br><span class="line">    <span class="keyword">if</span>(<span class="number">-1</span> == (bind(client_socket_fd, (struct sockaddr*)&amp;client_addr, <span class="keyword">sizeof</span>(client_addr))))</span><br><span class="line">    &#123;</span><br><span class="line">        perror(<span class="string">"Client Bind Failed:"</span>);</span><br><span class="line">        <span class="built_in">exit</span>(<span class="number">1</span>);</span><br><span class="line">    &#125;</span><br><span class="line"> </span><br><span class="line">    <span class="comment">// 声明一个服务器端的socket地址结构，并用服务器那边的IP地址及端口对其进行初始化，用于后面的连接</span></span><br><span class="line">    <span class="class"><span class="keyword">struct</span> <span class="title">sockaddr_in</span> <span class="title">server_addr</span>;</span></span><br><span class="line">    bzero(&amp;server_addr, <span class="keyword">sizeof</span>(server_addr));</span><br><span class="line">    server_addr.sin_family = AF_INET;</span><br><span class="line">    <span class="keyword">if</span>(inet_pton(AF_INET, <span class="string">"127.0.0.1"</span>, &amp;server_addr.sin_addr) == <span class="number">0</span>)</span><br><span class="line">    &#123;</span><br><span class="line">        perror(<span class="string">"Server IP Address Error:"</span>);</span><br><span class="line">        <span class="built_in">exit</span>(<span class="number">1</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    server_addr.sin_port = htons(SERVER_PORT);</span><br><span class="line">    <span class="keyword">socklen_t</span> server_addr_length = <span class="keyword">sizeof</span>(server_addr);</span><br><span class="line"> </span><br><span class="line">    <span class="comment">// 向服务器发起连接，连接成功后client_socket_fd代表了客户端和服务器的一个socket连接</span></span><br><span class="line">    <span class="keyword">if</span>(connect(client_socket_fd, (struct sockaddr*)&amp;server_addr, server_addr_length) &lt; <span class="number">0</span>)</span><br><span class="line">    &#123;</span><br><span class="line">        perror(<span class="string">"Can Not Connect To Server IP:"</span>);</span><br><span class="line">        <span class="built_in">exit</span>(<span class="number">0</span>);</span><br><span class="line">    &#125;</span><br><span class="line"> </span><br><span class="line">    <span class="comment">// 输入文件名 并放到缓冲区buffer中等待发送</span></span><br><span class="line">    <span class="keyword">char</span> file_name[FILE_NAME_MAX_SIZE+<span class="number">1</span>];</span><br><span class="line">    bzero(file_name, FILE_NAME_MAX_SIZE+<span class="number">1</span>);</span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">"Please Input File Name On Server:\t"</span>);</span><br><span class="line">    <span class="built_in">scanf</span>(<span class="string">"%s"</span>, file_name);</span><br><span class="line"> </span><br><span class="line">    <span class="keyword">char</span> buffer[BUFFER_SIZE];</span><br><span class="line">    bzero(buffer, BUFFER_SIZE);</span><br><span class="line">    <span class="built_in">strncpy</span>(buffer, file_name, <span class="built_in">strlen</span>(file_name)&gt;BUFFER_SIZE?BUFFER_SIZE:<span class="built_in">strlen</span>(file_name));</span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 向服务器发送buffer中的数据</span></span><br><span class="line">    <span class="keyword">if</span>(send(client_socket_fd, buffer, BUFFER_SIZE, <span class="number">0</span>) &lt; <span class="number">0</span>)</span><br><span class="line">    &#123;</span><br><span class="line">        perror(<span class="string">"Send File Name Failed:"</span>);</span><br><span class="line">        <span class="built_in">exit</span>(<span class="number">1</span>);</span><br><span class="line">    &#125;</span><br><span class="line"> </span><br><span class="line">    <span class="comment">// 打开文件，准备写入</span></span><br><span class="line">    FILE *fp = fopen(file_name, <span class="string">"w"</span>);</span><br><span class="line">    <span class="keyword">if</span>(<span class="literal">NULL</span> == fp)</span><br><span class="line">    &#123;</span><br><span class="line">        <span class="built_in">printf</span>(<span class="string">"File:\t%s Can Not Open To Write\n"</span>, file_name);</span><br><span class="line">        <span class="built_in">exit</span>(<span class="number">1</span>);</span><br><span class="line">    &#125;</span><br><span class="line"> </span><br><span class="line">    <span class="comment">// 从服务器接收数据到buffer中</span></span><br><span class="line">    <span class="comment">// 每接收一段数据，便将其写入文件中，循环直到文件接收完并写完为止</span></span><br><span class="line">    bzero(buffer, BUFFER_SIZE);</span><br><span class="line">    <span class="keyword">int</span> length = <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">while</span>((length = recv(client_socket_fd, buffer, BUFFER_SIZE, <span class="number">0</span>)) &gt; <span class="number">0</span>)</span><br><span class="line">    &#123;</span><br><span class="line">        <span class="keyword">if</span>(fwrite(buffer, <span class="keyword">sizeof</span>(<span class="keyword">char</span>), length, fp) &lt; length)</span><br><span class="line">        &#123;</span><br><span class="line">            <span class="built_in">printf</span>(<span class="string">"File:\t%s Write Failed\n"</span>, file_name);</span><br><span class="line">            <span class="keyword">break</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        bzero(buffer, BUFFER_SIZE);</span><br><span class="line">    &#125;</span><br><span class="line"> </span><br><span class="line">    <span class="comment">// 接收成功后，关闭文件，关闭socket</span></span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">"Receive File:\t%s From Server IP Successful!\n"</span>, file_name);</span><br><span class="line">    close(fp);</span><br><span class="line">    close(client_socket_fd);</span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;相关：&lt;br&gt;&lt;a href=&quot;https://blog.csdn.net/ffcjjhv/article/details/101433113&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;C++后台开发知识总结（一）C++基础&lt;/a&gt;&lt;br&gt;&lt;a href=&quot;https://blog.csdn.net/ffcjjhv/article/details/101481241&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;C++后台开发知识总结（二）数据库&lt;/a&gt;&lt;br&gt;&lt;a href=&quot;https://blog.csdn.net/ffcjjhv/article/details/101486572&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;C++后台开发知识总结（三）计算机网络&lt;/a&gt;&lt;br&gt;&lt;a href=&quot;https://blog.csdn.net/ffcjjhv/article/details/101546677&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;C++后台开发知识总结（四）操作系统/Linux 内核&lt;/a&gt;&lt;/p&gt;
&lt;h1 id=&quot;OSI与TCP-IP各层的结构与功能，都有哪些协议&quot;&gt;&lt;a href=&quot;#OSI与TCP-IP各层的结构与功能，都有哪些协议&quot; class=&quot;headerlink&quot; title=&quot;OSI与TCP/IP各层的结构与功能，都有哪些协议&quot;&gt;&lt;/a&gt;OSI与TCP/IP各层的结构与功能，都有哪些协议&lt;/h1&gt;&lt;p&gt;  &lt;img src=&quot;https://img-blog.csdnimg.cn/20190927001422658.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZmY2pqaHY=,size_16,color_FFFFFF,t_70&quot; alt=&quot;在这里插入图片描述&quot;&gt;&lt;br&gt;&lt;img src=&quot;https://img-blog.csdnimg.cn/20190927001554677.png&quot; alt=&quot;在这里插入图片描述&quot;&gt;&lt;br&gt;OSI七层模型及其包含的协议如下:&lt;br&gt;&lt;strong&gt;物理层：&lt;/strong&gt;&lt;br&gt;在物理媒体上传输原始的数据比特流,传输单位为bit，主要包括的协议为：IEE802.3 CLOCK RJ45&lt;/p&gt;
    
    </summary>
    
      <category term="C++" scheme="http://yoursite.com/categories/C/"/>
    
      <category term="后台开发" scheme="http://yoursite.com/categories/%E5%90%8E%E5%8F%B0%E5%BC%80%E5%8F%91/"/>
    
    
      <category term="后台开发" scheme="http://yoursite.com/tags/%E5%90%8E%E5%8F%B0%E5%BC%80%E5%8F%91/"/>
    
      <category term="计算机网络" scheme="http://yoursite.com/tags/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/"/>
    
  </entry>
  
  <entry>
    <title>C++后台开发知识总结（二）数据库</title>
    <link href="http://yoursite.com/2019/09/26/27/"/>
    <id>http://yoursite.com/2019/09/26/27/</id>
    <published>2019-09-26T14:36:00.000Z</published>
    <updated>2019-12-18T04:21:55.732Z</updated>
    
    <content type="html"><![CDATA[<p>相关：<br><a href="https://blog.csdn.net/ffcjjhv/article/details/101433113" target="_blank" rel="noopener">C++后台开发知识总结（一）C++基础</a><br><a href="https://blog.csdn.net/ffcjjhv/article/details/101481241" target="_blank" rel="noopener">C++后台开发知识总结（二）数据库</a><br><a href="https://blog.csdn.net/ffcjjhv/article/details/101486572" target="_blank" rel="noopener">C++后台开发知识总结（三）计算机网络</a><br><a href="https://blog.csdn.net/ffcjjhv/article/details/101546677" target="_blank" rel="noopener">C++后台开发知识总结（四）操作系统/Linux 内核</a></p><h1 id="数据库索引"><a href="#数据库索引" class="headerlink" title="数据库索引"></a>数据库索引</h1><p>索引是存储引擎快速找到记录的一种数据结构。<br><strong>添加索引原则：</strong><br>在查询中很少使用或者参考的列不应该创建索引。</p><a id="more"></a><p>只有很少数据值的列也不应该增加索引。<br>定义为text、image和bit数据类型的列不应该增加索引。<br>当修改性能远远大于检索性能时，不应该创建索引。这是因为，修改性能和检索性能是互相矛盾的。</p><p>目前大部分数据库系统及文件系统都采用B-Tree或其变种B+Tree作为索引结构<br><strong>B-Tree</strong><br>B-Tree是一种平衡的多路查找(又称排序)树，在文件系统中和数据库系统中有所应用。主要用作文件的索引。其中的B就表示平衡(Balance) 。<br>定义一条数据记录为一个二元组[key, data]，key为记录的键值，对于不同数据记录，key是互不相同的；data为数据记录除key外的数据。那么B-Tree是满足下列条件的数据结构：1.d&gt;=2，即B-Tree的度；<br>2.h为B-Tree的高；<br>3.每个非叶子结点由n-1个key和n个指针组成，其中d&lt;=n&lt;=2d；<br>4.每个叶子结点至少包含一个key和两个指针，最多包含2d-1个key和2d个指针，叶结点的指针均为NULL；<br>5.所有叶结点都在同一层，深度等于树高h；<br>6.key和指针相互间隔，结点两端是指针；<br>7.一个结点中的key从左至右非递减排列；<br>8.如果某个指针在结点node最左边且不为null，则其指向结点的所有key小于v(key1)，其中v(key1)为node的第一个key的值。<br>9.如果某个指针在结点node最右边且不为null，则其指向结点的所有key大于v(keym)，其中v(keym)为node的最后一个key的值。<br>10.如果某个指针在结点node的左右相邻key分别是keyi和keyi+1且不为null，则其指向结点的所有key小于v(keyi+1)且大于v(keyi)。<br>一个d=2的B-Tree示意图:<br> <img src="https://img-blog.csdnimg.cn/20190926222739454.png" alt="在这里插入图片描述"><br>B-Tree是一个非常有效率的索引数据结构。这主要得益于B-Tree的度可以非常大，高度会变的非常小，只需要二分几次就可以找到数据。例如一个度为d的B-Tree，设其索引N个key，则其树高h的上限为logd((N+1)/2))，检索一个key，其查找节点个数的渐进复杂度为O(logdN)。<br>索引本身也很大，不可能全部存储在内存中，因此索引往往以索引文件的形式存储的磁盘上。这样的话，索引查找过程中就要产生磁盘I/O消耗。索引的结构组织要尽量减少查找过程中磁盘I/O的存取次数。<br><strong>B+Tree的特性</strong><br>区别于B-Tree:<br>每个节点的指针上限为2d而不是2d+1<br>内节点不存储data，只存储key；叶子节点不存储指针<br>带有顺序访问指针的B+Tree</p><h1 id="数据库添加索引"><a href="#数据库添加索引" class="headerlink" title="数据库添加索引"></a>数据库添加索引</h1><p>1.普通索引：<br>仅加速查询 最基本的索引，没有任何限制，是大多数情况下使用到的索引。<code>CREATE INDEX index_name on user_info(name)</code></p><p>#创建表的时候同时创建索引：</p><figure class="highlight"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="function">create table <span class="title">healerjean</span> <span class="params">(</span></span></span><br><span class="line">  id   bigint(20)  NOT NULL AUTO_INCREMENT PRIMARY KEY COMMENT  '主键',</span><br><span class="line">  name  VARCHAR(32) NOT NULL COMMENT '姓名',</span><br><span class="line">  email VARCHAR(64) NOT NULL COMMENT  '邮箱',</span><br><span class="line">  message text DEFAULT  NULL COMMENT '个人信息',</span><br><span class="line">  INDEX index_name (name) COMMENT '索引name'</span><br><span class="line">) COMMENT  = '索引测试表';</span><br></pre></td></tr></table></figure><p>#在存在的表上创建索引</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="function">create index index_name on <span class="title">healerjean</span><span class="params">(name)</span></span></span><br></pre></td></tr></table></figure><p>#对于创建索引时如果是blob 和 text 类型，必须指定length。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="function">create index ix_extra on <span class="title">in1</span><span class="params">(message(<span class="number">200</span>))</span></span>;</span><br><span class="line"><span class="function">alter table employee add index <span class="title">emp_name</span> <span class="params">(name)</span></span>;</span><br></pre></td></tr></table></figure><p>2.唯一索引：<br>与普通索引类型不同的是：加速查询 + 列值唯一（可以有null）<code>CREATE UNIQUE INDEX mail on user_info(name)</code><br>3.全文索引：<br>全文索引（FULLTEXT）仅可以适用于MyISAM引擎的数据表；作用于CHAR、VARCHAR、TEXT数据类型的列。<br>4.组合索引：<br>将几个列作为一条索引进行检索，使用最左匹配原则。<br><code>create index ind_sales2_companyid_moneys on sales2(company_id,moneys)</code></p><p>想要查看表有几个字段设置了索引, <code>show index from healerjean</code></p><h1 id="MySQL索引实现"><a href="#MySQL索引实现" class="headerlink" title="MySQL索引实现"></a>MySQL索引实现</h1><p><strong>MyISAM索引实现</strong><br>MyISAM引擎使用B+Tree作为索引结构，叶结点的data域存放的是数据记录的地址。<br> <img src="https://img-blog.csdnimg.cn/20190926223327795.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZmY2pqaHY=,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"><br>MyISAM中索引检索的算法为首先按照B+Tree搜索算法搜索索引，如果指定的Key存在，则取出其data域的值，然后以data域的值为地址，读取相应数据记录。MyISAM的索引方式也叫做“非聚集”的。<br>在MyISAM中，主索引和辅助索引（Secondary key）在结构上没有任何区别，只是主索引要求key是唯一的，而辅助索引的key可以重复。<br> <img src="https://img-blog.csdnimg.cn/20190926223403474.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZmY2pqaHY=,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"><br><strong>InnoDB索引实现</strong><br>InnoDB的数据文件本身就是索引文件。MyISAM索引文件和数据文件是分离的，索引文件仅保存数据记录的地址。<br> <img src="https://img-blog.csdnimg.cn/20190926223412928.png" alt="在这里插入图片描述"><br>叶结点包含了完整的数据记录。这种索引叫做聚集索引。因为InnoDB的数据文件本身要按主键聚集，所以InnoDB要求表必须有主键（MyISAM可以没有），如果没有显式指定，则MySQL系统会自动选择一个可以唯一标识数据记录的列作为主键，如果不存在这种列，则MySQL自动为InnoDB表生成一个隐含字段作为主键，这个字段长度为6个字节，类型为长整形。<br>InnoDB的辅助索引data域存储相应记录主键的值而不是地址。换句话说，InnoDB的所有辅助索引都引用主键作为data域。<br> <img src="https://img-blog.csdnimg.cn/20190926230106338.png" alt="在这里插入图片描述"></p><h1 id="数据库事务：底层如何实现事务"><a href="#数据库事务：底层如何实现事务" class="headerlink" title="数据库事务：底层如何实现事务"></a>数据库事务：底层如何实现事务</h1><p>数据库事务(Database Transaction) ，是指作为单个逻辑工作单元执行的一系列操作，要么完全地执行，要么完全地不执行。<br>一个数据库事务通常包含了一个序列的对数据库的读/写操作。作用：<br>1.为数据库操作序列提供了一个从失败中恢复到正常状态的方法，同时提供了数据库即使在异常状态下仍能保持一致性的方法。<br>2.当多个应用程序在并发访问数据库时，可以在这些应用程序之间提供一个隔离方法，以防止彼此的操作互相干扰。<br>当事务被提交给了DBMS（数据库管理系统），则DBMS（数据库管理系统）需要确保该事务中的所有操作都成功完成且其结果被永久保存在数据库中，如果事务中有的操作没有成功完成，则事务中的所有操作都需要被回滚，回到事务执行前的状态;同时，该事务对数据库或者其他事务的执行无影响。<br>一个逻辑工作单元要成为事务，必须满足<strong>ACID（原子性、一致性、隔离性和持久性）</strong> 属性。<br><strong>原子性（Atomicity）：</strong><br>事务作为一个整体被执行，事物的所有操作要不成功，要不失败回滚而回滚可以通过日志来实现，日志记录着事务所执行的修改操作，在回滚时反向执行这些修改操作。<br><strong>一致性（Consistency）：</strong><br>数据库在事务执行前后都保持一致性状态，在一致性状态下，所有事务对一个数据的读取结果都是相同的。<br><strong>隔离性（Isolation）：</strong><br>多个事务并发执行时，一个事务的执行不应影响其他事务的执行。<br><strong>持久性（Durability）：</strong><br>一旦事务提交，则其所做的修改将会永远保存到数据库中。</p><h1 id="数据库事务隔离"><a href="#数据库事务隔离" class="headerlink" title="数据库事务隔离"></a>数据库事务隔离</h1><p>同一时间，只允许一个事务请求同一数据，不同的事务之间彼此没有任何干扰。比如A正在从一张银行卡中取钱，在A取钱的过程结束前，B不能向这张卡转账。</p><h1 id="MySQL-4-种隔离级别"><a href="#MySQL-4-种隔离级别" class="headerlink" title="MySQL 4 种隔离级别"></a>MySQL 4 种隔离级别</h1><p><strong>未提交读READ UNCOMMITTED：</strong><br>一个事务在提交之前，对其他事务是可见的，即事务可以读取未提交的数据。存在“脏读”（读到了脏数据）问题；<br><strong>提交读READ COMMITTED：</strong><br>事务在提交之前，对其它事务是不可见的。存在“不可重复读”（两次查询的得到的结果可能不同，即可能在查询的间隙，有事务提交了修改）问题。解决了“脏读”问题。<br><strong>可重复读REPEATABLE READ：</strong><br>在同一事务中多次读取的数据是一致的。解决了脏读和不可重复读问题，存在“幻读”（在事务两次查询间隙，有其他事务又插入或删除了新的记录）。— MySQL<strong>默认隔离级别</strong>。<strong>可串行化SERIALIZABLE：</strong><br>强制事务串行化执行。即一个事物一个事物挨个来执行，可以解决上述所有问题。</p><h1 id="mysql的MVCC机制"><a href="#mysql的MVCC机制" class="headerlink" title="mysql的MVCC机制"></a>mysql的MVCC机制</h1><p>MVCC是一种多版本并发控制机制，是MySQL的InnoDB存储引擎实现隔离级别的一种具体方式，用于实现提交读和可重复读这两种隔离级别。MVCC是通过保存数据在某个时间点的快照来实现该机制，其在每行记录后面保存两个隐藏的列，分别保存这个行的创建版本号和删除版本号，然后Innodb的MVCC使用到的快照存储在Undo日志中，该日志通过回滚指针把一个数据行所有快照连接起来。</p><h1 id="SQL优化"><a href="#SQL优化" class="headerlink" title="SQL优化"></a>SQL优化</h1><p>在经常性的检索列上，建立必要<strong>索引</strong>，以加快搜索速率，避免全表扫描（索引覆盖扫描）；<br>多次查询同样的数据，可以考虑<strong>缓存</strong>该组数据；<br>审视<strong>select * form tables</strong>, 你需要所有列数据吗？<br><strong>切分</strong>查询（大查询切分成为小查询，避免一次性锁住大量数据）<br>分解关联查询（单表查询，结果在应用程序中进行关联，可以减少处理过程中的锁争用）<br>尽量先做单表查询；</p><h1 id="inner-join和left-join"><a href="#inner-join和left-join" class="headerlink" title="inner join和left join"></a>inner join和left join</h1><p>left join(左联接) 返回包括左表中的所有记录和右表中联结字段相等的记录<br>right join(右联接) 返回包括右表中的所有记录和左表中联结字段相等的记录<br>inner join(等值连接) 只返回两个表中联结字段相等的行<br> 表A、    B记录如下：<br>| aID　 | 　aNum |  |bID | |<br>|–|–|-|–|–|<br>| 1 | a20050111 | | 1| 2006032401|<br>| 2 |  a20050112|| 2|2006032402 |<br>| 3 | a20050113 || 3|2006032403 |<br>| 4 |  a20050114|| 4| 2006032404|<br>| 5 |  a20050115| |8 | 2006032408|<br>sql语句如下: </p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">select * from A</span><br><span class="line">left join B </span><br><span class="line">on A.aID = B.bID</span><br></pre></td></tr></table></figure><p>结果如下:<br>| aID　 | 　aNum |  |bID | |<br>|–|–|-|–|–|<br>| 1 | a20050111 | | 1| 2006032401|<br>| 2 |  a20050112|| 2|2006032402 |<br>| 3 | a20050113 || 3|2006032403 |<br>| 4 |  a20050114|| 4| 2006032404|<br>| 5 |  a20050115| |NULL | NULL| </p><h1 id="数据库引擎innoDB与MyISAM"><a href="#数据库引擎innoDB与MyISAM" class="headerlink" title="数据库引擎innoDB与MyISAM"></a>数据库引擎innoDB与MyISAM</h1><p>数据库引擎是用于存储、处理和保护数据的核心服务。在Mysql数据库中，常用的引擎为innoDB和MyISAM（MySQL5.6版本开始Innodb已经成为Mysql的默认引擎，之前是MyISAM）。</p><p><strong>数据库引擎 innoDB与MyIASM区别：</strong><br>1.InnoDB支持事务，支持外键，MyISAM都不支持;<br>2.InnoDB是聚集索引，数据文件是和索引绑在一起的，必须要有主键，通过主键索引效率很高。但是辅助索引需要两次查询，先查询到主键，然后再通过主键查询到数据。因此，主键不应该过大，因为主键太大，其他索引也都会很大。<br>MyISAM是非聚集索引，数据文件是分离的，索引保存的是数据文件的指针。主键索引和辅助索引是独立的;</p><ol start="3"><li>行数保存： InnoDB不保存表的具体行数，执行select count(*) from table时需要全表扫描。MyISAM用一个变量保存了整个表的行数，执行上述语句时只需要读出该变量即可，速度很快；</li><li>Innodb不支持全文索引，MyISAM支持全文索引，查询效率上MyISAM要高于Innodb；</li></ol><p><strong>如何选择存储引擎</strong><br>如果在应用中执行大量select(查询)操作，应该选MyIASM，如果在应用中执行大量的insert（插入）和update（更新）操作，应该选择innoDB<br>如果要提供提交、回滚、崩溃恢复能力的事物安全（ACID兼容）能力，并要求实现并发控制，InnoDB是一个好的选择</p><p>#查看数据库支持的存储引擎<br><code>show engines</code></p><p>#查看数据库当前使用的存储引擎,就是默认引擎是什么。<br><code>show variables like &#39;storage_engine&#39;</code><br>也可以在MySQL配置文件中查看。<br>windows - <code>my.ini</code>    Linux - <code>my.cnf</code></p><p>#查看数据库表所用的存储引擎<br><code>show create table table_name</code></p><p>#创建表指定存储引擎<br><code>create table table_name (column_name column_type) engine = engine_name</code></p><p>#修改表的存储引擎<br><code>alter table table_name engine=engine_name</code></p><p>#修改默认的存储引擎<br>在MySQL配置文件中修改下述内容：<code>default-storage-engine=INNODB</code><br><strong>MySQL的端口号是多少，如何修改这个端口号</strong><br>查看端口号:<br>登录mysql: <code>mysql -u root –p</code><br>查看端口号: <code>show global variables like &#39;port&#39;</code><br>mysql的默认端口是<strong>3306</strong>。（补充：sqlserver默认端口号为：1433；oracle默认端口号为：1521；DB2默认端口号为：5000；PostgreSQL默认端口号为：5432）<br>修改端口号：编辑<code>/etc/my.cnf</code>文件，早期版本有可能是my.conf文件名，增加端口参数，并且设定端口，注意该端口未被使用，保存退出。重启mysql。</p><h1 id="存储过程"><a href="#存储过程" class="headerlink" title="存储过程"></a>存储过程</h1><p>存储过程简单来说，就是为以后的使用而保存的一条或多条MySQL语句的集合。<br>目的：把处理封装，简化复杂的操作；所有开发人员和应用程序都使用同一存储过程，防止错误保证了数据的一致性；简化对变动的管理，只需要更改存储过程的代码。</p><p>#创建存储过程</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="function">create procedure <span class="title">porcedureName</span> <span class="params">()</span> </span></span><br><span class="line"><span class="function">begin </span></span><br><span class="line"><span class="function">    select name from user</span>; </span><br><span class="line">end;</span><br></pre></td></tr></table></figure><p>#调用存储过程：</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="function">call <span class="title">procedureName</span> <span class="params">()</span></span>;</span><br></pre></td></tr></table></figure><p>#删除存储过程</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">DROP PROCEDURE IF EXISTS porcedureName;</span><br></pre></td></tr></table></figure><p>#含参数</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="function">create procedure <span class="title">getTotalById</span> <span class="params">( </span></span></span><br><span class="line"><span class="function"><span class="params">    in userId <span class="keyword">int</span>, </span></span></span><br><span class="line"><span class="function"><span class="params">    out total decimal(<span class="number">8</span>,<span class="number">2</span>) </span></span></span><br><span class="line"><span class="function"><span class="params">)</span> </span></span><br><span class="line"><span class="function">BEGIN </span></span><br><span class="line"><span class="function">    select <span class="title">SUM</span><span class="params">(r.price)</span> from order r </span></span><br><span class="line">    where r.u_id = userId </span><br><span class="line">    into total; </span><br><span class="line">END;</span><br></pre></td></tr></table></figure><p>调用</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="function">call <span class="title">getTotalById</span><span class="params">(<span class="number">1</span>, @total)</span></span>; </span><br><span class="line">select @total;</span><br></pre></td></tr></table></figure><h1 id="数据库的第一二三范式"><a href="#数据库的第一二三范式" class="headerlink" title="数据库的第一二三范式"></a>数据库的第一二三范式</h1><p><strong>第一范式（1NF）</strong><br>数据库表的每一列都是不可分割的原子数据项，而不能是集合，数组，记录等非原子数据项。<br>通俗讲就是：一个字段只存储一项信息。<br><strong>第二范式</strong><br>如果关系模式R满足第一范式，并且R得所有非主属性都完全依赖于R的每一个候选关键属性，称R满足第二范式（属性<strong>完全依赖</strong>于每一个主键）。满足第一范式前提，当一个主键由多个属性共同组成时，才会发生不符合第二范式的情况。比如有两个属性的主键，不能存在这样的属性，它只依赖于主键中的一个属性，这就是不符合第二范式 。<br>非主键列是否完全依赖于主键，还是依赖于主键的一部分？<br><strong>第三范式</strong><br>定义：第三范式（属性不能传递依赖于主属性）。满足第二范式前提，如果某一属性依赖于其他非主键属性，而其他非主键属性又依赖于主键，那么这个属性就是间接依赖于主键，这被称作传递依赖于主属性。<br>非主键列是<strong>直接依赖于主键</strong>，还是直接依赖于非主键列？</p><h1 id="delete、truncate、drop的区别及应用场所"><a href="#delete、truncate、drop的区别及应用场所" class="headerlink" title="delete、truncate、drop的区别及应用场所"></a>delete、truncate、drop的区别及应用场所</h1><p>1、delete属于DML（数据库操作语言），DELETE语句执行删除的过程是每次从表中删除一行，并且同时将该行的删除操作作为事务记录在日志中保存以便进行进行回滚操作，truncate、drop属于DDL（数据库定义语言），不能回滚<br>2、在速度上，一般来说，<strong>drop&gt; truncate &gt; delete</strong><br>3、TRUNCATE 和DELETE只删除数据， DROP则删除整个表（结构和数据）<br>4、<code>Truncate table 表名</code> 速度快,而且效率高,因为: truncate table 在功能上与不带 WHERE 子句的 DELETE 语句相同：二者均删除表中的全部行。但 TRUNCATE TABLE 比 DELETE 速度快，且使用的系统和事务日志资源少。DELETE 语句每次删除一行，并在事务日志中为所删除的每行记录一项。TRUNCATE TABLE 通过释放存储表数据所用的数据页来删除数据，并且只在事务日志中记录页的释放。<br><strong>实例：删除学生表</strong><br>1、当你不再需要该表时， 用 drop;<br>2、当你仍要保留该表，但要删除所有记录时， 用 truncate;<br>3、当你要删除部分记录时， 用 delete。<br>drop table table_name : 删除表全部数据和表结构，立刻释放磁盘空间，不管是 Innodb 和 MyISAM;<br>truncate table table_name : 删除表全部数据，保留表结构，立刻释放磁盘空间 ，不管是 Innodb 和 MyISAM;<br>delete from table_name :删除表全部数据，表结构不变，对于 MyISAM 会立刻释放磁盘空间，InnoDB 不会释放磁盘空间;<br>delete from table_name where xxx : 带条件的删除，表结构不变，不管是 innodb 还是 MyISAM 都不会释放磁盘空间;<br>delete 操作以后，使用 optimize table table_name 会立刻释放磁盘空间，不管是 innodb 还是 myisam;</p><p>DELETE FROM users WHERE name = ‘Mike’ ORDER BY id DESC LIMIT 6;</p><h1 id="Redis数据类型"><a href="#Redis数据类型" class="headerlink" title="Redis数据类型"></a>Redis数据类型</h1><p>Redis通常被称为数据结构服务器<br>Redis支持五种数据类型：<br>1）<strong>String</strong>: 字符串：整数值、embstr编码的简单动态字符串、简单动态字符串（SDS)<br>2）<strong>List</strong>: 列表：压缩列表、双端链表<br>3）<strong>Hash</strong>: 哈希：压缩列表、字典<br>4）<strong>Set</strong>: 集合：整数集合、字典<br>5）<strong>Sorted Set</strong>: 有序集合：压缩列表、跳跃表和字典</p><h1 id="mongodb和redis的区别"><a href="#mongodb和redis的区别" class="headerlink" title="mongodb和redis的区别"></a>mongodb和redis的区别</h1><p><strong>内存管理机制上：</strong> Redis 数据全部存在内存，定期写入磁盘，当内存不够时，可以选择指定的 LRU 算法删除数据。MongoDB 数据存在内存，由 linux系统 mmap 实现，当内存不够时，只将热点数据放入内存，其他数据存在磁盘。<br><strong>支持的数据结构上：</strong> Redis 支持的数据结构丰富，包括hash、set、list等。<br>MongoDB 数据结构比较单一，但是支持丰富的数据表达，索引，最类似关系型数据库，支持的查询语言非常丰富</p><h1 id="Redis是单线程的，但是为什么这么高效呢"><a href="#Redis是单线程的，但是为什么这么高效呢" class="headerlink" title="Redis是单线程的，但是为什么这么高效呢?"></a>Redis是单线程的，但是为什么这么高效呢?</h1><p>I/O多路复用监听多个套接字<br>完全基于内存，内存操作快速<br>单进程单线程不用考虑切换/锁的问题</p><p>单进程多线程模型：MySQL、Memcached、Oracle（win）<br>多进程模型：Oracle（Linux）</p><h1 id="Redis的rehash怎么做的，为什么要渐进rehash，渐进rehash又是怎么实现的"><a href="#Redis的rehash怎么做的，为什么要渐进rehash，渐进rehash又是怎么实现的" class="headerlink" title="Redis的rehash怎么做的，为什么要渐进rehash，渐进rehash又是怎么实现的?"></a>Redis的rehash怎么做的，为什么要渐进rehash，渐进rehash又是怎么实现的?</h1><p>因为redis是单线程，当K很多时，如果一次性将键值对全部rehash，庞大的计算量会影响服务器性能，甚至可能会导致服务器在一段时间内停止服务。不可能一步完成整个rehash操作，所以redis是分多次、渐进式的rehash。渐进性哈希分为两种：<br>1）操作redis时，额外做一步rehash<br>对redis做读取、插入、删除等操作时，会把位于table[dict-&gt;rehashidx]位置的链表移动到新的dictht中，然后把rehashidx做加一操作，移动到后面一个槽位。<br>2）后台定时任务调用rehash<br>后台定时任务rehash调用链，同时可以通过server.hz控制rehash调用频率</p><p> </p>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;相关：&lt;br&gt;&lt;a href=&quot;https://blog.csdn.net/ffcjjhv/article/details/101433113&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;C++后台开发知识总结（一）C++基础&lt;/a&gt;&lt;br&gt;&lt;a href=&quot;https://blog.csdn.net/ffcjjhv/article/details/101481241&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;C++后台开发知识总结（二）数据库&lt;/a&gt;&lt;br&gt;&lt;a href=&quot;https://blog.csdn.net/ffcjjhv/article/details/101486572&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;C++后台开发知识总结（三）计算机网络&lt;/a&gt;&lt;br&gt;&lt;a href=&quot;https://blog.csdn.net/ffcjjhv/article/details/101546677&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;C++后台开发知识总结（四）操作系统/Linux 内核&lt;/a&gt;&lt;/p&gt;
&lt;h1 id=&quot;数据库索引&quot;&gt;&lt;a href=&quot;#数据库索引&quot; class=&quot;headerlink&quot; title=&quot;数据库索引&quot;&gt;&lt;/a&gt;数据库索引&lt;/h1&gt;&lt;p&gt;索引是存储引擎快速找到记录的一种数据结构。&lt;br&gt;&lt;strong&gt;添加索引原则：&lt;/strong&gt;&lt;br&gt;在查询中很少使用或者参考的列不应该创建索引。&lt;/p&gt;
    
    </summary>
    
      <category term="C++" scheme="http://yoursite.com/categories/C/"/>
    
      <category term="后台开发" scheme="http://yoursite.com/categories/%E5%90%8E%E5%8F%B0%E5%BC%80%E5%8F%91/"/>
    
    
      <category term="数据库" scheme="http://yoursite.com/tags/%E6%95%B0%E6%8D%AE%E5%BA%93/"/>
    
      <category term="后台开发" scheme="http://yoursite.com/tags/%E5%90%8E%E5%8F%B0%E5%BC%80%E5%8F%91/"/>
    
  </entry>
  
  <entry>
    <title>C++后台开发知识总结（一）C++基础</title>
    <link href="http://yoursite.com/2019/09/26/26/"/>
    <id>http://yoursite.com/2019/09/26/26/</id>
    <published>2019-09-26T11:13:52.000Z</published>
    <updated>2019-12-18T04:20:53.805Z</updated>
    
    <content type="html"><![CDATA[<p>相关：<br><a href="https://blog.csdn.net/ffcjjhv/article/details/101433113" target="_blank" rel="noopener">C++后台开发知识总结（一）C++基础</a><br><a href="https://blog.csdn.net/ffcjjhv/article/details/101481241" target="_blank" rel="noopener">C++后台开发知识总结（二）数据库</a><br><a href="https://blog.csdn.net/ffcjjhv/article/details/101486572" target="_blank" rel="noopener">C++后台开发知识总结（三）计算机网络</a><br><a href="https://blog.csdn.net/ffcjjhv/article/details/101546677" target="_blank" rel="noopener">C++后台开发知识总结（四）操作系统/Linux 内核</a></p><h1 id="extern-“C”的作用"><a href="#extern-“C”的作用" class="headerlink" title="extern “C”的作用"></a>extern “C”的作用</h1><p>extern “C”的主要作用就是为了能够正确实现C++代码调用其他C语言代码。加上extern “C”后，会指示编译器这部分代码<strong>按C语言（而不是C++）的方式进行编译</strong>。</p><a id="more"></a><p>原因是：C++支持函数重载，因此编译器编译函数的过程中会将<strong>函数的参数类型</strong>也加到编译后的代码中，而不仅仅是函数名；<br>而C语言并不支持函数重载，因此编译C语言代码的函数时不会带上函数的参数类型，一般只包括函数名。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">ifndef</span> __INCvxWorksh <span class="comment">/*防止该头文件被重复引用*/</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> __INCvxWorksh</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">ifdef</span> __cplusplus  <span class="comment">//告诉编译器，这部分代码按C语言的格式进行编译，而不是C++的</span></span></span><br><span class="line"><span class="keyword">extern</span> <span class="string">"C"</span>&#123;</span><br><span class="line"><span class="meta">#<span class="meta-keyword">endif</span></span></span><br><span class="line"> <span class="comment">/*…*/</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">ifdef</span> __cplusplus</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="meta">#<span class="meta-keyword">endif</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">endif</span> <span class="comment">/*end of __INCvxWorksh*/</span></span></span><br></pre></td></tr></table></figure><h1 id="C-和C的区别"><a href="#C-和C的区别" class="headerlink" title="C++和C的区别"></a>C++和C的区别</h1><p>设计思想上：<br>C++是<strong>面向对象</strong>的语言，而C是<strong>面向过程</strong>的结构化编程语言<br>语法上：<br>C++具有<strong>封装、继承和多态</strong>三种特性<br>C++相比C，增加多许多类型安全的功能，比如<strong>强制类型转换</strong><br>C++支持范式编程，比如<strong>模板类</strong>、函数模板等</p><h1 id="C-C-const关键字"><a href="#C-C-const关键字" class="headerlink" title="C/C++ const关键字"></a>C/C++ const关键字</h1><p>（1）欲阻止一个变量被改变，可以使用const关键字。在定义该const变量时，通常需要对它进行<strong>初始化</strong>，因为以后就没有机会再去改变它了；<br>（2）对<strong>指针</strong>来说，可以指定指针本身为const，也可以指定<strong>指针所指的数据</strong>为const，或二者同时指定为const；<br>（3）在一个函数声明中，const可以<strong>修饰形参</strong>，表明它是一个输入参数，在函数内部不能改变其值；可以阻止用户修改<strong>返回值</strong>。返回值也要相应的付给一个常量或常指针。<br>（4）对于类的成员函数，若指定其为const类型，则表明其是一个常函数，不能修改类的成员变量。</p><h1 id="C-C-static关键字"><a href="#C-C-static关键字" class="headerlink" title="C/C++ static关键字"></a>C/C++ static关键字</h1><p>1.全局静态变量<br>在全局变量前加上关键字static，全局变量就定义成一个全局静态变量.<br>静态存储区，在整个程序运行期间一直存在。<br>初始化：未经初始化的全局静态变量会被自动初始化为0<br>作用域：全局静态变量在声明他的<strong>文件之外是不可见</strong>的，准确地说是从定义之处开始，到文件结尾。<br>2.局部静态变量<br>在局部变量之前加上关键字static，局部变量就成为一个局部静态变量。<br>内存中的位置：静态存储区<br>初始化：未经初始化的全局静态变量会被自动初始化为0<br>作用域：作用域<strong>仍为局部作用域</strong>，当定义它的函数或者语句块结束的时候，作用域结束。但是当局部静态变量离开作用域后，并<strong>没有销毁</strong>，而是仍然驻留在内存当中，只不过我们不能再对它进行访问，直到该函数再次被调用，并且值不变；  </p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">fun</span><span class="params">()</span></span>&#123;</span><br><span class="line">    <span class="keyword">static</span> <span class="keyword">int</span> count = <span class="number">10</span>; <span class="comment">//在第一次进入这个函数的时候，变量a被初始化为10！并接着自减1</span></span><br><span class="line">    <span class="keyword">return</span> count--; <span class="comment">//以后每次进入该函数，a就不会被再次初始化了，仅进行自减1的操作   </span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>3.静态函数<br>在函数返回类型前加static，函数就定义为静态函数。函数的定义和声明在默认情况下都是extern的，但静态函数只是在声明他的文件当中可见，<strong>不能被其他文件</strong>所用。<br>函数的实现使用static修饰，那么这个函数只可在本cpp内使用，不会同其他cpp中的<strong>同名函数引起冲突</strong>；warning：不要再头文件中声明static的全局函数，不要在cpp内声明非static的全局函数，如果你要在多个cpp中复用该函数，就把它的声明提到头文件里去，否则cpp内部声明需加上static修饰；<br>4.类的静态成员及静态成员函数<br>对象与对象之间的成员变量是相互独立的。要想共用数据，则需要使用静态成员和静态方法。<br>只要在类中声明静态成员变量，即使不定义对象，也可以为静态成员变量分配空间，进而可以使用静态成员变量。<br>静态成员变量是在程序<strong>编译时</strong>分配空间，而在程序结束时释放空间。<br>初始化静态成员变量要在<strong>类的外面</strong>进行。不能用参数初始化表，对静态成员变量进行初始化。</p><p>在静态成员函数的实现中<strong>不能直接引用</strong>类中说明的非静态成员，可以引用类中说明的静态成员（这点非常重要）。<br>可以通过类名/对象名直接访问类的公有静态成员函数</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">test</span></span></span><br><span class="line"><span class="class">&#123;</span></span><br><span class="line"><span class="keyword">private</span>:</span><br><span class="line">    <span class="keyword">static</span> <span class="keyword">int</span> m_value;   <span class="comment">//定义私有类的静态成员变量</span></span><br><span class="line"> </span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function"><span class="keyword">static</span> <span class="keyword">int</span> <span class="title">getValue</span><span class="params">()</span>   <span class="comment">//定义类的静态成员函数</span></span></span><br><span class="line"><span class="function">    </span>&#123;</span><br><span class="line">      <span class="keyword">return</span> m_value;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br><span class="line"><span class="keyword">int</span> test::m_value = <span class="number">0</span>;    <span class="comment">//类的静态成员变量需要在类外分配内存空间</span></span><br><span class="line"> </span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    test t1;</span><br><span class="line">    test t2;</span><br><span class="line">    test t3;</span><br><span class="line"></span><br><span class="line">    <span class="comment">//通过类名直接调用公有静态成员函数，获取对象个数</span></span><br><span class="line">    <span class="built_in">cout</span> &lt;&lt; <span class="string">"test::m_value2 = "</span> &lt;&lt; test::getValue() &lt;&lt; <span class="built_in">endl</span>;  </span><br><span class="line">    <span class="comment">//通过对象名调用静态成员函数获取对象个数</span></span><br><span class="line">    <span class="built_in">cout</span> &lt;&lt; <span class="string">"t3.getValue() = "</span> &lt;&lt; t3.getValue() &lt;&lt; <span class="built_in">endl</span>;</span><br><span class="line">    system(<span class="string">"pause"</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h1 id="C-C-volatile关键字"><a href="#C-C-volatile关键字" class="headerlink" title="C/C++ volatile关键字"></a>C/C++ volatile关键字</h1><p>volatile是“易变的”、“不稳定”的意思。volatile是C的一个较为少用的关键字，它用来解决变量在“共享”环境下容易出现读取错误的问题<br>变量可能会被意想不到地改变，即在你程序运行过程中一直会变，你希望这个值被正确的处理，凡是申明为volatile的变量，每次都是从内存中读取变量的值，而不是在某些情况下直接从寄存器中取值。（有可能被其他的程序（如中断程序、另外的线程等）所修改）</p><p>应用场景：<br>（1）并行设备的硬件寄存器（如状态寄存器）反复读操作，编译器在优化后，也许读操作只做了一次<br>（2）一个中断服务子程序中访问到的变量<br>（3）多线程应用中被多个任务共享的变量<br>当多个线程共享某一个变量时，该变量的值会被某一个线程更改，应该用 volatile 声明。作用是防止编译器优化把变量从内存装入CPU寄存器中，当一个线程更改变量后，未及时同步到其它线程中导致程序出错。</p><p>（1）一个参数既可以是const还可以是volatile吗？为什么？<br>是的。一个例子是只读的状态寄存器。它是volatile因为它可能被意想不到地改变。它是const因为程序不应该试图去修改它。<br>（2）一个指针可以是volatile吗？为什么？<br>是的。尽管这并不很常见。一个例子是当一个中断服务子程序修该一个指向一个buffer的指针时<br>（3）下面的函数有什么错误？</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">square</span><span class="params">(<span class="keyword">volatile</span> <span class="keyword">int</span> *ptr)</span> </span></span><br><span class="line"><span class="function"></span>&#123; </span><br><span class="line">    <span class="keyword">return</span> *ptr * *ptr; </span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">//正确的代码如下：</span></span><br><span class="line"><span class="function"><span class="keyword">long</span> <span class="title">square</span><span class="params">(<span class="keyword">volatile</span> <span class="keyword">int</span> *ptr)</span> </span></span><br><span class="line"><span class="function"></span>&#123; </span><br><span class="line">    <span class="keyword">int</span> a; </span><br><span class="line">    a = *ptr; </span><br><span class="line">    <span class="keyword">return</span> a * a; </span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>volatile能够避免编译器优化带来的错误，但使用volatile的同时，也需要注意频繁地使用volatile很可能会增加代码尺寸和降低性能，因此要合理的使用volatile。</p><h1 id="C-C-restrict关键字"><a href="#C-C-restrict关键字" class="headerlink" title="C/C++ restrict关键字"></a>C/C++ restrict关键字</h1><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> <span class="keyword">int</span> a=<span class="number">10</span>;</span><br><span class="line"><span class="keyword">int</span> * b=&amp;a; <span class="comment">//警告：初始化丢弃了指针目标类型的限定</span></span><br></pre></td></tr></table></figure><p>b失去了对目标对象的const的限定，并且可以通过指针b更改它们共同指向的空间。<br>const是无法保证某个对象不被更改的，restrict关键字是修饰指针的，对该指针指向的空间的访问，<strong>只能从这个指针</strong>进入。</p><h1 id="什么是右值引用，跟左值又有什么区别？"><a href="#什么是右值引用，跟左值又有什么区别？" class="headerlink" title="什么是右值引用，跟左值又有什么区别？"></a>什么是右值引用，跟左值又有什么区别？</h1><p>主要目的有两个方面：<br>1.消除两个对象交互时<strong>不必要的对象拷贝</strong>，节省运算存储资源，提高效率。<br>2.能够更简洁明确地定义泛型函数。<br>左值：能对表达式取地址、或具名对象/变量。一般指表达式结束后依然存在的持久对象。<br>右值：不能对表达式取地址，或匿名对象。一般指表达式结束就不再存在的<strong>临时对象</strong>。右值引用和左值引用的区别：<br>（1）左值可以寻址，而右值不可以。<br>（2）左值可以被赋值，右值不可以被赋值，可以用来给左值赋值。<br>（3）左值可变,右值不可变（仅对基础类型适用，用户自定义类型右值引用可以通过成员函数改变）。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">int</span> i = getVar();</span><br></pre></td></tr></table></figure><p>从getVar()函数获取一个整形值，然而，这行代码会产生两种类型的值，一种是左值i，一种是函数getVar()返回的临时值，这个临时值在表达式结束后就销毁了，而左值i在表达式结束后仍然存在，这个临时值就是右值。区分左值和右值的一个简单办法是：看能不能对表达式取地址，如果能，则为左值，否则为右值。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">int</span> i = <span class="number">0</span>;</span><br></pre></td></tr></table></figure><p>i 是左值，0 是字面量，就是右值。在上面的代码中，i 可以被引用，0 就不可以了。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">int</span>&amp;&amp; k = getVar();</span><br></pre></td></tr></table></figure><p>对右值的引用就是右值引用，getVar()产生的临时值不会像第一行代码那样，在表达式结束之后就销毁了，而是会被“续命”，他的生命周期将会通过右值引用得以延续，和变量k的声明周期一样长。</p><h1 id="C-11有哪些新特性"><a href="#C-11有哪些新特性" class="headerlink" title="C++11有哪些新特性"></a>C++11有哪些新特性</h1><p><strong>1.auto关键字</strong><br>编译器可以根据初始值自动推导出类型。但是不能用于函数传参以及数组类型的推导<br><strong>2.nullptr关键字</strong><br>nullptr是一种特殊类型的字面值，它可以被转换成任意其它的指针类型；而NULL一般被宏定义为0，在遇到重载时可能会出现问题。<br><strong>3.智能指针</strong><br>C++11新增了std::shared_ptr、std::weak_ptr等类型的智能指针，用于解决内存管理的问题。<br><strong>4.初始化列表</strong><br>使用初始化列表来对类进行初始化</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Line</span></span></span><br><span class="line"><span class="class">&#123;</span></span><br><span class="line">   <span class="keyword">public</span>:</span><br><span class="line">      <span class="function"><span class="keyword">double</span> <span class="title">getLength</span><span class="params">( <span class="keyword">void</span> )</span></span>;</span><br><span class="line">      Line(<span class="keyword">double</span> len);  </span><br><span class="line"> </span><br><span class="line">   <span class="keyword">private</span>:</span><br><span class="line">      <span class="keyword">double</span> length;</span><br><span class="line">&#125;;</span><br><span class="line"><span class="comment">// 成员函数定义，包括构造函数</span></span><br><span class="line">Line::Line( <span class="keyword">double</span> len)</span><br><span class="line">&#123;</span><br><span class="line">    <span class="built_in">cout</span> &lt;&lt; <span class="string">"Object is being created, length = "</span> &lt;&lt; len &lt;&lt; <span class="built_in">endl</span>;</span><br><span class="line">    length = len;</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">// 等同于</span></span><br><span class="line">Line::Line( <span class="keyword">double</span> len): length(len)</span><br><span class="line">&#123;</span><br><span class="line">    <span class="built_in">cout</span> &lt;&lt; <span class="string">"Object is being created, length = "</span> &lt;&lt; len &lt;&lt; <span class="built_in">endl</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p><strong>5.右值引用</strong><br>基于右值引用可以实现移动语义和完美转发，消除两个对象交互时不必要的对象拷贝，节省运算存储资源，提高效率<br><strong>6.lambda</strong><br>Lambda表达式定义一个匿名函数，并且可以捕获一定范围内的变量<br><strong>[捕获列表] (参数列表) mutable或exception声明 -&gt;返回值类型 {函数体}</strong><br>[捕获列表]，捕获上下文变量以供lambda使用。标识一个Lambda的开始，这部分必须存在，不能省略。<br>(参数列表)，与普通函数的参数列表一致，如果不需要传递参数，则可以连通括号一起省略。参数可以通过按值（如：(a,b)）和按引用（如：(&amp;a,&amp;b)）两种方式进行传递。<br>mutable是修饰符，默认情况下lambda函数总是一个const函数，Mutable可以取消其常量性。在使用该修饰符时，参数列表不可省略。<br>-&gt;返回值类型, 当返回值为void，或者函数体中只有一处return的地方（此时编译器可以自动推断出返回值类型）时，这部分可以省略。<br>{函数体}，内容与普通函数一样，除了可以使用参数之外，还可以使用所捕获的变量。<br>Lambda表达式与普通函数最大的区别就是其可以通过捕获列表访问一些上下文中的数据。<br> <figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; vctTemp;</span><br><span class="line">vctTemp.push_back(<span class="number">1</span>);</span><br><span class="line">vctTemp.push_back(<span class="number">2</span>);</span><br><span class="line"></span><br><span class="line">&#123; <span class="comment">// 无函数对象参数，输出：1 2</span></span><br><span class="line">  for_each(vctTemp.begin(), vctTemp.end(), [](<span class="keyword">int</span> v)&#123; <span class="built_in">cout</span> &lt;&lt; v &lt;&lt; <span class="built_in">endl</span>; &#125;);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">&#123; <span class="comment">// 以值方式传递作用域内所有可见的局部变量（包括this），输出：11 12</span></span><br><span class="line">  <span class="keyword">int</span> a = <span class="number">10</span>;</span><br><span class="line">  for_each(vctTemp.begin(), vctTemp.end(), [=](<span class="keyword">int</span> v)&#123; <span class="built_in">cout</span> &lt;&lt; v+a &lt;&lt; <span class="built_in">endl</span>; &#125;);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">&#123; <span class="comment">// 以引用方式传递作用域内所有可见的局部变量（包括this），输出：11 13 12</span></span><br><span class="line">  <span class="keyword">int</span> a = <span class="number">10</span>;</span><br><span class="line">  for_each(vctTemp.begin(), vctTemp.end(), [&amp;](<span class="keyword">int</span> v)<span class="keyword">mutable</span>&#123; <span class="built_in">cout</span> &lt;&lt; v+a &lt;&lt; <span class="built_in">endl</span>; a++; &#125;);</span><br><span class="line">  <span class="built_in">cout</span> &lt;&lt; a &lt;&lt; <span class="built_in">endl</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">&#123; <span class="comment">// 以值方式传递局部变量a，输出：11 13 10</span></span><br><span class="line">  <span class="keyword">int</span> a = <span class="number">10</span>;</span><br><span class="line">  for_each(vctTemp.begin(), vctTemp.end(), [a](<span class="keyword">int</span> v)<span class="keyword">mutable</span>&#123; <span class="built_in">cout</span> &lt;&lt; v+a &lt;&lt; <span class="built_in">endl</span>; a++; &#125;);</span><br><span class="line">  <span class="built_in">cout</span> &lt;&lt; a &lt;&lt; <span class="built_in">endl</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">&#123; <span class="comment">// 以引用方式传递局部变量a，输出：11 13 12</span></span><br><span class="line">  <span class="keyword">int</span> a = <span class="number">10</span>;</span><br><span class="line">  for_each(vctTemp.begin(), vctTemp.end(), [&amp;a](<span class="keyword">int</span> v)&#123; <span class="built_in">cout</span> &lt;&lt; v+a &lt;&lt; <span class="built_in">endl</span>; a++; &#125;);</span><br><span class="line">  <span class="built_in">cout</span> &lt;&lt; a &lt;&lt; <span class="built_in">endl</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">&#123; <span class="comment">// 传递this，输出：21 22</span></span><br><span class="line">  for_each(vctTemp.begin(), vctTemp.end(), [<span class="keyword">this</span>](<span class="keyword">int</span> v)&#123; <span class="built_in">cout</span> &lt;&lt; v+m_nData &lt;&lt; <span class="built_in">endl</span>; &#125;);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">&#123; <span class="comment">// 除b按引用传递外，其他均按值传递，输出：11 12 17</span></span><br><span class="line">  <span class="keyword">int</span> a = <span class="number">10</span>;</span><br><span class="line">  <span class="keyword">int</span> b = <span class="number">15</span>;</span><br><span class="line">  for_each(vctTemp.begin(), vctTemp.end(), [=, &amp;b](<span class="keyword">int</span> v)&#123; <span class="built_in">cout</span> &lt;&lt; v+a &lt;&lt; <span class="built_in">endl</span>; b++; &#125;);</span><br><span class="line">  <span class="built_in">cout</span> &lt;&lt; b &lt;&lt; <span class="built_in">endl</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">&#123; <span class="comment">// 操作符重载函数参数按引用传递，输出：2 3</span></span><br><span class="line">  for_each(vctTemp.begin(), vctTemp.end(), [](<span class="keyword">int</span> &amp;v)&#123; v++; &#125;);</span><br><span class="line">  for_each(vctTemp.begin(), vctTemp.end(), [](<span class="keyword">int</span> v)&#123; <span class="built_in">cout</span> &lt;&lt; v &lt;&lt; <span class="built_in">endl</span>; &#125;);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">&#123; <span class="comment">// 空的Lambda表达式</span></span><br><span class="line">  []()&#123;&#125;();</span><br><span class="line">  []&#123;&#125;();</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p><p><strong>7.可变参数模板</strong><br>C++11的可变参数模板，对参数进行了高度泛化，可以表示任意数目、任意类型的参数，其语法为：在class或typename后面带上省略号。<br>通过递归函数展开参数包，需要提供一个参数包展开的函数和一个递归终止函数。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//递归终止函数</span></span><br><span class="line"><span class="keyword">template</span>&lt;<span class="keyword">typename</span> T&gt;</span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">myprint</span><span class="params">(T end)</span><span class="comment">//递归到最后一次，调用单参数函数</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">  <span class="built_in">cout</span> &lt;&lt; <span class="string">"parameter "</span> &lt;&lt; end &lt;&lt; <span class="built_in">endl</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//展开函数</span></span><br><span class="line"><span class="keyword">template</span>&lt;<span class="keyword">typename</span> T, <span class="class"><span class="keyword">class</span> ...<span class="title">Args</span>&gt;</span></span><br><span class="line"><span class="class"><span class="title">void</span> <span class="title">myprint</span>(<span class="title">T</span> <span class="title">head</span>, <span class="title">Args</span>... <span class="title">rest</span>)</span></span><br><span class="line"><span class="class">&#123;</span></span><br><span class="line">  <span class="built_in">cout</span> &lt;&lt; <span class="string">"parameter "</span> &lt;&lt; head &lt;&lt; <span class="built_in">endl</span>;</span><br><span class="line">  myprint(rest...);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">  myprint(<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>);</span><br><span class="line">  <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>8.atomic原子操作用于多线程资源互斥操作<br>9.新增STL容器array以及tuple</p><h1 id="C-智能指针"><a href="#C-智能指针" class="headerlink" title="C++智能指针"></a>C++智能指针</h1><p>智能指针主要用于管理在堆上分配的内存，它将普通的指针封装为一个栈对象。当栈对象的生存周期结束后，会在析构函数中释放掉申请的内存，从而<strong>防止内存泄漏</strong>。C++ 11中最常用的智能指针类型为shared_ptr,它采用<strong>引用计数</strong>的方法，记录当前内存资源被多少个智能指针引用。该引用计数的内存在堆上分配。当新增一个时引用计数加1，当过期时引用计数减一。只有引用计数为0时，智能指针才会自动释放引用的内存资源。<br>对shared_ptr进行初始化时不能将一个普通指针直接赋值给智能指针，因为一个是指针，一个是类。可以通过make_shared函数或者通过构造函数传入普通指针。并可以通过get函数获得普通指针。<br>C++里面的四个智能指针: <strong>auto_ptr</strong>, <strong>shared_ptr</strong>, <strong>weak_ptr</strong>, <strong>unique_ptr</strong> 其中后三个是c++11支持，并且第一个已经被11弃用。#include&lt;memory&gt;<br>1.<strong>unique_ptr</strong>（替换auto_ptr）<br>保证同一时间内只有一个智能指针可以指向该对象。它对于避免资源泄露(例如“以new创建对象后因为发生异常而忘记调用delete”)特别有用。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">unique_ptr</span>&lt;<span class="built_in">string</span>&gt; p3 (<span class="keyword">new</span> <span class="built_in">string</span> (<span class="string">"auto"</span>));   <span class="comment">//#4</span></span><br><span class="line"><span class="built_in">unique_ptr</span>&lt;<span class="built_in">string</span>&gt; p4；                       <span class="comment">//#5</span></span><br><span class="line">p4 = p3;<span class="comment">//此时会报错！！</span></span><br></pre></td></tr></table></figure><p>编译器认为p4=p3非法，避免了p3不再指向有效数据的问题。因此，unique_ptr比auto_ptr更安全。<br>当程序试图将一个 unique_ptr 赋值给另一个时，如果源 unique_ptr 是个临时右值，编译器允许这么做；如果源 unique_ptr 将存在一段时间，编译器将禁止这么做，比如：</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">unique_ptr</span>&lt;<span class="built_in">string</span>&gt; pu1(<span class="keyword">new</span> <span class="built_in">string</span> (<span class="string">"hello world"</span>));</span><br><span class="line"><span class="built_in">unique_ptr</span>&lt;<span class="built_in">string</span>&gt; pu2;</span><br><span class="line">pu2 = pu1;                                      <span class="comment">// #1 not allowed</span></span><br><span class="line"><span class="built_in">unique_ptr</span>&lt;<span class="built_in">string</span>&gt; pu3;</span><br><span class="line">pu3 = <span class="built_in">unique_ptr</span>&lt;<span class="built_in">string</span>&gt;(<span class="keyword">new</span> <span class="built_in">string</span> (<span class="string">"You"</span>));   <span class="comment">// #2 allowed</span></span><br></pre></td></tr></table></figure><p>其中#1留下悬挂的unique_ptr(pu1)，这可能导致危害。而#2不会留下悬挂的unique_ptr，因为它调用 unique_ptr 的构造函数，该构造函数创建的临时对象在其所有权让给 pu3 后就会被销毁。这种随情况而已的行为表明，unique_ptr 优于允许两种赋值的auto_ptr 。<br>注：如果确实想执行类似与#1的操作，要安全的重用这种指针，可给它赋新值。C++有一个标准库函数std::move()，能够将一个unique_ptr赋给另一个。</p><ol start="2"><li><strong>shared_ptr</strong><br>多个智能指针可以指向相同对象，该对象和其相关资源会在“最后一个引用被销毁”时候释放。资源可以被多个指针共享，它使用计数机制来表明资源被几个指针共享。可以通过成员函数use_count()来查看资源的所有者个数。除了可以通过new来构造，还可以通过传入auto_ptr, unique_ptr,weak_ptr来构造。当我们调用release()时，当前指针会释放资源所有权，计数减一。当计数等于0时，资源会被释放。<br>shared_ptr 是为了解决 auto_ptr 在对象所有权上的<strong>局限性</strong>(auto_ptr 是独占的), 在使用引用计数的机制上提供了可以共享所有权的智能指针。<br>成员函数：</li></ol><p><strong>use_count 返回引用计数的个数</strong><br>unique 返回是否是独占所有权( use_count 为 1)<br>swap 交换两个 shared_ptr 对象(即交换所拥有的对象)<br>reset 放弃内部对象的所有权或拥有对象的变更, 会引起原有对象的引用计数的减少<br>get 返回内部对象(指针), 由于已经重载了()方法, 因此和直接使用对象是一样的.如 shared_ptr<int> sp(new int(1)); sp 与 sp.get()是等价的</int></p><ol start="3"><li><strong>weak_ptr</strong><br>weak_ptr 是一种不控制对象生命周期的智能指针, 它指向一个 shared_ptr 管理的对象. 进行该对象的内存管理的是那个强引用的 shared_ptr.<br>weak_ptr只是提供了对管理对象的一个<strong>访问手段</strong>。weak_ptr 设计的目的是为配合 shared_ptr 而引入的一种智能指针来协助 shared_ptr 工作, 它只可以从一个 shared_ptr 或另一个 weak_ptr 对象构造, 它的构造和析构<strong>不会引起引用记数的增加或减少</strong>。weak_ptr是用来解决shared_ptr相互引用时的<strong>死锁</strong>问题,如果说两个shared_ptr相互引用,那么这两个指针的引用计数永远不可能下降为0,资源永远不会释放。它是对对象的一种弱引用，不会增加对象的引用计数，和shared_ptr之间可以相互转化，shared_ptr可以直接赋值给它，它可以通过调用lock函数来获得shared_ptr。<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">B</span>;</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">A</span></span></span><br><span class="line"><span class="class">&#123;</span></span><br><span class="line">  <span class="keyword">public</span>:</span><br><span class="line">  <span class="built_in">shared_ptr</span>&lt;B&gt; pb_;</span><br><span class="line">  ~A()&#123;</span><br><span class="line">    <span class="built_in">cout</span>&lt;&lt;<span class="string">"A delete\n"</span>;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;;</span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">B</span></span></span><br><span class="line"><span class="class">&#123;</span></span><br><span class="line">  <span class="keyword">public</span>:</span><br><span class="line">  <span class="built_in">shared_ptr</span>&lt;A&gt; pa_;</span><br><span class="line">  ~B()&#123;</span><br><span class="line">    <span class="built_in">cout</span>&lt;&lt;<span class="string">"B delete\n"</span>;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;;</span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">fun</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">  <span class="built_in">shared_ptr</span>&lt;B&gt; pb(<span class="keyword">new</span> B());</span><br><span class="line">  <span class="built_in">shared_ptr</span>&lt;A&gt; pa(<span class="keyword">new</span> A());</span><br><span class="line">  pb-&gt;pa_ = pa;</span><br><span class="line">  pa-&gt;pb_ = pb;</span><br><span class="line">  <span class="built_in">cout</span>&lt;&lt;pb.use_count()&lt;&lt;<span class="built_in">endl</span>; <span class="comment">//2</span></span><br><span class="line">  <span class="built_in">cout</span>&lt;&lt;pa.use_count()&lt;&lt;<span class="built_in">endl</span>; <span class="comment">//2</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">  fun();</span><br><span class="line">  <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></li></ol><p>可以看到fun函数中pa ，pb之间互相引用，两个资源的引用计数为2，当要跳出函数时，智能指针pa，pb析构时两个资源引用计数会减一，但是两者引用计数还是为1，导致跳出函数时资源没有被释放（A B的析构函数没有被调用），如果把其中一个改为weak_ptr就可以了，我们把类A里面的shared_ptr pb_; 改为weak_ptr pb_; 运行结果如下<img src="https://img-blog.csdnimg.cn/20190926135120411.png" alt="在这里插入图片描述"> ，这样的话，资源B的引用开始就只有1，当pb析构时，B的计数变为0，B得到释放，B释放的同时也会使A的计数减一，同时pa析构时使A的计数减一，那么A的计数为0，A得到释放。<br>注意的是我们<strong>不能通过weak_ptr直接访问对象的方法</strong>，比如B对象中有一个方法print(),我们不能这样访问，pa-&gt;pb_-&gt;print(); 因为pb_是一个weak_ptr，应该先把它转化为shared_ptr,如：</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">shared_ptr</span> p = pa-&gt;pb_.lock();</span><br><span class="line">p-&gt;print();</span><br></pre></td></tr></table></figure><h1 id="隐式类型转换"><a href="#隐式类型转换" class="headerlink" title="隐式类型转换"></a>隐式类型转换</h1><p>隐式转换指的是<strong>不需要用户干预</strong>，编译器私下进行的类型转换行为。<br>首先，对于内置类型，低精度的变量给高精度变量赋值会发生隐式类型转换。如： int 到 double</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//混合类型的算术运算表达式中</span></span><br><span class="line"><span class="keyword">int</span> a = <span class="number">3</span>;</span><br><span class="line"><span class="keyword">double</span> b = <span class="number">4.5</span>;</span><br><span class="line"><span class="keyword">double</span> c = a + b;     <span class="comment">// a 将被自动转换为 double 类型，再加法。</span></span><br><span class="line"><span class="comment">//不同类型的赋值操作中//</span></span><br><span class="line"><span class="keyword">int</span> a = <span class="literal">true</span>;         <span class="comment">// bool 类型转换为 int 类型</span></span><br><span class="line"><span class="keyword">int</span> *ptr = null;      <span class="comment">// null 被转换为 int * 类型</span></span><br><span class="line"><span class="comment">//函数参数传值</span></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">func</span><span class="params">(<span class="keyword">double</span> a)</span> </span>&#123;&#125;;</span><br><span class="line">func(<span class="number">1</span>);               <span class="comment">// 1 被隐式的转换为 double 类型1.0</span></span><br><span class="line"><span class="comment">//函数返回值</span></span><br><span class="line"><span class="function"><span class="keyword">double</span> <span class="title">add</span><span class="params">(<span class="keyword">int</span> a, <span class="keyword">int</span> b)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="keyword">return</span> a + b;      <span class="comment">// 运算的结果会被隐式的转换为 double 类型再返回</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>其次，对于只存在<strong>单个参数的构造函数</strong>的对象构造来说，函数调用可以直接使用该参数传入，编译器会自动调用其构造函数生成临时对象。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="function">BOOK <span class="title">A</span><span class="params">(<span class="string">"A-A-A"</span>)</span></span>;</span><br><span class="line"><span class="function">BOOK <span class="title">B</span><span class="params">(<span class="string">"B-B-B"</span>)</span></span>;</span><br><span class="line"><span class="built_in">cout</span>&lt;&lt;A.isSameISBN(B)&lt;&lt;<span class="built_in">endl</span>;   <span class="comment">//正经地进行比较，无需发生转换</span></span><br><span class="line"><span class="built_in">cout</span>&lt;&lt;A.isSameISBN(<span class="built_in">string</span>(<span class="string">"A-A-A"</span>))&lt;&lt;<span class="built_in">endl</span>; <span class="comment">//此处即发生一个隐式转换：string类型--&gt;BOOK类型，借助BOOK的构造函数进行转换，以满足isSameISBN函数的参数期待。</span></span><br></pre></td></tr></table></figure><p>禁止隐式转换：explicit，该关键字只能用来修饰类内部的构造函数；</p><figure class="highlight"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">explicit BOOK(string ISBN,float price=0.0f):_bookISBN(ISBN),_price(price)&#123;&#125;</span><br></pre></td></tr></table></figure><h1 id="C-四种类型转换"><a href="#C-四种类型转换" class="headerlink" title="C++四种类型转换"></a>C++四种类型转换</h1><p>C风格的强制类型转换很简单，均用 Type b = (Type)a 形式转换。<br>C++风格的类型转换提供了4种类型转换操作符来应对不同场合的应用<br>1、<strong>const_cast</strong> 去掉类型的const或volatile属性<br>去掉类型的const或volatile属性</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">T</span> &#123;</span></span><br><span class="line">    <span class="keyword">int</span> i;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> T a;</span><br><span class="line"><span class="comment">//a.i = 10;  //直接修改const类型，编译错误</span></span><br><span class="line">T &amp;b = <span class="keyword">const_cast</span>&lt;T&amp;&gt;(a);</span><br><span class="line">b.i = <span class="number">10</span>;</span><br></pre></td></tr></table></figure><p>2、<strong>static_cast</strong> 无条件转换，静态类型转换<br>基类和子类之间的转换：其中子类指针转换为父类指针是安全的，但父类指针转换为子类指针是不安全的（基类和子类之间的动态类型转换建议用dynamic_cast）。<br><strong>基本数据类型</strong>转换，enum，struct，int，char，float等。static_cast<strong>不能进行无关类型</strong>（如非基类和子类）指针之间的转换。<br>把任何类型的表达式<strong>转换成void</strong>类型。<br>3、<strong>dynamic_cast</strong> 有条件转换，动态类型转换，运行时检查类型安全<br>更多使用static_cast，dynamic本身只能用于<strong>存在虚函数的父子关系</strong>的强制类型转换，对于指针，转换失败则返回nullptr，对于引用，转换失败会抛出异常<br>4、<strong>reinterpret_cast</strong> 仅重新解释类型，但没有进行二进制的转换<br>可以用于<strong>任意类型</strong>的指针之间的转换，对转换的结果<strong>不做任何保证</strong><br>为什么不使用C的强制转换？<br>C的强制转换表面上看起来功能强大什么都能转，但是转化不够明确，不能进行错误检查，容易出错。</p><h1 id="C-源文件从文本到可执行文件经历的过程"><a href="#C-源文件从文本到可执行文件经历的过程" class="headerlink" title="C++源文件从文本到可执行文件经历的过程"></a>C++源文件从文本到可执行文件经历的过程</h1><p>对于C++源文件，从文本到可执行文件一般需要四个过程：<br><strong>预处理阶段</strong>：主要处理源代码文件中的以“#”开头的预编译指令。对源代码文件中文件包含关系（头文件）、预编译语句（宏定义）进行分析和替换，生成预编译文件。<br><strong>编译阶段</strong>：将经过预处理后的预编译文件转换成特定汇编代码，生成汇编文件<br><strong>汇编阶段</strong>：将编译阶段生成的汇编文件转化成机器码，生成可重定位目标文件<br><strong>链接阶段</strong>：将多个目标文件及所需要的库连接成最终的可执行目标文件</p><h1 id="静态链接和动态链接"><a href="#静态链接和动态链接" class="headerlink" title="静态链接和动态链接"></a>静态链接和动态链接</h1><p>1、静态链接：<br>函数和数据被编译进一个二进制文件。在使用静态库的情况下，在编译链接可执行文件时，链接器从库中复制这些函数和数据并把它们和应用程序的其它模块组合起来创建最终的可执行文件。<br>空间浪费：因为每个可执行程序中对所有需要的目标文件都要有一份副本，所以如果多个程序对同一个目标文件都有依赖，会出现同一个目标文件都在内存存在多个副本；<br>更新困难：每当库函数的代码修改了，这个时候就需要<strong>重新进行编译链接</strong>形成可执行程序。<br>运行速度快：但是静态链接的优点就是，在可执行程序中已经具备了所有执行程序所需要的任何东西，在执行的时候<strong>运行速度快</strong>。2、动态链接：<br>动态链接的基本思想是把程序按照模块拆分成各个相对独立部分，在程序<strong>运行时才将它们链接在一起形成一个完整的程序</strong>，而不是像静态链接一样把所有程序模块都链接成一个单独的可执行文件。<br>共享库：就是即使需要每个程序都依赖同一个库，但是该库不会像静态链接那样在内存中存在多分，副本，而是这多个程序在执行时共享同一份副本；<br>更新方便：更新时只需要<strong>替换原来的目标文件</strong>，而无需将所有的程序再重新链接一遍。当程序下一次运行时，新版本的目标文件会被自动加载到内存并且链接起来，程序就完成了升级的目标。<br>性能损耗：因为把链接推迟到了程序运行时，所以<strong>每次执行程序都需要进行链接</strong>，所以性能会有一定损失。</p><h1 id="include头文件的顺序以及双引号””和尖括号-lt-gt-的区别"><a href="#include头文件的顺序以及双引号””和尖括号-lt-gt-的区别" class="headerlink" title="include头文件的顺序以及双引号””和尖括号&lt;&gt;的区别"></a>include头文件的顺序以及双引号””和尖括号&lt;&gt;的区别</h1><p>Include头文件的顺序：对于include的头文件来说，如果在文件a.h中声明一个在文件b.h中定义的变量，而不引用b.h。那么要在a.c文件中引用b.h文件，并且要先引用b.h，后引用a.h,否则汇报变量类型未声明错误。<br>双引号和尖括号的区别：编译器预处理阶段查找头文件的路径不一样。<br>对于使用双引号包含的头文件，查找头文件路径的顺序为：<br><strong>当前头文件目录 -&gt; 编译器设置的头文件路径（编译器可使用-I显式指定搜索路径 -&gt; 系统变量CPLUS_INCLUDE_PATH/C_INCLUDE_PATH指定的头文件路径</strong><br>对于使用尖括号包含的头文件，查找头文件的路径顺序为：<br><strong>编译器设置的头文件路径（编译器可使用-I显式指定搜索路径）-&gt; 系统变量CPLUS_INCLUDE_PATH/C_INCLUDE_PATH指定的头文件路径</strong></p><h1 id="什么时候会发生段错误"><a href="#什么时候会发生段错误" class="headerlink" title="什么时候会发生段错误"></a>什么时候会发生段错误</h1><p>段错误通常发生在<strong>访问非法内存地址</strong>的时候，具体来说分为以下几种情况：<br>使用野指针(指向一个不存在的对象或者未申请访问受限内存区域的指针)<br>试图修改字符串常量的内容</p><h1 id="C-模板"><a href="#C-模板" class="headerlink" title="C++ 模板"></a>C++ 模板</h1><p>模板是泛型编程的基础，泛型编程即以一种独立于任何特定类型的方式编写代码。<br>模板是创建泛型类或函数的蓝图或公式。库容器，比如迭代器和算法，都是泛型编程的例子，它们都使用了模板的概念。每个容器都有一个单一的定义，比如 向量，我们可以定义许多不同类型的向量，比如 vector &lt;int&gt; 或 vector &lt;string&gt;<br>函数模板</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;iostream&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;string&gt;</span></span></span><br><span class="line"> </span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> <span class="built_in">std</span>;</span><br><span class="line"> </span><br><span class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> T&gt;</span><br><span class="line"><span class="function"><span class="keyword">inline</span> T <span class="keyword">const</span>&amp; <span class="title">Max</span> <span class="params">(T <span class="keyword">const</span>&amp; a, T <span class="keyword">const</span>&amp; b)</span> </span></span><br><span class="line"><span class="function"></span>&#123; </span><br><span class="line">    <span class="keyword">return</span> a &lt; b ? b:a; </span><br><span class="line">&#125; </span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span> <span class="params">()</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="keyword">int</span> i = <span class="number">39</span>;</span><br><span class="line">    <span class="keyword">int</span> j = <span class="number">20</span>;</span><br><span class="line">    <span class="built_in">cout</span> &lt;&lt; <span class="string">"Max(i, j): "</span> &lt;&lt; Max(i, j) &lt;&lt; <span class="built_in">endl</span>;  <span class="comment">//Max(i, j): 39</span></span><br><span class="line"> </span><br><span class="line">    <span class="keyword">double</span> f1 = <span class="number">13.5</span>; </span><br><span class="line">    <span class="keyword">double</span> f2 = <span class="number">20.7</span>; </span><br><span class="line">    <span class="built_in">cout</span> &lt;&lt; <span class="string">"Max(f1, f2): "</span> &lt;&lt; Max(f1, f2) &lt;&lt; <span class="built_in">endl</span>;  <span class="comment">//Max(f1, f2): 20.7</span></span><br><span class="line"> </span><br><span class="line">    <span class="built_in">string</span> s1 = <span class="string">"Hello"</span>; </span><br><span class="line">    <span class="built_in">string</span> s2 = <span class="string">"World"</span>; </span><br><span class="line">    <span class="built_in">cout</span> &lt;&lt; <span class="string">"Max(s1, s2): "</span> &lt;&lt; Max(s1, s2) &lt;&lt; <span class="built_in">endl</span>;  <span class="comment">//Max(s1, s2): World</span></span><br><span class="line"> </span><br><span class="line">   <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>类模板</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;iostream&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;vector&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;cstdlib&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;string&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;stdexcept&gt;</span></span></span><br><span class="line"> </span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> <span class="built_in">std</span>;</span><br><span class="line"> </span><br><span class="line"><span class="keyword">template</span> &lt;<span class="class"><span class="keyword">class</span> <span class="title">T</span>&gt;</span></span><br><span class="line"><span class="class"><span class="title">class</span> <span class="title">Stack</span> &#123;</span> </span><br><span class="line">  <span class="keyword">private</span>: </span><br><span class="line">    <span class="built_in">vector</span>&lt;T&gt; elems;   <span class="comment">// 元素 </span></span><br><span class="line"> </span><br><span class="line">  <span class="keyword">public</span>: </span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">push</span><span class="params">(T <span class="keyword">const</span>&amp;)</span></span>;  <span class="comment">// 入栈</span></span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">pop</span><span class="params">()</span></span>;   <span class="comment">// 出栈</span></span><br><span class="line">    <span class="function">T <span class="title">top</span><span class="params">()</span> <span class="keyword">const</span></span>;   <span class="comment">// 返回栈顶元素</span></span><br><span class="line">    <span class="function"><span class="keyword">bool</span> <span class="title">empty</span><span class="params">()</span> <span class="keyword">const</span></span>&#123;   <span class="comment">// 如果为空则返回真</span></span><br><span class="line">        <span class="keyword">return</span> elems.empty(); </span><br><span class="line">    &#125; </span><br><span class="line">&#125;; </span><br><span class="line"> </span><br><span class="line"><span class="keyword">template</span> &lt;<span class="class"><span class="keyword">class</span> <span class="title">T</span>&gt;</span></span><br><span class="line"><span class="class"><span class="title">void</span> <span class="title">Stack</span>&lt;T&gt;:</span>:push (T <span class="keyword">const</span>&amp; elem) </span><br><span class="line">&#123; </span><br><span class="line">    <span class="comment">// 追加传入元素的副本</span></span><br><span class="line">    elems.push_back(elem);    </span><br><span class="line">&#125; </span><br><span class="line"> </span><br><span class="line"><span class="keyword">template</span> &lt;<span class="class"><span class="keyword">class</span> <span class="title">T</span>&gt;</span></span><br><span class="line"><span class="class"><span class="title">void</span> <span class="title">Stack</span>&lt;T&gt;:</span>:pop () </span><br><span class="line">&#123; </span><br><span class="line">    <span class="keyword">if</span> (elems.empty()) &#123; </span><br><span class="line">        <span class="keyword">throw</span> out_of_range(<span class="string">"Stack&lt;&gt;::pop(): empty stack"</span>); </span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">// 删除最后一个元素</span></span><br><span class="line">    elems.pop_back();         </span><br><span class="line">&#125; </span><br><span class="line"> </span><br><span class="line"><span class="keyword">template</span> &lt;<span class="class"><span class="keyword">class</span> <span class="title">T</span>&gt;</span></span><br><span class="line"><span class="class"><span class="title">T</span> <span class="title">Stack</span>&lt;T&gt;:</span>:top () <span class="keyword">const</span> </span><br><span class="line">&#123; </span><br><span class="line">    <span class="keyword">if</span> (elems.empty()) &#123; </span><br><span class="line">        <span class="keyword">throw</span> out_of_range(<span class="string">"Stack&lt;&gt;::top(): empty stack"</span>); </span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">// 返回最后一个元素的副本 </span></span><br><span class="line">    <span class="keyword">return</span> elems.back();      </span><br><span class="line">&#125; </span><br><span class="line"> </span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span> </span></span><br><span class="line"><span class="function"></span>&#123; </span><br><span class="line">    <span class="keyword">try</span> &#123; </span><br><span class="line">        Stack&lt;<span class="keyword">int</span>&gt; intStack;   <span class="comment">// int 类型的栈 </span></span><br><span class="line">        Stack&lt;<span class="built_in">string</span>&gt; stringStack;   <span class="comment">// string 类型的栈 </span></span><br><span class="line"> </span><br><span class="line">        <span class="comment">// 操作 int 类型的栈 </span></span><br><span class="line">        intStack.push(<span class="number">7</span>); </span><br><span class="line">        <span class="built_in">cout</span> &lt;&lt; intStack.top() &lt;&lt;<span class="built_in">endl</span>; <span class="comment">//7</span></span><br><span class="line"> </span><br><span class="line">        <span class="comment">// 操作 string 类型的栈 </span></span><br><span class="line">        stringStack.push(<span class="string">"hello"</span>); </span><br><span class="line">        <span class="built_in">cout</span> &lt;&lt; stringStack.top() &lt;&lt; <span class="built_in">std</span>::<span class="built_in">endl</span>; <span class="comment">//hello</span></span><br><span class="line">        stringStack.pop(); </span><br><span class="line">        stringStack.pop(); Exception: Stack&lt;&gt;::pop(): empty <span class="built_in">stack</span></span><br><span class="line">    &#125; </span><br><span class="line">    <span class="keyword">catch</span> (exception <span class="keyword">const</span>&amp; ex) &#123; </span><br><span class="line">        <span class="built_in">cerr</span> &lt;&lt; <span class="string">"Exception: "</span> &lt;&lt; ex.what() &lt;&lt;<span class="built_in">endl</span>; </span><br><span class="line">        <span class="keyword">return</span> <span class="number">-1</span>;</span><br><span class="line">    &#125; </span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h1 id="C-string实现原理"><a href="#C-string实现原理" class="headerlink" title="C++ string实现原理"></a>C++ string实现原理</h1><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;iostream&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;assert.h&gt;</span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> <span class="built_in">std</span>;</span><br><span class="line"> </span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">String</span></span></span><br><span class="line"><span class="class">&#123;</span> </span><br><span class="line">  <span class="keyword">public</span>: </span><br><span class="line">  String(<span class="keyword">const</span> <span class="keyword">char</span> *str = <span class="literal">NULL</span>); <span class="comment">// 普通构造函数 </span></span><br><span class="line">  String(<span class="keyword">const</span> String &amp;other); <span class="comment">// 拷贝构造函数 </span></span><br><span class="line">  ~ String(<span class="keyword">void</span>); <span class="comment">// 析构函数 </span></span><br><span class="line">  String &amp; <span class="keyword">operator</span> =(<span class="keyword">const</span> String &amp;other); <span class="comment">// 赋值函数 </span></span><br><span class="line">  <span class="keyword">private</span>: </span><br><span class="line">  <span class="keyword">char</span> *m_data; <span class="comment">// 用于保存字符串 </span></span><br><span class="line">&#125;;</span><br><span class="line"> </span><br><span class="line"><span class="comment">//普通构造函数</span></span><br><span class="line">String::String(<span class="keyword">const</span> <span class="keyword">char</span> *str) </span><br><span class="line">&#123;</span><br><span class="line">  <span class="keyword">if</span>(str==<span class="literal">NULL</span>) </span><br><span class="line">  &#123;</span><br><span class="line">    m_data = <span class="keyword">new</span> <span class="keyword">char</span>[<span class="number">1</span>]; <span class="comment">// 得分点：对空字符串自动申请存放结束标志'\0'的空</span></span><br><span class="line">    <span class="comment">//加分点：对m_data加NULL 判断</span></span><br><span class="line">    *m_data = <span class="string">'\0'</span>; </span><br><span class="line">  &#125; </span><br><span class="line">  <span class="keyword">else</span></span><br><span class="line">  &#123;</span><br><span class="line">    <span class="keyword">int</span> length = <span class="built_in">strlen</span>(str); </span><br><span class="line">    m_data = <span class="keyword">new</span> <span class="keyword">char</span>[length+<span class="number">1</span>]; </span><br><span class="line">    <span class="built_in">strcpy</span>(m_data, str); </span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">// String的析构函数</span></span><br><span class="line">String::~String(<span class="keyword">void</span>) </span><br><span class="line">&#123;</span><br><span class="line">  <span class="keyword">delete</span> [] m_data; <span class="comment">// 或delete m_data;</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">//拷贝构造函数</span></span><br><span class="line">String::String(<span class="keyword">const</span> String &amp;other) 　　　<span class="comment">// 得分点：输入参数为const型</span></span><br><span class="line">&#123; </span><br><span class="line">  <span class="keyword">int</span> length = <span class="built_in">strlen</span>(other.m_data); </span><br><span class="line">  m_data = <span class="keyword">new</span> <span class="keyword">char</span>[length+<span class="number">1</span>]; 　　　　</span><br><span class="line">  <span class="built_in">strcpy</span>(m_data, other.m_data); </span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">//赋值函数</span></span><br><span class="line">String &amp; String::<span class="keyword">operator</span> =(<span class="keyword">const</span> String &amp;other) <span class="comment">// 得分点：输入参数为const型</span></span><br><span class="line">&#123; </span><br><span class="line">  <span class="keyword">if</span>(<span class="keyword">this</span> == &amp;other) 　　<span class="comment">//得分点：检查自赋值</span></span><br><span class="line">  <span class="keyword">return</span> *<span class="keyword">this</span>; </span><br><span class="line">  <span class="keyword">delete</span> [] m_data; 　　　　<span class="comment">//得分点：释放原有的内存资源</span></span><br><span class="line">  <span class="keyword">int</span> length = <span class="built_in">strlen</span>( other.m_data ); </span><br><span class="line">  m_data = <span class="keyword">new</span> <span class="keyword">char</span>[length+<span class="number">1</span>]; 　</span><br><span class="line">  <span class="built_in">strcpy</span>( m_data, other.m_data ); </span><br><span class="line">  <span class="keyword">return</span> *<span class="keyword">this</span>; 　　　　　　　　<span class="comment">//得分点：返回本对象的引用</span></span><br><span class="line">&#125;</span><br><span class="line"> </span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">(<span class="keyword">char</span> argc, <span class="keyword">char</span> *argv)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">  String s1;</span><br><span class="line">  <span class="function">String <span class="title">s2</span><span class="params">(<span class="string">"222"</span>)</span></span>;</span><br><span class="line">  s1 = s2;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h1 id="C-map、set实现原理-红黑树"><a href="#C-map、set实现原理-红黑树" class="headerlink" title="C++ map、set实现原理:红黑树"></a>C++ map、set实现原理:红黑树</h1><p><strong>1、红黑树：</strong><br>红黑树是一种二叉查找树，但在每个节点增加一个存储位表示节点的颜色，可以是红或黑（非红即黑）。通过对任何一条从根到叶子的路径上各个节点着色的方式的限制，红黑树保证<strong>最长路径不超过最短路径的二倍</strong>，因而近似平衡。红黑树是一种<strong>弱平衡二叉树</strong>，相对于要求严格的AVL树来说，它的旋转次数少，所以对于搜索，插入，删除操作较多的情况下，通常使用红黑树。性质：<br>(1)每个节点非红即黑<br>(2)<strong>根节点是黑</strong>的;<br>(3)每个<strong>叶节点</strong>（叶节点即树尾端NULL指针或NULL节点）都是<strong>黑</strong>的;<br>(4)如果一个节点是<strong>红色的，则它的子节点必须是黑色</strong>的。<br>(5)对于任意节点而言，其<strong>到叶子点树NULL指针的每条路径都包含相同数目的黑节点</strong>;<strong>2、平衡二叉树（AVL树）：</strong><br>红黑树是在AVL树的基础上提出来的。平衡二叉树又称为AVL树，是一种特殊的二叉排序树。其左右子树都是平衡二叉树，且<strong>左右子树高度之差不超过1</strong>。<strong>3、红黑树较AVL树的优点：</strong><br>AVL 树是高度平衡的，频繁的插入和删除，会引起频繁的rebalance，导致效率下降；红黑树不是高度平衡的，算是一种折中，<strong>插入最多两次旋转，删除最多三次旋转</strong>。所以红黑树在查找，插入删除的性能都是<strong>O(logn)</strong>，且性能稳定，所以STL里面很多结构包括set、map底层实现都是使用的红黑树。<br><strong>4、红黑树旋转：</strong><br>旋转：红黑树的旋转是一种能保持二叉搜索树性质的搜索树局部操作。有左旋和右旋两种旋转，通过改变树中某些结点的颜色以及指针结构来保持对红黑树进行插入和删除操作后的红黑性质。<br>左旋：对某个结点x做左旋操作时，假设其右孩子为y：以x到y的链为“支轴”进行。使y成为该子树新的根结点，x成为y的左孩子，y的左孩子成为x的右孩子。<br> <img src="https://img-blog.csdnimg.cn/20190926144910944.png" alt="在这里插入图片描述"><br>右旋：对某个结点x做右旋操作时，假设其左孩子为y而不是T.nil：以x到y的链为“支轴”进行。使y成为该子树新的根结点，x成为y的右孩子，y的右孩子成为x的左孩子。<br> <img src="https://img-blog.csdnimg.cn/20190926144917548.png" alt="在这里插入图片描述"></p><h1 id="哈夫曼编码"><a href="#哈夫曼编码" class="headerlink" title="哈夫曼编码"></a>哈夫曼编码</h1><p>JPEG中就应用了哈夫曼编码。哈夫曼编码是哈夫曼树的一种应用，广泛用于数据文件压缩。<br>哈夫曼树又称最优二叉树，是一种<strong>带权路径长度最短</strong>的二叉树。所谓树的带权路径长度，就是树中所有的叶结点的权值乘上其到根结点的路径长度（若根结点为0层，叶结点到根结点的路径长度为叶结点的层数）。树的带权路径长度记为WPL= (W1<em>L1 + W2</em>L2 + W3<em>L3 + … + Wn</em>Ln)，N个权值Wi(i=1,2,…n)构成一棵有N个叶结点的二叉树，相应的叶结点的路径长度为Li(i=1,2,…n)。可以证明哈夫曼树的WPL是最小的。<br>哈夫曼编码步骤：<br>一、对给定的n个权值{W1,W2,W3,…,Wi,…,Wn}构成n棵二叉树的初始集合F= {T1,T2,T3,…,Ti,…,Tn}，其中每棵二叉树Ti中只有一个权值为Wi的根结点，它的左右子树均为空。（为方便在计算机上实现算 法，一般还要求以Ti的权值Wi的升序排列。）<br>二、在F中选取两棵根结点权值最小的树作为新构造的二叉树的左右子树，新二叉树的根结点的权值为其左右子树的根结点的权值之和。<br>三、从F中删除这两棵树，并把这棵新的二叉树同样以升序排列加入到集合F中。<br>四、重复二和三两步，直到集合F中只有一棵二叉树为止。<br>哈夫曼编码是一种无前缀编码。解码时不会混淆。其主要应用在数据压缩，加密解密等场合。<br>a b c d e :5 4 3 2 1<br> <img src="https://img-blog.csdnimg.cn/2019092614511520.png" alt="在这里插入图片描述"></p><h1 id="vector、list、deque、set、map的应用场景"><a href="#vector、list、deque、set、map的应用场景" class="headerlink" title="vector、list、deque、set、map的应用场景"></a>vector、list、deque、set、map的应用场景</h1><p><strong>1、set和map</strong><br>共同点：都是C++的关联容器,只是通过它提供的接口对里面的元素进行访问，底层都是采用<strong>红黑树</strong>实现<br>不同点：<br>set：用来判断某一个元素是不是在一个组里面，使用的比较少；<br>map：映射，相当于字典，把一个值映射成另一个值，可以创建字典<br>优点：查找某一个数的时间为<strong>O(logn)</strong>；遍历时采用iterator，效果不错<br>缺点：每次插入值的时候，都需要调整红黑树，效率有一定影响<br><strong>2、vector</strong><br>是<strong>动态数组</strong>，在堆中分配内存，元素连续存放，有保留内存，如果减少大小后，内存也不会释放；如果新值大于当前大小时才会重新分配内存。<br>特点：拥有一段连续的内存空间，并且起始地址不变，因此能够非常好的支持随机存取，即[]操作符；<br>对头部和中间进行添加删除元素操作需要移动内存，如果元素是结构或类，那么移动的同时还会进行构造和析构操作，所以性能不高；<br>对任何元素的访问时间都是<strong>O(1)</strong>，所以常用来保存需要经常进行<strong>随机访问</strong>的内容，并且不需要经常对中间元素进行添加删除操作<br><strong>3、list</strong><br><strong>双向链表</strong>，元素也存放在堆中，每个元素都是放在一块内存中，他的内存空间可以是不连续的，通过指针来进行数据的访问，这个特点使得它的随机存取变得非常没有效率，因此它没有提供[]操作符的重载。但是由于链表的特点，它可以很有效率的支持任意地方的删除和插入操作。<br>特点<br>在哪里添加删除元素性能都很高，不需要移动内存，当然也不需要对每个元素都进行构造与析构了，所以常用来做<strong>随机插入和删除</strong>操作容器；<br>访问开始和最后两个元素最快，其他元素的访问时间都是<strong>O(n)</strong><br><strong>4、deque</strong><br><strong>分段连续线性空间</strong>，支持[]操作符，也就是支持随机存取，有比较高的随机存取速度，由于deque需要处理内部跳转，因此速度上没有vector快</p><table><thead><tr><th></th><th>deque</th><th>vector</th></tr></thead><tbody><tr><td>组织方式</td><td>按页或块来分配存储器的，每页包含固定数目的元素</td><td>分配一段连续的内存来存储内容</td></tr><tr><td>效率</td><td>即使在容器的前端也可以提供常数时间的insert和erase操作，而且在体积增长方面也比vector更具有效率</td><td>只是在序列的尾端插入元素时才有效率，但是随机访问速度要比deque快</td></tr></tbody></table><p>总结vector    list    deque<br>| |vector|list|deque|<br>|–|–|–|–|<br>|特点|快速的随机存取，快速的在最后插入删除元素|可以快速的在任意位置添加删除元素，只能快速的访问最开始和最后面的元素|在开始和最后添加删除元素一样快，并且提供了随机访问的方法|<br>|适用|需要高效的<strong>随机存取</strong>，不在于插入删除的效率|需要大量的<strong>插入和删除</strong>操作，不关心随机存取|需要随机存取，也需要高效的在两端进行插入删除操作</p><h1 id="vector和list的区别"><a href="#vector和list的区别" class="headerlink" title="vector和list的区别"></a>vector和list的区别</h1><p>1）vector底层实现是数组；list是双向链表。<br>2）vector是顺序内存,支持随机访问，list不行。<br>4）vector在中间节点进行插入删除会导致内存拷贝，list不会。<br>5）vector一次性分配好内存，不够时才进行2倍扩容；list每次插入新节点都会进行内存申请。<br>6）vector随机访问性能好，插入删除性能差；list随机访问性能差，插入删除性能好。</p><h1 id="vector、list、map、set迭代器失效"><a href="#vector、list、map、set迭代器失效" class="headerlink" title="vector、list、map、set迭代器失效"></a>vector、list、map、set迭代器失效</h1><p>1.对于<strong>序列容器vector,deque</strong>来说，使用erase(itertor)后，后边的每个元素的迭代器都会失效，但是后边每个元素都会往前移动一个位置，但是erase会<strong>返回下一个有效的迭代器</strong>；iter =cont.erase(iter)<br>2.对于<strong>关联容器map set</strong>来说，使用了erase(iterator)后，当前元素的迭代器失效，但是其结构是红黑树，删除当前元素的，<strong>不会影响到下一个</strong>元素的迭代器，所以在调用erase之前，记录下一个元素的迭代器即可；<br>erase(iter++)<br>3.对于<strong>list</strong>来说，它使用了不连续分配的内存，并且它的erase方法也会返回下一个有效的iterator，因此上面两种正确的方法都可以使用。<br>| |vector|deque|list|set、map|<br>|–|–|–|–|–|<br>|内部数据结构|数组(一段连续内存空间)|数组(多段连续内存空间)|双向环状链表|红黑树|<br>|插入操作|插入后元素总数不大于capacity，插入位置之后的迭代器会失效；大于capacity,所有迭代器都会失效|两端插入, 不会引起迭代器失效；中间插入, 所有迭代器失效|不会出现迭代器失效|不会出现迭代器失效|<br>|删除操作|删除位置之后的迭代器都会失效,但是erase会返回下一个有效的迭代器|两端删除, 被删除元素的迭代器失效中间删除, 所有迭代器失效|被删除节点的迭代器失效|被删除节点的迭代器失效<br>|解决方法| iter =cont.erase(iter)| |iter =cont.erase(iter)或者m.erase(iter++)|m.erase(iter++)</p><p>解决方式1： iter =cont.erase(iter)</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//要求只是删除值为偶数的节点 , vector&lt;int&gt; vec&#123; 1, 2, 3, 4, 5 &#125;;</span></span><br><span class="line"> <span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; ::iterator it1 = vec.begin();</span><br><span class="line"></span><br><span class="line"> <span class="comment">//错误实现：链表删除节点导致的迭代器失效，容易造成访问野指针的问题，导致程序崩溃</span></span><br><span class="line"> <span class="keyword">while</span> (it1 != vec.end()) &#123;</span><br><span class="line">   <span class="keyword">if</span> (*it1 % <span class="number">2</span> == <span class="number">0</span>)&#123;</span><br><span class="line">     vec.erase(it1); </span><br><span class="line">   &#125;</span><br><span class="line">   it1++;</span><br><span class="line"> &#125;</span><br><span class="line"></span><br><span class="line"> <span class="comment">//正确实现：利用erase()函数的返回值为iterator，返回的是删除节点的下一个位置的迭代器</span></span><br><span class="line"> <span class="keyword">while</span> (it1 != vec.end()) &#123;</span><br><span class="line">   <span class="keyword">if</span> (*it1 % <span class="number">2</span> == <span class="number">0</span>)&#123;</span><br><span class="line">     it1 = vec.erase(it1); <span class="comment">//重点！！！</span></span><br><span class="line">   &#125;</span><br><span class="line">   <span class="keyword">else</span>&#123;</span><br><span class="line">     it1++;</span><br><span class="line">   &#125;</span><br><span class="line"> &#125;</span><br></pre></td></tr></table></figure><p>解决方式2：erase(iter++)</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//要求删除键值为偶数的键值对</span></span><br><span class="line"><span class="built_in">map</span>&lt;<span class="keyword">int</span>, <span class="keyword">int</span>&gt;::iterator it = m.begin();</span><br><span class="line"></span><br><span class="line"><span class="comment">//错误实现：</span></span><br><span class="line"><span class="keyword">while</span> (it != m.end())&#123;</span><br><span class="line">  <span class="keyword">if</span>(it-&gt;second % <span class="number">2</span> == <span class="number">0</span>)&#123;</span><br><span class="line">    m.erase(it);</span><br><span class="line">  &#125;</span><br><span class="line">  it++;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//正确实现：</span></span><br><span class="line"><span class="keyword">while</span> (it != m.end())&#123;</span><br><span class="line">  <span class="keyword">if</span>(it-&gt;second % <span class="number">2</span> == <span class="number">0</span>)&#123;</span><br><span class="line">    m.erase(it++); <span class="comment">//重点！！！</span></span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">else</span>&#123;</span><br><span class="line">    it++;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h1 id="C-内存分配管理"><a href="#C-内存分配管理" class="headerlink" title="C++内存分配管理"></a>C++内存分配管理</h1><p> <img src="https://img-blog.csdnimg.cn/20190926154738160.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZmY2pqaHY=,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"><br>在C++中，虚拟内存分为text代码段、data数据段、bss段、heap堆区、文件映射区以及stack栈区六部分。3G用户空间和1G内核空间<br><strong>代码段</strong> 包括只读存储区和文本区，其中只读存储区存储字符串常量，文本区存储程序的机器代码。<br><strong>数据段</strong> 存储程序中已初始化的全局变量和静态变量<br><strong>bss 段</strong> 存储未初始化的全局变量和静态变量（局部+全局），以及所有被初始化为0的全局变量和静态变量。<br><strong>堆区</strong> 调用new/malloc函数时在堆区动态分配内存，同时需要调用delete/free来手动释放申请的内存。<br><strong>映射区</strong> 存储动态链接库以及调用mmap函数进行的文件映射<br><strong>栈</strong> 使用栈空间存储函数的返回地址、参数、局部变量、返回值</p><p><strong>内存分配方式有三种：</strong><br>[1]从静态存储区域分配。内存在程序编译的时候就已经分配好，这块内存在程序的整个运行期间都存在。例如全局变量，static变量。<br>[2]在栈上创建。在执行函数时，函数内局部变量的存储单元都可以在栈上创建，函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中，效率很高，但是分配的内存容量有限。<br>[3]从堆上分配，亦称动态内存分配。程序在运行的时候用malloc或new申请任意多少的内存，程序员自己负责在何时用free或delete释放内存。动态内存的生存期由程序员决定，使用非常灵活，但如果在堆上分配了空间，就有责任回收它，否则运行的程序会出现内存泄漏，频繁地分配和释放不同大小的堆空间将会产生堆内碎块。</p><h1 id="A-a-new-A-a-gt-i-10-在内核中的内存分配上发生了什么？"><a href="#A-a-new-A-a-gt-i-10-在内核中的内存分配上发生了什么？" class="headerlink" title="A* a = new A; a-&gt;i = 10;在内核中的内存分配上发生了什么？"></a>A* a = new A; a-&gt;i = 10;在内核中的内存分配上发生了什么？</h1><p>1）A *a：a是一个局部变量，类型为指针，故而操作系统在程序栈区开辟4/8字节的空间（0x000m），分配给指针a。<br>2）new A：通过new动态的在堆区申请类A大小的空间（0x000n）。<br>3）a = new A：将指针a的内存区域填入栈中类A申请到的地址的地址。即*（0x000m）=0x000n。<br>4）a-&gt;i：先找到指针a的地址0x000m，通过a的值0x000n和i在类a中偏移offset，得到a-&gt;i的地址0x000n + offset，进行*(0x000n + offset) = 10的赋值操作，即内存0x000n + offset的值是10。</p><h1 id="给你一个类，里面有static，virtual，之类的，来说一说这个类的内存分布"><a href="#给你一个类，里面有static，virtual，之类的，来说一说这个类的内存分布" class="headerlink" title="给你一个类，里面有static，virtual，之类的，来说一说这个类的内存分布"></a>给你一个类，里面有static，virtual，之类的，来说一说这个类的内存分布</h1><p>1、static修饰符<br>1）static修饰成员变量<br>无论类被定义了多少个，静态数据成员都只有一份拷贝，为该类型的所有对象所共享(包括其派生类)。所以，静态数据成员的值对每个对象都是一样的，它的值可以更新。<br>因为静态数据成员在全局<strong>数据区</strong>分配内存，属于本类的所有对象共享，所以它不属于特定的类对象，在没有产生类对象前就可以使用。<br>2）static修饰成员函数<br>与普通的成员函数相比，静态成员函数由于不是与任何的对象相联系，因此它不具有this指针。从这个意义上来说，它无法访问属于类对象的非静态数据成员，也无法访问非静态成员函数，只能调用其他的静态成员函数。<br>Static修饰的成员函数，在<strong>代码区</strong>分配内存。</p><p>2、C++继承和虚函数<br>C++多态分为静态多态和动态多态。静态多态是通过重载和模板技术实现，在编译的时候确定。动态多态通过虚函数和继承关系来实现，执行动态绑定，在运行的时候确定。<br>动态多态实现有几个条件：<br>(1) 虚函数；<br>(2) 一个基类的指针或引用指向派生类的对象；<br>基类指针在调用成员函数(虚函数)时，就会去查找该对象的虚函数表。虚函数表的地址在每个对象的首地址。查找该虚函数表中该函数的指针进行调用。<br>每个对象中保存的只是一个虚函数表的指针，C++内部为每一个类维持一个虚函数表，该类的对象的都指向这同一个虚函数表。<br>虚函数表中为什么就能准确查找相应的函数指针呢？因为在类设计的时候，虚函数表直接从基类也继承过来，如果覆盖了其中的某个虚函数，那么虚函数表的指针就会被替换，因此可以根据指针准确找到该调用哪个函数。</p><p>3、virtual修饰符<br>如果一个类是局部变量则该类数据存储在<strong>栈区</strong>，如果一个类是通过new/malloc动态申请的，则该类数据存储在<strong>堆区</strong>。如果该类是virutal继承而来的子类，则该类的虚函数表指针和该类其他成员一起存储。虚函数表指针指向只读<strong>数据段</strong>中的类虚函数表，虚函数表中存放着一个个函数指针，函数指针指向<strong>代码段</strong>中的具体函数。<br>如果类中成员是virtual属性，会隐藏父类对应的属性。</p><h1 id="静态变量什么时候初始化"><a href="#静态变量什么时候初始化" class="headerlink" title="静态变量什么时候初始化"></a>静态变量什么时候初始化</h1><p>静态变量存储在虚拟地址空间的数据段和bss段，C语言中其在代码执行之前初始化，属于编译期初始化。而C++中由于引入对象，对象生成必须调用构造函数，因此C++规定全局或局部静态对象当且仅当对象首次用到时进行构造</p><h1 id="STL的allocator"><a href="#STL的allocator" class="headerlink" title="STL的allocator"></a>STL的allocator</h1><p>STL的分配器用于封装STL容器在内存管理上的底层细节。<br>在C++中，其内存配置和释放如下：<br>new运算分两个阶段：(1)调用::operator new配置内存;(2)调用对象构造函数构造对象内容<br>delete运算分两个阶段：(1)调用对象析构函数；(2)掉用::operator delete释放内存</p><p>为了精密分工，STL allocator将两个阶段操作区分开来：<br>内存配置由alloc::allocate()负责，内存释放由alloc::deallocate()负责；<br>对象构造由::construct()负责，对象析构由::destroy()负责。</p><p>同时为了提升内存管理的效率，减少申请小内存造成的内存碎片问题，SGI STL采用了两级配置器，当分配的空间大小超过128B时，会使用第一级空间配置器，使用malloc()、realloc()、free()函数进行内存空间的分配和释放；当分配的空间大小小于128B时，将使用第二级空间配置器，采用了内存池技术，通过空闲链表来管理内存。</p><h1 id="malloc的原理，另外brk系统调用和mmap系统调用的作用分别是什么？"><a href="#malloc的原理，另外brk系统调用和mmap系统调用的作用分别是什么？" class="headerlink" title="malloc的原理，另外brk系统调用和mmap系统调用的作用分别是什么？"></a>malloc的原理，另外brk系统调用和mmap系统调用的作用分别是什么？</h1><p>Malloc函数用于动态分配内存。为了减少内存碎片和系统调用的开销，malloc其采用内存池的方式，先申请大块内存作为堆区，然后将堆区分为多个内存块，以块作为内存管理的基本单位。当用户申请内存时，直接从堆区分配一块合适的空闲块。Malloc在申请内存时，一般会通过brk或者mmap系统调用进行申请。其中当申请内存小于128K时，会使用系统函数brk在堆区中分配；而当申请内存大于128K时，会使用系统函数mmap(内存映射)在映射区分配。</p><h1 id="C-STL-的内存优化"><a href="#C-STL-的内存优化" class="headerlink" title="C++ STL 的内存优化"></a>C++ STL 的内存优化</h1><p><strong>1）二级配置器结构</strong><br>STL内存管理使用二级内存配置器。<br>1、第一级配置器  分配的区块大于128bytes<br>第一级配置器以malloc()，free()，realloc()等C函数执行实际的内存配置、释放、重新配置等操作，并且能在内存需求不被满足的时候，调用一个指定的函数。<br>2、第二级配置器  分配的区块小于128bytes<br>在STL的第二级配置器中多了一些机制，避免太多小区块造成的内存碎片，小额区块带来的不仅是内存碎片，配置时还有额外的负担。<br><strong>内存池管理:</strong> 每次配置一大块内存，并维护对应的16个空闲链表（free-list）。下次若有相同大小的内存需求，则直接从free-list中取。如果有小额区块被释放，则由配置器回收到free-list中。<br>当用户申请的空间小于128字节时，将字节数扩展到8的倍数，然后在自由链表中查找对应大小的子链表<br>如果在自由链表查找不到或者块数不够，则向内存池进行申请，一般一次申请20块<br>如果内存池空间足够，则取出内存<br>如果不够分配20块，则分配最多的块数给自由链表<br>如果一块都无法提供，则把剩余的内存挂到自由链表，然后向系统heap申请空间，如果申请失败，则看看自由链表还有没有可用的块，如果也没有，则最后调用一级空间配置器</p><p><strong>2）二级内存池</strong><br><img src="https://img-blog.csdnimg.cn/20190926162534580.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZmY2pqaHY=,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"><br>二级内存池采用了16个空闲链表，这里的16个空闲链表分别管理大小为8、16、24……120、128的数据块。这里空闲链表节点的设计十分巧妙，这里用了一个联合体既可以表示下一个空闲数据块（存在于空闲链表中）的地址，也可以表示已经被用户使用的数据块（不存在空闲链表中）的地址。<br><strong>如何分配内存：</strong><br>它的内存分配主要分为以下几种情况：<br>1、对应的free_list不为空<br>所需空间大小提升为8的倍数后(如需要13bytes空间，我们会给它分配16bytes大小)，所对应的free_list不为空时，直接从对应的free_list中拔出，第一位置向后移动指向。<br>2、对应的free_list为空，其内存池不为空时：<br>（1）先检验它剩余空间是否够20个节点大小（即所需内存大小(提升后) *20），若足够则直接从内存池中拿出20个节点大小空间，将其中一个分配给用户使用，另外19个当作自由链表中的区块挂在相应的free_list下，这样下次再有相同大小的内存需求时，可直接从 free-list 中拨出。<br>（2）如果不够20个节点大小，则看它是否能满足1个节点大小，如果够的话则直接拿出一个分配给用户，然后从剩余的空间中分配尽可能多的节点挂在相应的free_list中。<br>（3）如果连一个节点内存都不能满足的话，则将内存池中剩余的空间挂在相应的free_list中（找到相应的free_list），然后再给内存池申请内存。<br>3、内存池为空，申请内存<br>此时二级空间配置器会使用malloc()从heap上申请内存。<br>4、malloc没有成功<br>在第三种情况下，如果malloc()失败了，说明heap上没有足够空间分配给我们了，这时，二级空间配置器会从比所需节点空间大的free_list中一一搜索，从任意一个比它所需节点空间大的free_list中拔除一个节点来使用。<br>5、查找失败，调用一级空间配置器<br><strong>释放内存</strong><br> 用户调用deallocate释放内存空间，如果要求释放的内存空间大于128bytes，直接调用free。<br> 否则按照其大小找到合适的自由链表，并将其插入。</p><h1 id="new-delete和-malloc-free的区别"><a href="#new-delete和-malloc-free的区别" class="headerlink" title="new/delete和 malloc/free的区别"></a>new/delete和 malloc/free的区别</h1><p>1、new/delete是C++关键字支持重载，需要编译器支持。malloc/free是库函数，需要头文件stdlib.h支持。<br>2、new分配内存按照数据类型进行分配，malloc分配内存按照指定的大小分配；<br>3、new返回的是指定对象的指针，而malloc返回的是void*，因此malloc的返回值一般都需要进行类型转化。<br>4、new不仅分配一段内存，而且会调用构造函数，malloc不会。<br>5、new分配的内存要用delete销毁，malloc要用free来销毁；delete销毁的时候会调用对象的析构函数，而free则不会。<br>6、malloc分配的内存不够的时候，可以用realloc扩容。扩容的原理？new没用这样操作。<br>7、new如果分配失败了会抛出bad_malloc的异常，而malloc失败了会返回NULL。<br>8、new操作符从自由存储区（free store）上为对象动态分配内存空间，而malloc函数从堆上动态分配内存。<br>自由存储区是C++基于new操作符的一个抽象概念，凡是通过new操作符进行内存申请，该内存即为自由存储区。而堆是操作系统中的术语，是操作系统所维护的一块特殊内存，用于程序的内存动态分配，C语言使用malloc从堆上分配内存，使用free释放已分配的对应内存。自由存储区不等于堆</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//申请ArraySize大小的数组</span></span><br><span class="line"><span class="keyword">int</span>* Array = (<span class="keyword">int</span>*)<span class="built_in">malloc</span>(ArraySize * <span class="keyword">sizeof</span>(<span class="keyword">int</span>)); <span class="comment">// 在堆中申请内存</span></span><br><span class="line"><span class="built_in">memset</span>(Array, <span class="number">0</span>, ArraySize * <span class="keyword">sizeof</span>(<span class="keyword">int</span>)); <span class="comment">// 初始化数组全为 0</span></span><br><span class="line"><span class="built_in">free</span>(Array); <span class="comment">// 释放内存</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">int</span>* Array = <span class="keyword">new</span> <span class="keyword">int</span>[ArraySize]; <span class="comment">// 申请内存，不初始化</span></span><br><span class="line"><span class="comment">//int* Array = new int[ArraySize](); // 初始化数组全为 0</span></span><br><span class="line"><span class="comment">//int* Array = new int[5]&#123; 1,2,3,4,5 &#125;; // 初始化数组为 1,2,3,4,5（VS2015支持）</span></span><br><span class="line"><span class="comment">//int* Array = new int[5]&#123; 1 &#125;; // 初始化数组为 1,0,0,0,0</span></span><br><span class="line"><span class="built_in">memset</span>(Array, <span class="number">1</span>, ArraySize * <span class="keyword">sizeof</span>(<span class="keyword">int</span>)); <span class="comment">// 初始化数组全为 1</span></span><br><span class="line"><span class="keyword">delete</span>[] Array; <span class="comment">// 释放内存</span></span><br></pre></td></tr></table></figure><h1 id="memory-leak，内存泄漏"><a href="#memory-leak，内存泄漏" class="headerlink" title="memory leak，内存泄漏"></a>memory leak，内存泄漏</h1><p>内存泄漏(memory leak)是指由于疏忽或错误造成了程序未能释放掉不再使用的内存的情况。内存泄漏并非指内存在物理上的消失，而是应用程序分配某段内存后，由于设计错误，失去了对该段内存的控制，因而造成了内存的浪费。可以使用<strong>Valgrind, mtrace</strong>进行内存泄漏检查。</p><p>内存泄漏的分类：<br>1.堆内存泄漏 （Heap leak）。对内存指的是程序运行中根据需要分配通过malloc,realloc new等从堆中分配的一块内存，再是完成后必须通过调用对应的 free或者delete 删掉。如果程序的设计的错误导致这部分内存没有被释放，那么此后这块内存将不会被使用，就会产生Heap Leak.<br>2.系统资源泄露（Resource Leak）。主要指程序使用系统分配的资源比如 Bitmap,handle ,SOCKET等没有使用相应的函数释放掉，导致系统资源的浪费，严重可导致系统效能降低，系统运行不稳定。<br>3.没有将基类的析构函数定义为虚函数。当基类指针指向子类对象时，如果基类的析构函数不是virtual，那么子类的析构函数将不会被调用，子类的资源没有正确是释放，因此造成内存泄露。</p><h1 id="STL有什么基本组成"><a href="#STL有什么基本组成" class="headerlink" title="STL有什么基本组成"></a>STL有什么基本组成</h1><p>算法、容器、迭代器</p><h1 id="STL中map与unordered-map"><a href="#STL中map与unordered-map" class="headerlink" title="STL中map与unordered_map"></a>STL中map与unordered_map</h1><p><strong>底层实现：</strong><br>map底层是基于红黑树实现的，因此map内部元素排列是有序的。而unordered_map底层则是基于哈希表实现的，因此其元素的排列顺序是杂乱无序的。<br><strong>map ：</strong><br>优点：<br>1)有序性，这是map结构最大的优点，其元素的有序性在很多应用中都会简化很多的操作<br>2)map的查找、删除、增加等一系列操作时间复杂度稳定，都为O(logn )<br>缺点：查找、删除、增加等操作平均时间复杂度较慢，与n相关<br><strong>unordered_map：</strong><br>优点：<br>查找、删除、添加的速度快，时间复杂度为常数级O(c )<br>unordered_map 缺点：<br>因为unordered_map内部基于哈希表，以（key,value）对的形式存储，因此空间占用率高<br>unordered_map的查找、删除、添加的时间复杂度不稳定，平均为O(c )，取决于哈希函数。极端情况下可能为O(n)</p><h1 id="STL中迭代器的作用，有指针为何还要迭代器"><a href="#STL中迭代器的作用，有指针为何还要迭代器" class="headerlink" title="STL中迭代器的作用，有指针为何还要迭代器"></a>STL中迭代器的作用，有指针为何还要迭代器</h1><p>Iterator类的访问方式就是把不同集合类的访问逻辑抽象出来，使得不用暴露集合内部的结构而达到循环遍历集合的效果。<br><strong>迭代器和指针的区别:</strong><br>迭代器不是指针，是类模板，表现的像指针。他模拟了指针的一些功能，通过重载了指针的一些操作符，-&gt;、*、++、- -等，提供了比指针更高级的行为，可以根据不同类型的数据结构来实现不同的++，- -等操作。</p><h1 id="STL里resize和reserve的区别"><a href="#STL里resize和reserve的区别" class="headerlink" title="STL里resize和reserve的区别"></a>STL里resize和reserve的区别</h1><p>resize()：改变当前容器内含有元素的数量(size())</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt;v&#123;<span class="number">1</span> ,<span class="number">2</span>&#125;; </span><br><span class="line">v.resize(<span class="number">4</span>);</span><br><span class="line">v.push_back(<span class="number">5</span>); <span class="comment">//1 2 0 0 5</span></span><br></pre></td></tr></table></figure><p>v的size变为len,如果原来v的size小于len，那么容器新增（len-size）个元素，元素的值为默认为0.当v.push_back(3);之后，则是3是放在了v的末尾，即下标为len，此时容器是size为len+1；</p><p>reserve()：改变当前容器的最大容量（capacity）<br>如果reserve(len)的值大于当前的capacity()，那么会重新分配一块能存len个对象的空间，然后把之前v.size()个对象通过copy construtor复制过来，销毁之前的内存；</p><p>注意：当v.resize(len)中len&gt;v.capacity()，则v中的size和capacity均设置为len；</p><p>当v.resize(len) 中len&lt;=v.capacity()，则v中的size设置为len，而capacity不变;<br>如果此时len&lt;v.size(),那么多出的那些对象(v[len], v[len+1]…)会被销毁，v[0]-v[len-1]仍保留在原地；<br>当v.reserve(len)中len&lt;=v.capacity()，则v中的capacity不变，size不变，即不对容器做任何改变。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; a;</span><br><span class="line">a.reserve(<span class="number">100</span>);</span><br><span class="line">a.resize(<span class="number">50</span>);</span><br><span class="line"><span class="built_in">cout</span>&lt;&lt;a.size()&lt;&lt;<span class="string">"  "</span>&lt;&lt;a.capacity()&lt;&lt;<span class="built_in">endl</span>; <span class="comment">//50  100</span></span><br><span class="line">a.resize(<span class="number">150</span>);</span><br><span class="line"><span class="built_in">cout</span>&lt;&lt;a.size()&lt;&lt;<span class="string">"  "</span>&lt;&lt;a.capacity()&lt;&lt;<span class="built_in">endl</span>; <span class="comment">//150  150</span></span><br><span class="line">a.reserve(<span class="number">50</span>);</span><br><span class="line"><span class="built_in">cout</span>&lt;&lt;a.size()&lt;&lt;<span class="string">"  "</span>&lt;&lt;a.capacity()&lt;&lt;<span class="built_in">endl</span>; <span class="comment">//150  150</span></span><br><span class="line">a.resize(<span class="number">50</span>);</span><br><span class="line"><span class="built_in">cout</span>&lt;&lt;a.size()&lt;&lt;<span class="string">"  "</span>&lt;&lt;a.capacity()&lt;&lt;<span class="built_in">endl</span>; <span class="comment">//50  150</span></span><br></pre></td></tr></table></figure><p>size可能改变capacity，但capacity不会改变size</p><h1 id="C-函数重载、覆盖、隐藏"><a href="#C-函数重载、覆盖、隐藏" class="headerlink" title="C++函数重载、覆盖、隐藏"></a>C++函数重载、覆盖、隐藏</h1><p><strong>重载:</strong><br>函数重载：两个函数名相同，但是参数列表不同（个数，类型），返回值类型没有要求，在同一作用域中<br>运算符重载：Box <strong>operator</strong>+(const Box&amp;); //返回类型 Box<br><strong>覆盖/重写:</strong><br>子类继承了父类，父类中的函数是虚函数，在子类中重新定义了这个虚函数，这种情况是重写<br><strong>隐藏:</strong><br>派生类的函数屏蔽了与其同名的基类函数。</p><p>不能重载的运算符：<br>“.”    “.*”    “?:”      “sizeof()”     “typeid()”     “static_cast&lt;&gt;”    “dynamic_cast&lt;&gt;”      “const_cast&lt;&gt;”       “#”    “##”</p><h1 id="C-编译时多态与运行时多态"><a href="#C-编译时多态与运行时多态" class="headerlink" title="C++编译时多态与运行时多态"></a>C++编译时多态与运行时多态</h1><p>多态的实现主要分为静态多态和动态多态，静态多态主要是重载，在编译的时候就已经确定；动态多态是用虚函数机制实现的，在运行期间动态绑定。<br>一个父类类型的指针指向一个子类对象时候，使用父类的指针去调用子类中重写了的父类中的虚函数的时候，会调用子类重写过后的函数。<br>静态多态</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">Add</span><span class="params">(<span class="keyword">int</span> left, <span class="keyword">int</span> right)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="keyword">return</span> left + right;</span><br><span class="line">&#125;</span><br><span class="line"><span class="function"><span class="keyword">double</span> <span class="title">Add</span><span class="params">(<span class="keyword">double</span> left, <span class="keyword">int</span> right)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="keyword">return</span> left + right;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    Add(<span class="number">10</span>, <span class="number">20</span>);</span><br><span class="line">    Add(<span class="number">10.0</span>,<span class="number">20</span>);  <span class="comment">//正常代码</span></span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>动态多态</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Father</span>&#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function"><span class="keyword">virtual</span> <span class="keyword">void</span> <span class="title">Say</span><span class="params">()</span></span>&#123; <span class="comment">//重点！！！</span></span><br><span class="line">        <span class="built_in">cout</span> &lt;&lt; <span class="string">"Father say hello"</span> &lt;&lt; <span class="built_in">endl</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Son</span>:</span><span class="keyword">public</span> Father&#123;</span><br><span class="line"><span class="keyword">public</span>:     </span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">Say</span><span class="params">()</span></span>&#123;</span><br><span class="line">        <span class="built_in">cout</span> &lt;&lt; <span class="string">"Son say hello"</span> &lt;&lt; <span class="built_in">endl</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    Father *pFather;</span><br><span class="line">    Son son;</span><br><span class="line">    pFather = &amp;son; </span><br><span class="line">    pFather-&gt;Say(); <span class="comment">//Son say hello</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h1 id="虚函数的实现"><a href="#虚函数的实现" class="headerlink" title="虚函数的实现"></a>虚函数的实现</h1><p>在有虚函数的类中，类的最开始部分是一个虚函数表的指针，这个指针指向一个虚函数表，表中放了虚函数的地址，实际的虚函数在代码段(.text)中。当子类继承了父类的时候也会继承其虚函数表，当子类重写父类中虚函数时候，会将其继承到的虚函数表中的地址替换为重新写的函数地址。使用了虚函数，会增加访问内存开销，降低效率。</p><h1 id="如何实现只能动态分配类对象，不能静态分配"><a href="#如何实现只能动态分配类对象，不能静态分配" class="headerlink" title="如何实现只能动态分配类对象，不能静态分配"></a>如何实现只能动态分配类对象，不能静态分配</h1><p>动态分配就是用运算符new来创建一个类的对象，在堆上分配内存。<br>静态分配就是A a;这样来由编译器来创建一个对象，在栈 上分配内存。<br><strong>1、动态分配（在堆上分配内存）</strong><br>将类的构造函数和析构函数设为protected属性，这样类对象不能够访问，但是派生类能够访问，能够正常的继承。同时创建另外两个create和destory函数类创建对象。（将create设为static原因是：创建对象的时候是A *p = A::create(); 只有静态成员函数才能够通过类名来访问。）</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">A</span>  </span></span><br><span class="line"><span class="class">&#123;</span>  </span><br><span class="line"><span class="keyword">protected</span>:  </span><br><span class="line">    A()&#123;&#125;  </span><br><span class="line">    ~A()&#123;&#125;  </span><br><span class="line"><span class="keyword">public</span>:  </span><br><span class="line">    <span class="function"><span class="keyword">static</span> A* <span class="title">create</span><span class="params">()</span>  </span></span><br><span class="line"><span class="function">    </span>&#123;  </span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">new</span> A();  </span><br><span class="line">    &#125;  </span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">destory</span><span class="params">()</span>  </span></span><br><span class="line"><span class="function">    </span>&#123;  </span><br><span class="line">        <span class="keyword">delete</span> <span class="keyword">this</span>;  </span><br><span class="line">    &#125;  </span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><p><strong>2、只能静态创建对象</strong><br>只有使用new运算符，对象才会被建立在堆上。因此只要限制new运算符就可以实现类对象只能建立在栈上。可以将new运算符设为私有，实现如下：</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">A</span>  </span></span><br><span class="line"><span class="class">&#123;</span>  </span><br><span class="line"><span class="keyword">private</span>:  </span><br><span class="line">     <span class="function"><span class="keyword">void</span>* <span class="keyword">operator</span> <span class="title">new</span><span class="params">(<span class="keyword">size_t</span> t)</span></span>&#123;&#125;</span><br><span class="line">     <span class="function"><span class="keyword">void</span> <span class="keyword">operator</span> <span class="title">delete</span><span class="params">(<span class="keyword">void</span>* ptr)</span></span>&#123;&#125; </span><br><span class="line"><span class="keyword">public</span>:  </span><br><span class="line">     A()&#123;&#125;  </span><br><span class="line">     ~A()&#123;&#125;  </span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="C-中类成员的访问权限"><a href="#C-中类成员的访问权限" class="headerlink" title="C++中类成员的访问权限"></a>C++中类成员的访问权限</h1><p>C++通过 public、protected、private 三个关键字来控制成员变量和成员函数的访问权限，它们分别表示公有的、受保护的、私有的，被称为成员访问限定符。<br>在类的内部（定义类的代码内部），无论成员被声明为 public、protected 还是 private，都是可以互相访问的，没有访问权限的限制。<br>在类的外部（定义类的代码之外），只能通过对象访问成员，并且通过对象只能访问 public 属性的成员，不能访问 private、protected 属性的成员。</p><p>无论共有继承、私有和保护继承，私有成员不能被“派生类”访问，基类中的共有和保护成员能被“派生类”访问。<br>对于共有继承，只有基类中的共有成员能被“派生类对象”访问，保护和私有成员不能被“派生类对象”访问。对于私有和保护继承，基类中的所有成员不能被“派生类对象”访问。</p><h1 id="C-类内可以定义引用数据成员吗？"><a href="#C-类内可以定义引用数据成员吗？" class="headerlink" title="C++类内可以定义引用数据成员吗？"></a>C++类内可以定义引用数据成员吗？</h1><p>可以，必须通过成员函数初始化列表初始化。</p><h1 id="动态链接库与静态链接库的区别"><a href="#动态链接库与静态链接库的区别" class="headerlink" title="动态链接库与静态链接库的区别"></a>动态链接库与静态链接库的区别</h1><p>1、 静态链接库的后缀名为lib，动态链接库的导入库的后缀名也为lib。不同的是，静态库中包含了函数的实际执行代码，而对于导入库而言，其实际的执行代码位于动态库中，导入库只包含了地址符号表等，确保程序找到对应函数的一些基本地址信息；<br>2、由于静态库是在编译期间直接将代码合到可执行程序中，而动态库是在执行期时调用DLL中的函数体，所以执行速度比动态库要快一点；<br>3、 静态库链接生成的可执行文件体积较大，且包含相同的公共代码，造成内存浪费；<br>4、 使用动态链接库的应用程序不是自完备的，它依赖的DLL模块也要存在，如果使用载入时动态链接，程序启动时发现DLL不存在，系统将终止程序并给出错误信息。而使用运行时动态链接，系统不会终止，但由于DLL中的导出函数不可用，程序会加载失败；<br>5、 DLL文件与EXE文件独立，只要输出接口不变（即名称、参数、返回值类型和调用约定不变），更换DLL文件不会对EXE文件造成任何影响，因而极大地提高了可维护性和可扩展性，适用于大规模的软件开发，使开发过程独立、耦合度小，便于不同开发者和开发组织之间进行开发和测试。</p><h1 id="C-中struct和class的区别"><a href="#C-中struct和class的区别" class="headerlink" title="C++中struct和class的区别"></a>C++中struct和class的区别</h1><p>在c中，struct不能包含任何函数, 在C++中struct得到了很大的扩充：1.struct可以包括成员函数2.struct可以实现继承3.struct可以实现多态。在C++中struct和class的区别并不是很大，两者之间有很大的相似性。那么为什么还要保留struct,这是因为C++是向下兼容的，因此C++中保留了很多C的东西。<br>区别：<br>1.默认的继承访问权。struct的默认继承权限和默认访问权限是public，而class的默认继承权限和默认访问权限是private。<br>2.另外，class还可以定义模板类形参，比如template &lt;class T, int i&gt;。</p><h1 id="C-接口（抽象类）"><a href="#C-接口（抽象类）" class="headerlink" title="C++接口（抽象类）"></a>C++接口（抽象类）</h1><p>如果类中至少有一个函数被声明为纯虚函数，则这个类就是抽象类，纯虚函数是通过在声明中使用 “= 0” 来指定的。设计抽象类的目的，是为了给其他类提供一个可以继承的适当的基类。抽象类不能被用于实例化对象，它只能作为接口使用。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">soapBase</span></span></span><br><span class="line"><span class="class">&#123;</span></span><br><span class="line">  <span class="keyword">public</span>:</span><br><span class="line">  <span class="keyword">virtual</span> ~soapBase()&#123;&#125;;</span><br><span class="line">  <span class="function"><span class="keyword">virtual</span> <span class="keyword">void</span> <span class="title">show</span><span class="params">()</span> </span>= <span class="number">0</span>;</span><br><span class="line">&#125;;</span><br><span class="line"> </span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">SFJSoap</span>:</span><span class="keyword">public</span> soapBase</span><br><span class="line">&#123;</span><br><span class="line">  <span class="keyword">public</span>:</span><br><span class="line">  <span class="function"><span class="keyword">void</span> <span class="title">show</span><span class="params">()</span> </span>&#123;<span class="built_in">cout</span>&lt;&lt;<span class="string">"SFJ Soap!"</span>&lt;&lt;<span class="built_in">endl</span>;&#125;</span><br><span class="line">&#125;;</span><br><span class="line"> </span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">XSLSoap</span>:</span><span class="keyword">public</span> soapBase</span><br><span class="line">&#123;</span><br><span class="line">  <span class="keyword">public</span>:</span><br><span class="line">  <span class="function"><span class="keyword">void</span> <span class="title">show</span><span class="params">()</span> </span>&#123;<span class="built_in">cout</span>&lt;&lt;<span class="string">"XSL Soap!"</span>&lt;&lt;<span class="built_in">endl</span>;&#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="虚函数与纯虚函数区别"><a href="#虚函数与纯虚函数区别" class="headerlink" title="虚函数与纯虚函数区别"></a>虚函数与纯虚函数区别</h1><p>C++的虚函数主要作用是“运行时多态”，父类中提供虚函数的实现，为子类提供默认的函数实现。子类可以重写父类的虚函数实现子类的特殊化。<br>C++中的纯虚函数更像是“只提供申明，没有实现”，是对子类的约束，是“接口继承”。 C++中包含纯虚函数的类，被称为是“抽象类”。抽象类不能使用new出对象，只有实现了这个纯虚函数的子类才能new出对象。</p><h1 id="构造函数、析构函数"><a href="#构造函数、析构函数" class="headerlink" title="构造函数、析构函数"></a>构造函数、析构函数</h1><p>构造函数 会在每次创建类的新对象时执行。构造函数的名称与类的名称是完全相同的，并且不会返回任何类型，也不会返回 void。构造函数可用于为某些成员变量设置初始值。<br>使用初始化列表来初始化字段</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">C::C( <span class="keyword">double</span> a, <span class="keyword">double</span> b, <span class="keyword">double</span> c): X(a), Y(b), Z(c)&#123;....&#125;</span><br></pre></td></tr></table></figure><p>析构函数的名称与类的名称是完全相同的，只是在前面加了个波浪号（~）作为前缀，它不会返回任何值，也不能带有任何参数。析构函数有助于在跳出程序（比如关闭文件、释放内存等）前释放资源。<br>当对象结束其生命周期，如对象所在的函数已调用完毕时，系统会自动执行析构函数。如果用户没有编写析构函数，编译系统会自动生成一个缺省的析构函数（即使自定义了析构函数，编译器也总是会为我们合成一个析构函数，并且如果自定义了析构函数，编译器在执行时会先调用自定义的析构函数再调用合成的析构函数），它也不进行任何操作。所以许多简单的类中没有用显式的析构函数。<br>如果一个类中有指针，且在使用的过程中动态的申请了内存，那么最好显示构造析构函数在销毁类之前，释放掉申请的内存空间，避免内存泄漏。<br>类析构顺序：1）派生类本身的析构函数；2）对象成员析构函数；3）基类析构函数。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Line</span> &#123;</span></span><br><span class="line">   <span class="keyword">public</span>:</span><br><span class="line">      <span class="function"><span class="keyword">void</span> <span class="title">setLength</span><span class="params">( <span class="keyword">double</span> len )</span></span>;</span><br><span class="line">      <span class="function"><span class="keyword">double</span> <span class="title">getLength</span><span class="params">( <span class="keyword">void</span> )</span></span>;</span><br><span class="line">      Line();   <span class="comment">// 这是构造函数声明</span></span><br><span class="line">      ~Line();  <span class="comment">// 这是析构函数声明</span></span><br><span class="line"> </span><br><span class="line">   <span class="keyword">private</span>:</span><br><span class="line">      <span class="keyword">double</span> length;</span><br><span class="line">&#125;;</span><br><span class="line"> </span><br><span class="line"><span class="comment">// 成员函数定义，包括构造函数</span></span><br><span class="line">Line::Line(<span class="keyword">void</span>)&#123;</span><br><span class="line">    <span class="built_in">cout</span> &lt;&lt; <span class="string">"Object is being created"</span> &lt;&lt; <span class="built_in">endl</span>;</span><br><span class="line">&#125;</span><br><span class="line">Line::~Line(<span class="keyword">void</span>) &#123;</span><br><span class="line">    <span class="built_in">cout</span> &lt;&lt; <span class="string">"Object is being deleted"</span> &lt;&lt; <span class="built_in">endl</span>;</span><br><span class="line">&#125;</span><br><span class="line"> </span><br><span class="line"><span class="keyword">void</span> Line::setLength( <span class="keyword">double</span> len ) &#123;</span><br><span class="line">    length = len;</span><br><span class="line">&#125;</span><br><span class="line"> </span><br><span class="line"><span class="keyword">double</span> Line::getLength( <span class="keyword">void</span> ) &#123;</span><br><span class="line">    <span class="keyword">return</span> length;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p><strong>为什么析构函数必须是虚函数？</strong><br>将可能会被继承的父类的析构函数设置为虚函数，可以保证当我们new一个子类，然后使用基类指针指向该子类对象，释放基类指针时可以释放掉子类的空间，防止内存泄漏。</p><p><strong>为什么C++默认的析构函数不是虚函数</strong><br>C++默认的析构函数不是虚函数是因为虚函数需要额外的虚函数表和虚表指针，占用额外的内存。而对于不会被继承的类来说，其析构函数如果是虚函数，就会浪费内存。因此C++默认的析构函数不是虚函数，而是只有当需要当作父类时，设置为虚函数。</p><h1 id="静态函数和虚函数的区别"><a href="#静态函数和虚函数的区别" class="headerlink" title="静态函数和虚函数的区别"></a>静态函数和虚函数的区别</h1><p>静态函数在编译的时候就已经确定运行时机，虚函数在运行的时候动态绑定。虚函数因为用了虚函数表机制，调用的时候会增加一次内存开销</p><h1 id="指针和引用的区别"><a href="#指针和引用的区别" class="headerlink" title="指针和引用的区别"></a>指针和引用的区别</h1><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">int</span> a=<span class="number">1</span>;<span class="keyword">int</span> *p=&amp;a;</span><br><span class="line"><span class="keyword">int</span> a=<span class="number">1</span>;<span class="keyword">int</span> &amp;b=a;</span><br></pre></td></tr></table></figure><p>指针是一个变量，存储的是一个地址，指向内存的一个存储单元；而引用跟原来的变量实质上是同一个东西，是原变量的一个别名。<br><strong>区别：</strong><br>1、指针有自己的一块空间，而引用只是一个别名；<br>2、使用sizeof看一个指针的大小是4（32位），而引用则是被引用对象的大小；<br>3、指针可以被初始化为NULL，而引用必须被初始化且必须是一个已有对象的引用；<br>4、作为参数传递时，指针需要被解引用才可以对对象进行操作，而直接对引 用的修改都会改变引用所指向的对象；<br>5、可以有const指针，但是没有const引用；<br>6、指针在使用中可以指向其它对象，但是引用只能是一个对象的引用，不能被改变；<br>7、指针可以有多级指针（**p），而引用至于一级；<br>8、指针和引用使用++运算符的意义不一样。</p><p><strong>实际上”引用”可以做的任何事情”指针”也都能够做，为什么还要”引用”这东西？</strong><br>答案是 指针能够毫无约束地操作内存中的任何东西，尽管指针功能强大，但是非常危险。<br>如果的确只需要借用一下某个对象的”别名”，那么就用”引用”，而不要用”指针”，以免发生意外。</p><h1 id="数组和指针的区别"><a href="#数组和指针的区别" class="headerlink" title="数组和指针的区别"></a>数组和指针的区别</h1><table><thead><tr><th>指针</th><th>数组</th></tr></thead><tbody><tr><td>保存数据的地址</td><td>保存数据</td></tr><tr><td>间接访问数据，首先获得指针的内容，然后将其作为地址，从该地址中提取数据</td><td>直接访问数据</td></tr><tr><td>通常用于动态的数据结构</td><td>通常用于固定数目且数据类型相同的元素</td></tr><tr><td>通过Malloc分配内存，free释放内存</td><td>隐式的分配和删除</td></tr><tr><td>通常指向匿名数据，操作匿名函数</td><td>自身即为数据名</td></tr><tr><td># 函数指针</td><td></td></tr><tr><td>函数指针是指向函数的指针变量。</td><td></td></tr><tr><td>函数指针本身首先是一个指针变量，该指针变量指向一个具体的函数。这正如用指针变量可指向整型变量、字符型、数组一样，这里是指向函数。C在编译时，每一个函数都有一个入口地址，该入口地址就是函数指针所指向的地址。有了指向函数的指针变量后，可用该指针变量调用函数</td><td></td></tr><tr><td><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">bool</span> <span class="title">LengthCompare</span><span class="params">(<span class="keyword">const</span> <span class="built_in">string</span> &amp;,<span class="keyword">const</span> <span class="built_in">string</span> &amp;)</span></span></span><br><span class="line"><span class="function"><span class="comment">//想要声明一个指向改函数的指针，只需要用指针替换函数名即可</span></span></span><br><span class="line"><span class="function"><span class="title">bool</span> <span class="params">(*pf)</span><span class="params">(<span class="keyword">const</span> <span class="built_in">string</span>&amp;, <span class="keyword">const</span> <span class="built_in">string</span>&amp;)</span></span>;<span class="comment">//未初始化　</span></span><br><span class="line">pf=LengthCompare;</span><br><span class="line"><span class="comment">//pf=&amp;LengthCompare;</span></span><br><span class="line"><span class="keyword">bool</span> b1=pf(<span class="string">"hello"</span>,<span class="string">"goodbye"</span>);</span><br><span class="line"><span class="keyword">bool</span> b2=(*pf)(<span class="string">"hello"</span>,<span class="string">"goodbye"</span>);</span><br><span class="line"><span class="keyword">bool</span> b3=LengthCompare(<span class="string">"hello"</span>,<span class="string">"goodbye"</span>);</span><br><span class="line"><span class="comment">//三个等价调用</span></span><br></pre></td></tr></table></figure></td><td></td></tr></tbody></table><h1 id="const-char-，char-，const-char-crr-，char-drr"><a href="#const-char-，char-，const-char-crr-，char-drr" class="headerlink" title="const char *，char *，const char crr[]，char drr[]"></a>const char *，char *，const char crr[]，char drr[]</h1><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> <span class="keyword">char</span> * arr = <span class="string">"123"</span>;</span><br><span class="line"><span class="comment">//字符串123保存在常量区，const本来是修饰arr指向的值不能通过arr去修改</span></span><br><span class="line"><span class="comment">//但是字符串“123”在常量区，本来就不能改变，所以加不加const效果都一样</span></span><br><span class="line"><span class="keyword">char</span> * brr = <span class="string">"123"</span>;</span><br><span class="line"><span class="comment">//字符串123保存在常量区，这个arr指针指向的是同一个位置，同样不能通过brr去修改"123"的值</span></span><br><span class="line"><span class="keyword">const</span> <span class="keyword">char</span> crr[] = <span class="string">"123"</span>;</span><br><span class="line"><span class="comment">//这里123本来是在栈上的，但是编译器可能会做某些优化，将其放到常量区</span></span><br><span class="line"><span class="keyword">char</span> drr[] = <span class="string">"123"</span>;</span><br><span class="line"><span class="comment">//字符串123保存在栈区，可以通过drr去修改</span></span><br></pre></td></tr></table></figure><h1 id="C-里是怎么定义常量的？常量存放在内存的哪个位置？"><a href="#C-里是怎么定义常量的？常量存放在内存的哪个位置？" class="headerlink" title="C++里是怎么定义常量的？常量存放在内存的哪个位置？"></a>C++里是怎么定义常量的？常量存放在内存的哪个位置？</h1><p>常量在C++里的定义const加上对象类型，常量定义必须初始化。<br>对于局部常量，存放在栈区；<br>对于全局常量，编译期一般不分配内存，放在符号表中以提高访问效率；<br>字面值常量，比如字符串，放在常量区。</p><h1 id="sizeof"><a href="#sizeof" class="headerlink" title="sizeof"></a>sizeof</h1><p>sizeof和new、delete等一样，是关键字，不是函数或者宏<br>sizeof返回内存中分配的字节数，它和操作系统的位数有关。例如在常见的32位系统中，int类型占4个字节；但是在16位系统中，int类型占2个字节。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 在32位系统中不同类型的内存分配</span></span><br><span class="line"><span class="comment">// 基本类型</span></span><br><span class="line"><span class="keyword">sizeof</span>(<span class="keyword">int</span>);        <span class="comment">// = 4   </span></span><br><span class="line"><span class="keyword">sizeof</span>(<span class="keyword">double</span>);     <span class="comment">// = 8   </span></span><br><span class="line"><span class="keyword">sizeof</span>(<span class="keyword">char</span>);       <span class="comment">// = 1   </span></span><br><span class="line"><span class="keyword">sizeof</span>(<span class="keyword">bool</span>);       <span class="comment">// = 1   </span></span><br><span class="line"><span class="keyword">sizeof</span>(<span class="keyword">short</span>);      <span class="comment">// = 2   </span></span><br><span class="line"><span class="keyword">sizeof</span>(<span class="keyword">float</span>);      <span class="comment">// = 4   </span></span><br><span class="line"><span class="keyword">sizeof</span>(<span class="keyword">long</span>);       <span class="comment">// = 4  </span></span><br><span class="line"><span class="comment">// 指针</span></span><br><span class="line"><span class="keyword">sizeof</span>(<span class="keyword">int</span> *);         <span class="comment">// = 4   </span></span><br><span class="line"><span class="keyword">sizeof</span>(<span class="keyword">double</span> *);      <span class="comment">// = 4   </span></span><br><span class="line"><span class="keyword">sizeof</span>(<span class="keyword">char</span> *);        <span class="comment">// = 4  </span></span><br><span class="line"><span class="comment">//函数</span></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">fn</span><span class="params">()</span> </span>&#123; &#125;   </span><br><span class="line"><span class="keyword">sizeof</span>(fn); <span class="comment">// error：函数   </span></span><br><span class="line"><span class="keyword">sizeof</span>(fn()); <span class="comment">// error：不能确定类型  </span></span><br><span class="line"><span class="comment">//sizeof对函数调用求值结果是函数返回值类型的大小，函数并不会被调用</span></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">fun</span><span class="params">()</span> </span>&#123; <span class="keyword">return</span> <span class="number">3</span>;&#125;   </span><br><span class="line"><span class="keyword">sizeof</span>(fun);  <span class="comment">// = sizeof(int) = 4</span></span><br><span class="line"><span class="comment">// 数组 </span></span><br><span class="line"><span class="keyword">int</span> ai[] = &#123;<span class="number">1</span>, <span class="number">2</span>&#125;;  <span class="comment">//数组的sizeof返回整个数组所占的字节数，即（数组元素个数×每个元素所占字节）。</span></span><br><span class="line"><span class="keyword">sizeof</span>(ai);         <span class="comment">// = 2*4 = 8  </span></span><br><span class="line"><span class="comment">// 常量字符串与字符数组的内存分配方式相同</span></span><br><span class="line"><span class="keyword">char</span> ac[] = <span class="string">"abcd"</span>;  <span class="comment">//注意数组末尾的字符串终结符'\0'   </span></span><br><span class="line"><span class="keyword">sizeof</span>(ac);          <span class="comment">// = 5*1 = 5   //注意！！！</span></span><br><span class="line"><span class="keyword">sizeof</span>(<span class="string">"abcd"</span>);      <span class="comment">// = 5*1 = 5  </span></span><br><span class="line"><span class="comment">// 数组和指针所占的字节数不同</span></span><br><span class="line"><span class="keyword">int</span> *pi = <span class="keyword">new</span> <span class="keyword">int</span>[<span class="number">10</span>]; <span class="comment">//这是指针   </span></span><br><span class="line"><span class="keyword">sizeof</span>(pi);            <span class="comment">// = 4   </span></span><br><span class="line"><span class="keyword">int</span> ai[<span class="number">10</span>];   </span><br><span class="line"><span class="keyword">int</span> *p = ai;           <span class="comment">//这还是指针   </span></span><br><span class="line"><span class="keyword">sizeof</span>(p);             <span class="comment">// = 4   </span></span><br><span class="line">  </span><br><span class="line"><span class="keyword">double</span>* (*a)[<span class="number">3</span>][<span class="number">6</span>];    <span class="comment">//看成(double *) (*a)[3][6]，即一个3×6的二维数组，数组元素为指针，指向double类型。   </span></span><br><span class="line"><span class="keyword">sizeof</span>(a);             <span class="comment">// = 4，a为指向上述二维数组的指针   </span></span><br><span class="line"><span class="keyword">sizeof</span>(*a);            <span class="comment">// = sizeof(double *)*3*6 = 72，*a表示上述二维数组       </span></span><br><span class="line"><span class="keyword">sizeof</span>(**a);           <span class="comment">// = sizeof(double *)*6 = 24，**a即*(*a)，表示double*[6]，是元素为double指针的一维数组。   </span></span><br><span class="line"><span class="keyword">sizeof</span>(***a);          <span class="comment">// = sizeof(double *) = 4，表示上述一维数组中的第一个元素，元素类型为double指针。   </span></span><br><span class="line"><span class="keyword">sizeof</span>(****a);         <span class="comment">// = sizeof(double) = 8，表示上述数组首元素指向的double类型。 </span></span><br><span class="line"><span class="comment">// 函数形式参数中的数组会蜕变为指针，原因是数组参数“传址调用”</span></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">aif</span><span class="params">(<span class="keyword">int</span> p[])</span>       <span class="comment">//参数类型是int[]，表示指向int的指针   </span></span></span><br><span class="line"><span class="function"></span>&#123;   </span><br><span class="line">    <span class="keyword">sizeof</span>( p );        <span class="comment">// = 4   </span></span><br><span class="line">&#125;   </span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">pif</span><span class="params">(<span class="keyword">int</span> (*p)[<span class="number">6</span>])</span>   <span class="comment">//参数类型是int (*)[6]，表示指向int数组的指针   </span></span></span><br><span class="line"><span class="function"></span>&#123;   </span><br><span class="line">    <span class="keyword">sizeof</span>( p);         <span class="comment">// = 4   </span></span><br><span class="line">    <span class="keyword">sizeof</span>( *p );       <span class="comment">// = sizeof(int)*6 = 24   </span></span><br><span class="line">&#125;   </span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">ppf</span><span class="params">(<span class="keyword">int</span> *p[<span class="number">6</span>])</span>     <span class="comment">//参数类型是int *[]，表示指向int指针的指针   </span></span></span><br><span class="line"><span class="function"></span>&#123;   </span><br><span class="line">    <span class="keyword">sizeof</span>( p );        <span class="comment">// = 4   </span></span><br><span class="line">    <span class="keyword">sizeof</span>( *p );       <span class="comment">// = 4   </span></span><br><span class="line">&#125;  </span><br><span class="line"><span class="comment">// 32位 类和结构体的内存分配</span></span><br><span class="line"><span class="comment">// 空类或空结构体占一个字节</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">CEmpty</span> &#123;</span> &#125;;   </span><br><span class="line"><span class="keyword">sizeof</span>(CEmpty); <span class="comment">// = 1   </span></span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">SEmpty</span> &#123;</span> &#125;;   </span><br><span class="line"><span class="keyword">sizeof</span>(SEmpty); <span class="comment">// = 1 </span></span><br><span class="line"><span class="comment">// 非空类和结构体所占字节为所有成员占字节的和，但是不包括成员函数和静态成员所占的空间</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">CInt</span> :</span> <span class="keyword">public</span> CEmpty &#123; <span class="keyword">int</span> i;&#125;;   </span><br><span class="line"><span class="keyword">sizeof</span>(CInt); <span class="comment">// = 4;   </span></span><br><span class="line">  </span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">CFunc</span> &#123;</span> <span class="function"><span class="keyword">void</span> <span class="title">f</span><span class="params">()</span></span>&#123;&#125; &#125;;   </span><br><span class="line"><span class="keyword">sizeof</span>(CFunc); <span class="comment">// = 1;   </span></span><br><span class="line">  </span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">SInt</span> :</span> SEmpty &#123; <span class="keyword">static</span> <span class="keyword">int</span> i;&#125;;   </span><br><span class="line"><span class="keyword">sizeof</span>(SInt); <span class="comment">// = 1;  </span></span><br><span class="line"><span class="comment">// 字节对齐</span></span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">SByte1</span>   </span></span><br><span class="line"><span class="class">&#123;</span>   </span><br><span class="line">    <span class="keyword">double</span> d;    <span class="comment">// 长度8，偏移量为0；存放位置区间[0,7]</span></span><br><span class="line">    <span class="keyword">char</span> j;      <span class="comment">// 长度1，偏移量为8；存放位置区间[8]</span></span><br><span class="line">    <span class="keyword">int</span> a;       <span class="comment">// 长度4，偏移量12；存放位置区间[12，15] </span></span><br><span class="line">&#125;;    </span><br><span class="line"><span class="keyword">sizeof</span>(SByte1);  <span class="comment">// = 16   </span></span><br><span class="line">  </span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">SByte2</span>   </span></span><br><span class="line"><span class="class">&#123;</span>         </span><br><span class="line">    <span class="keyword">char</span> j;      <span class="comment">// 长度1，偏移量为0；存放位置区间[0,1]</span></span><br><span class="line">    <span class="keyword">double</span> d;    <span class="comment">// 长度8，偏移量8；存放位置区间[8,15]  </span></span><br><span class="line">    <span class="keyword">int</span> a;       <span class="comment">// 长度4，偏移量16；存放位置区间[16,19]</span></span><br><span class="line">&#125;;    </span><br><span class="line"><span class="keyword">sizeof</span>(SByte2);  <span class="comment">// = 24，为了凑成8的倍数，填充20~23  </span></span><br><span class="line"><span class="comment">//可以通过#pragma pack(n)来设定变量以n字节对齐方式，n=1,2,4,8,16</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">pragma</span> pack(push) <span class="comment">//保存对齐状态   </span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">pragma</span> pack(4)    <span class="comment">//设定为4字节对齐   </span></span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">CByte</span>   </span></span><br><span class="line"><span class="class">&#123;</span>   </span><br><span class="line">    <span class="keyword">char</span> c;       <span class="comment">//长度1 &lt; 4 按1对齐；偏移量为0；存放位置区间[0,1]</span></span><br><span class="line">    <span class="keyword">double</span> d;     <span class="comment">//长度8 &gt; 4 按4对齐；偏移量为4；存放位置区间[4,11] </span></span><br><span class="line">    <span class="keyword">int</span> i;        <span class="comment">//长度4 = 4 按4对齐；偏移量为12；存放位置区间[12,15]</span></span><br><span class="line">&#125;;   </span><br><span class="line"><span class="meta">#<span class="meta-keyword">pragma</span> pack(pop)  <span class="comment">//恢复对齐状态   </span></span></span><br><span class="line"><span class="keyword">sizeof</span>(CByte); <span class="comment">// = 16 </span></span><br><span class="line"><span class="comment">// 联合</span></span><br><span class="line"><span class="keyword">union</span> U   </span><br><span class="line">&#123;   </span><br><span class="line">    <span class="keyword">int</span> i;   </span><br><span class="line">    <span class="keyword">char</span> c;   </span><br><span class="line">    <span class="keyword">double</span> d;   </span><br><span class="line">&#125;;   </span><br><span class="line"><span class="keyword">sizeof</span>(U); <span class="comment">// = Max(sizeof(i), sizeof(c), sizeof(d)) = sizeof(d) = 8</span></span><br></pre></td></tr></table></figure><h1 id="空类的大小是多少，如果是派生类呢"><a href="#空类的大小是多少，如果是派生类呢" class="headerlink" title="空类的大小是多少，如果是派生类呢"></a>空类的大小是多少，如果是派生类呢</h1><p><strong>为何空类的大小不是0呢？</strong><br>为了确保两个不同对象的地址不同，必须如此。<br>类的实例化是在内存中分配一块地址，每个实例在内存中都有独一无二的二地址。同样，空类也会实例化，所以编译器会给空类隐含的添加一个字节，这样空类实例化后就有独一无二的地址了。所以，空类的sizeof为1，而不是0.</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">A</span>&#123;</span> <span class="function"><span class="keyword">virtual</span> <span class="keyword">void</span> <span class="title">f</span><span class="params">()</span></span>&#123;&#125; &#125;; <span class="comment">//4 具有虚函数表的地址</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">B</span>:</span><span class="keyword">public</span> A&#123;&#125; <span class="comment">//4 具有虚函数的类sizeof都是4</span></span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">A</span>&#123;</span>&#125;; <span class="comment">//1 A是空类，其大小为1</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">B</span>:</span><span class="keyword">public</span> <span class="keyword">virtual</span> A&#123;&#125;; <span class="comment">//4 </span></span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Father1</span>&#123;</span>&#125;; <span class="class"><span class="keyword">class</span> <span class="title">Father2</span>&#123;</span>&#125;; <span class="comment">//1 1</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Child</span>:</span>Father1, Father2&#123;&#125;; <span class="comment">//1 多重继承的空类的大小也是1</span></span><br></pre></td></tr></table></figure><p><strong>何时共享虚函数地址表：</strong><br>如果派生类继承的第一个是基类，且该基类定义了虚函数地址表，则派生类就共享该表首址占用的存储单元。对于除前述情形以外的其他任何情形，派生类在处理完所有基类或虚基类后，根据派生类是否建立了虚函数地址表，确定是否为该表首址分配存储单元。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">X</span>&#123;</span>&#125;; <span class="comment">//sizeof(X):1</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Y</span> :</span> <span class="keyword">public</span> <span class="keyword">virtual</span> X &#123;&#125;; <span class="comment">//sizeof(Y):4</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Z</span> :</span> <span class="keyword">public</span> <span class="keyword">virtual</span> X &#123;&#125;; <span class="comment">//sizeof(Z):4</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">A</span> :</span> <span class="keyword">public</span> <span class="keyword">virtual</span> Y &#123;&#125;; <span class="comment">//sizeof(A):8</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">B</span> :</span> <span class="keyword">public</span> Y, <span class="keyword">public</span> Z&#123;&#125;; <span class="comment">//sizeof(B):8</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">C</span> :</span> <span class="keyword">public</span> <span class="keyword">virtual</span> Y, <span class="keyword">public</span> <span class="keyword">virtual</span> Z &#123;&#125;; <span class="comment">//sizeof(C):12</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">D</span> :</span> <span class="keyword">public</span> <span class="keyword">virtual</span> C&#123;&#125;; <span class="comment">//sizeof(D):16</span></span><br></pre></td></tr></table></figure><h1 id="C语言是怎么进行函数调用的"><a href="#C语言是怎么进行函数调用的" class="headerlink" title="C语言是怎么进行函数调用的"></a>C语言是怎么进行函数调用的</h1><p>eip是指令指针，即指向下一条即将执行的指令的地址；<br>ebp为基址指针，常用来指向栈底；<br>esp为栈指针，常用来指向栈顶。<br>假设函数A调用函数B，我们称A函数为”调用者”,B函数为“被调用者”则函数调用过程可以这么描述：<br>(1)先将调用者(A)的堆栈的基址(ebp)入栈，以保存之前任务的信息。<br>(2)然后将调用者(A)的栈顶指针(esp)的值赋给ebp，作为新的基址(即被调用者B的栈底)。<br>(3)然后在这个基址(被调用者B的栈底)上开辟(一般用sub指令)相应的空间用作被调用者B的栈空间。<br>…执行 B函数的主体机器指令段…<br>(4)函数B返回后，从当前栈帧的ebp即恢复为调用者A的栈顶(esp)，使栈顶恢复函数B被调用前的位置;然后调用者A再从恢复后的栈顶可弹出之前的ebp值(可以这么做是因为这个值在函数调用前一步被压入堆栈)。这样，ebp和esp就都恢复了调用函数B前的位置，也就是栈恢复函数B调用前的状态。</p><p>每一个函数调用都会分配函数栈，在栈内进行函数执行过程。调用前，先把返回地址压栈，然后把当前函数的esp指针压栈。<br><strong>参数压栈顺序</strong>：从右到左</p><p><strong>C++如何处理返回值</strong><br>生成一个临时变量，把它的引用作为函数参数传入函数内。<br><strong>C++中拷贝赋值函数的形参能否进行值传递</strong><br>不能。如果是这种情况下，调用拷贝构造函数的时候，首先要将实参传递给形参，这个传递的时候又要调用拷贝构造函数。。如此循环，无法完成拷贝，栈也会满。</p><h1 id="Hash函数"><a href="#Hash函数" class="headerlink" title="Hash函数"></a>Hash函数</h1><p>哈希的过程中需要使用哈希函数进行计算。<br>哈希函数是一种映射关系，根据数据的关键词 key ，通过一定的函数关系，计算出该元素存储位置的函数。表示为：address = H [key]<br><strong>几种常见的哈希函数（散列函数）构造方法</strong><br><strong>直接定址法</strong><br>取关键字或关键字的某个线性函数值为散列地址。<br>即 H(key) = key 或 H(key) = a<em>key + b，其中a和b为常数<br>*</em>除留余数法** 取关键字被某个不大于散列表长度 m 的数 p 求余，得到的作为散列地址。<br>即 H(key) = key % p, p &lt; m。<br><strong>数字分析法</strong><br>当关键字的位数大于地址的位数，对关键字的各位分布进行分析，选出分布均匀的任意几位作为<strong>散列地址</strong><br>仅适用于所有关键字都已知的情况下，根据实际应用确定要选取的部分，尽量避免发生冲突。<br><strong>平方取中法</strong><br>先计算出关键字值的平方，然后取平方值中间几位作为散列地址。<br>随机分布的关键字，得到的散列地址也是随机分布的。<br><strong>折叠法（叠加法）</strong><br>将关键字分为位数相同的几部分，然后取这几部分的叠加和（舍去进位）作为散列地址。<br>用于关键字位数较多，并且关键字中每一位上数字分布大致均匀。<br><strong>随机数法</strong><br>选择一个随机函数，把关键字的随机函数值作为它的哈希值。<br>通常当关键字的长度不等时用这种方法。<br>当关键字是整数类型时就可以用除留余数法；如果关键字是小数类型，选择随机数法会比较好。</p><h1 id="哈希冲突的解决"><a href="#哈希冲突的解决" class="headerlink" title="哈希冲突的解决"></a>哈希冲突的解决</h1><p>加载因子：hash表中已经存储的关键字个数，与可以散列位置的比值，<br>表示Hsah表中元素的填满的程度.若:加载因子越大,填满的元素越多,好处是,空间利用率高了,但:冲突的机会加大了.反之,加载因子越小,填满的元素越少,好处是:冲突的机会减小了,但:空间浪费多了.冲突的机会越大,则查找的成本越高.反之,查找的成本越小.因而,查找时间就越小.<br>选用哈希函数计算哈希值时，可能不同的 key 会得到相同的结果，一个地址怎么存放多个数据呢？这就是冲突。<br><strong>1、开放地址法</strong>（前提是散列表的长度大于等于所要存放的元素）<br>发生哈希冲突后，按照某一次序找到下一个空闲的单元，把冲突的元素放入。<br><strong>线性探查法</strong><br>    从发生冲突的单元开始探查，依次查看下一个单元是否为空，如果到了最后一个单元还是空，那么再从表首依次判断。如此执行直到碰到了空闲的单元或者已经探查完所有单元。<br><strong>平方探查法</strong><br>    从发生冲突的单元加上1^2,2^2,3^2,…,n^2，直到遇到空闲的单元<br>双散列函数探查法<br>定义两个散列函数，分别为s1和s2，s1的算法和前面一致，s2取一个1～m-1之间并和m互为素数的数。s2作为步长。<br>更适合于造表前无法确定表长的情况；平均查找长度较短；适合结点规模较大时<br><strong>2、链地址法</strong><br>   将哈希值相同的元素构成一个链表，head放在散列表中。一般链表长度超过了8就转为红黑树，长度少于6个就变为链表。 缺点：指针需要额外的空间<br><strong>3、再哈希法</strong><br>    同时构造多个不同的哈希函数，Hi = RHi(key) i= 1,2,3 … k;<br>当H1 = RH1(key) 发生冲突时，再用H2 = RH2(key) 进行计算，直到冲突不再产生，这种方法不易产生聚集，但是增加了计算时间。缺点：每次冲突都要重新散列，计算时间增加 </p><h1 id="设计模式（一）：工厂模式"><a href="#设计模式（一）：工厂模式" class="headerlink" title="设计模式（一）：工厂模式"></a>设计模式（一）：工厂模式</h1><p>工厂模式的两个最重要的功能：<br>定义创建对象的接口，封装了对象的创建；使得具体化类的工作延迟到了子类中。<br>对于工厂模式，为了使其能更好的解决多种情况的问题，将其分为三类：简单工厂模式（Simple Factory），工厂方法模式（Factory Method），抽象工厂模式（Abstract Factory）。<br><strong>简单工厂模式（Simple Factory）</strong><br><img src="https://img-blog.csdnimg.cn/20190926124913807.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZmY2pqaHY=,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"><br>简单设计模式存在的目的很简单：定义一个用于创建对象的接口。<br>缺点：对修改不封闭，新增加产品要修改工厂。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;iostream&gt;</span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> <span class="built_in">std</span>;</span><br><span class="line"><span class="keyword">enum</span> PRODUCTTYPE &#123;SFJ,XSL,NAS&#125;;</span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">soapBase</span></span></span><br><span class="line"><span class="class">&#123;</span></span><br><span class="line">  <span class="keyword">public</span>:</span><br><span class="line">  <span class="keyword">virtual</span> ~soapBase()&#123;&#125;;</span><br><span class="line">  <span class="function"><span class="keyword">virtual</span> <span class="keyword">void</span> <span class="title">show</span><span class="params">()</span> </span>= <span class="number">0</span>;</span><br><span class="line">&#125;;</span><br><span class="line"> </span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">SFJSoap</span>:</span><span class="keyword">public</span> soapBase</span><br><span class="line">&#123;</span><br><span class="line">  <span class="keyword">public</span>:</span><br><span class="line">  <span class="function"><span class="keyword">void</span> <span class="title">show</span><span class="params">()</span> </span>&#123;<span class="built_in">cout</span>&lt;&lt;<span class="string">"SFJ Soap!"</span>&lt;&lt;<span class="built_in">endl</span>;&#125;</span><br><span class="line">&#125;;</span><br><span class="line"> </span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">XSLSoap</span>:</span><span class="keyword">public</span> soapBase</span><br><span class="line">&#123;</span><br><span class="line">  <span class="keyword">public</span>:</span><br><span class="line">  <span class="function"><span class="keyword">void</span> <span class="title">show</span><span class="params">()</span> </span>&#123;<span class="built_in">cout</span>&lt;&lt;<span class="string">"XSL Soap!"</span>&lt;&lt;<span class="built_in">endl</span>;&#125;</span><br><span class="line">&#125;;</span><br><span class="line"> </span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">NASSoap</span>:</span><span class="keyword">public</span> soapBase</span><br><span class="line">&#123;</span><br><span class="line">  <span class="keyword">public</span>:</span><br><span class="line">  <span class="function"><span class="keyword">void</span> <span class="title">show</span><span class="params">()</span> </span>&#123;<span class="built_in">cout</span>&lt;&lt;<span class="string">"NAS Soap!"</span>&lt;&lt;<span class="built_in">endl</span>;&#125;</span><br><span class="line">&#125;;</span><br><span class="line"> </span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Factory</span></span></span><br><span class="line"><span class="class">&#123;</span></span><br><span class="line">  <span class="keyword">public</span>:</span><br><span class="line">  <span class="function">soapBase * <span class="title">creatSoap</span><span class="params">(PRODUCTTYPE type)</span></span></span><br><span class="line"><span class="function">  </span>&#123;</span><br><span class="line">    <span class="keyword">switch</span>(type)</span><br><span class="line">    &#123;</span><br><span class="line">      <span class="keyword">case</span> SFJ: </span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">new</span> SFJSoap();</span><br><span class="line">        <span class="keyword">break</span>;</span><br><span class="line">      <span class="keyword">case</span> XSL:</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">new</span> XSLSoap();</span><br><span class="line">        <span class="keyword">break</span>;</span><br><span class="line">      <span class="keyword">case</span> NAS:</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">new</span> NASSoap();</span><br><span class="line">        <span class="keyword">break</span>;</span><br><span class="line">      <span class="keyword">default</span>:<span class="keyword">break</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">  &#125;</span><br><span class="line">&#125;;</span><br><span class="line"> </span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">  Factory factory;</span><br><span class="line">  soapBase* pSoap1 = factory.creatSoap(SFJ);</span><br><span class="line">  pSoap1-&gt;show();</span><br><span class="line">  soapBase* pSoap2 = factory.creatSoap(XSL);</span><br><span class="line">  pSoap2-&gt;show();</span><br><span class="line">  soapBase* pSoap3 = factory.creatSoap(NAS);</span><br><span class="line">  pSoap3-&gt;show();</span><br><span class="line">  <span class="keyword">delete</span> pSoap1;</span><br><span class="line">  <span class="keyword">delete</span> pSoap2;</span><br><span class="line">  <span class="keyword">delete</span> pSoap3;</span><br><span class="line">  <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p><strong>工厂模式（Factory Method）</strong><br><img src="https://img-blog.csdnimg.cn/20190926124926125.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZmY2pqaHY=,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"><br>工厂方法模式的应用并不是只是为了封装对象的创建，而是要把对象的创建放到子类中实现：Factory中只是提供了对象创建的接口，其实现将放在Factory的子类ConcreteFactory中进行<br>缺点：每增加一种产品，就需要增加一个对象的工厂。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;iostream&gt;</span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> <span class="built_in">std</span>;</span><br><span class="line"><span class="keyword">enum</span> SOAPTYPE &#123;SFJ,XSL,NAS&#125;;</span><br><span class="line"> </span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">soapBase</span></span></span><br><span class="line"><span class="class">&#123;</span></span><br><span class="line">  <span class="keyword">public</span>:</span><br><span class="line">  <span class="keyword">virtual</span> ~soapBase()&#123;&#125;;</span><br><span class="line">  <span class="function"><span class="keyword">virtual</span> <span class="keyword">void</span> <span class="title">show</span><span class="params">()</span> </span>= <span class="number">0</span>;</span><br><span class="line">&#125;;</span><br><span class="line"> </span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">SFJSoap</span>:</span><span class="keyword">public</span> soapBase</span><br><span class="line">&#123;</span><br><span class="line">  <span class="keyword">public</span>:</span><br><span class="line">  <span class="function"><span class="keyword">void</span> <span class="title">show</span><span class="params">()</span> </span>&#123;<span class="built_in">cout</span>&lt;&lt;<span class="string">"SFJ Soap!"</span>&lt;&lt;<span class="built_in">endl</span>;&#125;</span><br><span class="line">&#125;;</span><br><span class="line"> </span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">XSLSoap</span>:</span><span class="keyword">public</span> soapBase</span><br><span class="line">&#123;</span><br><span class="line">  <span class="keyword">public</span>:</span><br><span class="line">  <span class="function"><span class="keyword">void</span> <span class="title">show</span><span class="params">()</span> </span>&#123;<span class="built_in">cout</span>&lt;&lt;<span class="string">"XSL Soap!"</span>&lt;&lt;<span class="built_in">endl</span>;&#125;</span><br><span class="line">&#125;;</span><br><span class="line"> </span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">NASSoap</span>:</span><span class="keyword">public</span> soapBase</span><br><span class="line">&#123;</span><br><span class="line">  <span class="keyword">public</span>:</span><br><span class="line">  <span class="function"><span class="keyword">void</span> <span class="title">show</span><span class="params">()</span> </span>&#123;<span class="built_in">cout</span>&lt;&lt;<span class="string">"NAS Soap!"</span>&lt;&lt;<span class="built_in">endl</span>;&#125;</span><br><span class="line">&#125;;</span><br><span class="line"> </span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">FactoryBase</span></span></span><br><span class="line"><span class="class">&#123;</span></span><br><span class="line">  <span class="keyword">public</span>:</span><br><span class="line">  <span class="function"><span class="keyword">virtual</span> soapBase * <span class="title">creatSoap</span><span class="params">()</span> </span>= <span class="number">0</span>;</span><br><span class="line">&#125;;</span><br><span class="line"> </span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">SFJFactory</span>:</span><span class="keyword">public</span> FactoryBase</span><br><span class="line">&#123;</span><br><span class="line">  <span class="keyword">public</span>:</span><br><span class="line">  <span class="function">soapBase * <span class="title">creatSoap</span><span class="params">()</span></span></span><br><span class="line"><span class="function">  </span>&#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">new</span> SFJSoap();</span><br><span class="line">  &#125;</span><br><span class="line">&#125;;</span><br><span class="line"> </span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">XSLFactory</span>:</span><span class="keyword">public</span> FactoryBase</span><br><span class="line">&#123;</span><br><span class="line">  <span class="keyword">public</span>:</span><br><span class="line">  <span class="function">soapBase * <span class="title">creatSoap</span><span class="params">()</span></span></span><br><span class="line"><span class="function">  </span>&#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">new</span> XSLSoap();</span><br><span class="line">  &#125;</span><br><span class="line">&#125;;</span><br><span class="line"> </span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">NASFactory</span>:</span><span class="keyword">public</span> FactoryBase</span><br><span class="line">&#123;</span><br><span class="line">  <span class="keyword">public</span>:</span><br><span class="line">  <span class="function">soapBase * <span class="title">creatSoap</span><span class="params">()</span></span></span><br><span class="line"><span class="function">  </span>&#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">new</span> NASSoap();</span><br><span class="line">  &#125;</span><br><span class="line">&#125;;</span><br><span class="line"> </span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">  SFJFactory factory1;</span><br><span class="line">  soapBase* pSoap1 = factory1.creatSoap();</span><br><span class="line">  pSoap1-&gt;show();</span><br><span class="line">  XSLFactory factory2;</span><br><span class="line">  soapBase* pSoap2 = factory2.creatSoap();</span><br><span class="line">  pSoap2-&gt;show();</span><br><span class="line">  NASFactory factory3;</span><br><span class="line">  soapBase* pSoap3 = factory3.creatSoap();</span><br><span class="line">  pSoap3-&gt;show();</span><br><span class="line">  <span class="keyword">delete</span> pSoap1;</span><br><span class="line">  <span class="keyword">delete</span> pSoap2;</span><br><span class="line">  <span class="keyword">delete</span> pSoap3;</span><br><span class="line">  <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p><strong>抽象工厂模式（Abstract Factory）</strong><br> <img src="https://img-blog.csdnimg.cn/20190926124936714.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZmY2pqaHY=,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"><br>抽象工厂模式：给客户端提供一个接口，可以创建多个产品族中的产品对象 ，而且使用抽象工厂模式还要满足一下条件：<br>1)系统中有多个产品族，而系统一次只可能消费其中一族产品。<br>2)同属于同一个产品族的产品以其使用。</p><p>Eg：搞两个厂房，一个生产低档的牙膏和肥皂，一个生产高档的牙膏和肥皂。比如，厂房一生产中华牙膏、娜爱斯肥皂，厂房二生产黑人牙膏和舒肤佳牙膏</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;iostream&gt;</span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> <span class="built_in">std</span>;</span><br><span class="line"><span class="keyword">enum</span> SOAPTYPE &#123;SFJ,XSL,NAS&#125;;</span><br><span class="line"><span class="keyword">enum</span> TOOTHTYPE &#123;HR,ZH&#125;;</span><br><span class="line"> </span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">SoapBase</span></span></span><br><span class="line"><span class="class">&#123;</span></span><br><span class="line">  <span class="keyword">public</span>:</span><br><span class="line">  <span class="keyword">virtual</span> ~SoapBase()&#123;&#125;;</span><br><span class="line">  <span class="function"><span class="keyword">virtual</span> <span class="keyword">void</span> <span class="title">show</span><span class="params">()</span> </span>= <span class="number">0</span>;</span><br><span class="line">&#125;;</span><br><span class="line"> </span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">SFJSoap</span>:</span><span class="keyword">public</span> SoapBase</span><br><span class="line">&#123;</span><br><span class="line">  <span class="keyword">public</span>:</span><br><span class="line">  <span class="function"><span class="keyword">void</span> <span class="title">show</span><span class="params">()</span> </span>&#123;<span class="built_in">cout</span>&lt;&lt;<span class="string">"SFJ Soap!"</span>&lt;&lt;<span class="built_in">endl</span>;&#125;</span><br><span class="line">&#125;;</span><br><span class="line"> </span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">NASSoap</span>:</span><span class="keyword">public</span> SoapBase</span><br><span class="line">&#123;</span><br><span class="line">  <span class="keyword">public</span>:</span><br><span class="line">  <span class="function"><span class="keyword">void</span> <span class="title">show</span><span class="params">()</span> </span>&#123;<span class="built_in">cout</span>&lt;&lt;<span class="string">"NAS Soap!"</span>&lt;&lt;<span class="built_in">endl</span>;&#125;</span><br><span class="line">&#125;;</span><br><span class="line"> </span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">ToothBase</span></span></span><br><span class="line"><span class="class">&#123;</span></span><br><span class="line">  <span class="keyword">public</span>:</span><br><span class="line">  <span class="keyword">virtual</span> ~ToothBase()&#123;&#125;;</span><br><span class="line">  <span class="function"><span class="keyword">virtual</span> <span class="keyword">void</span> <span class="title">show</span><span class="params">()</span> </span>= <span class="number">0</span>;</span><br><span class="line">&#125;;</span><br><span class="line"> </span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">HRTooth</span>:</span><span class="keyword">public</span> ToothBase</span><br><span class="line">&#123;</span><br><span class="line">  <span class="keyword">public</span>:</span><br><span class="line">  <span class="function"><span class="keyword">void</span> <span class="title">show</span><span class="params">()</span> </span>&#123;<span class="built_in">cout</span>&lt;&lt;<span class="string">"Hei ren Toothpaste!"</span>&lt;&lt;<span class="built_in">endl</span>;&#125;</span><br><span class="line">&#125;;</span><br><span class="line"> </span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">ChinaTooth</span>:</span><span class="keyword">public</span> ToothBase</span><br><span class="line">&#123;</span><br><span class="line">  <span class="keyword">public</span>:</span><br><span class="line">  <span class="function"><span class="keyword">void</span> <span class="title">show</span><span class="params">()</span> </span>&#123;<span class="built_in">cout</span>&lt;&lt;<span class="string">"China Toothpaste!"</span>&lt;&lt;<span class="built_in">endl</span>;&#125;</span><br><span class="line">&#125;;</span><br><span class="line"> </span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">FactoryBase</span></span></span><br><span class="line"><span class="class">&#123;</span></span><br><span class="line">  <span class="keyword">public</span>:</span><br><span class="line">  <span class="function"><span class="keyword">virtual</span> SoapBase * <span class="title">creatSoap</span><span class="params">()</span> </span>= <span class="number">0</span>;</span><br><span class="line">  <span class="function"><span class="keyword">virtual</span> ToothBase * <span class="title">creatToothpaste</span><span class="params">()</span> </span>= <span class="number">0</span>;</span><br><span class="line">&#125;;</span><br><span class="line"> </span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">FactoryA</span> :</span><span class="keyword">public</span> FactoryBase</span><br><span class="line">&#123;</span><br><span class="line">  <span class="keyword">public</span>:</span><br><span class="line">  <span class="function">SoapBase * <span class="title">creatSoap</span><span class="params">()</span></span></span><br><span class="line"><span class="function">  </span>&#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">new</span> SFJSoap();</span><br><span class="line">  &#125;</span><br><span class="line">  </span><br><span class="line">  <span class="function">ToothBase * <span class="title">creatToothpaste</span><span class="params">()</span></span></span><br><span class="line"><span class="function">  </span>&#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">new</span> HRTooth();</span><br><span class="line">  &#125;</span><br><span class="line">&#125;;</span><br><span class="line"> </span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">FactoryB</span> :</span><span class="keyword">public</span> FactoryBase</span><br><span class="line">&#123;</span><br><span class="line">  <span class="keyword">public</span>:</span><br><span class="line">  <span class="function">SoapBase * <span class="title">creatSoap</span><span class="params">()</span></span></span><br><span class="line"><span class="function">  </span>&#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">new</span> NASSoap();</span><br><span class="line">  &#125;</span><br><span class="line">  </span><br><span class="line">  <span class="function">ToothBase * <span class="title">creatToothpaste</span><span class="params">()</span></span></span><br><span class="line"><span class="function">  </span>&#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">new</span> ChinaTooth();</span><br><span class="line">  &#125;</span><br><span class="line">&#125;;</span><br><span class="line"> </span><br><span class="line"> </span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">  FactoryA factory1;</span><br><span class="line">  FactoryB factory2;</span><br><span class="line">  SoapBase *pSoap1 = <span class="literal">NULL</span>;</span><br><span class="line">  ToothBase *pToothpaste1 = <span class="literal">NULL</span>;</span><br><span class="line">  pSoap1 = factory1.creatSoap();</span><br><span class="line">  pToothpaste1 = factory1.creatToothpaste();</span><br><span class="line">  pSoap1-&gt;show();</span><br><span class="line">  pToothpaste1-&gt;show();</span><br><span class="line">  </span><br><span class="line">  SoapBase *pSoap2 = <span class="literal">NULL</span>;</span><br><span class="line">  ToothBase *pToothpaste2 = <span class="literal">NULL</span>;</span><br><span class="line">  pSoap2 = factory2.creatSoap();</span><br><span class="line">  pToothpaste2 = factory2.creatToothpaste();</span><br><span class="line">  pSoap2-&gt;show();</span><br><span class="line">  pToothpaste2-&gt;show();</span><br><span class="line">  </span><br><span class="line">  <span class="keyword">delete</span> pSoap1;</span><br><span class="line">  <span class="keyword">delete</span> pSoap2;</span><br><span class="line">  <span class="keyword">delete</span> pToothpaste1;</span><br><span class="line">  <span class="keyword">delete</span> pToothpaste2;</span><br><span class="line">  </span><br><span class="line">  <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h1 id="设计模式（二）：单例模式"><a href="#设计模式（二）：单例模式" class="headerlink" title="设计模式（二）：单例模式"></a>设计模式（二）：单例模式</h1><p>单例模式主要解决一个全局使用的类频繁的创建和销毁的问题。单例模式下可以确保某一个类只有一个实例，而且自行实例化并向整个系统提供这个实例。<br>单例模式有三个要素：一是某个类只能有一个实例；二是它必须自行创建这个实例；三是它必须自行向整个系统提供这个实例。<br>单例的实现主要是通过以下两个步骤：<br>将该类的构造方法定义为私有方法，这样其他处的代码就无法通过调用该类的构造方法来实例化该类的对象，只有通过该类提供的静态方法来得到该类的唯一实例；<br>在该类内提供一个静态方法，当我们调用这个方法时，如果类持有的引用不为空就返回这个引用，如果类保持的引用为空就创建该类的实例并将实例的引用赋予该类保持的引用。</p><p><strong>懒汉：</strong><br>懒汉式的特点是延迟加载，比如配置文件，在第一次用到类实例的时候才会去实例化；<br>懒汉加载，如果并发访问：使用锁机制，防止多次访问,可以这样，第一次判断为空不加锁，若为空，再进行加锁判断是否为空，若为空则生成对象。在访问量较小时，采用懒汉实现。这是以时间换空间。<br><strong>饿汉：</strong><br>饿汉式的特点是一开始就加载了，在单例类定义的时候就进行实例化。<br>由于要进行线程同步，所以在访问量比较大，或者可能访问的线程比较多时，采用饿汉实现，可以实现更好的性能。这是以空间换时间。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//懒汉式 第一次用到类的实例的时候才回去实例化</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">singleton</span></span></span><br><span class="line"><span class="class">&#123;</span></span><br><span class="line"><span class="keyword">private</span>:</span><br><span class="line">    singleton()&#123;&#125; <span class="comment">//构造函数私有</span></span><br><span class="line">    <span class="keyword">static</span> singleton* _instance;  </span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function"><span class="keyword">static</span> singleton* <span class="title">Get_instance</span><span class="params">()</span></span></span><br><span class="line"><span class="function">    </span>&#123;</span><br><span class="line">        <span class="keyword">if</span>(_instance == <span class="literal">NULL</span>)&#123;  <span class="comment">//判断是否第一次调用</span></span><br><span class="line">           Lock();</span><br><span class="line">           <span class="keyword">if</span>(_instance == <span class="literal">NULL</span>)&#123;</span><br><span class="line">              _instance = <span class="keyword">new</span> singleton();</span><br><span class="line">           &#125;</span><br><span class="line">           UnLock();</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> _instance;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">//饿汉式 单例类定义的时候就进行实例化</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">singleton</span>  </span></span><br><span class="line"><span class="class">  &#123;</span>  </span><br><span class="line">  <span class="keyword">private</span>:  </span><br><span class="line">      singleton()&#123;&#125;  <span class="comment">//私有构造函数  </span></span><br><span class="line">  <span class="keyword">public</span>:  </span><br><span class="line">      <span class="function"><span class="keyword">static</span> singleton* <span class="title">Get_instance</span><span class="params">()</span>  </span></span><br><span class="line"><span class="function">      </span>&#123;  </span><br><span class="line">          <span class="keyword">static</span> singleton _instance;  </span><br><span class="line">          <span class="keyword">return</span> &amp;_instance;  </span><br><span class="line">      &#125;  </span><br><span class="line">  &#125;;</span><br></pre></td></tr></table></figure><p>应用场景：<br>Windows的Task Manager（任务管理器）就是很典型的单例模式，你不能同时打开两个任务管理器。Windows的回收站也是同理。<br>应用程序的日志应用，一般都可以用单例模式实现，只能有一个实例去操作文件。<br>读取配置文件，读取的配置项是公有的，一个地方读取了所有地方都能用，没有必要所有的地方都能读取一遍配置。<br>数据库连接池，多线程的线程池。</p>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;相关：&lt;br&gt;&lt;a href=&quot;https://blog.csdn.net/ffcjjhv/article/details/101433113&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;C++后台开发知识总结（一）C++基础&lt;/a&gt;&lt;br&gt;&lt;a href=&quot;https://blog.csdn.net/ffcjjhv/article/details/101481241&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;C++后台开发知识总结（二）数据库&lt;/a&gt;&lt;br&gt;&lt;a href=&quot;https://blog.csdn.net/ffcjjhv/article/details/101486572&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;C++后台开发知识总结（三）计算机网络&lt;/a&gt;&lt;br&gt;&lt;a href=&quot;https://blog.csdn.net/ffcjjhv/article/details/101546677&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;C++后台开发知识总结（四）操作系统/Linux 内核&lt;/a&gt;&lt;/p&gt;
&lt;h1 id=&quot;extern-“C”的作用&quot;&gt;&lt;a href=&quot;#extern-“C”的作用&quot; class=&quot;headerlink&quot; title=&quot;extern “C”的作用&quot;&gt;&lt;/a&gt;extern “C”的作用&lt;/h1&gt;&lt;p&gt;extern “C”的主要作用就是为了能够正确实现C++代码调用其他C语言代码。加上extern “C”后，会指示编译器这部分代码&lt;strong&gt;按C语言（而不是C++）的方式进行编译&lt;/strong&gt;。&lt;/p&gt;
    
    </summary>
    
      <category term="C++" scheme="http://yoursite.com/categories/C/"/>
    
      <category term="后台开发" scheme="http://yoursite.com/categories/%E5%90%8E%E5%8F%B0%E5%BC%80%E5%8F%91/"/>
    
    
      <category term="C++" scheme="http://yoursite.com/tags/C/"/>
    
      <category term="后台开发" scheme="http://yoursite.com/tags/%E5%90%8E%E5%8F%B0%E5%BC%80%E5%8F%91/"/>
    
  </entry>
  
  <entry>
    <title>刷题汇总（三）leetcode 精选50题 C++答案总结</title>
    <link href="http://yoursite.com/2019/09/26/25/"/>
    <id>http://yoursite.com/2019/09/26/25/</id>
    <published>2019-09-25T17:49:22.000Z</published>
    <updated>2019-12-18T04:20:26.679Z</updated>
    
    <content type="html"><![CDATA[<h3 id="题目来源"><a href="#题目来源" class="headerlink" title="题目来源"></a>题目来源</h3><p> <a href="https://leetcode-cn.com/problemset/50/" target="_blank" rel="noopener">腾讯精选练习（50 题）</a></p><p>相关：<br><a href="https://blog.csdn.net/ffcjjhv/article/details/88409676" target="_blank" rel="noopener">刷题汇总（一）leetcode 精选50题 JavaScript答案总结</a><br><a href="https://blog.csdn.net/ffcjjhv/article/details/96879804" target="_blank" rel="noopener">刷题汇总（二）剑指Offer 66题 C++答案总结</a><br><a href="https://blog.csdn.net/ffcjjhv/article/details/103195691" target="_blank" rel="noopener">刷题汇总（四）技术类编程题汇总 C++</a><br><a href="https://blog.csdn.net/ffcjjhv/article/details/103381516" target="_blank" rel="noopener">刷题汇总（五）leetcode 热题 HOT 100 C++ 答案总结</a><br><a href="https://blog.csdn.net/ffcjjhv/article/details/103503745" target="_blank" rel="noopener">刷题汇总（六）leetcode 多线程 / Shell</a></p><p><a href="https://pan.baidu.com/s/1fHto2ckVlwQzgUi8TxYReA" target="_blank" rel="noopener">PDF版 code</a>  （提取码：0wxr ）</p><h1 id="1、两数相加"><a href="#1、两数相加" class="headerlink" title="1、两数相加"></a>1、两数相加</h1><p>给出两个 非空 的链表用来表示两个非负的整数。其中，它们各自的位数是按照 逆序 的方式存储的，并且它们的每个节点只能存储 一位 数字。<br> <a id="more"></a><br>如果，我们将这两个数相加起来，则会返回一个新的链表来表示它们的和。<br>您可以假设除了数字 0 之外，这两个数都不会以 0 开头。</p><p>输入：(2 -&gt; 4 -&gt; 3) + (5 -&gt; 6 -&gt; 4)<br>输出：7 -&gt; 0 -&gt; 8<br>原因：342 + 465 = 807</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Definition for singly-linked list.</span></span><br><span class="line"><span class="comment"> * struct ListNode &#123;</span></span><br><span class="line"><span class="comment"> *     int val;</span></span><br><span class="line"><span class="comment"> *     ListNode *next;</span></span><br><span class="line"><span class="comment"> *     ListNode(int x) : val(x), next(NULL) &#123;&#125;</span></span><br><span class="line"><span class="comment"> * &#125;;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function">ListNode* <span class="title">addTwoNumbers</span><span class="params">(ListNode* l1, ListNode* l2)</span> </span>&#123;</span><br><span class="line">        ListNode* res = <span class="keyword">new</span> ListNode(<span class="number">0</span>);</span><br><span class="line">        ListNode* head = res;</span><br><span class="line">        <span class="keyword">int</span> flag = <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">while</span>(l1 || l2)&#123;</span><br><span class="line">            <span class="keyword">int</span> x = l1?l1-&gt;val:<span class="number">0</span>;</span><br><span class="line">            <span class="keyword">int</span> y = l2?l2-&gt;val:<span class="number">0</span>;</span><br><span class="line">            head-&gt;next = <span class="keyword">new</span> ListNode((x+y+flag)%<span class="number">10</span>);</span><br><span class="line">            flag = x+y+flag&gt;<span class="number">9</span>?<span class="number">1</span>:<span class="number">0</span>;</span><br><span class="line">            <span class="keyword">if</span>(l1) l1= l1-&gt;next;</span><br><span class="line">            <span class="keyword">if</span>(l2) l2 = l2-&gt;next;</span><br><span class="line">            head = head-&gt;next;                         </span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span>(flag) head-&gt;next = <span class="keyword">new</span> ListNode(<span class="number">1</span>);</span><br><span class="line">        <span class="keyword">return</span> res-&gt;next;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="2、寻找两个有序数组的中位数"><a href="#2、寻找两个有序数组的中位数" class="headerlink" title="2、寻找两个有序数组的中位数"></a>2、寻找两个有序数组的中位数</h1><p>给定两个大小为 m 和 n 的有序数组 nums1 和 nums2。<br>请你找出这两个有序数组的中位数，并且要求算法的时间复杂度为 O(log(m + n))。<br>你可以假设 nums1 和 nums2 不会同时为空。</p><p>示例 1:<br>nums1 = [1, 3]<br>nums2 = [2]<br>则中位数是 2.0<br>示例 2:<br>nums1 = [1, 2]<br>nums2 = [3, 4]<br>则中位数是 (2 + 3)/2 = 2.5</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function"><span class="keyword">double</span> <span class="title">findMedianSortedArrays</span><span class="params">(<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt;&amp; nums1, <span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt;&amp; nums2)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">int</span> m = nums1.size();</span><br><span class="line">        <span class="keyword">int</span> n = nums2.size();</span><br><span class="line">        <span class="keyword">if</span>(m &gt; n) <span class="keyword">return</span> findMedianSortedArrays(nums2, nums1); <span class="comment">//保证nums1更短</span></span><br><span class="line">        <span class="keyword">int</span> lMax1,rMin1,lMax2,rMin2,c1,c2,low=<span class="number">0</span>,high=<span class="number">2</span>*m;</span><br><span class="line">        <span class="keyword">while</span>(low &lt;= high)&#123;</span><br><span class="line">            c1 = (low + high)/<span class="number">2</span>;</span><br><span class="line">            c2 = m + n - c1;</span><br><span class="line">            lMax1 = c1==<span class="number">0</span>? INT_MIN:nums1[(c1<span class="number">-1</span>)/<span class="number">2</span>];</span><br><span class="line">            rMin1 = c1==<span class="number">2</span>*m? INT_MAX:nums1[c1/<span class="number">2</span>];</span><br><span class="line">            lMax2 = c2==<span class="number">0</span>? INT_MIN:nums2[(c2<span class="number">-1</span>)/<span class="number">2</span>];</span><br><span class="line">            rMin2 = c2==<span class="number">2</span>*n? INT_MAX:nums2[c2/<span class="number">2</span>];</span><br><span class="line">            <span class="keyword">if</span>(lMax1 &gt; rMin2) high=c1<span class="number">-1</span>;</span><br><span class="line">            <span class="keyword">else</span> <span class="keyword">if</span>(lMax2 &gt; rMin1) low=c1+<span class="number">1</span>;</span><br><span class="line">            <span class="keyword">else</span> <span class="keyword">break</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> (max(lMax1,lMax2)+min(rMin1,rMin2))/<span class="number">2.0</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="3、最长回文子串"><a href="#3、最长回文子串" class="headerlink" title="3、最长回文子串"></a>3、最长回文子串</h1><p>给定一个字符串 s，找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。</p><p>输入: “babad”<br>输出: “bab”<br>注意: “aba” 也是一个有效答案。</p><p>输入: “cbbd”<br>输出: “bb”</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="comment">// 时间复杂度：O(n^2)，空间复杂度：O(1)</span></span><br><span class="line">    <span class="function"><span class="built_in">string</span> <span class="title">longestPalindrome</span><span class="params">(<span class="built_in">string</span> s)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">int</span> start=<span class="number">0</span>, len=<span class="number">0</span>;</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;s.size();i++)&#123;</span><br><span class="line">            <span class="keyword">int</span> tmp = max(getsub(i,i,s),getsub(i,i+<span class="number">1</span>,s));</span><br><span class="line">            <span class="keyword">if</span>(tmp&gt;len)&#123;</span><br><span class="line">                len = tmp;</span><br><span class="line">                start = i-(len<span class="number">-1</span>)/<span class="number">2</span>;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> s.substr(start,len);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">int</span> <span class="title">getsub</span><span class="params">(<span class="keyword">int</span> i,<span class="keyword">int</span> j,<span class="built_in">string</span> s)</span></span>&#123;</span><br><span class="line">        <span class="keyword">while</span>(i&gt;=<span class="number">0</span> &amp;&amp; j&lt;s.size() &amp;&amp; s[i]==s[j])&#123;</span><br><span class="line">            i--;</span><br><span class="line">            j++;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> j-i<span class="number">-1</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="4、整数反转"><a href="#4、整数反转" class="headerlink" title="4、整数反转"></a>4、整数反转</h1><p>给出一个 32 位的有符号整数，你需要将这个整数中每位上的数字进行反转。</p><p>输入: 123<br>输出: 321</p><p>输入: -123<br>输出: -321</p><p>输入: 120<br>输出: 21</p><p>注意:<br>假设我们的环境只能存储得下 32 位的有符号整数，则其数值范围为 [−2^31,  2^31 − 1]。请根据这个假设，如果反转后整数溢出那么就返回 0。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function"><span class="keyword">int</span> <span class="title">reverse</span><span class="params">(<span class="keyword">int</span> x)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">int</span> res=<span class="number">0</span>;</span><br><span class="line">        <span class="keyword">while</span>(x!=<span class="number">0</span>)&#123;</span><br><span class="line">            <span class="keyword">if</span>(res&gt;INT_MAX/<span class="number">10</span> || res==INT_MAX/<span class="number">10</span> &amp;&amp; x%<span class="number">10</span>&gt;<span class="number">7</span>) <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">            <span class="keyword">if</span>(res&lt;INT_MIN/<span class="number">10</span> || res==INT_MIN/<span class="number">10</span> &amp;&amp; x%<span class="number">10</span>&lt;<span class="number">-8</span>) <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">            res=res*<span class="number">10</span>+x%<span class="number">10</span>;</span><br><span class="line">            x=x/<span class="number">10</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="5、字符串转换整数-atoi"><a href="#5、字符串转换整数-atoi" class="headerlink" title="5、字符串转换整数 (atoi)"></a>5、字符串转换整数 (atoi)</h1><p>请你来实现一个 atoi 函数，使其能将字符串转换成整数。<br>首先，该函数会根据需要丢弃无用的开头空格字符，直到寻找到第一个非空格的字符为止。<br>当我们寻找到的第一个非空字符为正或者负号时，则将该符号与之后面尽可能多的连续数字组合起来，作为该整数的正负号；假如第一个非空字符是数字，则直接将其与之后连续的数字字符组合起来，形成整数。<br>该字符串除了有效的整数部分之后也可能会存在多余的字符，这些字符可以被忽略，它们对于函数不应该造成影响。<br>注意：假如该字符串中的第一个非空格字符不是一个有效整数字符、字符串为空或字符串仅包含空白字符时，则你的函数不需要进行转换。<br>在任何情况下，若函数不能进行有效的转换时，请返回 0。<br>说明：<br>假设我们的环境只能存储 32 位大小的有符号整数，那么其数值范围为 [−2^31,  2^31 − 1]。如果数值超过这个范围，请返回  INT_MAX (231 − 1) 或 INT_MIN (−231) 。</p><p>输入: “42”<br>输出: 42</p><p>输入: “   -42”<br>输出: -42<br>解释: 第一个非空白字符为 ‘-‘, 它是一个负号。<br>     我们尽可能将负号与后面所有连续出现的数字组合起来，最后得到 -42 。</p><p>输入: “4193 with words”<br>输出: 4193<br>解释: 转换截止于数字 ‘3’ ，因为它的下一个字符不为数字。</p><p>输入: “words and 987”<br>输出: 0<br>解释: 第一个非空字符是 ‘w’, 但它不是数字或正、负号。<br>     因此无法执行有效的转换。</p><p>输入: “-91283472332”<br>输出: -2147483648<br>解释: 数字 “-91283472332” 超过 32 位有符号整数范围。<br>     因此返回 INT_MIN (−231) 。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function"><span class="keyword">int</span> <span class="title">myAtoi</span><span class="params">(<span class="built_in">string</span> str)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">int</span> res = <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">bool</span> flag = <span class="literal">true</span>;</span><br><span class="line">        <span class="keyword">int</span> i = <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">while</span>(i&lt;str.size() &amp;&amp; str[i]==<span class="string">' '</span>) i++;</span><br><span class="line">        <span class="keyword">if</span>(str[i] == <span class="string">'+'</span>)&#123;flag=<span class="literal">true</span>;i++;&#125;</span><br><span class="line">        <span class="keyword">else</span> <span class="keyword">if</span>(str[i] == <span class="string">'-'</span>)&#123;flag=<span class="literal">false</span>;i++;&#125;</span><br><span class="line">        <span class="keyword">for</span>(;i&lt;str.size();i++)&#123;</span><br><span class="line">            <span class="keyword">if</span>(str[i]&lt;=<span class="string">'9'</span> &amp;&amp; str[i]&gt;=<span class="string">'0'</span>)&#123;</span><br><span class="line">                <span class="keyword">if</span>(res&gt;INT_MAX/<span class="number">10</span> || res==INT_MAX/<span class="number">10</span>&amp;&amp;(str[i]-<span class="string">'0'</span>)&gt;<span class="number">7</span>) <span class="keyword">return</span> flag?INT_MAX:INT_MIN;</span><br><span class="line">                res = res*<span class="number">10</span>+(str[i]-<span class="string">'0'</span>);</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">else</span> <span class="keyword">return</span> flag?res:-res;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> flag?res:-res;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="6、回文数"><a href="#6、回文数" class="headerlink" title="6、回文数"></a>6、回文数</h1><p>判断一个整数是否是回文数。回文数是指正序（从左向右）和倒序（从右向左）读都是一样的整数。</p><p>输入: 121<br>输出: true</p><p>输入: -121<br>输出: false<br>解释: 从左向右读, 为 -121 。 从右向左读, 为 121- 。因此它不是一个回文数。</p><p>输入: 10<br>输出: false<br>解释: 从右向左读, 为 01 。因此它不是一个回文数。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function"><span class="keyword">bool</span> <span class="title">isPalindrome</span><span class="params">(<span class="keyword">int</span> x)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">if</span>(x&lt;<span class="number">0</span>) <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">        <span class="built_in">string</span> s = to_string(x);</span><br><span class="line">        <span class="keyword">int</span> l=<span class="number">0</span>,r=s.size()<span class="number">-1</span>;</span><br><span class="line">        <span class="keyword">while</span>(l&lt;=r)&#123;</span><br><span class="line">            <span class="keyword">if</span>(s[l] == s[r])&#123;</span><br><span class="line">                l++;</span><br><span class="line">                r--;</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">else</span> <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="7、盛最多水的容器"><a href="#7、盛最多水的容器" class="headerlink" title="7、盛最多水的容器"></a>7、盛最多水的容器</h1><p>给定 n 个非负整数 a1，a2，…，an，每个数代表坐标中的一个点 (i, ai) 。在坐标内画 n 条垂直线，垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0)。找出其中的两条线，使得它们与 x 轴共同构成的容器可以容纳最多的水。<br>说明：你不能倾斜容器，且 n 的值至少为 2。<br>图中垂直线代表输入数组 [1,8,6,2,5,4,8,3,7]。在此情况下，容器能够容纳水（表示为蓝色部分）的最大值为 49。</p><p>输入: [1,8,6,2,5,4,8,3,7]<br>输出: 49</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function"><span class="keyword">int</span> <span class="title">maxArea</span><span class="params">(<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt;&amp; height)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">int</span> smax = <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">int</span> i = <span class="number">0</span>,j = height.size()<span class="number">-1</span>;</span><br><span class="line">        <span class="keyword">while</span>(i&lt;=j)&#123;</span><br><span class="line">            <span class="keyword">int</span> s = min(height[i],height[j])*(j-i);</span><br><span class="line">            <span class="keyword">if</span>(s &gt; smax) smax = s;</span><br><span class="line">            <span class="keyword">if</span>(height[i]&lt;height[j]) i++;</span><br><span class="line">            <span class="keyword">else</span> j--;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> smax;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="8、最长公共前缀"><a href="#8、最长公共前缀" class="headerlink" title="8、最长公共前缀"></a>8、最长公共前缀</h1><p>编写一个函数来查找字符串数组中的最长公共前缀。<br>如果不存在公共前缀，返回空字符串 “”。</p><p>输入: [“flower”,”flow”,”flight”]<br>输出: “fl”</p><p>输入: [“dog”,”racecar”,”car”]<br>输出: “”<br>解释: 输入不存在公共前缀。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function"><span class="built_in">string</span> <span class="title">longestCommonPrefix</span><span class="params">(<span class="built_in">vector</span>&lt;<span class="built_in">string</span>&gt;&amp; strs)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">int</span> imin = <span class="number">0</span>; <span class="comment">//最短的字符串</span></span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;strs.size();i++)&#123;</span><br><span class="line">            <span class="keyword">if</span>(strs[i].size()&lt;strs[imin].size()) imin = i;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="built_in">string</span> res;</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;strs[imin].size();i++)&#123;</span><br><span class="line">            <span class="keyword">for</span>(<span class="keyword">int</span> j=<span class="number">0</span>;j&lt;strs.size();j++)&#123;</span><br><span class="line">                <span class="keyword">if</span>(strs[j][i] != strs[imin][i]) <span class="keyword">return</span> res;</span><br><span class="line">            &#125;</span><br><span class="line">            res.push_back(strs[imin][i]);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="9、三数之和"><a href="#9、三数之和" class="headerlink" title="9、三数之和"></a>9、三数之和</h1><p>给定一个包含 n 个整数的数组 nums，判断 nums 中是否存在三个元素 a，b，c ，使得 a + b + c = 0 ？找出所有满足条件且不重复的三元组。<br>注意：答案中不可以包含重复的三元组。</p><p>例如, 给定数组 nums = [-1, 0, 1, 2, -1, -4]，<br>满足要求的三元组集合为：<br>[<br>  [-1, 0, 1],<br>  [-1, -1, 2]<br>]</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="built_in">vector</span>&lt;<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; &gt; threeSum(<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt;&amp; nums) &#123;</span><br><span class="line">        sort(nums.begin(),nums.end());</span><br><span class="line">        <span class="built_in">vector</span>&lt;<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; &gt; res;</span><br><span class="line">        <span class="keyword">int</span> add;</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;nums.size();i++)&#123;</span><br><span class="line">            <span class="keyword">if</span>(i&gt;<span class="number">0</span> &amp;&amp; nums[i] == nums[i<span class="number">-1</span>]) <span class="keyword">continue</span>; <span class="comment">//i和前面一样，跳过</span></span><br><span class="line">            <span class="keyword">if</span>((add = nums[i])&gt;<span class="number">0</span>) <span class="keyword">break</span>;</span><br><span class="line">            </span><br><span class="line">            <span class="keyword">int</span> l = i+<span class="number">1</span>, r = nums.size()<span class="number">-1</span>; <span class="comment">//双指针，找和为add</span></span><br><span class="line">            <span class="keyword">while</span>(l&lt;r)&#123;</span><br><span class="line">                <span class="keyword">if</span>(nums[l]+nums[r]+add&gt;<span class="number">0</span>) r--;</span><br><span class="line">                <span class="keyword">else</span> <span class="keyword">if</span>(nums[l]+nums[r]+add&lt;<span class="number">0</span>) l++;</span><br><span class="line">                <span class="keyword">else</span> &#123;</span><br><span class="line">                    res.push_back(&#123;add,nums[l],nums[r]&#125;);</span><br><span class="line">                    l++;r--;</span><br><span class="line">                    <span class="keyword">while</span>(l&lt;r &amp;&amp; nums[l] == nums[l<span class="number">-1</span>]) l++;</span><br><span class="line">                    <span class="keyword">while</span>(l&lt;r &amp;&amp; nums[r] == nums[r+<span class="number">1</span>]) r--;</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;  </span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="10、最接近的三数之和"><a href="#10、最接近的三数之和" class="headerlink" title="10、最接近的三数之和"></a>10、最接近的三数之和</h1><p>给定一个包括 n 个整数的数组 nums 和 一个目标值 target。找出 nums 中的三个整数，使得它们的和与 target 最接近。返回这三个数的和。假定每组输入只存在唯一答案。</p><p>例如，给定数组 nums = [-1，2，1，-4], 和 target = 1.<br>与 target 最接近的三个数的和为 2. (-1 + 2 + 1 = 2).</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function"><span class="keyword">int</span> <span class="title">threeSumClosest</span><span class="params">(<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt;&amp; nums, <span class="keyword">int</span> target)</span> </span>&#123;</span><br><span class="line">        sort(nums.begin(),nums.end());</span><br><span class="line">        <span class="keyword">int</span> add = <span class="number">0</span>,dis = INT_MAX;</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;nums.size();i++)&#123;</span><br><span class="line">            <span class="keyword">int</span> l = <span class="number">0</span>, r = nums.size()<span class="number">-1</span>;</span><br><span class="line">            <span class="keyword">while</span>(l&lt;r)&#123;</span><br><span class="line">                <span class="keyword">if</span>(l==i) l++;</span><br><span class="line">                <span class="keyword">if</span>(r==i) r--;</span><br><span class="line">                <span class="keyword">if</span>(l&gt;=r) <span class="keyword">break</span>;</span><br><span class="line">                <span class="keyword">int</span> tadd = nums[i]+nums[l]+nums[r];</span><br><span class="line">                <span class="keyword">int</span> tdis = <span class="built_in">abs</span>(tadd-target);</span><br><span class="line">                <span class="keyword">if</span>(tdis &lt; dis)&#123;</span><br><span class="line">                    add = tadd;</span><br><span class="line">                    dis = tdis;</span><br><span class="line">                &#125;</span><br><span class="line">                <span class="keyword">if</span>(tadd == target) <span class="keyword">return</span> add;</span><br><span class="line">                <span class="keyword">if</span>(tadd &lt; target) l++;</span><br><span class="line">                <span class="keyword">else</span> r--;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> add;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="11、有效的括号"><a href="#11、有效的括号" class="headerlink" title="11、有效的括号"></a>11、有效的括号</h1><p>给定一个只包括 ‘(‘，’)’，’{‘，’}’，’[‘，’]’ 的字符串，判断字符串是否有效。<br>有效字符串需满足：<br>左括号必须用相同类型的右括号闭合。<br>左括号必须以正确的顺序闭合。<br>注意空字符串可被认为是有效字符串。</p><p>输入: “()”<br>输出: true</p><p>输入: “()[]{}”<br>输出: true</p><p>输入: “(]”<br>输出: false</p><p>输入: “([)]”<br>输出: false</p><p>输入: “{[]}”<br>输出: true</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function"><span class="keyword">bool</span> <span class="title">isValid</span><span class="params">(<span class="built_in">string</span> s)</span> </span>&#123;</span><br><span class="line">        <span class="built_in">stack</span>&lt;<span class="keyword">char</span>&gt; <span class="built_in">stack</span>;</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;s.size();i++)&#123;</span><br><span class="line">            <span class="keyword">if</span>(!<span class="built_in">stack</span>.empty() &amp;&amp; check(<span class="built_in">stack</span>.top(),s[i])) <span class="built_in">stack</span>.pop();</span><br><span class="line">            <span class="keyword">else</span> <span class="built_in">stack</span>.push(s[i]);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> <span class="built_in">stack</span>.empty();</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="function"><span class="keyword">bool</span> <span class="title">check</span><span class="params">(<span class="keyword">char</span> a,<span class="keyword">char</span> b)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">if</span>(a==<span class="string">'('</span>&amp;&amp;b==<span class="string">')'</span> || a==<span class="string">'['</span>&amp;&amp;b==<span class="string">']'</span> || a==<span class="string">'&#123;'</span>&amp;&amp;b==<span class="string">'&#125;'</span>) <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line">        <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="12、合并两个有序链表"><a href="#12、合并两个有序链表" class="headerlink" title="12、合并两个有序链表"></a>12、合并两个有序链表</h1><p>将两个有序链表合并为一个新的有序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 </p><p>输入：1-&gt;2-&gt;4, 1-&gt;3-&gt;4<br>输出：1-&gt;1-&gt;2-&gt;3-&gt;4-&gt;4···c</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Definition for singly-linked list.</span></span><br><span class="line"><span class="comment"> * struct ListNode &#123;</span></span><br><span class="line"><span class="comment"> *     int val;</span></span><br><span class="line"><span class="comment"> *     ListNode *next;</span></span><br><span class="line"><span class="comment"> *     ListNode(int x) : val(x), next(NULL) &#123;&#125;</span></span><br><span class="line"><span class="comment"> * &#125;;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function">ListNode* <span class="title">mergeTwoLists</span><span class="params">(ListNode* l1, ListNode* l2)</span> </span>&#123;</span><br><span class="line">        ListNode* res = <span class="keyword">new</span> ListNode(<span class="number">0</span>);</span><br><span class="line">        ListNode* head = res;</span><br><span class="line">        <span class="keyword">while</span>(l1 &amp;&amp; l2)&#123;</span><br><span class="line">            <span class="keyword">if</span>(l1-&gt;val &lt; l2-&gt;val)&#123;</span><br><span class="line">                head-&gt;next = l1;</span><br><span class="line">                l1 = l1-&gt;next;</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">else</span>&#123;</span><br><span class="line">                head-&gt;next = l2;</span><br><span class="line">                l2 = l2-&gt;next;</span><br><span class="line">            &#125;</span><br><span class="line">            head = head-&gt;next;</span><br><span class="line">        &#125;</span><br><span class="line">        head-&gt;next = l1?l1:l2;</span><br><span class="line">        <span class="keyword">return</span> res-&gt;next;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="13、合并K个排序链表"><a href="#13、合并K个排序链表" class="headerlink" title="13、合并K个排序链表"></a>13、合并K个排序链表</h1><p>合并 k 个排序链表，返回合并后的排序链表。请分析和描述算法的复杂度。</p><p>输入:<br>[<br>  1-&gt;4-&gt;5,<br>  1-&gt;3-&gt;4,<br>  2-&gt;6<br>]输出: 1-&gt;1-&gt;2-&gt;3-&gt;4-&gt;4-&gt;5-&gt;6</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Definition for singly-linked list.</span></span><br><span class="line"><span class="comment"> * struct ListNode &#123;</span></span><br><span class="line"><span class="comment"> *     int val;</span></span><br><span class="line"><span class="comment"> *     ListNode *next;</span></span><br><span class="line"><span class="comment"> *     ListNode(int x) : val(x), next(NULL) &#123;&#125;</span></span><br><span class="line"><span class="comment"> * &#125;;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function">ListNode* <span class="title">mergeKLists</span><span class="params">(<span class="built_in">vector</span>&lt;ListNode*&gt;&amp; lists)</span> </span>&#123;</span><br><span class="line">        ListNode* <span class="built_in">list</span> = <span class="literal">NULL</span>;</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;lists.size();i++)&#123;</span><br><span class="line">            <span class="built_in">list</span> = merge2Lists(<span class="built_in">list</span>,lists[i]);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> <span class="built_in">list</span>; </span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="function">ListNode* <span class="title">merge2Lists</span><span class="params">(ListNode* l1, ListNode* l2)</span> </span>&#123;</span><br><span class="line">        ListNode* res = <span class="keyword">new</span> ListNode(<span class="number">0</span>);</span><br><span class="line">        ListNode* head = res;</span><br><span class="line">        <span class="keyword">while</span>(l1 &amp;&amp; l2)&#123;</span><br><span class="line">            <span class="keyword">if</span>(l1-&gt;val &lt; l2-&gt;val)&#123;</span><br><span class="line">                head-&gt;next = l1;</span><br><span class="line">                l1 = l1-&gt;next;</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">else</span>&#123;</span><br><span class="line">                head-&gt;next = l2;</span><br><span class="line">                l2 = l2-&gt;next;</span><br><span class="line">            &#125;</span><br><span class="line">            head = head-&gt;next;</span><br><span class="line">        &#125;</span><br><span class="line">        head-&gt;next = l1?l1:l2;</span><br><span class="line">        <span class="keyword">return</span> res-&gt;next;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="14、删除排序数组中的重复项"><a href="#14、删除排序数组中的重复项" class="headerlink" title="14、删除排序数组中的重复项"></a>14、删除排序数组中的重复项</h1><p>给定一个排序数组，你需要在原地删除重复出现的元素，使得每个元素只出现一次，返回移除后数组的新长度。<br>不要使用额外的数组空间，你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成。</p><p>给定数组 nums = [1,1,2],<br>函数应该返回新的长度 2, 并且原数组 nums 的前两个元素被修改为 1, 2。<br>你不需要考虑数组中超出新长度后面的元素。</p><p>给定 nums = [0,0,1,1,1,2,2,3,3,4],<br>函数应该返回新的长度 5, 并且原数组 nums 的前五个元素被修改为 0, 1, 2, 3, 4。<br>你不需要考虑数组中超出新长度后面的元素。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function"><span class="keyword">int</span> <span class="title">removeDuplicates</span><span class="params">(<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt;&amp; nums)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">if</span>(nums.empty()) <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">int</span> i = <span class="number">0</span>; <span class="comment">//双指针</span></span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> j=<span class="number">1</span>;j&lt;nums.size();j++)&#123;</span><br><span class="line">            <span class="keyword">if</span>(nums[i] != nums[j])&#123;</span><br><span class="line">                i++;</span><br><span class="line">                nums[i]=nums[j];</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> i+<span class="number">1</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="15、搜索旋转排序数组"><a href="#15、搜索旋转排序数组" class="headerlink" title="15、搜索旋转排序数组"></a>15、搜索旋转排序数组</h1><p>假设按照升序排序的数组在预先未知的某个点上进行了旋转。<br>( 例如，数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] )。<br>搜索一个给定的目标值，如果数组中存在这个目标值，则返回它的索引，否则返回 -1 。<br>你可以假设数组中不存在重复的元素。<br>你的算法时间复杂度必须是 O(log n) 级别。</p><p>输入: nums = [4,5,6,7,0,1,2], target = 0<br>输出: 4</p><p>输入: nums = [4,5,6,7,0,1,2], target = 3<br>输出: -1</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function"><span class="keyword">int</span> <span class="title">search</span><span class="params">(<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt;&amp; nums, <span class="keyword">int</span> target)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> helper(nums,target,<span class="number">0</span>,nums.size()<span class="number">-1</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="function"><span class="keyword">int</span> <span class="title">helper</span><span class="params">(<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt;&amp; nums, <span class="keyword">int</span> target, <span class="keyword">int</span> i, <span class="keyword">int</span> j)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">if</span>(i&gt;j) <span class="keyword">return</span> <span class="number">-1</span>;</span><br><span class="line">        <span class="keyword">int</span> mid = (i+j)/<span class="number">2</span>;</span><br><span class="line">        <span class="keyword">if</span>(nums[mid] == target) <span class="keyword">return</span> mid;</span><br><span class="line">        <span class="keyword">if</span>(nums[mid] &lt; nums[j])&#123; <span class="comment">//7 8 1 2 3 4  旋转点在左，右顺序</span></span><br><span class="line">            <span class="keyword">if</span>(nums[mid] &lt; target &amp;&amp; target &lt;= nums[j]) <span class="keyword">return</span> helper(nums,target,mid+<span class="number">1</span>,j);</span><br><span class="line">            <span class="keyword">else</span> <span class="keyword">return</span> helper(nums,target,i,mid<span class="number">-1</span>);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">else</span>&#123; <span class="comment">//3 4 7 8 1 2  旋转点在右，左顺序</span></span><br><span class="line">            <span class="keyword">if</span>(nums[mid] &gt; target &amp;&amp; target &gt;= nums[i]) <span class="keyword">return</span> helper(nums,target,i,mid<span class="number">-1</span>);</span><br><span class="line">            <span class="keyword">else</span> <span class="keyword">return</span> helper(nums,target,mid+<span class="number">1</span>,j);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="16、字符串相乘"><a href="#16、字符串相乘" class="headerlink" title="16、字符串相乘"></a>16、字符串相乘</h1><p>给定两个以字符串形式表示的非负整数 num1 和 num2，返回 num1 和 num2 的乘积，它们的乘积也表示为字符串形式。</p><p>输入: num1 = “2”, num2 = “3”<br>输出: “6”</p><p>输入: num1 = “123”, num2 = “456”<br>输出: “56088”<br>说明：</p><p>num1 和 num2 的长度小于110。<br>num1 和 num2 只包含数字 0-9。<br>num1 和 num2 均不以零开头，除非是数字 0 本身。<br>不能使用任何标准库的大数类型（比如 BigInteger）或直接将输入转换为整数来处理。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function"><span class="built_in">string</span> <span class="title">multiply</span><span class="params">(<span class="built_in">string</span> num1, <span class="built_in">string</span> num2)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">int</span> len1 = num1.size(),len2 = num2.size();</span><br><span class="line">        <span class="function"><span class="built_in">string</span> <span class="title">res</span><span class="params">(len1+len2,<span class="string">'0'</span>)</span></span>;</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i=len1<span class="number">-1</span>;i&gt;=<span class="number">0</span>;i--)&#123;</span><br><span class="line">            <span class="keyword">for</span>(<span class="keyword">int</span> j=len2<span class="number">-1</span>;j&gt;=<span class="number">0</span>;j--)&#123;</span><br><span class="line">                <span class="keyword">int</span> t = (res[i+j+<span class="number">1</span>]-<span class="string">'0'</span>)+(num1[i]-<span class="string">'0'</span>)*(num2[j]-<span class="string">'0'</span>);</span><br><span class="line">                res[i+j+<span class="number">1</span>] = t%<span class="number">10</span> +<span class="string">'0'</span>;</span><br><span class="line">                res[i+j] += t/<span class="number">10</span>;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;len1+len2;i++)&#123;</span><br><span class="line">            <span class="keyword">if</span>(res[i] != <span class="string">'0'</span>) <span class="keyword">return</span> res.substr(i);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> <span class="string">"0"</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="17、全排列"><a href="#17、全排列" class="headerlink" title="17、全排列"></a>17、全排列</h1><p>给定一个没有重复数字的序列，返回其所有可能的全排列。</p><p>输入: [1,2,3]<br>输出:<br>[<br>  [1,2,3],<br>  [1,3,2],<br>  [2,1,3],<br>  [2,3,1],<br>  [3,1,2],<br>  [3,2,1]<br>]</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="built_in">vector</span>&lt;<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt;&gt; permute(<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt;&amp; nums) &#123;</span><br><span class="line">        <span class="built_in">vector</span>&lt;<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt;&gt; res;</span><br><span class="line">        backtrack(nums,res,<span class="number">0</span>);</span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">backtrack</span><span class="params">(<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; &amp;nums,<span class="built_in">vector</span>&lt;<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt;&gt; &amp;res,<span class="keyword">int</span> n)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">if</span>(n == nums.size()<span class="number">-1</span>) res.push_back(nums);</span><br><span class="line">        <span class="keyword">else</span>&#123;</span><br><span class="line">            <span class="keyword">for</span>(<span class="keyword">int</span> i=n;i&lt;nums.size();i++)&#123;</span><br><span class="line">                swap(nums[i],nums[n]);</span><br><span class="line">                backtrack(nums,res,n+<span class="number">1</span>);</span><br><span class="line">                swap(nums[i],nums[n]);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">swap</span><span class="params">(<span class="keyword">int</span> &amp;i ,<span class="keyword">int</span> &amp;j)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">int</span> t = i; i = j; j = t;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">//剑指offer 27题 字典序输出有重复字符串序列的全排列</span></span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment"> 问题转换为先固定第一个字符，求剩余字符的排列</span></span><br><span class="line"><span class="comment"> 再把第一个字符与后面每一个字符交换，并同样递归获得首位后面的字符串组合</span></span><br><span class="line"><span class="comment"> a b b c:</span></span><br><span class="line"><span class="comment"> a+f(bbc),b+f(abc),c+f(cbba); 遍历出所有可能出现在第一个位置的字符</span></span><br><span class="line"><span class="comment"> f(bbc)=b+f(bc),c+f(bb);</span></span><br><span class="line"><span class="comment"> f(bc)=b+f(c),c+f(b);</span></span><br><span class="line"><span class="comment"> f(c)=c;</span></span><br><span class="line"><span class="comment">class Solution &#123;</span></span><br><span class="line"><span class="comment">public:</span></span><br><span class="line"><span class="comment">    vector&lt;string&gt; Permutation(string str) &#123;</span></span><br><span class="line"><span class="comment">        vector&lt;string&gt; res;</span></span><br><span class="line"><span class="comment">        helper(str,res,0);</span></span><br><span class="line"><span class="comment">        sort(res.begin(),res.end());</span></span><br><span class="line"><span class="comment">        return res;</span></span><br><span class="line"><span class="comment">    &#125;</span></span><br><span class="line"><span class="comment">    void helper(string s, vector&lt;string&gt; &amp;res, int n) &#123;</span></span><br><span class="line"><span class="comment">        if(n == s.size()-1)&#123; //终止条件</span></span><br><span class="line"><span class="comment">            if(find(res.begin(),res.end(),s) == res.end()) res.push_back(s);</span></span><br><span class="line"><span class="comment">        &#125;</span></span><br><span class="line"><span class="comment">        else&#123;</span></span><br><span class="line"><span class="comment">            for(int i=n;i&lt;s.size();i++)&#123;</span></span><br><span class="line"><span class="comment">                swap(s[i],s[n]);</span></span><br><span class="line"><span class="comment">                helper(s,n+1);</span></span><br><span class="line"><span class="comment">                swap(s[i],s[n]);</span></span><br><span class="line"><span class="comment">            &#125;</span></span><br><span class="line"><span class="comment">        &#125;</span></span><br><span class="line"><span class="comment">    &#125;</span></span><br><span class="line"><span class="comment">    void swap(char &amp;i ,char &amp;j) &#123;</span></span><br><span class="line"><span class="comment">        char t = i; i = j; j = t;</span></span><br><span class="line"><span class="comment">    &#125;</span></span><br><span class="line"><span class="comment">&#125;;</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">*/</span></span><br></pre></td></tr></table></figure><h1 id="18、最大子序和"><a href="#18、最大子序和" class="headerlink" title="18、最大子序和"></a>18、最大子序和</h1><p>给定一个整数数组 nums ，找到一个具有最大和的连续子数组（子数组最少包含一个元素），返回其最大和。</p><p>输入: [-2,1,-3,4,-1,2,1,-5,4],<br>输出: 6<br>解释: 连续子数组 [4,-1,2,1] 的和最大，为 6。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function"><span class="keyword">int</span> <span class="title">maxSubArray</span><span class="params">(<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt;&amp; nums)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">int</span> max = nums[<span class="number">0</span>];</span><br><span class="line">        <span class="keyword">int</span> add = <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;nums.size();i++)&#123;</span><br><span class="line">            add += nums[i];</span><br><span class="line">            <span class="keyword">if</span>(add &gt; max) max = add;</span><br><span class="line">            <span class="keyword">if</span>(add &lt; <span class="number">0</span>) add = <span class="number">0</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> max;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="19、螺旋矩阵"><a href="#19、螺旋矩阵" class="headerlink" title="19、螺旋矩阵"></a>19、螺旋矩阵</h1><p>给定一个包含 m x n 个元素的矩阵（m 行, n 列），请按照顺时针螺旋顺序，返回矩阵中的所有元素。</p><p>输入:<br>[<br> [ 1, 2, 3 ],<br> [ 4, 5, 6 ],<br> [ 7, 8, 9 ]<br>]输出: [1,2,3,6,9,8,7,4,5]</p><p>输入:<br>[<br>  [1, 2, 3, 4],<br>  [5, 6, 7, 8],<br>  [9,10,11,12]<br>]输出: [1,2,3,4,8,12,11,10,9,5,6,7]</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="comment">/*</span></span><br><span class="line"><span class="comment">       m   n</span></span><br><span class="line"><span class="comment">     i 1 2 3</span></span><br><span class="line"><span class="comment">       4 5 6</span></span><br><span class="line"><span class="comment">     j 7 8 9</span></span><br><span class="line"><span class="comment">    */</span></span><br><span class="line">    <span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; spiralOrder(<span class="built_in">vector</span>&lt;<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt;&gt;&amp; matrix) &#123;</span><br><span class="line">        <span class="keyword">if</span>(matrix.empty() || matrix[<span class="number">0</span>].empty()) <span class="keyword">return</span> &#123;&#125;;</span><br><span class="line">        <span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; res;</span><br><span class="line">        <span class="keyword">int</span> i=<span class="number">0</span>,j=matrix.size()<span class="number">-1</span>,m=<span class="number">0</span>,n=matrix[<span class="number">0</span>].size()<span class="number">-1</span>;</span><br><span class="line">        <span class="keyword">while</span>(i&lt;=j &amp;&amp; m&lt;=n)&#123;</span><br><span class="line">            <span class="keyword">for</span>(<span class="keyword">int</span> k=m;k&lt;=n;k++) res.push_back(matrix[i][k]);</span><br><span class="line">            i++;</span><br><span class="line">            <span class="keyword">if</span>(i&gt;j) <span class="keyword">break</span>;</span><br><span class="line">            <span class="keyword">for</span>(<span class="keyword">int</span> k=i;k&lt;=j;k++) res.push_back(matrix[k][n]);</span><br><span class="line">            n--;</span><br><span class="line">            <span class="keyword">if</span>(m&gt;n) <span class="keyword">break</span>;</span><br><span class="line">            <span class="keyword">for</span>(<span class="keyword">int</span> k=n;k&gt;=m;k--) res.push_back(matrix[j][k]);</span><br><span class="line">            j--;</span><br><span class="line">            <span class="keyword">if</span>(i&gt;j) <span class="keyword">break</span>;</span><br><span class="line">            <span class="keyword">for</span>(<span class="keyword">int</span> k=j;k&gt;=i;k--) res.push_back(matrix[k][m]);</span><br><span class="line">            m++;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="20、螺旋矩阵-II"><a href="#20、螺旋矩阵-II" class="headerlink" title="20、螺旋矩阵 II"></a>20、螺旋矩阵 II</h1><p>给定一个正整数 n，生成一个包含 1 到 n2 所有元素，且元素按顺时针顺序螺旋排列的正方形矩阵。</p><p>输入: 3<br>输出:<br>[<br> [ 1, 2, 3 ],<br> [ 8, 9, 4 ],<br> [ 7, 6, 5 ]<br>]</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="built_in">vector</span>&lt;<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt;&gt; generateMatrix(<span class="keyword">int</span> n) &#123;</span><br><span class="line">        <span class="built_in">vector</span>&lt;<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt;&gt; arr(n,<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt;(n,<span class="number">0</span>));</span><br><span class="line">        <span class="keyword">int</span> c = <span class="number">1</span>,k = <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">while</span>(c&lt;=n*n)&#123;</span><br><span class="line">            <span class="keyword">for</span>(<span class="keyword">int</span> i=k;i&lt;n-k;i++) arr[k][i]=c++;</span><br><span class="line">            <span class="keyword">for</span>(<span class="keyword">int</span> i=k+<span class="number">1</span>;i&lt;n-k;i++) arr[i][n-k<span class="number">-1</span>]=c++;</span><br><span class="line">            <span class="keyword">for</span>(<span class="keyword">int</span> i=n-k<span class="number">-2</span>;i&gt;=k;i--) arr[n-k<span class="number">-1</span>][i]=c++;</span><br><span class="line">            <span class="keyword">for</span>(<span class="keyword">int</span> i=n-k<span class="number">-2</span>;i&gt;=k+<span class="number">1</span>;i--) arr[i][k]=c++;</span><br><span class="line">            k++;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> arr;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="21、旋转链表"><a href="#21、旋转链表" class="headerlink" title="21、旋转链表"></a>21、旋转链表</h1><p>给定一个链表，旋转链表，将链表每个节点向右移动 k 个位置，其中 k 是非负数。</p><p>输入: 1-&gt;2-&gt;3-&gt;4-&gt;5-&gt;NULL, k = 2<br>输出: 4-&gt;5-&gt;1-&gt;2-&gt;3-&gt;NULL<br>解释:<br>向右旋转 1 步: 5-&gt;1-&gt;2-&gt;3-&gt;4-&gt;NULL<br>向右旋转 2 步: 4-&gt;5-&gt;1-&gt;2-&gt;3-&gt;NULL</p><p>输入: 0-&gt;1-&gt;2-&gt;NULL, k = 4<br>输出: 2-&gt;0-&gt;1-&gt;NULL<br>解释:<br>向右旋转 1 步: 2-&gt;0-&gt;1-&gt;NULL<br>向右旋转 2 步: 1-&gt;2-&gt;0-&gt;NULL<br>向右旋转 3 步: 0-&gt;1-&gt;2-&gt;NULL<br>向右旋转 4 步: 2-&gt;0-&gt;1-&gt;NULL</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Definition for singly-linked list.</span></span><br><span class="line"><span class="comment"> * struct ListNode &#123;</span></span><br><span class="line"><span class="comment"> *     int val;</span></span><br><span class="line"><span class="comment"> *     ListNode *next;</span></span><br><span class="line"><span class="comment"> *     ListNode(int x) : val(x), next(NULL) &#123;&#125;</span></span><br><span class="line"><span class="comment"> * &#125;;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function">ListNode* <span class="title">rotateRight</span><span class="params">(ListNode* head, <span class="keyword">int</span> k)</span> </span>&#123; <span class="comment">//1-&gt;2-&gt;3-&gt;4-&gt;5-&gt;NULL, k = 2</span></span><br><span class="line">        <span class="keyword">if</span>(k==<span class="number">0</span> || !head) <span class="keyword">return</span> head;</span><br><span class="line">        <span class="keyword">int</span> len = getlen(head);</span><br><span class="line">        <span class="keyword">if</span>((k = k%len)==<span class="number">0</span>) <span class="keyword">return</span> head;</span><br><span class="line">        ListNode* pre = head; <span class="comment">//1-&gt;2-&gt;3-&gt;NULL</span></span><br><span class="line">        ListNode* cur = pre;</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;len-k<span class="number">-1</span>;i++)&#123;</span><br><span class="line">            cur = cur-&gt;next;</span><br><span class="line">        &#125;</span><br><span class="line">        ListNode* last = cur-&gt;next; <span class="comment">//4-&gt;5-&gt;NULL</span></span><br><span class="line">        cur-&gt;next = <span class="literal">NULL</span>;</span><br><span class="line">        cur = last;</span><br><span class="line">        <span class="keyword">while</span>(cur-&gt;next)&#123;</span><br><span class="line">            cur = cur-&gt;next;</span><br><span class="line">        &#125;</span><br><span class="line">        cur-&gt;next = head; <span class="comment">//4-&gt;5-&gt;1-&gt;2-&gt;3-&gt;NULL</span></span><br><span class="line">        <span class="keyword">return</span> last; </span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="function"><span class="keyword">int</span> <span class="title">getlen</span><span class="params">(ListNode* head)</span></span>&#123;</span><br><span class="line">        <span class="keyword">int</span> res = <span class="number">0</span>;</span><br><span class="line">        ListNode* root = head;</span><br><span class="line">        <span class="keyword">while</span>(root)&#123;</span><br><span class="line">            res++;root = root-&gt;next;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="22、不同路径"><a href="#22、不同路径" class="headerlink" title="22、不同路径"></a>22、不同路径</h1><p>一个机器人位于一个 m x n 网格的左上角 （起始点在下图中标记为“Start” ）。<br>机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角（在下图中标记为“Finish”）。<br>问总共有多少条不同的路径？<br>例如，上图是一个7 x 3 的网格。有多少可能的路径？<br>说明：m 和 n 的值均不超过 100。</p><p>输入: m = 3, n = 2<br>输出: 3<br>解释:<br>从左上角开始，总共有 3 条路径可以到达右下角。</p><ol><li>向右 -&gt; 向右 -&gt; 向下</li><li>向右 -&gt; 向下 -&gt; 向右</li><li>向下 -&gt; 向右 -&gt; 向右</li></ol><p>输入: m = 7, n = 3<br>输出: 28</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function"><span class="keyword">int</span> <span class="title">uniquePaths</span><span class="params">(<span class="keyword">int</span> m, <span class="keyword">int</span> n)</span> </span>&#123;</span><br><span class="line">        <span class="built_in">vector</span>&lt;<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt;&gt; dp(m,<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt;(n,<span class="number">0</span>));<span class="comment">//m*n零矩阵</span></span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;m;i++)&#123;</span><br><span class="line">            <span class="keyword">for</span>(<span class="keyword">int</span> j=<span class="number">0</span>;j&lt;n;j++)&#123;</span><br><span class="line">                <span class="keyword">if</span>(i==<span class="number">0</span> || j==<span class="number">0</span>) dp[i][j]=<span class="number">1</span>;</span><br><span class="line">                <span class="keyword">else</span> dp[i][j] = dp[i<span class="number">-1</span>][j]+dp[i][j<span class="number">-1</span>];</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> dp[m<span class="number">-1</span>][n<span class="number">-1</span>];</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="23、爬楼梯"><a href="#23、爬楼梯" class="headerlink" title="23、爬楼梯"></a>23、爬楼梯</h1><p>假设你正在爬楼梯。需要 n 阶你才能到达楼顶。<br>每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢？<br>注意：给定 n 是一个正整数。</p><p>输入： 2<br>输出： 2<br>解释： 有两种方法可以爬到楼顶。</p><ol><li>1 阶 + 1 阶</li><li>2 阶</li></ol><p>输入： 3<br>输出： 3<br>解释： 有三种方法可以爬到楼顶。</p><ol><li>1 阶 + 1 阶 + 1 阶</li><li>1 阶 + 2 阶</li><li>2 阶 + 1 阶<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//当n=45时，结果已经超出了返回值类型int有效范围无法通过，不知道测试怎么回事，同剑指offer 8，剑指可通过</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function"><span class="keyword">int</span> <span class="title">climbStairs</span><span class="params">(<span class="keyword">int</span> n)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">int</span> i=<span class="number">1</span>,j=<span class="number">1</span>;</span><br><span class="line">        <span class="keyword">while</span>(n &gt; <span class="number">0</span>)&#123;</span><br><span class="line">            <span class="keyword">int</span> t = i;</span><br><span class="line">            i = j;</span><br><span class="line">            j = t+j;</span><br><span class="line">            n--;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> i;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure></li></ol><h1 id="24、子集"><a href="#24、子集" class="headerlink" title="24、子集"></a>24、子集</h1><p>给定一组不含重复元素的整数数组 nums，返回该数组所有可能的子集（幂集）。<br>说明：解集不能包含重复的子集。</p><p>输入: nums = [1,2,3]<br>输出:<br>[<br>  [3],<br>  [1],<br>  [2],<br>  [1,2,3],<br>  [1,3],<br>  [2,3],<br>  [1,2],<br>  []<br>]</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="built_in">vector</span>&lt;<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt;&gt; subsets(<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt;&amp; nums) &#123;</span><br><span class="line">        <span class="built_in">vector</span>&lt;<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt;&gt; res;</span><br><span class="line">        <span class="keyword">int</span> l = <span class="number">1</span> &lt;&lt; nums.size();</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;l;i++)&#123;</span><br><span class="line">            <span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; tmp;</span><br><span class="line">            <span class="keyword">for</span>(<span class="keyword">int</span> j=<span class="number">0</span>;j&lt;nums.size();j++)&#123;</span><br><span class="line">                <span class="keyword">if</span>(i&amp;(<span class="number">1</span>&lt;&lt;j)) tmp.push_back(nums[j]);</span><br><span class="line">            &#125;</span><br><span class="line">            res.push_back(tmp);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="25、合并两个有序数组"><a href="#25、合并两个有序数组" class="headerlink" title="25、合并两个有序数组"></a>25、合并两个有序数组</h1><p>给定两个有序整数数组 nums1 和 nums2，将 nums2 合并到 nums1 中，使得 num1 成为一个有序数组。<br>说明:<br>初始化 nums1 和 nums2 的元素数量分别为 m 和 n。<br>你可以假设 nums1 有足够的空间（空间大小大于或等于 m + n）来保存 nums2 中的元素。</p><p>输入:<br>nums1 = [1,2,3,0,0,0], m = 3<br>nums2 = [2,5,6],       n = 3<br>输出: [1,2,2,3,5,6]</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">merge</span><span class="params">(<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt;&amp; nums1, <span class="keyword">int</span> m, <span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt;&amp; nums2, <span class="keyword">int</span> n)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">int</span> i=m<span class="number">-1</span>,j=n<span class="number">-1</span>,cur=n+m<span class="number">-1</span>;</span><br><span class="line">        <span class="keyword">while</span>(i&gt;=<span class="number">0</span> &amp;&amp; j&gt;=<span class="number">0</span>)&#123;</span><br><span class="line">            <span class="keyword">if</span>(nums1[i]&lt;nums2[j])&#123;</span><br><span class="line">                nums1[cur]=nums2[j];</span><br><span class="line">                j--;</span><br><span class="line">            &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">                nums1[cur]=nums1[i];</span><br><span class="line">                i--;</span><br><span class="line">            &#125;</span><br><span class="line">            cur--;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">while</span>(i&gt;=<span class="number">0</span>)&#123;</span><br><span class="line">            nums1[cur]=nums1[i];i--;cur--;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">while</span>(j&gt;=<span class="number">0</span>)&#123;</span><br><span class="line">            nums1[cur]=nums2[j];j--;cur--;</span><br><span class="line">        &#125; </span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="26、格雷编码"><a href="#26、格雷编码" class="headerlink" title="26、格雷编码"></a>26、格雷编码</h1><p>格雷编码是一个二进制数字系统，在该系统中，两个连续的数值仅有一个位数的差异。<br>给定一个代表编码总位数的非负整数 n，打印其格雷编码序列。格雷编码序列必须以 0 开头。</p><p>输入: 2<br>输出: [0,1,3,2]<br>解释:<br>00 - 0<br>01 - 1<br>11 - 3<br>10 - 2</p><p>对于给定的 n，其格雷编码序列并不唯一。<br>例如，[0,2,3,1] 也是一个有效的格雷编码序列。<br>00 - 0<br>10 - 2<br>11 - 3<br>01 - 1</p><p>输入: 0<br>输出: [0]<br>解释: 我们定义格雷编码序列必须以 0 开头。<br>     给定编码总位数为 n 的格雷编码序列，其长度为 2n。当 n = 0 时，长度为 20 = 1。<br>     因此，当 n = 0 时，其格雷编码序列为 [0]。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line"><span class="comment">/*n: 0   1   2   3</span></span><br><span class="line"><span class="comment">     0   0  00  000</span></span><br><span class="line"><span class="comment">         1  10  100</span></span><br><span class="line"><span class="comment">                010</span></span><br><span class="line"><span class="comment">            01  110</span></span><br><span class="line"><span class="comment">            11</span></span><br><span class="line"><span class="comment">                001</span></span><br><span class="line"><span class="comment">                101</span></span><br><span class="line"><span class="comment">                011</span></span><br><span class="line"><span class="comment">                111</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line">    <span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; grayCode(<span class="keyword">int</span> n) &#123;</span><br><span class="line">        <span class="keyword">if</span>(n==<span class="number">0</span>) <span class="keyword">return</span> &#123;<span class="number">0</span>&#125;;</span><br><span class="line">        <span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; res&#123;<span class="number">0</span>,<span class="number">1</span>&#125;;</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">1</span>;i&lt;n;i++)&#123;</span><br><span class="line">            <span class="keyword">for</span>(<span class="keyword">int</span> j=<span class="number">0</span>;j&lt;res.size();j++)&#123;</span><br><span class="line">                res[j]*=<span class="number">2</span>; <span class="comment">//末位加0</span></span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">for</span>(<span class="keyword">int</span> j=res.size()<span class="number">-1</span>;j&gt;=<span class="number">0</span>;j--)&#123;</span><br><span class="line">                res.push_back(res[j]+<span class="number">1</span>); <span class="comment">//末位加1</span></span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="27、二叉树的最大深度"><a href="#27、二叉树的最大深度" class="headerlink" title="27、二叉树的最大深度"></a>27、二叉树的最大深度</h1><p>给定一个二叉树，找出其最大深度。<br>二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。<br>说明: 叶子节点是指没有子节点的节点。</p><p>给定二叉树 [3,9,20,null,null,15,7]，<br>    3<br>   / <br>  9  20<br>    /  <br>   15   7<br>返回它的最大深度 3 。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Definition for a binary tree node.</span></span><br><span class="line"><span class="comment"> * struct TreeNode &#123;</span></span><br><span class="line"><span class="comment"> *     int val;</span></span><br><span class="line"><span class="comment"> *     TreeNode *left;</span></span><br><span class="line"><span class="comment"> *     TreeNode *right;</span></span><br><span class="line"><span class="comment"> *     TreeNode(int x) : val(x), left(NULL), right(NULL) &#123;&#125;</span></span><br><span class="line"><span class="comment"> * &#125;;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function"><span class="keyword">int</span> <span class="title">maxDepth</span><span class="params">(TreeNode* root)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">if</span>(!root) <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">return</span> max(maxDepth(root-&gt;left),maxDepth(root-&gt;right))+<span class="number">1</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="28、买卖股票的最佳时机"><a href="#28、买卖股票的最佳时机" class="headerlink" title="28、买卖股票的最佳时机"></a>28、买卖股票的最佳时机</h1><p>给定一个数组，它的第 i 个元素是一支给定股票第 i 天的价格。<br>如果你最多只允许完成一笔交易（即买入和卖出一支股票），设计一个算法来计算你所能获取的最大利润。<br>注意你不能在买入股票前卖出股票。</p><p>输入: [7,1,5,3,6,4]<br>输出: 5<br>解释: 在第 2 天（股票价格 = 1）的时候买入，在第 5 天（股票价格 = 6）的时候卖出，最大利润 = 6-1 = 5 。<br>     注意利润不能是 7-1 = 6, 因为卖出价格需要大于买入价格。</p><p>输入: [7,6,4,3,1]<br>输出: 0<br>解释: 在这种情况下, 没有交易完成, 所以最大利润为 0。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function"><span class="keyword">int</span> <span class="title">maxProfit</span><span class="params">(<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt;&amp; prices)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">int</span> max = <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;prices.size();i++)&#123;  </span><br><span class="line">            <span class="keyword">for</span>(<span class="keyword">int</span> j=i+<span class="number">1</span>;j&lt;prices.size();j++)&#123; </span><br><span class="line">                <span class="keyword">if</span>(prices[j]-prices[i]&gt;max)&#123;</span><br><span class="line">                    max = prices[j]-prices[i];</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;   </span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> max;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="29、买卖股票的最佳时机-II"><a href="#29、买卖股票的最佳时机-II" class="headerlink" title="29、买卖股票的最佳时机 II"></a>29、买卖股票的最佳时机 II</h1><p>给定一个数组，它的第 i 个元素是一支给定股票第 i 天的价格。<br>设计一个算法来计算你所能获取的最大利润。你可以尽可能地完成更多的交易（多次买卖一支股票）。<br>注意：你不能同时参与多笔交易（你必须在再次购买前出售掉之前的股票）。</p><p>输入: [7,1,5,3,6,4]<br>输出: 7<br>解释: 在第 2 天（股票价格 = 1）的时候买入，在第 3 天（股票价格 = 5）的时候卖出, 这笔交易所能获得利润 = 5-1 = 4 。<br>     随后，在第 4 天（股票价格 = 3）的时候买入，在第 5 天（股票价格 = 6）的时候卖出, 这笔交易所能获得利润 = 6-3 = 3 。</p><p>输入: [1,2,3,4,5]<br>输出: 4<br>解释: 在第 1 天（股票价格 = 1）的时候买入，在第 5 天 （股票价格 = 5）的时候卖出, 这笔交易所能获得利润 = 5-1 = 4 。<br>     注意你不能在第 1 天和第 2 天接连购买股票，之后再将它们卖出。<br>     因为这样属于同时参与了多笔交易，你必须在再次购买前出售掉之前的股票。</p><p>输入: [7,6,4,3,1]<br>输出: 0<br>解释: 在这种情况下, 没有交易完成, 所以最大利润为 0。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function"><span class="keyword">int</span> <span class="title">maxProfit</span><span class="params">(<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt;&amp; prices)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">if</span>(prices.empty()) <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">int</span> max = <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;prices.size()<span class="number">-1</span>;i++)&#123;</span><br><span class="line">            <span class="keyword">if</span>(prices[i+<span class="number">1</span>]&gt;prices[i]) max += prices[i+<span class="number">1</span>]-prices[i];</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> max;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="30、二叉树中的最大路径和"><a href="#30、二叉树中的最大路径和" class="headerlink" title="30、二叉树中的最大路径和"></a>30、二叉树中的最大路径和</h1><p>给定一个非空二叉树，返回其最大路径和。<br>本题中，路径被定义为一条从树中任意节点出发，达到任意节点的序列。该路径至少包含一个节点，且不一定经过根节点。</p><p>输入: [1,2,3]<br>       1<br>      / <br>     2   3<br>输出: 6</p><p>输入: [-10,9,20,null,null,15,7]<br>   -10<br>   / <br>  9  20<br>    /  <br>   15   7<br>输出: 42</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Definition for a binary tree node.</span></span><br><span class="line"><span class="comment"> * struct TreeNode &#123;</span></span><br><span class="line"><span class="comment"> *     int val;</span></span><br><span class="line"><span class="comment"> *     TreeNode *left;</span></span><br><span class="line"><span class="comment"> *     TreeNode *right;</span></span><br><span class="line"><span class="comment"> *     TreeNode(int x) : val(x), left(NULL), right(NULL) &#123;&#125;</span></span><br><span class="line"><span class="comment"> * &#125;;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="keyword">int</span> res = INT_MIN;</span><br><span class="line">    <span class="function"><span class="keyword">int</span> <span class="title">maxPathSum</span><span class="params">(TreeNode* root)</span> </span>&#123;</span><br><span class="line">        submax(root);</span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="function"><span class="keyword">int</span> <span class="title">submax</span><span class="params">(TreeNode* root)</span> </span>&#123; <span class="comment">//从root向下走的最长距离</span></span><br><span class="line">        <span class="keyword">if</span>(!root) <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">int</span> l = max(<span class="number">0</span>,submax(root-&gt;left));</span><br><span class="line">        <span class="keyword">int</span> r = max(<span class="number">0</span>,submax(root-&gt;right));</span><br><span class="line">        <span class="keyword">if</span>(root-&gt;val+l+r &gt; res) res=root-&gt;val+l+r;</span><br><span class="line">        <span class="keyword">return</span> root-&gt;val+max(l,r);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="31、只出现一次的数字"><a href="#31、只出现一次的数字" class="headerlink" title="31、只出现一次的数字"></a>31、只出现一次的数字</h1><p>给定一个非空整数数组，除了某个元素只出现一次以外，其余每个元素均出现两次。找出那个只出现了一次的元素。<br>说明：<br>你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗？</p><p>输入: [2,2,1]<br>输出: 1</p><p>输入: [4,1,2,1,2]<br>输出: 4</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function"><span class="keyword">int</span> <span class="title">singleNumber</span><span class="params">(<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt;&amp; nums)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">int</span> res = <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;nums.size();i++)&#123;</span><br><span class="line">            res ^= nums[i];</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="32、环形链表"><a href="#32、环形链表" class="headerlink" title="32、环形链表"></a>32、环形链表</h1><p>给定一个链表，判断链表中是否有环。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Definition for singly-linked list.</span></span><br><span class="line"><span class="comment"> * struct ListNode &#123;</span></span><br><span class="line"><span class="comment"> *     int val;</span></span><br><span class="line"><span class="comment"> *     ListNode *next;</span></span><br><span class="line"><span class="comment"> *     ListNode(int x) : val(x), next(NULL) &#123;&#125;</span></span><br><span class="line"><span class="comment"> * &#125;;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function"><span class="keyword">bool</span> <span class="title">hasCycle</span><span class="params">(ListNode *head)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">if</span>(!head) <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">        ListNode *fast = head;</span><br><span class="line">        ListNode *slow = head;</span><br><span class="line">        <span class="keyword">while</span>(fast-&gt;next &amp;&amp; fast-&gt;next-&gt;next)&#123;</span><br><span class="line">            slow = slow-&gt;next;</span><br><span class="line">            fast = fast-&gt;next-&gt;next;</span><br><span class="line">            <span class="keyword">if</span>(slow == fast) <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="33、环形链表-II"><a href="#33、环形链表-II" class="headerlink" title="33、环形链表 II"></a>33、环形链表 II</h1><p>给定一个链表，返回链表开始入环的第一个节点。 如果链表无环，则返回 null。<br>为了表示给定链表中的环，我们使用整数 pos 来表示链表尾连接到链表中的位置（索引从 0 开始）。 如果 pos 是 -1，则在该链表中没有环。<br>说明：不允许修改给定的链表。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Definition for singly-linked list.</span></span><br><span class="line"><span class="comment"> * struct ListNode &#123;</span></span><br><span class="line"><span class="comment"> *     int val;</span></span><br><span class="line"><span class="comment"> *     ListNode *next;</span></span><br><span class="line"><span class="comment"> *     ListNode(int x) : val(x), next(NULL) &#123;&#125;</span></span><br><span class="line"><span class="comment"> * &#125;;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function">ListNode *<span class="title">detectCycle</span><span class="params">(ListNode *head)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">if</span>(!head) <span class="keyword">return</span> <span class="literal">NULL</span>;</span><br><span class="line">        <span class="keyword">bool</span> loop = <span class="literal">false</span>;</span><br><span class="line">        ListNode* slow = head;</span><br><span class="line">        ListNode* fast = head;</span><br><span class="line">        <span class="keyword">while</span>(fast-&gt;next&amp;&amp;fast-&gt;next-&gt;next)&#123;</span><br><span class="line">            slow = slow-&gt;next;</span><br><span class="line">            fast = fast-&gt;next-&gt;next;</span><br><span class="line">            <span class="keyword">if</span>(slow == fast)&#123;</span><br><span class="line">                loop = <span class="literal">true</span>;</span><br><span class="line">                <span class="keyword">break</span>;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span>(loop)&#123;</span><br><span class="line">            ListNode* res = head;</span><br><span class="line">            <span class="keyword">while</span>(res!=slow)&#123;</span><br><span class="line">                res = res-&gt;next;</span><br><span class="line">                slow = slow-&gt;next;</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">return</span> res;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> <span class="literal">NULL</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="34、LRU缓存机制"><a href="#34、LRU缓存机制" class="headerlink" title="34、LRU缓存机制"></a>34、LRU缓存机制</h1><p>运用你所掌握的数据结构，设计和实现一个  LRU (最近最少使用) 缓存机制。它应该支持以下操作： 获取数据 get 和 写入数据 put 。<br>获取数据 get(key) - 如果密钥 (key) 存在于缓存中，则获取密钥的值（总是正数），否则返回 -1。<br>写入数据 put(key, value) - 如果密钥不存在，则写入其数据值。当缓存容量达到上限时，它应该在写入新数据之前删除最近最少使用的数据值，从而为新的数据值留出空间。</p><p>进阶:<br>你是否可以在 O(1) 时间复杂度内完成这两种操作？</p><p>LRUCache cache = new LRUCache( 2 /* 缓存容量 */ );<br>cache.put(1, 1);<br>cache.put(2, 2);<br>cache.get(1);       // 返回  1<br>cache.put(3, 3);    // 该操作会使得密钥 2 作废<br>cache.get(2);       // 返回 -1 (未找到)<br>cache.put(4, 4);    // 该操作会使得密钥 1 作废<br>cache.get(1);       // 返回 -1 (未找到)<br>cache.get(3);       // 返回  3<br>cache.get(4);       // 返回  4</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">LRUCache</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    LRUCache(<span class="keyword">int</span> capacity) &#123;</span><br><span class="line">        _cap = capacity;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="function"><span class="keyword">int</span> <span class="title">get</span><span class="params">(<span class="keyword">int</span> key)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">auto</span> iter = _map.find(key);</span><br><span class="line">        <span class="keyword">if</span>(iter == _map.end()) <span class="keyword">return</span> <span class="number">-1</span>;</span><br><span class="line">        <span class="keyword">int</span> res = iter-&gt;second-&gt;second;</span><br><span class="line">        _list.erase(iter-&gt;second);</span><br><span class="line">        _list.push_front(make_pair(key,res));</span><br><span class="line">        _map[key] = _list.begin();</span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">put</span><span class="params">(<span class="keyword">int</span> key, <span class="keyword">int</span> value)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">auto</span> iter = _map.find(key);</span><br><span class="line">        <span class="keyword">if</span>(iter != _map.end()) _list.erase(iter-&gt;second);</span><br><span class="line">        _list.push_front(make_pair(key,value));</span><br><span class="line">        _map[key] = _list.begin();</span><br><span class="line">        <span class="keyword">if</span>(_list.size()&gt;_cap)&#123;</span><br><span class="line">            <span class="keyword">int</span> t = _list.back().first;</span><br><span class="line">            _map.erase(t);</span><br><span class="line">            _list.pop_back();</span><br><span class="line">        &#125;   </span><br><span class="line">    &#125;</span><br><span class="line"><span class="keyword">private</span>:</span><br><span class="line">    <span class="built_in">unordered_map</span>&lt;<span class="keyword">int</span>,<span class="built_in">list</span>&lt;pair&lt;<span class="keyword">int</span>,<span class="keyword">int</span>&gt;&gt;::iterator&gt; _map;</span><br><span class="line">    <span class="built_in">list</span>&lt;pair&lt;<span class="keyword">int</span>,<span class="keyword">int</span>&gt;&gt; _list;</span><br><span class="line">    <span class="keyword">int</span> _cap;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Your LRUCache object will be instantiated and called as such:</span></span><br><span class="line"><span class="comment"> * LRUCache* obj = new LRUCache(capacity);</span></span><br><span class="line"><span class="comment"> * int param_1 = obj-&gt;get(key);</span></span><br><span class="line"><span class="comment"> * obj-&gt;put(key,value);</span></span><br><span class="line"><span class="comment"> */</span></span><br></pre></td></tr></table></figure><h1 id="35、排序链表"><a href="#35、排序链表" class="headerlink" title="35、排序链表"></a>35、排序链表</h1><p>在 O(n log n) 时间复杂度和常数级空间复杂度下，对链表进行排序。</p><p>输入: 4-&gt;2-&gt;1-&gt;3<br>输出: 1-&gt;2-&gt;3-&gt;4</p><p>输入: -1-&gt;5-&gt;3-&gt;4-&gt;0<br>输出: -1-&gt;0-&gt;3-&gt;4-&gt;5</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Definition for singly-linked list.</span></span><br><span class="line"><span class="comment"> * struct ListNode &#123;</span></span><br><span class="line"><span class="comment"> *     int val;</span></span><br><span class="line"><span class="comment"> *     ListNode *next;</span></span><br><span class="line"><span class="comment"> *     ListNode(int x) : val(x), next(NULL) &#123;&#125;</span></span><br><span class="line"><span class="comment"> * &#125;;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function">ListNode* <span class="title">sortList</span><span class="params">(ListNode* head)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">if</span>(!head || !head-&gt;next) <span class="keyword">return</span> head;</span><br><span class="line">        ListNode* slow = head;</span><br><span class="line">        ListNode* fast = head;</span><br><span class="line">        <span class="keyword">while</span>(fast-&gt;next &amp;&amp; fast-&gt;next-&gt;next)&#123;</span><br><span class="line">            slow = slow-&gt;next;</span><br><span class="line">            fast = fast-&gt;next-&gt;next;</span><br><span class="line">        &#125;</span><br><span class="line">        ListNode* bk = slow-&gt;next;</span><br><span class="line">        slow-&gt;next = <span class="literal">NULL</span>;</span><br><span class="line">        ListNode* l1 = sortList(head);</span><br><span class="line">        ListNode* l2 = sortList(bk);</span><br><span class="line">        <span class="comment">//合并有序链表</span></span><br><span class="line">        ListNode* res = <span class="keyword">new</span> ListNode(<span class="number">0</span>);</span><br><span class="line">        ListNode* h = res;</span><br><span class="line">        <span class="keyword">while</span>(l1 &amp;&amp; l2)&#123;</span><br><span class="line">            <span class="keyword">if</span>(l1-&gt;val&gt;l2-&gt;val)&#123;</span><br><span class="line">                h-&gt;next = l2;</span><br><span class="line">                l2 = l2-&gt;next;</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">else</span>&#123;</span><br><span class="line">                h-&gt;next = l1;</span><br><span class="line">                l1 = l1-&gt;next;</span><br><span class="line">            &#125;</span><br><span class="line">            h = h-&gt;next;</span><br><span class="line">        &#125;</span><br><span class="line">        h-&gt;next = l1?l1:l2;</span><br><span class="line">        <span class="keyword">return</span> res-&gt;next;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="36、最小栈"><a href="#36、最小栈" class="headerlink" title="36、最小栈"></a>36、最小栈</h1><p>设计一个支持 push，pop，top 操作，并能在常数时间内检索到最小元素的栈。<br>push(x) – 将元素 x 推入栈中。<br>pop() – 删除栈顶的元素。<br>top() – 获取栈顶元素。<br>getMin() – 检索栈中的最小元素。</p><p>MinStack minStack = new MinStack();<br>minStack.push(-2);<br>minStack.push(0);<br>minStack.push(-3);<br>minStack.getMin();   –&gt; 返回 -3.<br>minStack.pop();<br>minStack.top();      –&gt; 返回 0.<br>minStack.getMin();   –&gt; 返回 -2.</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">MinStack</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="comment">/** initialize your data structure here. */</span></span><br><span class="line">    MinStack() &#123;</span><br><span class="line">        </span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">push</span><span class="params">(<span class="keyword">int</span> x)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">if</span>(smin.empty() || x &lt;= smin.top()) smin.push(x);</span><br><span class="line">        s.push(x);</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">pop</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">if</span>(smin.top() == s.top()) smin.pop();</span><br><span class="line">        s.pop();</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="function"><span class="keyword">int</span> <span class="title">top</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> s.top();</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="function"><span class="keyword">int</span> <span class="title">getMin</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> smin.top();</span><br><span class="line">    &#125;</span><br><span class="line"><span class="keyword">private</span>:</span><br><span class="line">    <span class="built_in">stack</span>&lt;<span class="keyword">int</span>&gt; s;</span><br><span class="line">    <span class="built_in">stack</span>&lt;<span class="keyword">int</span>&gt; smin;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Your MinStack object will be instantiated and called as such:</span></span><br><span class="line"><span class="comment"> * MinStack* obj = new MinStack();</span></span><br><span class="line"><span class="comment"> * obj-&gt;push(x);</span></span><br><span class="line"><span class="comment"> * obj-&gt;pop();</span></span><br><span class="line"><span class="comment"> * int param_3 = obj-&gt;top();</span></span><br><span class="line"><span class="comment"> * int param_4 = obj-&gt;getMin();</span></span><br><span class="line"><span class="comment"> */</span></span><br></pre></td></tr></table></figure><h1 id="37、相交链表"><a href="#37、相交链表" class="headerlink" title="37、相交链表"></a>37、相交链表</h1><p>编写一个程序，找到两个单链表相交的起始节点。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Definition for singly-linked list.</span></span><br><span class="line"><span class="comment"> * struct ListNode &#123;</span></span><br><span class="line"><span class="comment"> *     int val;</span></span><br><span class="line"><span class="comment"> *     ListNode *next;</span></span><br><span class="line"><span class="comment"> *     ListNode(int x) : val(x), next(NULL) &#123;&#125;</span></span><br><span class="line"><span class="comment"> * &#125;;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function">ListNode *<span class="title">getIntersectionNode</span><span class="params">(ListNode *headA, ListNode *headB)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">int</span> len1 = getlen(headA);</span><br><span class="line">        <span class="keyword">int</span> len2 = getlen(headB);</span><br><span class="line">        <span class="keyword">int</span> step = <span class="built_in">abs</span>(len1-len2);</span><br><span class="line">        <span class="keyword">while</span>(step!=<span class="number">0</span>)&#123;</span><br><span class="line">            <span class="keyword">if</span>(len1&gt;len2) headA = headA-&gt;next;</span><br><span class="line">            <span class="keyword">else</span> headB = headB-&gt;next;</span><br><span class="line">            step--;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">while</span>(headA)&#123;</span><br><span class="line">            <span class="keyword">if</span>(headA == headB) <span class="keyword">return</span> headA;</span><br><span class="line">            headA = headA-&gt;next;</span><br><span class="line">            headB = headB-&gt;next;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> <span class="literal">NULL</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="function"><span class="keyword">int</span> <span class="title">getlen</span><span class="params">(ListNode* l)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">int</span> res = <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">while</span>(l)&#123;</span><br><span class="line">            res++;</span><br><span class="line">            l = l-&gt;next;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="38、求众数"><a href="#38、求众数" class="headerlink" title="38、求众数"></a>38、求众数</h1><p>给定一个大小为 n 的数组，找到其中的众数。众数是指在数组中出现次数大于 ⌊ n/2 ⌋ 的元素。<br>你可以假设数组是非空的，并且给定的数组总是存在众数。</p><p>输入: [3,2,3]<br>输出: 3</p><p>输入: [2,2,1,1,1,2,2]<br>输出: 2</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="comment">/*</span></span><br><span class="line"><span class="comment">     如果重复的次数超过一半的话，一定有相邻的数字相同这种情况的</span></span><br><span class="line"><span class="comment">     对数组同时去掉两个不同的数字，到最后剩下的一个数就是该数字</span></span><br><span class="line"><span class="comment">    */</span></span><br><span class="line">    <span class="function"><span class="keyword">int</span> <span class="title">majorityElement</span><span class="params">(<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt;&amp; nums)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">int</span> res = nums[<span class="number">0</span>];</span><br><span class="line">        <span class="keyword">int</span> count = <span class="number">1</span>;</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">1</span>;i&lt;nums.size();i++)&#123;</span><br><span class="line">            <span class="keyword">if</span>(nums[i] == res) count++;</span><br><span class="line">            <span class="keyword">else</span>&#123;</span><br><span class="line">                count--;</span><br><span class="line">                <span class="keyword">if</span>(count == <span class="number">0</span>)&#123;</span><br><span class="line">                    res = nums[i];</span><br><span class="line">                    count = <span class="number">1</span>;</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="39、反转链表"><a href="#39、反转链表" class="headerlink" title="39、反转链表"></a>39、反转链表</h1><p>反转一个单链表。</p><p>输入: 1-&gt;2-&gt;3-&gt;4-&gt;5-&gt;NULL<br>输出: 5-&gt;4-&gt;3-&gt;2-&gt;1-&gt;NULL</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Definition for singly-linked list.</span></span><br><span class="line"><span class="comment"> * struct ListNode &#123;</span></span><br><span class="line"><span class="comment"> *     int val;</span></span><br><span class="line"><span class="comment"> *     ListNode *next;</span></span><br><span class="line"><span class="comment"> *     ListNode(int x) : val(x), next(NULL) &#123;&#125;</span></span><br><span class="line"><span class="comment"> * &#125;;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function">ListNode* <span class="title">reverseList</span><span class="params">(ListNode* head)</span> </span>&#123;</span><br><span class="line">        ListNode* res = <span class="literal">NULL</span>;</span><br><span class="line">        <span class="keyword">while</span>(head)&#123;</span><br><span class="line">            ListNode* tmp = <span class="keyword">new</span> ListNode(head-&gt;val);</span><br><span class="line">            tmp-&gt;next = res;</span><br><span class="line">            res = tmp;</span><br><span class="line">            head = head-&gt;next;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="40、数组中的第K个最大元素"><a href="#40、数组中的第K个最大元素" class="headerlink" title="40、数组中的第K个最大元素"></a>40、数组中的第K个最大元素</h1><p>在未排序的数组中找到第 k 个最大的元素。请注意，你需要找的是数组排序后的第 k 个最大的元素，而不是第 k 个不同的元素。</p><p>输入: [3,2,1,5,6,4] 和 k = 2<br>输出: 5</p><p>输入: [3,2,3,1,2,4,5,5,6] 和 k = 4<br>输出: 4</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function"><span class="keyword">int</span> <span class="title">findKthLargest</span><span class="params">(<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt;&amp; nums, <span class="keyword">int</span> k)</span> </span>&#123;</span><br><span class="line">        priority_queue &lt;<span class="keyword">int</span>,<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt;,greater&lt;<span class="keyword">int</span>&gt;&gt; q;</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;nums.size();i++)&#123;</span><br><span class="line">            <span class="keyword">if</span>(q.size()==k)&#123;</span><br><span class="line">                <span class="keyword">if</span>(q.top()&lt;nums[i])&#123;</span><br><span class="line">                    q.pop();</span><br><span class="line">                    q.push(nums[i]);</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">else</span>&#123;</span><br><span class="line">                q.push(nums[i]);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> q.top();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="41、存在重复元素"><a href="#41、存在重复元素" class="headerlink" title="41、存在重复元素"></a>41、存在重复元素</h1><p>给定一个整数数组，判断是否存在重复元素。<br>如果任何值在数组中出现至少两次，函数返回 true。如果数组中每个元素都不相同，则返回 false。</p><p>输入: [1,2,3,1]<br>输出: true</p><p>输入: [1,2,3,4]<br>输出: false</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function"><span class="keyword">bool</span> <span class="title">containsDuplicate</span><span class="params">(<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt;&amp; nums)</span> </span>&#123;</span><br><span class="line">        <span class="built_in">unordered_map</span>&lt;<span class="keyword">int</span>,<span class="keyword">int</span>&gt; m;</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;nums.size();i++)&#123;</span><br><span class="line">            <span class="keyword">if</span>(m.find(nums[i]) != m.end()) <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line">            <span class="keyword">else</span> m[nums[i]] = <span class="number">1</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="42、二叉搜索树中第K小的元素"><a href="#42、二叉搜索树中第K小的元素" class="headerlink" title="42、二叉搜索树中第K小的元素"></a>42、二叉搜索树中第K小的元素</h1><p>给定一个二叉搜索树，编写一个函数 kthSmallest 来查找其中第 k 个最小的元素。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Definition for a binary tree node.</span></span><br><span class="line"><span class="comment"> * struct TreeNode &#123;</span></span><br><span class="line"><span class="comment"> *     int val;</span></span><br><span class="line"><span class="comment"> *     TreeNode *left;</span></span><br><span class="line"><span class="comment"> *     TreeNode *right;</span></span><br><span class="line"><span class="comment"> *     TreeNode(int x) : val(x), left(NULL), right(NULL) &#123;&#125;</span></span><br><span class="line"><span class="comment"> * &#125;;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="keyword">int</span> res;</span><br><span class="line">    <span class="keyword">int</span> cur = <span class="number">0</span>;</span><br><span class="line">    <span class="function"><span class="keyword">int</span> <span class="title">kthSmallest</span><span class="params">(TreeNode* root, <span class="keyword">int</span> k)</span> </span>&#123;</span><br><span class="line">        midfor(root, k);</span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">midfor</span><span class="params">(TreeNode* root, <span class="keyword">int</span> k)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">if</span>(!root) <span class="keyword">return</span>;</span><br><span class="line">        <span class="keyword">if</span>(cur != k) midfor(root-&gt;left,k);</span><br><span class="line">        cur++;</span><br><span class="line">        <span class="keyword">if</span>(cur == k)&#123;</span><br><span class="line">            res = root-&gt;val;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span>(cur != k) midfor(root-&gt;right,k);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="43、2的幂"><a href="#43、2的幂" class="headerlink" title="43、2的幂"></a>43、2的幂</h1><p>给定一个整数，编写一个函数来判断它是否是 2 的幂次方。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function"><span class="keyword">bool</span> <span class="title">isPowerOfTwo</span><span class="params">(<span class="keyword">int</span> n)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">if</span>(n&lt;=<span class="number">0</span>) <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">        <span class="keyword">while</span>(n!=<span class="number">1</span>)&#123;</span><br><span class="line">            <span class="keyword">double</span> t = n/<span class="number">2.0</span>;</span><br><span class="line">            <span class="keyword">if</span>(!isint(t)) <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">            n /= <span class="number">2</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="function"><span class="keyword">bool</span> <span class="title">isint</span><span class="params">(<span class="keyword">double</span> d)</span></span>&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="built_in">abs</span>(d-(<span class="keyword">int</span>)d)&lt;<span class="number">1e-5</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="44、-二叉搜索树的最近公共祖先"><a href="#44、-二叉搜索树的最近公共祖先" class="headerlink" title="44、 二叉搜索树的最近公共祖先"></a>44、 二叉搜索树的最近公共祖先</h1><p>给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。<br>百度百科中最近公共祖先的定义为：“对于有根树 T 的两个结点 p、q，最近公共祖先表示为一个结点 x，满足 x 是 p、q 的祖先且 x 的深度尽可能大（一个节点也可以是它自己的祖先）。”</p><p>例如，给定如下二叉搜索树:  root = [6,2,8,0,4,7,9,null,null,3,5]</p><p>输入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 8<br>输出: 6<br>解释: 节点 2 和节点 8 的最近公共祖先是 6。</p><p>输入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 4<br>输出: 2<br>解释: 节点 2 和节点 4 的最近公共祖先是 2, 因为根据定义最近公共祖先节点可以为节点本身。</p><p>说明:<br>所有节点的值都是唯一的。<br>p、q 为不同节点且均存在于给定的二叉搜索树中。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Definition for a binary tree node.</span></span><br><span class="line"><span class="comment"> * struct TreeNode &#123;</span></span><br><span class="line"><span class="comment"> *     int val;</span></span><br><span class="line"><span class="comment"> *     TreeNode *left;</span></span><br><span class="line"><span class="comment"> *     TreeNode *right;</span></span><br><span class="line"><span class="comment"> *     TreeNode(int x) : val(x), left(NULL), right(NULL) &#123;&#125;</span></span><br><span class="line"><span class="comment"> * &#125;;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    TreeNode* res;</span><br><span class="line">    <span class="function">TreeNode* <span class="title">lowestCommonAncestor</span><span class="params">(TreeNode* root, TreeNode* p, TreeNode* q)</span> </span>&#123;</span><br><span class="line">        search(root,p,q);</span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">search</span><span class="params">(TreeNode* root, TreeNode* p, TreeNode* q)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">if</span>((root-&gt;val-p-&gt;val)*(root-&gt;val-q-&gt;val)&lt;=<span class="number">0</span>) res = root;</span><br><span class="line">        <span class="keyword">else</span> <span class="keyword">if</span>(p-&gt;val &gt; root-&gt;val &amp;&amp; q-&gt;val &gt; root-&gt;val) search(root-&gt;right,p,q);</span><br><span class="line">        <span class="keyword">else</span> search(root-&gt;left,p,q);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="45、二叉树的最近公共祖先"><a href="#45、二叉树的最近公共祖先" class="headerlink" title="45、二叉树的最近公共祖先"></a>45、二叉树的最近公共祖先</h1><p>给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。<br>百度百科中最近公共祖先的定义为：“对于有根树 T 的两个结点 p、q，最近公共祖先表示为一个结点 x，满足 x 是 p、q 的祖先且 x 的深度尽可能大（一个节点也可以是它自己的祖先）。”<br>例如，给定如下二叉树:  root = [3,5,1,6,2,0,8,null,null,7,4]</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Definition for a binary tree node.</span></span><br><span class="line"><span class="comment"> * struct TreeNode &#123;</span></span><br><span class="line"><span class="comment"> *     int val;</span></span><br><span class="line"><span class="comment"> *     TreeNode *left;</span></span><br><span class="line"><span class="comment"> *     TreeNode *right;</span></span><br><span class="line"><span class="comment"> *     TreeNode(int x) : val(x), left(NULL), right(NULL) &#123;&#125;</span></span><br><span class="line"><span class="comment"> * &#125;;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function">TreeNode* <span class="title">lowestCommonAncestor</span><span class="params">(TreeNode* root, TreeNode* p, TreeNode* q)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">if</span>(!root) <span class="keyword">return</span> <span class="literal">NULL</span>;</span><br><span class="line">        <span class="keyword">if</span>(root == p || root == q) <span class="keyword">return</span> root;</span><br><span class="line">        TreeNode* l = lowestCommonAncestor(root-&gt;left,p,q);</span><br><span class="line">        TreeNode* r = lowestCommonAncestor(root-&gt;right,p,q);</span><br><span class="line">        <span class="keyword">if</span>(l&amp;&amp;r) <span class="keyword">return</span> root;</span><br><span class="line">        <span class="keyword">if</span>(l) <span class="keyword">return</span> l;</span><br><span class="line">        <span class="keyword">if</span>(r) <span class="keyword">return</span> r;</span><br><span class="line">        <span class="keyword">return</span> <span class="literal">NULL</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="46、删除链表中的节点"><a href="#46、删除链表中的节点" class="headerlink" title="46、删除链表中的节点"></a>46、删除链表中的节点</h1><p>请编写一个函数，使其可以删除某个链表中给定的（非末尾）节点，你将只被给定要求被删除的节点。<br>现有一个链表 – head = [4,5,1,9]，它可以表示为:</p><p>输入: head = [4,5,1,9], node = 5<br>输出: [4,1,9]<br>解释: 给定你链表中值为 5 的第二个节点，那么在调用了你的函数之后，该链表应变为 4 -&gt; 1 -&gt; 9.</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Definition for singly-linked list.</span></span><br><span class="line"><span class="comment"> * struct ListNode &#123;</span></span><br><span class="line"><span class="comment"> *     int val;</span></span><br><span class="line"><span class="comment"> *     ListNode *next;</span></span><br><span class="line"><span class="comment"> *     ListNode(int x) : val(x), next(NULL) &#123;&#125;</span></span><br><span class="line"><span class="comment"> * &#125;;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">deleteNode</span><span class="params">(ListNode* node)</span> </span>&#123;</span><br><span class="line">        node-&gt;val = node-&gt;next-&gt;val;</span><br><span class="line">        node-&gt;next = node-&gt;next-&gt;next;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="47、除自身以外数组的乘积"><a href="#47、除自身以外数组的乘积" class="headerlink" title="47、除自身以外数组的乘积"></a>47、除自身以外数组的乘积</h1><p>给定长度为 n 的整数数组 nums，其中 n &gt; 1，返回输出数组 output ，其中 output[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积。</p><p>输入: [1,2,3,4]<br>输出: [24,12,8,6]<br>说明: 请不要使用除法，且在 O(n) 时间复杂度内完成此题。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; productExceptSelf(<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt;&amp; nums) &#123;</span><br><span class="line">        <span class="keyword">int</span> l=<span class="number">1</span>, r=<span class="number">1</span>;</span><br><span class="line">        <span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; res(nums.size());</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;nums.size();i++)&#123;</span><br><span class="line">            res[i] = l;</span><br><span class="line">            l *= nums[i];</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i=nums.size()<span class="number">-1</span>;i&gt;=<span class="number">0</span>;i--)&#123;</span><br><span class="line">            res[i] *= r;</span><br><span class="line">            r *= nums[i];</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="48、Nim-游戏"><a href="#48、Nim-游戏" class="headerlink" title="48、Nim 游戏"></a>48、Nim 游戏</h1><p>你和你的朋友，两个人一起玩 Nim 游戏：桌子上有一堆石头，每次你们轮流拿掉 1 - 3 块石头。 拿掉最后一块石头的人就是获胜者。你作为先手。<br>你们是聪明人，每一步都是最优解。 编写一个函数，来判断你是否可以在给定石头数量的情况下赢得游戏。</p><p>输入: 4<br>输出: false<br>解释: 如果堆中有 4 块石头，那么你永远不会赢得比赛；<br>     因为无论你拿走 1 块、2 块 还是 3 块石头，最后一块石头总是会被你的朋友拿走。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function"><span class="keyword">bool</span> <span class="title">canWinNim</span><span class="params">(<span class="keyword">int</span> n)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> !(n%<span class="number">4</span>==<span class="number">0</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="49、反转字符串"><a href="#49、反转字符串" class="headerlink" title="49、反转字符串"></a>49、反转字符串</h1><p>编写一个函数，其作用是将输入的字符串反转过来。输入字符串以字符数组 char[] 的形式给出。<br>不要给另外的数组分配额外的空间，你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。<br>你可以假设数组中的所有字符都是 ASCII 码表中的可打印字符。</p><p>输入：[“h”,”e”,”l”,”l”,”o”]<br>输出：[“o”,”l”,”l”,”e”,”h”]</p><p>输入：[“H”,”a”,”n”,”n”,”a”,”h”]<br>输出：[“h”,”a”,”n”,”n”,”a”,”H”]·</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">reverseString</span><span class="params">(<span class="built_in">vector</span>&lt;<span class="keyword">char</span>&gt;&amp; s)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">int</span> i=<span class="number">0</span>,j=s.size()<span class="number">-1</span>;</span><br><span class="line">        <span class="keyword">while</span>(i&lt;j)&#123;</span><br><span class="line">            swap(s[i],s[j]);</span><br><span class="line">            i++;j--;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="50、反转字符串中的单词-III"><a href="#50、反转字符串中的单词-III" class="headerlink" title="50、反转字符串中的单词 III"></a>50、反转字符串中的单词 III</h1><p>给定一个字符串，你需要反转字符串中每个单词的字符顺序，同时仍保留空格和单词的初始顺序。</p><p>输入: “Let’s take LeetCode contest”<br>输出: “s’teL ekat edoCteeL tsetnoc”<br>注意：在字符串中，每个单词由单个空格分隔，并且字符串中不会有任何额外的空格。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function"><span class="built_in">string</span> <span class="title">reverseWords</span><span class="params">(<span class="built_in">string</span> s)</span> </span>&#123;</span><br><span class="line">        <span class="built_in">string</span> res;</span><br><span class="line">        <span class="built_in">stack</span>&lt;<span class="keyword">char</span>&gt; <span class="built_in">stack</span>;</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;s.size();i++)&#123;</span><br><span class="line">            <span class="keyword">if</span>(s[i] == <span class="string">' '</span>)&#123;</span><br><span class="line">                <span class="keyword">while</span>(!<span class="built_in">stack</span>.empty())&#123;</span><br><span class="line">                    res.push_back(<span class="built_in">stack</span>.top());</span><br><span class="line">                    <span class="built_in">stack</span>.pop();</span><br><span class="line">                &#125;</span><br><span class="line">                res.push_back(<span class="string">' '</span>);</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">else</span>&#123;</span><br><span class="line">                <span class="built_in">stack</span>.push(s[i]);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">while</span>(!<span class="built_in">stack</span>.empty())&#123;</span><br><span class="line">            res.push_back(<span class="built_in">stack</span>.top());</span><br><span class="line">            <span class="built_in">stack</span>.pop();</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure>]]></content>
    
    <summary type="html">
    
      &lt;h3 id=&quot;题目来源&quot;&gt;&lt;a href=&quot;#题目来源&quot; class=&quot;headerlink&quot; title=&quot;题目来源&quot;&gt;&lt;/a&gt;题目来源&lt;/h3&gt;&lt;p&gt; &lt;a href=&quot;https://leetcode-cn.com/problemset/50/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;腾讯精选练习（50 题）&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;相关：&lt;br&gt;&lt;a href=&quot;https://blog.csdn.net/ffcjjhv/article/details/88409676&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;刷题汇总（一）leetcode 精选50题 JavaScript答案总结&lt;/a&gt;&lt;br&gt;&lt;a href=&quot;https://blog.csdn.net/ffcjjhv/article/details/96879804&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;刷题汇总（二）剑指Offer 66题 C++答案总结&lt;/a&gt;&lt;br&gt;&lt;a href=&quot;https://blog.csdn.net/ffcjjhv/article/details/103195691&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;刷题汇总（四）技术类编程题汇总 C++&lt;/a&gt;&lt;br&gt;&lt;a href=&quot;https://blog.csdn.net/ffcjjhv/article/details/103381516&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;刷题汇总（五）leetcode 热题 HOT 100 C++ 答案总结&lt;/a&gt;&lt;br&gt;&lt;a href=&quot;https://blog.csdn.net/ffcjjhv/article/details/103503745&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;刷题汇总（六）leetcode 多线程 / Shell&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://pan.baidu.com/s/1fHto2ckVlwQzgUi8TxYReA&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;PDF版 code&lt;/a&gt;  （提取码：0wxr ）&lt;/p&gt;
&lt;h1 id=&quot;1、两数相加&quot;&gt;&lt;a href=&quot;#1、两数相加&quot; class=&quot;headerlink&quot; title=&quot;1、两数相加&quot;&gt;&lt;/a&gt;1、两数相加&lt;/h1&gt;&lt;p&gt;给出两个 非空 的链表用来表示两个非负的整数。其中，它们各自的位数是按照 逆序 的方式存储的，并且它们的每个节点只能存储 一位 数字。&lt;br&gt;
    
    </summary>
    
      <category term="C++" scheme="http://yoursite.com/categories/C/"/>
    
      <category term="后台开发" scheme="http://yoursite.com/categories/%E5%90%8E%E5%8F%B0%E5%BC%80%E5%8F%91/"/>
    
      <category term="CodeCode" scheme="http://yoursite.com/categories/CodeCode/"/>
    
    
      <category term="C++" scheme="http://yoursite.com/tags/C/"/>
    
      <category term="Leetcode" scheme="http://yoursite.com/tags/Leetcode/"/>
    
  </entry>
  
  <entry>
    <title>常见算法的c++实现总结</title>
    <link href="http://yoursite.com/2019/08/07/24/"/>
    <id>http://yoursite.com/2019/08/07/24/</id>
    <published>2019-08-07T03:11:48.000Z</published>
    <updated>2019-12-18T04:19:53.589Z</updated>
    
    <content type="html"><![CDATA[<h2 id="目录"><a href="#目录" class="headerlink" title="目录"></a>目录</h2><p>一、七大排序算法<br>二、大整数计算<br>三、编kmp辑距离问题<br>四、kmp算法<br>五、dijkstra算法<br>六、0/1背包问题</p><h1 id="一、七大排序算法"><a href="#一、七大排序算法" class="headerlink" title="一、七大排序算法"></a>一、七大排序算法</h1><a id="more"></a><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;iostream&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;vector&gt;</span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> <span class="built_in">std</span>;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">swap</span><span class="params">(<span class="keyword">int</span> &amp;a, <span class="keyword">int</span> &amp;b)</span> </span>&#123;</span><br><span class="line"><span class="keyword">int</span> tmp;</span><br><span class="line">tmp = a;</span><br><span class="line">a = b;</span><br><span class="line">b = tmp;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//一、插入排序</span></span><br><span class="line"><span class="comment">//1.1 直接插入排序  时间复杂度O(n^2)  空间复杂度O(1)  稳定</span></span><br><span class="line"><span class="comment">//构建有序序列，对于未排序数据，在已排序序列中从后向前扫描，找到相应位置并插入。</span></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">insert_sort</span><span class="params">(<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; &amp;nums)</span> </span>&#123;</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; nums.size(); i++)&#123;</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">int</span> j = i; j &gt; <span class="number">0</span>; j--)&#123;</span><br><span class="line"><span class="keyword">if</span> (nums[j] &lt; nums[j - <span class="number">1</span>])</span><br><span class="line">swap(nums[j], nums[j - <span class="number">1</span>]);</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//1.2 希尔排序  时间复杂度O(n^1.3)  空间复杂度O(1)  不稳定</span></span><br><span class="line"><span class="comment">//按照一定步长分成子序列进行排序，然后逐步递减步长来完成最终排序。增量 d = 1时， 就是插入排序</span></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">shell_sort</span><span class="params">(<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; &amp;nums)</span> </span>&#123;</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">int</span> gap = nums.size() &gt;&gt; <span class="number">1</span>; gap&gt;<span class="number">0</span>; gap &gt;&gt;= <span class="number">1</span>)&#123;</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">int</span> i = gap; i &lt; nums.size(); i++)</span><br><span class="line">&#123;</span><br><span class="line"><span class="keyword">int</span> tmp = nums[i];</span><br><span class="line"><span class="keyword">int</span> j = i - gap;</span><br><span class="line"><span class="keyword">for</span> (; j &gt;= <span class="number">0</span> &amp;&amp; nums[j] &gt; tmp; j -= gap)&#123;</span><br><span class="line">nums[j + gap] = nums[j];</span><br><span class="line">&#125;</span><br><span class="line">nums[j + gap] = tmp;</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//二、选择排序</span></span><br><span class="line"><span class="comment">//2.1 选择排序  时间复杂度O(n^2)  空间复杂度O(1)  不稳定</span></span><br><span class="line"><span class="comment">//先进行第一轮循环比较相邻两项，找到最小值得下标，将最小值与第一项交换，然后重复排序剩余部分。</span></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">select_sort</span><span class="params">(<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; &amp;nums)</span> </span>&#123;</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; nums.size(); i++) &#123;</span><br><span class="line"><span class="keyword">int</span> min = i;</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">int</span> j = i + <span class="number">1</span>; j &lt; nums.size(); j++)&#123;</span><br><span class="line"><span class="keyword">if</span> (nums[j] &lt; nums[min])</span><br><span class="line">min = j;</span><br><span class="line">&#125;</span><br><span class="line">swap(nums[i], nums[min]);</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//2.2 堆排序  时间复杂度O(nlgn)  空间复杂度O(1)  稳定</span></span><br><span class="line"><span class="comment">//构造一个最大堆（完全二叉树），父结点大于左右子结点，然后取出根结点（最大值）与最后一个结点交换，重复调整剩余的结点成最大堆，得到有序的序列。</span></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">max_heapify</span><span class="params">(<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; &amp;nums, <span class="keyword">int</span> l, <span class="keyword">int</span> r)</span> </span>&#123;</span><br><span class="line"><span class="keyword">int</span> curr = l;</span><br><span class="line"><span class="keyword">int</span> child = curr * <span class="number">2</span> + <span class="number">1</span>;</span><br><span class="line"><span class="keyword">while</span> (child &lt; r) &#123;</span><br><span class="line"><span class="keyword">if</span> (child + <span class="number">1</span> &lt; r &amp;&amp;nums[child] &lt; nums[child + <span class="number">1</span>])</span><br><span class="line">child++;</span><br><span class="line"><span class="keyword">if</span> (nums[curr] &lt; nums[child]) &#123;</span><br><span class="line">swap(nums[curr], nums[child]);</span><br><span class="line">curr = child;</span><br><span class="line">child = <span class="number">2</span> * curr + <span class="number">1</span>;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">else</span></span><br><span class="line"><span class="keyword">break</span>;</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">heap_sort</span><span class="params">(<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; &amp;nums)</span> </span>&#123;</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">int</span> i = nums.size() / <span class="number">2</span> - <span class="number">1</span>; i &gt;= <span class="number">0</span>; i--)</span><br><span class="line">&#123;</span><br><span class="line">max_heapify(nums, i, nums.size());</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">int</span> i = nums.size() - <span class="number">1</span>; i &gt; <span class="number">0</span>; i--)</span><br><span class="line">&#123;</span><br><span class="line">swap(nums[<span class="number">0</span>], nums[i]);</span><br><span class="line">max_heapify(nums, <span class="number">0</span>, i);</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">//三、交换排序</span></span><br><span class="line"><span class="comment">//3.1 冒泡排序  时间复杂度O(n^2)  空间复杂度O(1)  稳定</span></span><br><span class="line"><span class="comment">//每次通过两两比较交换位置，选出剩余无序序列里最大（小）的数据元素放到队尾。</span></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">bubble_sort</span><span class="params">(<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; &amp;nums)</span> </span>&#123;</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; nums.size() - <span class="number">1</span>; i++)&#123;</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">int</span> j = <span class="number">0</span>; j &lt; nums.size() - i - <span class="number">1</span>; j++)&#123;</span><br><span class="line"><span class="keyword">if</span> (nums[j] &gt; nums[j + <span class="number">1</span>])</span><br><span class="line">swap(nums[j], nums[j + <span class="number">1</span>]);</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//3.2快速排序  时间复杂度O(nlgn)  空间复杂度O(1)  不稳定</span></span><br><span class="line"><span class="comment">//将无序序列分隔成两部分，左边均比右边小，分别对这两部分进行排序</span></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">quick_sort</span><span class="params">(<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; &amp;nums, <span class="keyword">int</span> l, <span class="keyword">int</span> r)</span> </span>&#123;</span><br><span class="line"><span class="keyword">if</span> (l &lt; r) &#123;</span><br><span class="line"><span class="keyword">int</span> i = l, j = r;</span><br><span class="line"><span class="keyword">while</span> (i &lt; j) &#123;</span><br><span class="line"><span class="keyword">while</span> (nums[j] &gt;= nums[l] &amp;&amp; i &lt; j)</span><br><span class="line">j--;</span><br><span class="line"><span class="keyword">while</span> (nums[i] &lt;= nums[l] &amp;&amp; i &lt; j)</span><br><span class="line">i++;</span><br><span class="line">swap(nums[i], nums[j]);</span><br><span class="line">&#125;</span><br><span class="line">swap(nums[l], nums[i]);</span><br><span class="line">quick_sort(nums, l, i<span class="number">-1</span>);</span><br><span class="line">quick_sort(nums, i + <span class="number">1</span>, r);</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//四、归并排序  时间复杂度O(nlgn)  空间复杂度O(n)  稳定</span></span><br><span class="line"><span class="comment">//将序列递归分成单位为1的小序列，然后两两合并排序，最终得到有序的序列。</span></span><br><span class="line"><span class="function"><span class="keyword">void</span>  <span class="title">merge_sort</span><span class="params">(<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; &amp;nums, <span class="keyword">int</span> l, <span class="keyword">int</span> r, <span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; &amp;tmp)</span> </span>&#123;</span><br><span class="line"><span class="keyword">if</span> (l &gt;= r) <span class="keyword">return</span>;</span><br><span class="line"><span class="keyword">int</span> m = (l + r) / <span class="number">2</span>;</span><br><span class="line">merge_sort(nums, l, m, tmp);</span><br><span class="line">merge_sort(nums, m + <span class="number">1</span>, r, tmp);</span><br><span class="line"><span class="keyword">int</span> i = l, j = m + <span class="number">1</span>, index = l;</span><br><span class="line"><span class="keyword">while</span> (i &lt;= m &amp;&amp;  j &lt;= r) &#123;</span><br><span class="line"><span class="keyword">if</span> (nums[i] &lt; nums[j])</span><br><span class="line">tmp[index++] = nums[i++];</span><br><span class="line"><span class="keyword">else</span></span><br><span class="line">tmp[index++] = nums[j++];</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">while</span> (i &lt;= m)</span><br><span class="line">tmp[index++] = nums[i++];</span><br><span class="line"><span class="keyword">while</span> (j &lt;= r)</span><br><span class="line">tmp[index++] = nums[j++];</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">int</span> i = l; i &lt;= r; i++)</span><br><span class="line">nums[i] = tmp[i];</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span> </span>&#123;</span><br><span class="line"></span><br><span class="line"><span class="built_in">cout</span> &lt;&lt; <span class="string">"原始数列：8, 3, 1, 4, 11, 2, 2, 1, 5, 2, 7, 9, 1, 6 "</span> &lt;&lt; <span class="built_in">endl</span>;</span><br><span class="line"><span class="built_in">cout</span> &lt;&lt; <span class="string">"请选择排序算法："</span> &lt;&lt; <span class="built_in">endl</span>;</span><br><span class="line"><span class="built_in">cout</span> &lt;&lt; <span class="string">"1 插入排序，2 希尔排序，3 选择排序，4 堆排序，5 冒泡排序，6 快速排序，7 归并排序"</span> &lt;&lt; <span class="built_in">endl</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">int</span> index;</span><br><span class="line"><span class="keyword">while</span> (<span class="built_in">cin</span> &gt;&gt; index)&#123;</span><br><span class="line"><span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; nums&#123; <span class="number">8</span>, <span class="number">3</span>, <span class="number">1</span>, <span class="number">4</span>, <span class="number">11</span>, <span class="number">2</span>, <span class="number">2</span>, <span class="number">1</span>, <span class="number">5</span>, <span class="number">2</span>, <span class="number">7</span>, <span class="number">9</span>, <span class="number">1</span>, <span class="number">6</span> &#125;;</span><br><span class="line"><span class="keyword">int</span> len = nums.size();</span><br><span class="line"><span class="keyword">switch</span> (index)&#123;</span><br><span class="line"><span class="keyword">case</span> <span class="number">1</span>:</span><br><span class="line">insert_sort(nums); <span class="comment">//插入排序</span></span><br><span class="line"><span class="keyword">break</span>;</span><br><span class="line"><span class="keyword">case</span> <span class="number">2</span>:</span><br><span class="line">shell_sort(nums); <span class="comment">//希尔排序</span></span><br><span class="line"><span class="keyword">break</span>;</span><br><span class="line"><span class="keyword">case</span> <span class="number">3</span>:</span><br><span class="line">select_sort(nums); <span class="comment">//选择排序</span></span><br><span class="line"><span class="keyword">break</span>;</span><br><span class="line"><span class="keyword">case</span> <span class="number">4</span>:</span><br><span class="line">heap_sort(nums); <span class="comment">//堆排序</span></span><br><span class="line"><span class="keyword">break</span>;</span><br><span class="line"><span class="keyword">case</span> <span class="number">5</span>:</span><br><span class="line">bubble_sort(nums); <span class="comment">//冒泡排序</span></span><br><span class="line"><span class="keyword">break</span>;</span><br><span class="line"><span class="keyword">case</span> <span class="number">6</span>:</span><br><span class="line">quick_sort(nums, <span class="number">0</span>, len - <span class="number">1</span>); <span class="comment">//快速排序</span></span><br><span class="line"><span class="keyword">break</span>;</span><br><span class="line"><span class="keyword">case</span> <span class="number">7</span>:</span><br><span class="line"><span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; tmp(len);</span><br><span class="line">merge_sort(nums, <span class="number">0</span>, len - <span class="number">1</span>, tmp); <span class="comment">//归并排序</span></span><br><span class="line"><span class="keyword">break</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i&lt;nums.size(); i++)&#123;</span><br><span class="line"><span class="built_in">cout</span> &lt;&lt; nums[i] &lt;&lt; <span class="string">' '</span>;</span><br><span class="line">&#125;</span><br><span class="line"><span class="built_in">cout</span> &lt;&lt; <span class="built_in">endl</span>;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p><img src="https://img-blog.csdnimg.cn/20190807111344829.JPG?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZmY2pqaHY=,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"></p><h1 id="二、大整数计算"><a href="#二、大整数计算" class="headerlink" title="二、大整数计算"></a>二、大整数计算</h1><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;iostream&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;string&gt;</span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> <span class="built_in">std</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">//大数相加</span></span><br><span class="line"><span class="function"><span class="built_in">string</span> <span class="title">addstr</span><span class="params">(<span class="built_in">string</span> s1, <span class="built_in">string</span> s2)</span> </span>&#123;</span><br><span class="line"><span class="keyword">if</span> (s1.size()&gt;s2.size()) <span class="keyword">return</span> addstr(s2, s1); <span class="comment">//s1短</span></span><br><span class="line">s1.insert(s1.begin(), s2.size() - s1.size(), <span class="string">'0'</span>);</span><br><span class="line"><span class="function"><span class="built_in">string</span> <span class="title">res</span><span class="params">(s2.size() + <span class="number">1</span>, <span class="string">'0'</span>)</span></span>;</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">int</span> i = s2.size() - <span class="number">1</span>; i &gt;= <span class="number">0</span>; i--)&#123;</span><br><span class="line"><span class="keyword">int</span> t = (s1[i] - <span class="string">'0'</span>) + (s2[i] - <span class="string">'0'</span>) + (res[i + <span class="number">1</span>] - <span class="string">'0'</span>);</span><br><span class="line">res[i + <span class="number">1</span>] = t % <span class="number">10</span> + <span class="string">'0'</span>;</span><br><span class="line">res[i] = t / <span class="number">10</span> + <span class="string">'0'</span>;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">if</span> (res[<span class="number">0</span>] == <span class="string">'0'</span>) <span class="keyword">return</span> res.substr(<span class="number">1</span>);</span><br><span class="line"><span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">//大数相乘</span></span><br><span class="line"><span class="function"><span class="built_in">string</span> <span class="title">multiply</span><span class="params">(<span class="built_in">string</span> num1, <span class="built_in">string</span> num2)</span> </span>&#123;</span><br><span class="line"><span class="keyword">int</span> len1 = num1.size(), len2 = num2.size();</span><br><span class="line"><span class="function"><span class="built_in">string</span> <span class="title">res</span><span class="params">(len1 + len2, <span class="string">'0'</span>)</span></span>;</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">int</span> i = len1 - <span class="number">1</span>; i &gt;= <span class="number">0</span>; i--)&#123;</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">int</span> j = len2 - <span class="number">1</span>; j &gt;= <span class="number">0</span>; j--)&#123;</span><br><span class="line"><span class="keyword">int</span> t = (res[i + j + <span class="number">1</span>] - <span class="string">'0'</span>) + (num1[i] - <span class="string">'0'</span>)*(num2[j] - <span class="string">'0'</span>);</span><br><span class="line">res[i + j + <span class="number">1</span>] = t % <span class="number">10</span> + <span class="string">'0'</span>;</span><br><span class="line">res[i + j] += t / <span class="number">10</span>;</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i&lt;len1 + len2; i++)&#123;</span><br><span class="line"><span class="keyword">if</span> (res[i] != <span class="string">'0'</span>) <span class="keyword">return</span> res.substr(i);</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">return</span> <span class="string">"0"</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line"><span class="built_in">string</span> s1, s2;</span><br><span class="line"><span class="built_in">cin</span> &gt;&gt; s1 &gt;&gt; s2;</span><br><span class="line"></span><br><span class="line"><span class="built_in">cout</span> &lt;&lt; <span class="string">"相加:"</span> &lt;&lt; addstr(s1,s2) &lt;&lt; <span class="built_in">endl</span>;</span><br><span class="line"><span class="built_in">cout</span> &lt;&lt; <span class="string">"相乘:"</span> &lt;&lt; multiply(s1, s2) &lt;&lt; <span class="built_in">endl</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p><img src="https://img-blog.csdnimg.cn/20190919212759500.png" alt="在这里插入图片描述"></p><h1 id="三、编辑距离问题"><a href="#三、编辑距离问题" class="headerlink" title="三、编辑距离问题"></a>三、编辑距离问题</h1><p><a href="https://www.nowcoder.com/questionTerminal/95a00cada0df40f29c598928521684a2" target="_blank" rel="noopener">题目地址</a></p><p>编辑距离，又称Levenshtein距离，是指两个子串之间，由一个转成另一个所需的最少编辑操作次数。许可的编辑操作包括将一个字符替换成另一个字符，插入一个字符，删除一个字符。请尝试写出一个算法来计算两个字符串的编辑距离。</p><p>1、当min(i,j)=0时，f(i,j)=max(i,j)，一个字符串的长度为0，编辑距离是另一个字符串的长度<br>2、当a[i]=b[j]时，f(i,j)=f(i−1,j−1)，比如xxcz和xyz的距离=xxc和xy的距离<br>3、否则，lev(i,j)为如下三项的最小值：<br> f(i−1,j)+1(在a中删除ai);<br> f(i,j−1)+1(在a中插入bj);<br> f(i−1,j−1)+1(在a中把ai替换bj)，</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;iostream&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;vector&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;string&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;algorithm&gt;</span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> <span class="built_in">std</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">//编辑距离</span></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">EditDistance</span><span class="params">(<span class="built_in">string</span> s1, <span class="built_in">string</span> s2)</span> </span>&#123;</span><br><span class="line"><span class="keyword">int</span> m = s1.size(), n = s2.size();</span><br><span class="line"><span class="built_in">vector</span>&lt;<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt;&gt; arr(m + <span class="number">1</span>, <span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt;(n + <span class="number">1</span>));</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i &lt;= m; i++)&#123;</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">int</span> j = <span class="number">0</span>; j &lt;= n; j++)&#123;</span><br><span class="line"><span class="keyword">if</span> (i == <span class="number">0</span> || j == <span class="number">0</span>)&#123;</span><br><span class="line">arr[i][j] = max(i, j);</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">else</span> <span class="keyword">if</span>(s1[i<span class="number">-1</span>] == s2[j<span class="number">-1</span>])&#123; <span class="comment">//注意</span></span><br><span class="line">arr[i][j] = arr[i - <span class="number">1</span>][j - <span class="number">1</span>];</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">else</span>&#123;</span><br><span class="line">arr[i][j] = min(arr[i - <span class="number">1</span>][j] + <span class="number">1</span>, min(arr[i][j<span class="number">-1</span>] + <span class="number">1</span>, arr[i - <span class="number">1</span>][j - <span class="number">1</span>] + <span class="number">1</span>));</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">return</span> arr[m][n];</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line"><span class="built_in">string</span> s1, s2;</span><br><span class="line"><span class="built_in">cin</span> &gt;&gt; s1 &gt;&gt; s2;</span><br><span class="line"></span><br><span class="line"><span class="built_in">cout</span> &lt;&lt; EditDistance(s1, s2) &lt;&lt; <span class="built_in">endl</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>时间复杂度O（nm)， 空间复杂度O（nm）</p><h1 id="四、kmp算法"><a href="#四、kmp算法" class="headerlink" title="四、kmp算法"></a>四、kmp算法</h1><p><a href="https://www.nowcoder.com/questionTerminal/a376cfc811db43719768b1a79ec3829a" target="_blank" rel="noopener">题目地址</a></p><p>给定两个字符串str和match，长度分别为N和M。实现一个算法，如果字符串str中含有子串match，则返回match在str中的开始位置，不含有则返回-1</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;iostream&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;vector&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;string&gt;</span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> <span class="built_in">std</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 暴力匹配算法</span></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">ViolentMatch</span><span class="params">(<span class="built_in">string</span> s, <span class="built_in">string</span> p)</span> </span>&#123;</span><br><span class="line"><span class="keyword">int</span> i = <span class="number">0</span>, j = <span class="number">0</span>, slen = s.size(), plen = p.size();</span><br><span class="line"><span class="keyword">while</span> (i &lt; slen &amp;&amp; j &lt; plen)</span><br><span class="line">&#123;</span><br><span class="line"><span class="keyword">if</span> (s[i] == p[j])&#123;</span><br><span class="line">i++;</span><br><span class="line">j++;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">else</span>&#123;</span><br><span class="line">i = i - j + <span class="number">1</span>;</span><br><span class="line">j = <span class="number">0</span>;</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> (j == plen) <span class="keyword">return</span> i - j;</span><br><span class="line"><span class="keyword">else</span> <span class="keyword">return</span> <span class="number">-1</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// KMP算法</span></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">KMP</span><span class="params">(<span class="built_in">string</span> s, <span class="built_in">string</span> p, <span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt;next)</span> </span>&#123;</span><br><span class="line"><span class="keyword">int</span> i = <span class="number">0</span>, j = <span class="number">0</span>, slen = s.size(), plen = p.size();</span><br><span class="line"><span class="keyword">while</span> (i &lt; slen &amp;&amp; j &lt; plen)</span><br><span class="line">&#123;</span><br><span class="line"><span class="keyword">if</span> (j == <span class="number">-1</span> || s[i] == p[j])&#123;</span><br><span class="line">i++;</span><br><span class="line">j++;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">else</span>&#123;</span><br><span class="line">j = next[j];</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> (j == plen) <span class="keyword">return</span> i - j;</span><br><span class="line"><span class="keyword">else</span> <span class="keyword">return</span> <span class="number">-1</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// MultiKMP算法</span></span><br><span class="line"><span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; MultiKMP(<span class="built_in">string</span> s, <span class="built_in">string</span> p, <span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt;next) &#123;</span><br><span class="line"><span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; res;</span><br><span class="line"><span class="keyword">int</span> i = <span class="number">0</span>, j = <span class="number">0</span>, slen = s.size(), plen = p.size();</span><br><span class="line"><span class="keyword">while</span> (i &lt; slen)</span><br><span class="line">&#123;</span><br><span class="line"><span class="keyword">if</span> (j == <span class="number">-1</span> || s[i] == p[j])&#123;</span><br><span class="line">i++;</span><br><span class="line">j++;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">else</span>&#123;</span><br><span class="line">j = next[j];</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">if</span> (j == plen)&#123;</span><br><span class="line">res.push_back(i - j);</span><br><span class="line">j = <span class="number">0</span>;</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// MultiKMP2算法</span></span><br><span class="line"><span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; MultiKMP2(<span class="built_in">string</span> s, <span class="built_in">string</span> p, <span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt;next) &#123;</span><br><span class="line"><span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; res;</span><br><span class="line"><span class="keyword">int</span> i = <span class="number">0</span>, j = <span class="number">0</span>, slen = s.size(), plen = p.size();</span><br><span class="line"><span class="keyword">while</span> (i &lt; slen)</span><br><span class="line">&#123;</span><br><span class="line"><span class="keyword">if</span> (j == <span class="number">-1</span> || s[i] == p[j])&#123;</span><br><span class="line">i++;</span><br><span class="line">j++;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">else</span>&#123;</span><br><span class="line">j = next[j];</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">if</span> (j == plen)&#123;</span><br><span class="line">res.push_back(i - j);</span><br><span class="line">i = i - j + <span class="number">1</span>;</span><br><span class="line">j = <span class="number">0</span>;</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; GetNext(<span class="built_in">string</span> p)</span><br><span class="line">&#123;</span><br><span class="line"><span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; next(p.size());</span><br><span class="line">next[<span class="number">0</span>] = <span class="number">-1</span>;</span><br><span class="line"><span class="keyword">int</span> k = <span class="number">-1</span>, j = <span class="number">0</span>;</span><br><span class="line"><span class="keyword">while</span> (j &lt; p.size() - <span class="number">1</span>)</span><br><span class="line">&#123;</span><br><span class="line"><span class="comment">//p[k]表示前缀，p[j]表示后缀  </span></span><br><span class="line"><span class="keyword">if</span> (k == <span class="number">-1</span> || p[j] == p[k])&#123;</span><br><span class="line">++k;</span><br><span class="line">++j;</span><br><span class="line"><span class="keyword">if</span> (p[j] != p[k]) next[j] = k;</span><br><span class="line"><span class="keyword">else</span> next[j] = next[k];</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">else</span>&#123;</span><br><span class="line">k = next[k];</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">return</span> next;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">printvec</span><span class="params">(<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; vec)</span> </span>&#123;</span><br><span class="line"><span class="keyword">if</span> (!vec.empty())&#123;</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; vec.size(); i++)&#123;</span><br><span class="line"><span class="built_in">cout</span> &lt;&lt; vec[i] &lt;&lt; <span class="string">' '</span>;</span><br><span class="line">&#125;</span><br><span class="line"><span class="built_in">cout</span> &lt;&lt; <span class="built_in">endl</span>;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">else</span>&#123;</span><br><span class="line"><span class="built_in">cout</span> &lt;&lt; <span class="number">-1</span> &lt;&lt; <span class="built_in">endl</span>;</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line"><span class="built_in">string</span> s1, s2;</span><br><span class="line"><span class="built_in">cin</span> &gt;&gt; s1 &gt;&gt; s2;</span><br><span class="line"></span><br><span class="line"><span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; next = GetNext(s2);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 暴力匹配第一次出现位置</span></span><br><span class="line"><span class="built_in">cout</span> &lt;&lt; ViolentMatch(s1, s2) &lt;&lt; <span class="built_in">endl</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">// KMP匹配第一次出现位置</span></span><br><span class="line"><span class="built_in">cout</span> &lt;&lt; KMP(s1, s2, next) &lt;&lt; <span class="built_in">endl</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">// KMP匹配无重复所有出现位置</span></span><br><span class="line"><span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; res = MultiKMP(s1, s2, next);</span><br><span class="line">printvec(res);</span><br><span class="line"></span><br><span class="line"><span class="comment">// KMP匹配可重复所有出现位置</span></span><br><span class="line"><span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; res2 = MultiKMP2(s1, s2, next);</span><br><span class="line">printvec(res2);</span><br><span class="line"></span><br><span class="line"><span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p><img src="https://img-blog.csdnimg.cn/20191121092551906.png" alt="在这里插入图片描述"><br><a href="https://blog.csdn.net/v_july_v/article/details/7041827#" target="_blank" rel="noopener">算法详解</a>  时间复杂度为O(m + n)<br>扩展：BM算法、Sunday算法。</p><h1 id="五、dijkstra算法"><a href="#五、dijkstra算法" class="headerlink" title="五、dijkstra算法"></a>五、dijkstra算法</h1><p>迪杰斯特拉(Dijkstra)算法是典型最短路径算法，用于计算一个节点到其他节点的最短路径。它的主要特点是以起始点为中心向外层层扩展(广度优先搜索思想)，直到扩展到终点为止。它解决的是带权重的有向图上单源最短路径问题。<br><img src="https://img-blog.csdnimg.cn/20191121095620601.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZmY2pqaHY=,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"></p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;iostream&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;string&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> <span class="built_in">std</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> <span class="keyword">int</span> maxn = <span class="number">100</span>; <span class="comment">// 最大顶点数</span></span><br><span class="line"><span class="keyword">int</span> <span class="built_in">map</span>[maxn][maxn]; <span class="comment">// 邻接矩阵存图</span></span><br><span class="line"><span class="keyword">int</span> dis[maxn]; <span class="comment">// dist[i]表示距离源点的最短距离</span></span><br><span class="line"><span class="keyword">int</span> vis[maxn];  <span class="comment">// vis[i] = 1表示已加入集合S</span></span><br><span class="line"><span class="keyword">int</span> path[maxn]; <span class="comment">// 记录路径</span></span><br><span class="line"><span class="keyword">int</span> n, m, r;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">dijk</span><span class="params">(<span class="keyword">int</span> s)</span> <span class="comment">// 求顶点s到其他顶点的最短路径</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line"><span class="comment">//初始化</span></span><br><span class="line"><span class="built_in">memset</span>(path, <span class="number">-1</span>, <span class="keyword">sizeof</span>(path));</span><br><span class="line"><span class="comment">/*INF使用0x3f3f3f3f的好处：</span></span><br><span class="line"><span class="comment">* 1：满足无穷大加一个有穷的数依然是无穷大（在DijKstra算法松弛操作中避免了溢出而出现负数）</span></span><br><span class="line"><span class="comment">* 2：满足无穷大加无穷大依然是无穷大（两个0x3f3f3f3f相加并未溢出）</span></span><br><span class="line"><span class="comment">* 3：初始化时，由于每一个字节为0x3f，所以只需要memset（buf，0x3f,sizeof(buf)）即可</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="built_in">memset</span>(dis, <span class="number">0x3f</span>, <span class="keyword">sizeof</span>(dis)); <span class="comment">//初始化为无穷大</span></span><br><span class="line"><span class="built_in">memset</span>(vis, <span class="number">0</span>, <span class="keyword">sizeof</span>(vis));</span><br><span class="line">dis[s] = <span class="number">0</span>; <span class="comment">//自身到自身的距离为0</span></span><br><span class="line"><span class="keyword">while</span> (<span class="number">1</span>)</span><br><span class="line">&#123;</span><br><span class="line"><span class="keyword">int</span> k = <span class="number">0</span>;</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">int</span> j = <span class="number">1</span>; j &lt;= n; j++)</span><br><span class="line">&#123;</span><br><span class="line"><span class="keyword">if</span> (!vis[j] &amp;&amp; dis[j]&lt;dis[k])<span class="comment">//找未收录顶点中dis值最小的</span></span><br><span class="line">k = j; <span class="comment">//这里第一次找到的是起点</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">if</span> (!k) <span class="keyword">return</span>; <span class="comment">//没有未收录的点，则返回</span></span><br><span class="line">vis[k] = <span class="number">1</span>;</span><br><span class="line"><span class="comment">//松弛操作</span></span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">int</span> j = <span class="number">1</span>; j &lt;= n; j++)</span><br><span class="line">&#123;</span><br><span class="line"><span class="comment">//第一次循环只有起点的邻接点距离被更新，每次都更新新找到的点的邻接点</span></span><br><span class="line"><span class="keyword">if</span> (dis[j]&gt;dis[k] + <span class="built_in">map</span>[k][j])</span><br><span class="line">&#123;</span><br><span class="line">dis[j] = dis[k] + <span class="built_in">map</span>[k][j];</span><br><span class="line">path[j] = k;<span class="comment">//路径被改变，重新记录前驱，最短路是由最短路+某一条固定路组成，所以前驱是有效的</span></span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">printPath</span><span class="params">(<span class="keyword">int</span> x)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line"><span class="keyword">if</span> (x == <span class="number">-1</span>) </span><br><span class="line"><span class="keyword">return</span>;</span><br><span class="line"><span class="comment">//递归</span></span><br><span class="line">printPath(path[x]);</span><br><span class="line"><span class="keyword">if</span> (x == r) </span><br><span class="line"><span class="built_in">cout</span> &lt;&lt; x;</span><br><span class="line"><span class="keyword">else</span> </span><br><span class="line"><span class="built_in">cout</span> &lt;&lt; <span class="string">" -&gt; "</span> &lt;&lt; x;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">/*问题描述：</span></span><br><span class="line"><span class="comment">* 输入n,m和r，代表n个节点，m条边，出发点r，然后是m行输入，每行有x,y,z，代表x到y的路距离为z。</span></span><br><span class="line"><span class="comment">* 问题：从r出发到各点的最短路径。</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line"><span class="built_in">cin</span> &gt;&gt; n &gt;&gt; m &gt;&gt; r;</span><br><span class="line"></span><br><span class="line"><span class="built_in">memset</span>(<span class="built_in">map</span>, <span class="number">0x3f</span>, <span class="keyword">sizeof</span>(<span class="built_in">map</span>));</span><br><span class="line"></span><br><span class="line"><span class="keyword">int</span> x, y, z;</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">1</span>; i &lt;= m; i++)</span><br><span class="line">&#123;</span><br><span class="line"><span class="built_in">cin</span> &gt;&gt; x &gt;&gt; y &gt;&gt; z;</span><br><span class="line"><span class="keyword">if</span> (<span class="built_in">map</span>[x][y] &gt; z)&#123; <span class="comment">// 防止1-&gt;1的环</span></span><br><span class="line"><span class="built_in">map</span>[x][y] = z;</span><br><span class="line"><span class="comment">//map[y][x] = z; // 无向图</span></span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">dijk(r);</span><br><span class="line"></span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">1</span>; i &lt;= n; i++)&#123;</span><br><span class="line">printPath(i);</span><br><span class="line"><span class="built_in">cout</span>&lt;&lt; <span class="string">" "</span>&lt;&lt; dis[i];</span><br><span class="line"><span class="built_in">cout</span>&lt;&lt; <span class="built_in">endl</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p><img src="https://img-blog.csdnimg.cn/20191121111932365.png" alt="在这里插入图片描述"><br><a href="https://www.jianshu.com/p/ff6db00ad866" target="_blank" rel="noopener">算法详解</a> <a href="https://blog.csdn.net/lbperfect123/article/details/84281300" target="_blank" rel="noopener">算法详解</a> 时间复杂度为O( n^2)</p><h1 id="六、0-1背包问题"><a href="#六、0-1背包问题" class="headerlink" title="六、0/1背包问题"></a>六、0/1背包问题</h1><p><img src="https://img-blog.csdnimg.cn/20191121112640282.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZmY2pqaHY=,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"><br>0/1背包问题:满足总重量&lt;=背包重量限制，使价值最大。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;iostream&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;vector&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;algorithm&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> <span class="built_in">std</span>;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">ZeroOnePack</span><span class="params">(<span class="keyword">int</span> m, <span class="keyword">int</span> s, <span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; weight, <span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; value)</span> </span>&#123;</span><br><span class="line"><span class="comment">// F[i ][ v] 表示  前i件物品恰放入一个容量恰为v的背包可以获得的最大价值</span></span><br><span class="line"><span class="built_in">vector</span>&lt;<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; &gt; F(m + <span class="number">1</span>, <span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt;(s + <span class="number">1</span>));</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i &lt;= s; i++) &#123;</span><br><span class="line">F[<span class="number">0</span>][i] = <span class="number">0</span>; <span class="comment">//如果要求恰好装满背包，除了F[0]为0，其余F[1 .. s]均设为-INF</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">1</span>; i &lt;= m; i++)&#123;</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">int</span> j = <span class="number">0</span>; j &lt;= s; j++)&#123;</span><br><span class="line"><span class="keyword">if</span> (j &gt;= weight[i - <span class="number">1</span>])</span><br><span class="line">F[i][j] = max(F[i - <span class="number">1</span>][j], F[i - <span class="number">1</span>][j - weight[i - <span class="number">1</span>]] + value[i - <span class="number">1</span>]);</span><br><span class="line"><span class="keyword">else</span></span><br><span class="line">F[i][j] = F[i - <span class="number">1</span>][j];</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//打印哪几样物品能够获得最大价值</span></span><br><span class="line"><span class="built_in">vector</span>&lt;<span class="keyword">bool</span>&gt; isAdd(m,<span class="literal">false</span>);</span><br><span class="line"><span class="keyword">int</span> j = s;</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">int</span> i = m; i &gt;= <span class="number">1</span>; i--)&#123;</span><br><span class="line"><span class="keyword">if</span> (F[i][j] != F[i - <span class="number">1</span>][j])&#123;</span><br><span class="line">isAdd[i - <span class="number">1</span>] = <span class="literal">true</span>;</span><br><span class="line">j = j - weight[i - <span class="number">1</span>];</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; m; i++)&#123;</span><br><span class="line"><span class="built_in">cout</span> &lt;&lt; isAdd[i] &lt;&lt; <span class="string">" "</span>;</span><br><span class="line">&#125;</span><br><span class="line"><span class="built_in">cout</span> &lt;&lt; <span class="built_in">endl</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">return</span> F[m][s];</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span> </span>&#123;</span><br><span class="line"><span class="keyword">int</span> m, s; <span class="comment">// 物品种类m，背包总空间t，求最大价值</span></span><br><span class="line"><span class="built_in">cin</span> &gt;&gt; m &gt;&gt; s;</span><br><span class="line"></span><br><span class="line"><span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; weight;</span><br><span class="line"><span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; value;</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; m; i++)&#123;</span><br><span class="line"><span class="keyword">int</span> t1, t2;</span><br><span class="line"><span class="built_in">cin</span> &gt;&gt; t1 &gt;&gt; t2;</span><br><span class="line">weight.push_back(t1);</span><br><span class="line">value.push_back(t2);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">int</span> res = ZeroOnePack(m, s, weight, value);</span><br><span class="line"><span class="built_in">cout</span> &lt;&lt; res &lt;&lt; <span class="built_in">endl</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p><img src="https://img-blog.csdnimg.cn/20191121171129285.png" alt="在这里插入图片描述"><br><a href="https://blog.csdn.net/u013885699/article/details/80248536" target="_blank" rel="noopener">算法详解</a> </p>]]></content>
    
    <summary type="html">
    
      &lt;h2 id=&quot;目录&quot;&gt;&lt;a href=&quot;#目录&quot; class=&quot;headerlink&quot; title=&quot;目录&quot;&gt;&lt;/a&gt;目录&lt;/h2&gt;&lt;p&gt;一、七大排序算法&lt;br&gt;二、大整数计算&lt;br&gt;三、编kmp辑距离问题&lt;br&gt;四、kmp算法&lt;br&gt;五、dijkstra算法&lt;br&gt;六、0/1背包问题&lt;/p&gt;
&lt;h1 id=&quot;一、七大排序算法&quot;&gt;&lt;a href=&quot;#一、七大排序算法&quot; class=&quot;headerlink&quot; title=&quot;一、七大排序算法&quot;&gt;&lt;/a&gt;一、七大排序算法&lt;/h1&gt;
    
    </summary>
    
      <category term="C++" scheme="http://yoursite.com/categories/C/"/>
    
      <category term="后台开发" scheme="http://yoursite.com/categories/%E5%90%8E%E5%8F%B0%E5%BC%80%E5%8F%91/"/>
    
      <category term="CodeCode" scheme="http://yoursite.com/categories/CodeCode/"/>
    
    
      <category term="C++" scheme="http://yoursite.com/tags/C/"/>
    
      <category term="排序算法" scheme="http://yoursite.com/tags/%E6%8E%92%E5%BA%8F%E7%AE%97%E6%B3%95/"/>
    
      <category term="大整数计算" scheme="http://yoursite.com/tags/%E5%A4%A7%E6%95%B4%E6%95%B0%E8%AE%A1%E7%AE%97/"/>
    
      <category term="编辑距离" scheme="http://yoursite.com/tags/%E7%BC%96%E8%BE%91%E8%B7%9D%E7%A6%BB/"/>
    
      <category term="Kmp" scheme="http://yoursite.com/tags/Kmp/"/>
    
      <category term="Dijkstra" scheme="http://yoursite.com/tags/Dijkstra/"/>
    
      <category term="0/1背包" scheme="http://yoursite.com/tags/0-1%E8%83%8C%E5%8C%85/"/>
    
  </entry>
  
  <entry>
    <title>刷题汇总（二）剑指Offer 66题 C++答案总结</title>
    <link href="http://yoursite.com/2019/08/01/23/"/>
    <id>http://yoursite.com/2019/08/01/23/</id>
    <published>2019-08-01T03:32:27.000Z</published>
    <updated>2019-12-18T04:18:44.657Z</updated>
    
    <content type="html"><![CDATA[<h3 id="题目来源"><a href="#题目来源" class="headerlink" title="题目来源"></a>题目来源</h3><p> <a href="https://www.nowcoder.com/ta/coding-interviews?page=1" target="_blank" rel="noopener">剑指Offer 66题</a></p><p>相关：<br><a href="https://blog.csdn.net/ffcjjhv/article/details/88409676" target="_blank" rel="noopener">刷题汇总（一）leetcode 精选50题 JavaScript答案总结</a><br><a href="https://blog.csdn.net/ffcjjhv/article/details/100104411" target="_blank" rel="noopener">刷题汇总（三）leetcode 精选50题 C++答案总结</a><br><a href="https://blog.csdn.net/ffcjjhv/article/details/103195691" target="_blank" rel="noopener">刷题汇总（四）技术类编程题汇总 C++</a><br><a href="https://blog.csdn.net/ffcjjhv/article/details/103381516" target="_blank" rel="noopener">刷题汇总（五）leetcode 热题 HOT 100 C++ 答案总结</a><br><a href="https://blog.csdn.net/ffcjjhv/article/details/103503745" target="_blank" rel="noopener">刷题汇总（六）leetcode 多线程 / Shell</a></p><p><a href="https://pan.baidu.com/s/1fHto2ckVlwQzgUi8TxYReA" target="_blank" rel="noopener">PDF版 code</a>  （提取码：0wxr ）</p><h1 id="1、二维数组中的查找"><a href="#1、二维数组中的查找" class="headerlink" title="1、二维数组中的查找"></a>1、二维数组中的查找</h1><p>在一个二维数组中（每个一维数组的长度相同），每一行都按照从左到右递增的顺序排序，每一列都按照从上到下递增的顺序排序。请完成一个函数，输入这样的一个二维数组和一个整数，判断数组中是否含有该整数。</p><a id="more"></a><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/* </span></span><br><span class="line"><span class="comment"> 3 4 5</span></span><br><span class="line"><span class="comment"> 4 5 6</span></span><br><span class="line"><span class="comment"> 6 7 8</span></span><br><span class="line"><span class="comment"> 从左下角开始查找，当target比左下角数字大时，右移；小时，上移</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function"><span class="keyword">bool</span> <span class="title">Find</span><span class="params">(<span class="keyword">int</span> target, <span class="built_in">vector</span>&lt;<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; &gt; <span class="built_in">array</span>)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">int</span> rows = <span class="built_in">array</span>.size(), cols = <span class="built_in">array</span>[<span class="number">0</span>].size();</span><br><span class="line">        <span class="keyword">int</span> i = rows - <span class="number">1</span>, j = <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">while</span>(i&gt;=<span class="number">0</span>&amp;&amp;j&lt;cols)&#123;</span><br><span class="line">            <span class="keyword">if</span>(<span class="built_in">array</span>[i][j] == target) <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line">            <span class="keyword">else</span> <span class="keyword">if</span>(<span class="built_in">array</span>[i][j] &gt; target) i--;</span><br><span class="line">            <span class="keyword">else</span> j++;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="2、替换空格"><a href="#2、替换空格" class="headerlink" title="2、替换空格"></a>2、替换空格</h1><p>请实现一个函数，将一个字符串中的每个空格替换成“%20”。例如，当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment"> 从前往后替换，后面的字符要多次移动，效率低下</span></span><br><span class="line"><span class="comment"> 从后往前，先计算需要多少空间，每个字符只移动一次，效率更高</span></span><br><span class="line"><span class="comment"> 例如：a b c</span></span><br><span class="line"><span class="comment"> 从后往前，当前第i位为'c'（非空格），前有n个空格，则i+2*n位为c</span></span><br><span class="line"><span class="comment"> 当前第i位为' '（空格）,前有n个空格，则i+2*n位为%，i+2*n+1位为2，i+2*n+2位为0</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">replaceSpace</span><span class="params">(<span class="keyword">char</span> *str,<span class="keyword">int</span> length)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">int</span> sum = <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;length;i++)&#123;</span><br><span class="line">            <span class="keyword">if</span>(str[i] == <span class="string">' '</span>) sum++;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i=length<span class="number">-1</span>;i&gt;=<span class="number">0</span>;i--)&#123;</span><br><span class="line">            <span class="keyword">if</span>(str[i] != <span class="string">' '</span>) str[i + <span class="number">2</span>*sum] = str[i];</span><br><span class="line">            <span class="keyword">else</span>&#123;</span><br><span class="line">                sum--;</span><br><span class="line">                str[i + <span class="number">2</span>*sum] = <span class="string">'%'</span>;</span><br><span class="line">                str[i + <span class="number">2</span>*sum + <span class="number">1</span>] = <span class="string">'2'</span>;</span><br><span class="line">                str[i + <span class="number">2</span>*sum + <span class="number">2</span>] = <span class="string">'0'</span>;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br><span class="line">`</span><br></pre></td></tr></table></figure><h1 id="3、从尾到头打印链表"><a href="#3、从尾到头打印链表" class="headerlink" title="3、从尾到头打印链表"></a>3、从尾到头打印链表</h1><p>输入一个链表，按链表值从尾到头的顺序返回一个ArrayList。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment">*  struct ListNode &#123;</span></span><br><span class="line"><span class="comment">*        int val;</span></span><br><span class="line"><span class="comment">*        struct ListNode *next;</span></span><br><span class="line"><span class="comment">*        ListNode(int x) :</span></span><br><span class="line"><span class="comment">*              val(x), next(NULL) &#123;</span></span><br><span class="line"><span class="comment">*        &#125;</span></span><br><span class="line"><span class="comment">*  &#125;;</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; printListFromTailToHead(ListNode* head) &#123;</span><br><span class="line">        <span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; res;</span><br><span class="line">        <span class="built_in">stack</span>&lt;<span class="keyword">int</span>&gt; <span class="built_in">stack</span>;</span><br><span class="line">        <span class="keyword">while</span>(head)&#123;</span><br><span class="line">            <span class="built_in">stack</span>.push(head-&gt;val);</span><br><span class="line">            head = head-&gt;next;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">while</span>(!<span class="built_in">stack</span>.empty())&#123;</span><br><span class="line">            res.push_back(<span class="built_in">stack</span>.top());</span><br><span class="line">            <span class="built_in">stack</span>.pop();</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="4、重建二叉树"><a href="#4、重建二叉树" class="headerlink" title="4、重建二叉树"></a>4、重建二叉树</h1><p>输入某二叉树的前序遍历和中序遍历的结果，请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6}，则重建二叉树并返回。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment"> 前序遍历序列&#123;1,2,4,7,3,5,6,8&#125; 1是根元素</span></span><br><span class="line"><span class="comment"> 中序遍历序列&#123;4,7,2,1,5,3,8,6&#125; 1之前4,7,2是左子树中序，之后5,3,8,6是右子树中序</span></span><br><span class="line"><span class="comment"> 前序中1后的3个是左子树前序，之后是右子树前序</span></span><br><span class="line"><span class="comment"> 问题转换为根元素已知，求左子树和右子树的重建二叉树，进行递归</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Definition for binary tree</span></span><br><span class="line"><span class="comment"> * struct TreeNode &#123;</span></span><br><span class="line"><span class="comment"> *     int val;</span></span><br><span class="line"><span class="comment"> *     TreeNode *left;</span></span><br><span class="line"><span class="comment"> *     TreeNode *right;</span></span><br><span class="line"><span class="comment"> *     TreeNode(int x) : val(x), left(NULL), right(NULL) &#123;&#125;</span></span><br><span class="line"><span class="comment"> * &#125;;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function">TreeNode* <span class="title">reConstructBinaryTree</span><span class="params">(<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; pre,<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; vin)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> buildtree(pre,vin,<span class="number">0</span>,pre.size()<span class="number">-1</span>,<span class="number">0</span>,vin.size()<span class="number">-1</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="function">TreeNode* <span class="title">buildtree</span><span class="params">(<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; pre,<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; vin,<span class="keyword">int</span> pl,<span class="keyword">int</span> pr,<span class="keyword">int</span> vl,<span class="keyword">int</span> vr)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">if</span>(pl &gt; pr || vl &gt; vr) <span class="keyword">return</span> <span class="literal">NULL</span>;</span><br><span class="line">        TreeNode* root = <span class="keyword">new</span> TreeNode(pre[pl]);</span><br><span class="line">        <span class="keyword">int</span> i;</span><br><span class="line">        <span class="keyword">for</span>(i=vl;i&lt;=vr;i++)&#123;</span><br><span class="line">            <span class="keyword">if</span>(vin[i] == pre[pl]) <span class="keyword">break</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">int</span> num = i - vl; <span class="comment">//左子树个数</span></span><br><span class="line">        root-&gt;left =  buildtree(pre,vin,pl+<span class="number">1</span>,pl+num,vl,vl+num<span class="number">-1</span>);</span><br><span class="line">        root-&gt;right =  buildtree(pre,vin,pl+num+<span class="number">1</span>,pr,vl+num+<span class="number">1</span>,vr);</span><br><span class="line">        <span class="keyword">return</span> root;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="5、用两个栈实现队列"><a href="#5、用两个栈实现队列" class="headerlink" title="5、用两个栈实现队列"></a>5、用两个栈实现队列</h1><p>用两个栈来实现一个队列，完成队列的Push和Pop操作。 队列中的元素为int类型。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment"> 用两个栈实现一个队列的功能</span></span><br><span class="line"><span class="comment"> 入队：将元素进栈A</span></span><br><span class="line"><span class="comment"> 出队：判断栈B是否为空，如果为空，则将栈A中所有元素pop，并push进栈B，栈B出栈；</span></span><br><span class="line"><span class="comment"> 如果不为空，栈B直接出栈。</span></span><br><span class="line"><span class="comment"> </span></span><br><span class="line"><span class="comment"> 用两个队列实现一个栈的功能</span></span><br><span class="line"><span class="comment"> 入栈：将元素进队列A</span></span><br><span class="line"><span class="comment"> 出栈：判断队列A中元素的个数是否为1，如果等于1，则出队列，否则将队列A中的元素依次出队列并放入队列B，直到队列A中的元素留下一个，然后队列A出队列，再把队列B中的元素出队列以此放入队列A中。</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span></span></span><br><span class="line"><span class="class">&#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">push</span><span class="params">(<span class="keyword">int</span> node)</span> </span>&#123;</span><br><span class="line">        stack1.push(node);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">int</span> <span class="title">pop</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">while</span>(!stack1.empty())&#123;</span><br><span class="line">            stack2.push(stack1.top());</span><br><span class="line">            stack1.pop();</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">int</span> res = stack2.top();</span><br><span class="line">        stack2.pop();</span><br><span class="line">        <span class="keyword">while</span>(!stack2.empty())&#123;</span><br><span class="line">            stack1.push(stack2.top());</span><br><span class="line">            stack2.pop();</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line"><span class="keyword">private</span>:</span><br><span class="line">    <span class="built_in">stack</span>&lt;<span class="keyword">int</span>&gt; stack1;</span><br><span class="line">    <span class="built_in">stack</span>&lt;<span class="keyword">int</span>&gt; stack2;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="6、旋转数组的最小数字"><a href="#6、旋转数组的最小数字" class="headerlink" title="6、旋转数组的最小数字"></a>6、旋转数组的最小数字</h1><p>把一个数组最开始的若干个元素搬到数组的末尾，我们称之为数组的旋转。 输入一个非减排序的数组的一个旋转，输出旋转数组的最小元素。 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转，该数组的最小值为1。 NOTE：给出的所有元素都大于0，若数组大小为0，请返回0。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function"><span class="keyword">int</span> <span class="title">minNumberInRotateArray</span><span class="params">(<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; rotateArray)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">if</span>(rotateArray.size() == <span class="number">0</span>) <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">int</span> i = <span class="number">0</span>, j = rotateArray.size()<span class="number">-1</span>;</span><br><span class="line">        <span class="keyword">while</span>(i &lt; j)&#123;</span><br><span class="line">            <span class="keyword">int</span> mid = (i + j)/<span class="number">2</span>;</span><br><span class="line">            <span class="keyword">if</span>(rotateArray[mid] &gt; rotateArray[j])&#123; </span><br><span class="line">                i = mid + <span class="number">1</span>; <span class="comment">//3 4 7 8 1 2  旋转点在右，左顺序</span></span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">else</span> <span class="keyword">if</span>(rotateArray[mid] &lt; rotateArray[j])&#123; </span><br><span class="line">                j = mid; <span class="comment">//7 8 1 2 3 4  旋转点在左，右顺序</span></span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">else</span>&#123; <span class="comment">//1 0 1 1 1  或  1 1 1 0 1 顺序部分为常数</span></span><br><span class="line">                i ++; <span class="comment">//或 j --;</span></span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> rotateArray[i];</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="7、斐波那契数列"><a href="#7、斐波那契数列" class="headerlink" title="7、斐波那契数列"></a>7、斐波那契数列</h1><p>大家都知道斐波那契数列，现在要求输入一个整数n，请你输出斐波那契数列的第n项（从0开始，第0项为0）。<br>n&lt;=39</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function"><span class="keyword">int</span> <span class="title">Fibonacci</span><span class="params">(<span class="keyword">int</span> n)</span> </span>&#123; <span class="comment">//0 1 1 2 3 5 …,使用动态规划</span></span><br><span class="line">        <span class="keyword">int</span> i = <span class="number">0</span>, j = <span class="number">1</span>;</span><br><span class="line">        <span class="keyword">while</span>(n&gt;<span class="number">0</span>)&#123;</span><br><span class="line">            <span class="keyword">int</span> tmp = j;</span><br><span class="line">            j = i+j;</span><br><span class="line">            i = tmp;</span><br><span class="line">            n--;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> i;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="8、跳台阶"><a href="#8、跳台阶" class="headerlink" title="8、跳台阶"></a>8、跳台阶</h1><p>一只青蛙一次可以跳上1级台阶，也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法（先后次序不同算不同的结果）。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment"> 最后一步跳1，有f(n-1)种情况</span></span><br><span class="line"><span class="comment"> 最后一步跳2，有f(n-2)种情况</span></span><br><span class="line"><span class="comment"> 共f(n)=f(n-1)+f(n-2)，1 1 2 3 5（斐波那契数列）使用动态规划</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function"><span class="keyword">int</span> <span class="title">jumpFloor</span><span class="params">(<span class="keyword">int</span> number)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">int</span> i = <span class="number">1</span>, j = <span class="number">1</span>;</span><br><span class="line">        <span class="keyword">while</span>(number&gt;<span class="number">0</span>)&#123;</span><br><span class="line">            <span class="keyword">int</span> tmp = j;</span><br><span class="line">            j = i + j;</span><br><span class="line">            i = tmp;</span><br><span class="line">            number--;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> i;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="9、变态跳台阶"><a href="#9、变态跳台阶" class="headerlink" title="9、变态跳台阶"></a>9、变态跳台阶</h1><p>一只青蛙一次可以跳上1级台阶，也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//f(n) = f(1) + f(2) + f(3) +...+ f(n-1) + 1</span></span><br><span class="line"><span class="comment">//1 2 4 8 ...</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function"><span class="keyword">int</span> <span class="title">jumpFloorII</span><span class="params">(<span class="keyword">int</span> number)</span> </span>&#123;</span><br><span class="line">        <span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; step;</span><br><span class="line">        <span class="keyword">while</span>(number&gt;<span class="number">0</span>)&#123;</span><br><span class="line">            <span class="keyword">int</span> sum = <span class="number">0</span>;</span><br><span class="line">            <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;step.size();i++)&#123;</span><br><span class="line">                sum += step[i];</span><br><span class="line">            &#125;</span><br><span class="line">            step.push_back(sum+<span class="number">1</span>); </span><br><span class="line">            number--;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> step.back();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment">class Solution &#123;</span></span><br><span class="line"><span class="comment">public:</span></span><br><span class="line"><span class="comment">    int jumpFloorII(int number) &#123;</span></span><br><span class="line"><span class="comment">        int res = 1;</span></span><br><span class="line"><span class="comment">        for(int i=1;i&lt;number;i++)&#123;</span></span><br><span class="line"><span class="comment">            res += jumpFloorII(i);</span></span><br><span class="line"><span class="comment">        &#125;</span></span><br><span class="line"><span class="comment">        return res;</span></span><br><span class="line"><span class="comment">    &#125;</span></span><br><span class="line"><span class="comment">&#125;;</span></span><br><span class="line"><span class="comment">*/</span></span><br></pre></td></tr></table></figure><h1 id="10、矩形覆盖"><a href="#10、矩形覆盖" class="headerlink" title="10、矩形覆盖"></a>10、矩形覆盖</h1><p>我们可以用2*1的小矩形横着或者竖着去覆盖更大的矩形。请问用n个2*1的小矩形无重叠地覆盖一个2*n的大矩形，总共有多少种方法？</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment">|    | | |   f(n-1)</span></span><br><span class="line"><span class="comment">|    | | |</span></span><br><span class="line"><span class="comment"> </span></span><br><span class="line"><span class="comment">— —    | |   f(n-2)</span></span><br><span class="line"><span class="comment">— —    | |</span></span><br><span class="line"><span class="comment">f(n) = f(n-1) + f(n-2),1 2 3 5 8…,动态规划</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function"><span class="keyword">int</span> <span class="title">rectCover</span><span class="params">(<span class="keyword">int</span> number)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">if</span>(number == <span class="number">0</span>) <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">int</span> i = <span class="number">1</span>, j = <span class="number">1</span>;</span><br><span class="line">        <span class="keyword">while</span>(number&gt;<span class="number">0</span>)&#123;</span><br><span class="line">            <span class="keyword">int</span> tmp = j;</span><br><span class="line">            j = i + j;</span><br><span class="line">            i = tmp;</span><br><span class="line">            number--;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> i;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="11、二进制中1的个数"><a href="#11、二进制中1的个数" class="headerlink" title="11、二进制中1的个数"></a>11、二进制中1的个数</h1><p>输入一个整数，输出该数二进制表示中1的个数。其中负数用补码表示。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment"> 将n与n-1相与会把n的最右边的1变为0，比如</span></span><br><span class="line"><span class="comment"> 1100&amp;1011 = 1000</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">     <span class="function"><span class="keyword">int</span>  <span class="title">NumberOf1</span><span class="params">(<span class="keyword">int</span> n)</span> </span>&#123;</span><br><span class="line">         <span class="keyword">int</span> res=<span class="number">0</span>;</span><br><span class="line">         <span class="keyword">while</span>(n!=<span class="number">0</span>)&#123;</span><br><span class="line">             res++;</span><br><span class="line">             n = n&amp;(n<span class="number">-1</span>);</span><br><span class="line">         &#125;</span><br><span class="line">         <span class="keyword">return</span> res;</span><br><span class="line">     &#125;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment"> #include &lt;bitset&gt;</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">     <span class="function"><span class="keyword">int</span>  <span class="title">NumberOf1</span><span class="params">(<span class="keyword">int</span> n)</span> </span>&#123;</span><br><span class="line">         <span class="built_in">bitset</span>&lt;32&gt;a(n); <span class="comment">//32位的2进制</span></span><br><span class="line">         <span class="keyword">return</span> a.count(); <span class="comment">//返回1的个数</span></span><br><span class="line">     &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="12、数值的整数次方"><a href="#12、数值的整数次方" class="headerlink" title="12、数值的整数次方"></a>12、数值的整数次方</h1><p>给定一个double类型的浮点数base和int类型的整数exponent。求base的exponent次方。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment"> 10^1101 = 10^0001*10^0100*10^1000，即base*1 * base^2 * base^4 * …</span></span><br><span class="line"><span class="comment"> 通过&amp;1和&gt;&gt;1来逐位读取1101</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function"><span class="keyword">double</span> <span class="title">Power</span><span class="params">(<span class="keyword">double</span> base, <span class="keyword">int</span> exponent)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">double</span> res = <span class="number">1</span>;</span><br><span class="line">        <span class="keyword">int</span> e = <span class="built_in">abs</span>(exponent);</span><br><span class="line">        <span class="keyword">while</span>(e!=<span class="number">0</span>)&#123;</span><br><span class="line">            <span class="keyword">if</span>(e&amp;<span class="number">1</span> == <span class="number">1</span>)&#123;</span><br><span class="line">                res *= base;</span><br><span class="line">            &#125;</span><br><span class="line">            base *= base;</span><br><span class="line">            e = e&gt;&gt;<span class="number">1</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> exponent&gt;<span class="number">0</span>?res:<span class="number">1</span>/res;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="13、调整数组顺序使奇数位于偶数前面"><a href="#13、调整数组顺序使奇数位于偶数前面" class="headerlink" title="13、调整数组顺序使奇数位于偶数前面"></a>13、调整数组顺序使奇数位于偶数前面</h1><p>输入一个整数数组，实现一个函数来调整该数组中数字的顺序，使得所有的奇数位于数组的前半部分，所有的偶数位于数组的后半部分，并保证奇数和奇数，偶数和偶数之间的相对位置不变。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment"> 要想保证原有次序，则只能顺次移动或相邻交换。</span></span><br><span class="line"><span class="comment"> 1.i从左向右遍历，找到第一个偶数。</span></span><br><span class="line"><span class="comment"> 2.j从i+1开始向后找，找到第一个奇数。</span></span><br><span class="line"><span class="comment"> 3.将[i,...,j-1]的元素整体后移一位，将找到的奇数放入i位置</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">reOrderArray</span><span class="params">(<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; &amp;<span class="built_in">array</span>)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;<span class="built_in">array</span>.size();i++)&#123;</span><br><span class="line">            <span class="keyword">if</span>(<span class="built_in">array</span>[i]%<span class="number">2</span> == <span class="number">0</span>)&#123;</span><br><span class="line">                <span class="keyword">for</span>(<span class="keyword">int</span> j=i+<span class="number">1</span>;j&lt;<span class="built_in">array</span>.size();j++)&#123;</span><br><span class="line">                    <span class="keyword">if</span>(<span class="built_in">array</span>[j]%<span class="number">2</span> == <span class="number">1</span>)&#123;</span><br><span class="line">                        <span class="keyword">int</span> tmp = <span class="built_in">array</span>[j];</span><br><span class="line">                        <span class="keyword">for</span>(<span class="keyword">int</span> k=j<span class="number">-1</span>;k&gt;=i;k--)&#123;</span><br><span class="line">                            <span class="built_in">array</span>[k+<span class="number">1</span>] = <span class="built_in">array</span>[k];</span><br><span class="line">                        &#125;</span><br><span class="line">                        <span class="built_in">array</span>[i] = tmp;</span><br><span class="line">                        <span class="keyword">break</span>;</span><br><span class="line">                    &#125;</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="14、链表中倒数第k个结点"><a href="#14、链表中倒数第k个结点" class="headerlink" title="14、链表中倒数第k个结点"></a>14、链表中倒数第k个结点</h1><p>输入一个链表，输出该链表中倒数第k个结点。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment">struct ListNode &#123;</span></span><br><span class="line"><span class="comment">int val;</span></span><br><span class="line"><span class="comment">struct ListNode *next;</span></span><br><span class="line"><span class="comment">ListNode(int x) :</span></span><br><span class="line"><span class="comment">val(x), next(NULL) &#123;</span></span><br><span class="line"><span class="comment">&#125;</span></span><br><span class="line"><span class="comment">&#125;;*/</span></span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment"> 两指针指向头结点，</span></span><br><span class="line"><span class="comment"> 第一个指针走(k-1)步，到k节点</span></span><br><span class="line"><span class="comment"> 两个指针同时往后移动，当第一个结点到达末尾的时候，第二个结点所在位置就是倒数第k个节点</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function">ListNode* <span class="title">FindKthToTail</span><span class="params">(ListNode* pListHead, <span class="keyword">unsigned</span> <span class="keyword">int</span> k)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">if</span>(!pListHead || k==<span class="number">0</span>) <span class="keyword">return</span> <span class="literal">NULL</span>;</span><br><span class="line">        ListNode* node1 = pListHead;</span><br><span class="line">        ListNode* node2 = pListHead;</span><br><span class="line">        <span class="keyword">int</span> i = <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">while</span>(node1)&#123;</span><br><span class="line">            <span class="keyword">if</span>(i&gt;=k)&#123;</span><br><span class="line">                node2 = node2 -&gt; next;</span><br><span class="line">            &#125;</span><br><span class="line">            node1 = node1 -&gt; next;</span><br><span class="line">            i++;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> i&lt;k ? <span class="literal">NULL</span> : node2;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="15、反转链表"><a href="#15、反转链表" class="headerlink" title="15、反转链表"></a>15、反转链表</h1><p>输入一个链表，反转链表后，输出新链表的表头。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment">struct ListNode &#123;</span></span><br><span class="line"><span class="comment">int val;</span></span><br><span class="line"><span class="comment">struct ListNode *next;</span></span><br><span class="line"><span class="comment">ListNode(int x) :</span></span><br><span class="line"><span class="comment">val(x), next(NULL) &#123;</span></span><br><span class="line"><span class="comment">&#125;</span></span><br><span class="line"><span class="comment">&#125;;*/</span></span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment">1 2 3 4 5</span></span><br><span class="line"><span class="comment">遍历链表，当前值为4时，相当于新建值为4的链表node，node-&gt;next = 前面链表反转，node即为所求</span></span><br><span class="line"><span class="comment">当前值为5时，相当于新建值为5的链表node，node-&gt;next = 上一步的值</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function">ListNode* <span class="title">ReverseList</span><span class="params">(ListNode* pHead)</span> </span>&#123;</span><br><span class="line">        ListNode* res = <span class="literal">NULL</span>;</span><br><span class="line">        <span class="keyword">while</span>(pHead)&#123;</span><br><span class="line">            ListNode* tmp = <span class="keyword">new</span> ListNode(pHead-&gt;val);</span><br><span class="line">            tmp -&gt; next = res;</span><br><span class="line">            res = tmp;</span><br><span class="line">            pHead = pHead -&gt; next;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">//原地修改</span></span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment">struct ListNode &#123;</span></span><br><span class="line"><span class="comment">int val;</span></span><br><span class="line"><span class="comment">struct ListNode *next;</span></span><br><span class="line"><span class="comment">ListNode(int x) :</span></span><br><span class="line"><span class="comment">val(x), next(NULL) &#123;</span></span><br><span class="line"><span class="comment">&#125;</span></span><br><span class="line"><span class="comment">&#125;;*/</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function">ListNode* <span class="title">ReverseList</span><span class="params">(ListNode* pHead)</span> </span>&#123;</span><br><span class="line">        ListNode* res = <span class="literal">NULL</span>;</span><br><span class="line">        <span class="keyword">while</span>(pHead)&#123;</span><br><span class="line">            ListNode* tmp = pHead-&gt;next;</span><br><span class="line">            pHead-&gt;next = res;</span><br><span class="line">            res = pHead;</span><br><span class="line">            pHead = tmp;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="16、合并两个排序的链表"><a href="#16、合并两个排序的链表" class="headerlink" title="16、合并两个排序的链表"></a>16、合并两个排序的链表</h1><p>输入两个单调递增的链表，输出两个链表合成后的链表，当然我们需要合成后的链表满足单调不减规则。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment">struct ListNode &#123;</span></span><br><span class="line"><span class="comment">int val;</span></span><br><span class="line"><span class="comment">struct ListNode *next;</span></span><br><span class="line"><span class="comment">ListNode(int x) :</span></span><br><span class="line"><span class="comment">val(x), next(NULL) &#123;</span></span><br><span class="line"><span class="comment">&#125;</span></span><br><span class="line"><span class="comment">&#125;;*/</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function">ListNode* <span class="title">Merge</span><span class="params">(ListNode* pHead1, ListNode* pHead2)</span></span></span><br><span class="line"><span class="function">    </span>&#123;</span><br><span class="line">        ListNode* res = <span class="keyword">new</span> ListNode(<span class="number">0</span>);<span class="comment">//初始化，取几不重要</span></span><br><span class="line">        ListNode* here = res; <span class="comment">//标记位置</span></span><br><span class="line">        <span class="keyword">while</span>(pHead1 &amp;&amp; pHead2)&#123;</span><br><span class="line">            <span class="keyword">if</span>(pHead1-&gt;val &lt; pHead2-&gt;val)&#123;</span><br><span class="line">                res -&gt; next = pHead1;</span><br><span class="line">                pHead1 = pHead1 -&gt; next;</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">else</span>&#123;</span><br><span class="line">                res -&gt; next = pHead2;</span><br><span class="line">                pHead2 = pHead2 -&gt; next;</span><br><span class="line">            &#125;</span><br><span class="line">            res = res -&gt; next;</span><br><span class="line">        &#125;</span><br><span class="line">        res -&gt; next = pHead1 ? pHead1:pHead2;</span><br><span class="line">        <span class="keyword">return</span> here-&gt;next;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="17、树的子结构"><a href="#17、树的子结构" class="headerlink" title="17、树的子结构"></a>17、树的子结构</h1><p>输入两棵二叉树A，B，判断B是不是A的子结构。（ps：我们约定空树不是任意一个树的子结构）</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment">struct TreeNode &#123;</span></span><br><span class="line"><span class="comment">int val;</span></span><br><span class="line"><span class="comment">struct TreeNode *left;</span></span><br><span class="line"><span class="comment">struct TreeNode *right;</span></span><br><span class="line"><span class="comment">TreeNode(int x) :</span></span><br><span class="line"><span class="comment">val(x), left(NULL), right(NULL) &#123;</span></span><br><span class="line"><span class="comment">&#125;</span></span><br><span class="line"><span class="comment">&#125;;*/</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function"><span class="keyword">bool</span> <span class="title">HasSubtree</span><span class="params">(TreeNode* pRoot1, TreeNode* pRoot2)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">if</span>(pRoot1 &amp;&amp; pRoot2)&#123;</span><br><span class="line">            <span class="keyword">return</span> issub(pRoot1,pRoot2)|| </span><br><span class="line">                HasSubtree(pRoot1-&gt;left,pRoot2)|| </span><br><span class="line">                HasSubtree(pRoot1-&gt;right,pRoot2);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="function"><span class="keyword">bool</span> <span class="title">issub</span><span class="params">(TreeNode* l1, TreeNode* l2)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">if</span>(l2)&#123;</span><br><span class="line">            <span class="keyword">return</span> l1&amp;&amp; l1-&gt;val==l2-&gt;val&amp;&amp; </span><br><span class="line">                issub(l1-&gt;left,l2-&gt;left)&amp;&amp; </span><br><span class="line">                issub(l1-&gt;right,l2-&gt;right);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="18、二叉树的镜像"><a href="#18、二叉树的镜像" class="headerlink" title="18、二叉树的镜像"></a>18、二叉树的镜像</h1><p>操作给定的二叉树，将其变换为源二叉树的镜像。</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">二叉树的镜像定义：</span><br><span class="line">         源二叉树 </span><br><span class="line">        8</span><br><span class="line">       /  \</span><br><span class="line">      6   10</span><br><span class="line">     / \  / \</span><br><span class="line">    5  7 9 11</span><br><span class="line">    镜像二叉树</span><br><span class="line">        8</span><br><span class="line">       /  \</span><br><span class="line">      10   6</span><br><span class="line">     / \  / \</span><br><span class="line">    11 9 7  5</span><br></pre></td></tr></table></figure><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment">struct TreeNode &#123;</span></span><br><span class="line"><span class="comment">int val;</span></span><br><span class="line"><span class="comment">struct TreeNode *left;</span></span><br><span class="line"><span class="comment">struct TreeNode *right;</span></span><br><span class="line"><span class="comment">TreeNode(int x) :</span></span><br><span class="line"><span class="comment">val(x), left(NULL), right(NULL) &#123;</span></span><br><span class="line"><span class="comment">&#125;</span></span><br><span class="line"><span class="comment">&#125;;*/</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">Mirror</span><span class="params">(TreeNode *pRoot)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">if</span>(!pRoot) <span class="keyword">return</span>;</span><br><span class="line">        TreeNode *tmp = pRoot-&gt;left;</span><br><span class="line">        pRoot-&gt;left = pRoot-&gt;right;</span><br><span class="line">        pRoot-&gt;right = tmp;</span><br><span class="line">        Mirror(pRoot-&gt;left);</span><br><span class="line">        Mirror(pRoot-&gt;right);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="19、顺时针打印矩阵"><a href="#19、顺时针打印矩阵" class="headerlink" title="19、顺时针打印矩阵"></a>19、顺时针打印矩阵</h1><p>输入一个矩阵，按照从外向里以顺时针的顺序依次打印出每一个数字，例如，如果输入如下4 X 4矩阵： 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 则依次打印出数字1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10.</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment">   m   n</span></span><br><span class="line"><span class="comment"> i 1 2 3</span></span><br><span class="line"><span class="comment">   4 5 6</span></span><br><span class="line"><span class="comment"> j 7 8 9</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; printMatrix(<span class="built_in">vector</span>&lt;<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; &gt; matrix) &#123;</span><br><span class="line">        <span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; res;</span><br><span class="line">        <span class="keyword">int</span> i = <span class="number">0</span>,j = matrix.size()<span class="number">-1</span>,m = <span class="number">0</span>,n = matrix[<span class="number">0</span>].size()<span class="number">-1</span>;</span><br><span class="line">        <span class="keyword">while</span>(i&lt;=j &amp;&amp; m&lt;=n)&#123;</span><br><span class="line">            <span class="keyword">for</span>(<span class="keyword">int</span> k=m;k&lt;=n;k++) res.push_back(matrix[i][k]);</span><br><span class="line">            i++;<span class="comment">//削首行</span></span><br><span class="line">            <span class="keyword">if</span>(i&gt;j) <span class="keyword">break</span>;</span><br><span class="line">            <span class="keyword">for</span>(<span class="keyword">int</span> k=i;k&lt;=j;k++) res.push_back(matrix[k][n]);</span><br><span class="line">            n--;<span class="comment">//削尾列</span></span><br><span class="line">            <span class="keyword">if</span>(m&gt;n) <span class="keyword">break</span>;</span><br><span class="line">            <span class="keyword">for</span>(<span class="keyword">int</span> k=n;k&gt;=m;k--) res.push_back(matrix[j][k]); </span><br><span class="line">            j--;<span class="comment">//削尾行</span></span><br><span class="line">            <span class="keyword">if</span>(i&gt;j) <span class="keyword">break</span>;</span><br><span class="line">            <span class="keyword">for</span>(<span class="keyword">int</span> k=j;k&gt;=i;k--) res.push_back(matrix[k][m]);</span><br><span class="line">            m++;<span class="comment">//削首列</span></span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="20、包含min函数的栈"><a href="#20、包含min函数的栈" class="headerlink" title="20、包含min函数的栈"></a>20、包含min函数的栈</h1><p>定义栈的数据结构，请在该类型中实现一个能够得到栈中所含最小元素的min函数（时间复杂度应为O（1））。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment"> 用stack1保存数据，用stack2做辅助栈保存依次入栈最小的数</span></span><br><span class="line"><span class="comment"> stack1:5, 4, 3, 8, 10, 11, 12, 1</span></span><br><span class="line"><span class="comment"> stack2:5, 4, 3,no, no, no, no, 1</span></span><br><span class="line"><span class="comment"> no代表此次不入栈</span></span><br><span class="line"><span class="comment"> 入栈，如果stack1的压入比stack2压入大，stack2不压;小于等于，两栈同时压入</span></span><br><span class="line"><span class="comment"> 出栈，如果两栈顶元素不等，stack1出，stack2不出;相等，都出</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="built_in">stack</span>&lt;<span class="keyword">int</span>&gt; stack1,stack2;</span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">push</span><span class="params">(<span class="keyword">int</span> value)</span> </span>&#123;</span><br><span class="line">        stack1.push(value);</span><br><span class="line">        <span class="keyword">if</span>(stack2.empty()) stack2.push(value);</span><br><span class="line">        <span class="keyword">else</span>&#123;</span><br><span class="line">            <span class="keyword">if</span>(value &lt;= stack2.top()) stack2.push(value);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">pop</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">if</span>(stack1.top() == stack2.top()) stack2.pop();</span><br><span class="line">        stack1.pop();</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="function"><span class="keyword">int</span> <span class="title">top</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> stack1.top();</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="function"><span class="keyword">int</span> <span class="title">min</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> stack2.top();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="21、栈的压入、弹出序列"><a href="#21、栈的压入、弹出序列" class="headerlink" title="21、栈的压入、弹出序列"></a>21、栈的压入、弹出序列</h1><p>输入两个整数序列，第一个序列表示栈的压入顺序，请判断第二个序列是否可能为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序，序列4,5,3,2,1是该压栈序列对应的一个弹出序列，但4,3,5,1,2就不可能是该压栈序列的弹出序列。（注意：这两个序列的长度是相等的）</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function"><span class="keyword">bool</span> <span class="title">IsPopOrder</span><span class="params">(<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; pushV,<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; popV)</span> </span>&#123;</span><br><span class="line">        <span class="built_in">stack</span>&lt;<span class="keyword">int</span>&gt; s;</span><br><span class="line">        <span class="keyword">int</span> k = <span class="number">0</span>,len = pushV.size();</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;len;i++)&#123;</span><br><span class="line">            s.push(pushV[i]);</span><br><span class="line">            <span class="keyword">while</span>(k&lt;len &amp;&amp; popV[k] == s.top())&#123;</span><br><span class="line">                s.pop();</span><br><span class="line">                k++;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> s.empty();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="22、从上往下打印二叉树"><a href="#22、从上往下打印二叉树" class="headerlink" title="22、从上往下打印二叉树"></a>22、从上往下打印二叉树</h1><p>从上往下打印出二叉树的每个节点，同层节点从左至右打印。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment">struct TreeNode &#123;</span></span><br><span class="line"><span class="comment">int val;</span></span><br><span class="line"><span class="comment">struct TreeNode *left;</span></span><br><span class="line"><span class="comment">struct TreeNode *right;</span></span><br><span class="line"><span class="comment">TreeNode(int x) :</span></span><br><span class="line"><span class="comment">val(x), left(NULL), right(NULL) &#123;</span></span><br><span class="line"><span class="comment">&#125;</span></span><br><span class="line"><span class="comment">&#125;;*/</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; PrintFromTopToBottom(TreeNode* root) &#123;</span><br><span class="line">        <span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; res;</span><br><span class="line">        <span class="built_in">queue</span>&lt;TreeNode* &gt; q;</span><br><span class="line">        <span class="keyword">if</span>(root) q.push(root);</span><br><span class="line">        <span class="keyword">while</span>(!q.empty())&#123;</span><br><span class="line">            <span class="keyword">if</span>(q.front()-&gt;left) q.push(q.front()-&gt;left);</span><br><span class="line">            <span class="keyword">if</span>(q.front()-&gt;right) q.push(q.front()-&gt;right);</span><br><span class="line">            res.push_back(q.front()-&gt;val);</span><br><span class="line">            q.pop();</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="23、二叉搜索树的后序遍历序列"><a href="#23、二叉搜索树的后序遍历序列" class="headerlink" title="23、二叉搜索树的后序遍历序列"></a>23、二叉搜索树的后序遍历序列</h1><p>输入一个整数数组，判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则输出Yes,否则输出No。假设输入的数组的任意两个数字都互不相同。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment"> 二叉搜索树BST 左子树值都比root小，右子树值都比root大。</span></span><br><span class="line"><span class="comment"> 去掉最后一个元素root，其他分成两段:</span></span><br><span class="line"><span class="comment"> 前一段（左子树）小于x，后一段（右子树）大于x，且这两段（子树）都是BST的后序遍历</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function"><span class="keyword">bool</span> <span class="title">VerifySquenceOfBST</span><span class="params">(<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; sequence)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">if</span>(sequence.size()==<span class="number">0</span>) <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">        <span class="keyword">return</span> isok(sequence,<span class="number">0</span>,sequence.size()<span class="number">-1</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="function"><span class="keyword">bool</span> <span class="title">isok</span><span class="params">(<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; arr,<span class="keyword">int</span> l,<span class="keyword">int</span> r)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">if</span>(l &gt;= r) <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line">        <span class="keyword">int</span> i=l;</span><br><span class="line">        <span class="keyword">while</span>(i&lt;r &amp;&amp; arr[i]&lt;arr[r]) i++; <span class="comment">//找到满足BST的右子树开头</span></span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> j=i;j&lt;r;j++) <span class="keyword">if</span>(arr[j] &lt; arr[r]) <span class="keyword">return</span> <span class="literal">false</span>; <span class="comment">//判断剩下是否为右子树</span></span><br><span class="line">        <span class="keyword">return</span> isok(arr,l,i<span class="number">-1</span>)&amp;&amp; isok(arr,i,r<span class="number">-1</span>);</span><br><span class="line">    &#125; </span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="24、二叉树中和为某一值的路径"><a href="#24、二叉树中和为某一值的路径" class="headerlink" title="24、二叉树中和为某一值的路径"></a>24、二叉树中和为某一值的路径</h1><p>输入一颗二叉树的根节点和一个整数，打印出二叉树中结点值的和为输入整数的所有路径。路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。(注意: 在返回值的list中，数组长度大的数组靠前)</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment">struct TreeNode &#123;</span></span><br><span class="line"><span class="comment">int val;</span></span><br><span class="line"><span class="comment">struct TreeNode *left;</span></span><br><span class="line"><span class="comment">struct TreeNode *right;</span></span><br><span class="line"><span class="comment">TreeNode(int x) :</span></span><br><span class="line"><span class="comment">val(x), left(NULL), right(NULL) &#123;</span></span><br><span class="line"><span class="comment">&#125;</span></span><br><span class="line"><span class="comment">&#125;;*/</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="built_in">vector</span>&lt;<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; &gt; res;</span><br><span class="line">    <span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; tmp;</span><br><span class="line">    <span class="built_in">vector</span>&lt;<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; &gt; FindPath(TreeNode* root,<span class="keyword">int</span> expectNumber) &#123;</span><br><span class="line">        <span class="keyword">if</span>(root) helper(root,expectNumber);</span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">helper</span><span class="params">(TreeNode* root,<span class="keyword">int</span> n)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">if</span>(!root) <span class="keyword">return</span>;</span><br><span class="line">        tmp.push_back(root-&gt;val);</span><br><span class="line">        <span class="keyword">if</span>(root-&gt;val == n &amp;&amp; !root-&gt;left &amp;&amp; !root-&gt;right) res.push_back(tmp);</span><br><span class="line">        helper(root-&gt;left,n-root-&gt;val);</span><br><span class="line">        helper(root-&gt;right,n-root-&gt;val);</span><br><span class="line">        tmp.pop_back();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="25、复杂链表的复制"><a href="#25、复杂链表的复制" class="headerlink" title="25、复杂链表的复制"></a>25、复杂链表的复制</h1><p>输入一个复杂链表（每个节点中有节点值，以及两个指针，一个指向下一个节点，另一个特殊指针指向任意一个节点），返回结果为复制后复杂链表的head。（注意，输出结果中请不要返回参数中的节点引用，否则判题程序会直接返回空）</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment">struct RandomListNode &#123;</span></span><br><span class="line"><span class="comment">    int label;</span></span><br><span class="line"><span class="comment">    struct RandomListNode *next, *random;</span></span><br><span class="line"><span class="comment">    RandomListNode(int x) :</span></span><br><span class="line"><span class="comment">            label(x), next(NULL), random(NULL) &#123;</span></span><br><span class="line"><span class="comment">    &#125;</span></span><br><span class="line"><span class="comment">&#125;;</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment"> 复制节点，如：复制节点A得到A1，将A1插入节点A后面</span></span><br><span class="line"><span class="comment"> 复制random，遍历链表，A1-&gt;random = A-&gt;random-&gt;next;</span></span><br><span class="line"><span class="comment"> 将链表拆分成原链表和复制后的链表</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function">RandomListNode* <span class="title">Clone</span><span class="params">(RandomListNode* pHead)</span></span></span><br><span class="line"><span class="function">    </span>&#123;</span><br><span class="line">        <span class="keyword">if</span>(!pHead) <span class="keyword">return</span> <span class="literal">NULL</span>;</span><br><span class="line">        </span><br><span class="line">        RandomListNode* cur = pHead;<span class="comment">//从头复制节点 A-&gt;B-&gt;C 变成A-&gt;A'-&gt;B-&gt;B'-&gt;C-&gt;C'</span></span><br><span class="line">        <span class="keyword">while</span>(cur)&#123;</span><br><span class="line">            RandomListNode* copynode = <span class="keyword">new</span> RandomListNode(cur-&gt;label);</span><br><span class="line">            copynode -&gt; next = cur -&gt; next;</span><br><span class="line">            cur-&gt;next = copynode;</span><br><span class="line">            cur = cur -&gt; next -&gt; next;</span><br><span class="line">        &#125;</span><br><span class="line">        </span><br><span class="line">        cur = pHead;<span class="comment">//从头复制random,A1-&gt;random = A-&gt;random-&gt;next;</span></span><br><span class="line">        <span class="keyword">while</span>(cur)&#123;</span><br><span class="line">            <span class="keyword">if</span>(cur -&gt; random) cur -&gt; next -&gt; random = cur -&gt; random -&gt; next;</span><br><span class="line">            cur = cur -&gt; next -&gt; next;</span><br><span class="line">        &#125;</span><br><span class="line">        </span><br><span class="line">        cur = pHead;<span class="comment">//从头将链表拆分成原链表和复制后的链表</span></span><br><span class="line">        RandomListNode* res = cur -&gt; next; <span class="comment">//复制后的链表,标记位置</span></span><br><span class="line">        RandomListNode* tmp;</span><br><span class="line">        <span class="keyword">while</span>(cur -&gt; next)&#123;</span><br><span class="line">            tmp = cur -&gt; next;</span><br><span class="line">            cur -&gt; next = tmp -&gt; next;</span><br><span class="line">            cur = tmp;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="26、二叉搜索树与双向链表"><a href="#26、二叉搜索树与双向链表" class="headerlink" title="26、二叉搜索树与双向链表"></a>26、二叉搜索树与双向链表</h1><p>输入一棵二叉搜索树，将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点，只能调整树中结点指针的指向。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment">struct TreeNode &#123;</span></span><br><span class="line"><span class="comment">int val;</span></span><br><span class="line"><span class="comment">struct TreeNode *left;</span></span><br><span class="line"><span class="comment">struct TreeNode *right;</span></span><br><span class="line"><span class="comment">TreeNode(int x) :</span></span><br><span class="line"><span class="comment">val(x), left(NULL), right(NULL) &#123;</span></span><br><span class="line"><span class="comment">&#125;</span></span><br><span class="line"><span class="comment">&#125;;*/</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line"><span class="comment">//树的线索化，利用了二叉树结点中的空指针，让它们分别指向本结点的前驱或者后继</span></span><br><span class="line">    TreeNode* head = <span class="literal">NULL</span>;</span><br><span class="line">    TreeNode* res = <span class="literal">NULL</span>;</span><br><span class="line">    <span class="function">TreeNode* <span class="title">Convert</span><span class="params">(TreeNode* pRootOfTree)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">if</span>(!pRootOfTree) <span class="keyword">return</span> <span class="literal">NULL</span>;</span><br><span class="line">        helper(pRootOfTree);</span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">helper</span><span class="params">(TreeNode* root)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">if</span>(!root) <span class="keyword">return</span>;</span><br><span class="line">        helper(root-&gt;left);</span><br><span class="line">        <span class="keyword">if</span>(!head)&#123; <span class="comment">//中序遍历第一个，即树的左下角</span></span><br><span class="line">            head = root;</span><br><span class="line">            res = root;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">else</span>&#123;</span><br><span class="line">            head -&gt; right = root;</span><br><span class="line">            root -&gt; left = head;</span><br><span class="line">            head = root;</span><br><span class="line">        &#125;</span><br><span class="line">        helper(root-&gt;right);</span><br><span class="line">    &#125; </span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="27、字符串的排列"><a href="#27、字符串的排列" class="headerlink" title="27、字符串的排列"></a>27、字符串的排列</h1><p>输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。<br>输入一个字符串,长度不超过9(可能有字符重复),字符只包括大小写字母。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment"> 问题转换为先固定第一个字符，求剩余字符的排列</span></span><br><span class="line"><span class="comment"> 再把第一个字符与后面每一个字符交换，并同样递归获得首位后面的字符串组合</span></span><br><span class="line"><span class="comment"> a b b c:</span></span><br><span class="line"><span class="comment"> a+f(bbc),b+f(abc),c+f(abb); 遍历出所有可能出现在第一个位置的字符</span></span><br><span class="line"><span class="comment"> f(bbc)=b+f(bc),b+f(bc),c+f(bb);</span></span><br><span class="line"><span class="comment"> f(bc)=b+f(c),c+f(b);</span></span><br><span class="line"><span class="comment"> f(c)=c;</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="built_in">vector</span>&lt;<span class="built_in">string</span>&gt; res;</span><br><span class="line">    <span class="built_in">vector</span>&lt;<span class="built_in">string</span>&gt; Permutation(<span class="built_in">string</span> str) &#123;</span><br><span class="line">        <span class="keyword">if</span>(str.empty()) <span class="keyword">return</span> res;</span><br><span class="line">        help(str,<span class="number">0</span>);</span><br><span class="line">        sort(res.begin(),res.end());</span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">help</span><span class="params">(<span class="built_in">string</span> s,<span class="keyword">int</span> n)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">if</span>(n==s.size()<span class="number">-1</span>)&#123;</span><br><span class="line">            <span class="keyword">if</span>(find(res.begin(),res.end(),s)==res.end()) res.push_back(s);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">else</span>&#123;</span><br><span class="line">            <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;s.size();i++)&#123;</span><br><span class="line">                swap(s[i],s[n]);</span><br><span class="line">                help(s,n+<span class="number">1</span>);</span><br><span class="line">                swap(s[n],s[i]);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="28、数组中出现次数超过一半的数字"><a href="#28、数组中出现次数超过一半的数字" class="headerlink" title="28、数组中出现次数超过一半的数字"></a>28、数组中出现次数超过一半的数字</h1><p>数组中有一个数字出现的次数超过数组长度的一半，请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次，超过数组长度的一半，因此输出2。如果不存在则输出0。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment"> 如果重复的次数超过一半的话，一定有相邻的数字相同这种情况的</span></span><br><span class="line"><span class="comment"> 对数组同时去掉两个不同的数字，到最后剩下的一个数就是该数字</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function"><span class="keyword">int</span> <span class="title">MoreThanHalfNum_Solution</span><span class="params">(<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; numbers)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">if</span>(numbers.empty()) <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">int</span> res = numbers[<span class="number">0</span>];</span><br><span class="line">        <span class="keyword">int</span> times = <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;numbers.size();i++)&#123;</span><br><span class="line">            <span class="keyword">if</span>(numbers[i] == res) times++;</span><br><span class="line">            <span class="keyword">else</span>&#123;</span><br><span class="line">                times--;</span><br><span class="line">                <span class="keyword">if</span>(times == <span class="number">0</span>)&#123;</span><br><span class="line">                    res = numbers[i];</span><br><span class="line">                    times = <span class="number">1</span>;</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="comment">//check</span></span><br><span class="line">        times = <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;numbers.size();i++)&#123;</span><br><span class="line">            <span class="keyword">if</span>(numbers[i] == res) times++;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> times&gt;numbers.size()/<span class="number">2</span>?res:<span class="number">0</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br><span class="line"><span class="comment">/* 涉及到快排sort，其时间复杂度为O(NlogN)并非最优</span></span><br><span class="line"><span class="comment">class Solution &#123;</span></span><br><span class="line"><span class="comment">public:</span></span><br><span class="line"><span class="comment">    int MoreThanHalfNum_Solution(vector&lt;int&gt; numbers)</span></span><br><span class="line"><span class="comment">    &#123;</span></span><br><span class="line"><span class="comment">        // 因为用到了sort，时间复杂度O(NlogN)，并非最优</span></span><br><span class="line"><span class="comment">        if(numbers.empty()) return 0;</span></span><br><span class="line"><span class="comment">         </span></span><br><span class="line"><span class="comment">        sort(numbers.begin(),numbers.end());</span></span><br><span class="line"><span class="comment">        int middle = numbers[numbers.size()/2];//假设存在众数may</span></span><br><span class="line"><span class="comment">        </span></span><br><span class="line"><span class="comment">        //check</span></span><br><span class="line"><span class="comment">        int count=0; // 出现次数</span></span><br><span class="line"><span class="comment">        for(int i=0;i&lt;numbers.size();++i)</span></span><br><span class="line"><span class="comment">        &#123;</span></span><br><span class="line"><span class="comment">            if(numbers[i]==middle) ++count;</span></span><br><span class="line"><span class="comment">        &#125;</span></span><br><span class="line"><span class="comment">         </span></span><br><span class="line"><span class="comment">        return (count&gt;numbers.size()/2) ? middle :  0;</span></span><br><span class="line"><span class="comment">    &#125;</span></span><br><span class="line"><span class="comment">&#125;;</span></span><br><span class="line"><span class="comment">*/</span></span><br></pre></td></tr></table></figure><h1 id="29、最小的k个数"><a href="#29、最小的k个数" class="headerlink" title="29、最小的k个数"></a>29、最小的k个数</h1><p>输入n个整数，找出其中最小的K个数。例如输入4,5,1,6,2,7,3,8这8个数字，则最小的4个数字是1,2,3,4,。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment"> 基于堆排序算法，构建最大堆。时间复杂度为O(nlogk)</span></span><br><span class="line"><span class="comment"> 用最大堆保存这k个数，每次只和堆顶比，如果比堆顶小，删除堆顶，新数入堆</span></span><br><span class="line"><span class="comment"> 如果用快速排序，时间复杂度为O(nlogn)；</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; GetLeastNumbers_Solution(<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; input, <span class="keyword">int</span> k) &#123;</span><br><span class="line">        <span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; res;</span><br><span class="line">        priority_queue&lt;<span class="keyword">int</span>&gt; q; </span><br><span class="line">        <span class="comment">//priority_queue&lt;int,vector&lt;int&gt;,greater&lt;int&gt;&gt; q;最小堆</span></span><br><span class="line">        <span class="keyword">if</span>(input.empty() || k&gt;input.size() || k==<span class="number">0</span>) <span class="keyword">return</span> res;</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;input.size();i++)&#123;</span><br><span class="line">            <span class="keyword">if</span>(i&lt;k) q.push(input[i]);</span><br><span class="line">            <span class="keyword">else</span>&#123;</span><br><span class="line">                <span class="keyword">if</span>(input[i] &lt; q.top())&#123;</span><br><span class="line">                    q.pop();</span><br><span class="line">                    q.push(input[i]);</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">while</span>(!q.empty())&#123;</span><br><span class="line">            res.push_back(q.top());</span><br><span class="line">            q.pop();</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="30、连续子数组的最大和"><a href="#30、连续子数组的最大和" class="headerlink" title="30、连续子数组的最大和"></a>30、连续子数组的最大和</h1><p>HZ偶尔会拿些专业问题来忽悠那些非计算机专业的同学。今天测试组开完会后,他又发话了:在古老的一维模式识别中,常常需要计算连续子向量的最大和,当向量全为正数的时候,问题很好解决。但是,如果向量中包含负数,是否应该包含某个负数,并期望旁边的正数会弥补它呢？例如:{6,-3,-2,7,-15,1,2,2},连续子向量的最大和为8(从第0个开始,到第3个为止)。给一个数组，返回它的最大连续子序列的和，你会不会被他忽悠住？(子向量的长度至少是1)</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function"><span class="keyword">int</span> <span class="title">FindGreatestSumOfSubArray</span><span class="params">(<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; <span class="built_in">array</span>)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">int</span> res = <span class="built_in">array</span>[<span class="number">0</span>];</span><br><span class="line">        <span class="keyword">int</span> max = <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;<span class="built_in">array</span>.size();i++)&#123;</span><br><span class="line">            max += <span class="built_in">array</span>[i];</span><br><span class="line">            <span class="keyword">if</span>(max &gt; res) res = max;</span><br><span class="line">            <span class="keyword">if</span>(max &lt; <span class="number">0</span>) max = <span class="number">0</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="31、整数中1出现的次数"><a href="#31、整数中1出现的次数" class="headerlink" title="31、整数中1出现的次数"></a>31、整数中1出现的次数</h1><p>求出1<del>13的整数中1出现的次数,并算出100</del>1300的整数中1出现的次数？为此他特别数了一下1~13中包含1的数字有1、10、11、12、13因此共出现6次,但是对于后面问题他就没辙了。ACMer希望你们帮帮他,并把问题更加普遍化,可以很快的求出任意非负整数区间中1出现的次数（从1 到 n 中1出现的次数）。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment"> n=10917 1~10917</span></span><br><span class="line"><span class="comment"> 所有数里在个位的1的数量：</span></span><br><span class="line"><span class="comment"> 前面为0~1090，个位后无，排列组合共1*1091种情况；前面为1091时，个位后为1。总共：1*1091+1(m=1，情况3)</span></span><br><span class="line"><span class="comment"> 所有数里在十位的1的数量：</span></span><br><span class="line"><span class="comment"> 前面为0~108，十位后为0~9，排列组合共10*109种情况；前面为109时，十位后为0~7。总共：10*109+8(m=8，情况2)</span></span><br><span class="line"><span class="comment"> 所有数里在百位的1的数量：</span></span><br><span class="line"><span class="comment"> 前面为0~9，百位后为0~99，排列组合共100*10种情况；前面为10时，百位后为0~99。总共：100*10+100(m=100，情况3)</span></span><br><span class="line"><span class="comment"> 所有数里在千位的1的数量：</span></span><br><span class="line"><span class="comment"> 前面为0~0，千位后为0~999，排列组合共1000*1种情况；前面为1时，千位后没有满足的。总共：1000*1+0(m=0，情况1)</span></span><br><span class="line"><span class="comment"> 所有数里在万位的1的数量：</span></span><br><span class="line"><span class="comment"> 前面为无，万位后为0~917。总共：1000*0+918(m=918，情况2)</span></span><br><span class="line"><span class="comment"> </span></span><br><span class="line"><span class="comment"> 精髓在于后面部分m值分三种情况：</span></span><br><span class="line"><span class="comment"> ①当前位为0时，m=0；②当前位为1时，m=后面值+1；③当前位为2~9时，m=10^(后面的位数)</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function"><span class="keyword">int</span> <span class="title">NumberOf1Between1AndN_Solution</span><span class="params">(<span class="keyword">int</span> n)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">if</span>(n == <span class="number">0</span>) <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">int</span> res = <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">int</span> base = <span class="number">1</span>,t = n,m;</span><br><span class="line">        <span class="keyword">while</span>(t!=<span class="number">0</span>)&#123;</span><br><span class="line">            <span class="keyword">if</span>(t%<span class="number">10</span> == <span class="number">0</span>) m = <span class="number">0</span>;</span><br><span class="line">            <span class="keyword">else</span> <span class="keyword">if</span>(t%<span class="number">10</span> == <span class="number">1</span>) m = n-t*base+<span class="number">1</span>;</span><br><span class="line">            <span class="keyword">else</span> m = base;</span><br><span class="line">            t/=<span class="number">10</span>; res+=base*t+m; base*=<span class="number">10</span>; </span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="32、把数组排成最小的数"><a href="#32、把数组排成最小的数" class="headerlink" title="32、把数组排成最小的数"></a>32、把数组排成最小的数</h1><p>输入一个正整数数组，把数组里所有数字拼接起来排成一个数，打印能拼接出的所有数字中最小的一个。例如输入数组{3，32，321}，则打印出这三个数字能排成的最小数字为321323。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="comment">//sort中的比较函数compare要声明为静态成员函数或全局函数，不能作为普通成员函数</span></span><br><span class="line">    <span class="function"><span class="built_in">string</span> <span class="title">PrintMinNumber</span><span class="params">(<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; numbers)</span> </span>&#123;</span><br><span class="line">        <span class="built_in">string</span> res = <span class="string">""</span>;</span><br><span class="line">        sort(numbers.begin(),numbers.end(),cmp);</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;numbers.size();i++)&#123;</span><br><span class="line">            res += to_string(numbers[i]); </span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="function"><span class="keyword">static</span> <span class="keyword">bool</span> <span class="title">cmp</span><span class="params">(<span class="keyword">int</span> &amp;i,<span class="keyword">int</span> &amp;j)</span> </span>&#123;</span><br><span class="line">        <span class="built_in">string</span> si = to_string(i);</span><br><span class="line">        <span class="built_in">string</span> sj = to_string(j);</span><br><span class="line">        <span class="keyword">return</span> si+sj&lt;sj+si; <span class="comment">// 2 23和23 2</span></span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="33、丑数"><a href="#33、丑数" class="headerlink" title="33、丑数"></a>33、丑数</h1><p>把只包含质因子2、3和5的数称作丑数（Ugly Number）。例如6、8都是丑数，但14不是，因为它包含质因子7。 习惯上我们把1当做是第一个丑数。求按从小到大的顺序的第N个丑数。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment"> 如果p是丑数，那么p=2^x * 3^y * 5^z, 且x,y,z需满足是前面的丑数</span></span><br><span class="line"><span class="comment"> 初始x=y=z=1， 2^x、3^y、5^z最小的数2^x加进结果，x在结果中位置后移一位</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function"><span class="keyword">int</span> <span class="title">GetUglyNumber_Solution</span><span class="params">(<span class="keyword">int</span> index)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">if</span>(index &lt; <span class="number">7</span>) <span class="keyword">return</span> index;</span><br><span class="line">        <span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; res(index);</span><br><span class="line">        res[<span class="number">0</span>] = <span class="number">1</span>;</span><br><span class="line">        <span class="keyword">int</span> x=<span class="number">0</span>, y=<span class="number">0</span>, z=<span class="number">0</span>;</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">1</span>;i&lt;index;i++)&#123;</span><br><span class="line">            res[i] = min(min(res[x]*<span class="number">2</span>,res[y]*<span class="number">3</span>),res[z]*<span class="number">5</span>);</span><br><span class="line">            <span class="keyword">if</span>(res[i] == res[x]*<span class="number">2</span>) x++;</span><br><span class="line">            <span class="keyword">if</span>(res[i] == res[y]*<span class="number">3</span>) y++;</span><br><span class="line">            <span class="keyword">if</span>(res[i] == res[z]*<span class="number">5</span>) z++;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> res[index<span class="number">-1</span>];</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="34、第一个只出现一次的字符"><a href="#34、第一个只出现一次的字符" class="headerlink" title="34、第一个只出现一次的字符"></a>34、第一个只出现一次的字符</h1><p>在一个字符串(0&lt;=字符串长度&lt;=10000，全部由字母组成)中找到第一个只出现一次的字符,并返回它的位置, 如果没有则返回 -1（需要区分大小写）.</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function"><span class="keyword">int</span> <span class="title">FirstNotRepeatingChar</span><span class="params">(<span class="built_in">string</span> str)</span> </span>&#123;</span><br><span class="line">        <span class="comment">//字符在计算机中以ASCII码的形式存储，当字符作为数组下标时，其表示的下标值为该字符的ASCII码的十进制值</span></span><br><span class="line">        <span class="comment">//0-9:  48-57， A-Z:  65-90， a-z:  97-122</span></span><br><span class="line">        <span class="built_in">map</span>&lt;<span class="keyword">char</span>,<span class="keyword">int</span>&gt; <span class="built_in">map</span>; <span class="comment">//map支持int，char，string</span></span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;str.size();i++)&#123;</span><br><span class="line">            <span class="built_in">map</span>[str[i]]++;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;str.size();i++)&#123;</span><br><span class="line">            <span class="keyword">if</span>(<span class="built_in">map</span>[str[i]] == <span class="number">1</span>) <span class="keyword">return</span> i;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> <span class="number">-1</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="35、数组中的逆序对"><a href="#35、数组中的逆序对" class="headerlink" title="35、数组中的逆序对"></a>35、数组中的逆序对</h1><p>在数组中的两个数字，如果前面一个数字大于后面的数字，则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。并将P对1000000007取模的结果输出。 即输出P%1000000007</p><figure class="highlight m"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">输入描述:</span><br><span class="line">题目保证输入的数组中没有的相同的数字</span><br><span class="line">数据范围：</span><br><span class="line">对于<span class="comment">%50的数据,size&lt;=10^4</span></span><br><span class="line">对于<span class="comment">%75的数据,size&lt;=10^5</span></span><br><span class="line">对于<span class="comment">%100的数据,size&lt;=2*10^5</span></span><br><span class="line"></span><br><span class="line">示例:</span><br><span class="line">输入   <span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>,<span class="number">5</span>,<span class="number">6</span>,<span class="number">7</span>,<span class="number">0</span></span><br><span class="line">输出   <span class="number">7</span></span><br></pre></td></tr></table></figure><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment"> 先把数组分割成子数组，先统计出子数组内部的逆序对的数目，然后再统计出两个相邻子数组之间的逆序对的数目</span></span><br><span class="line"><span class="comment"> 在统计逆序对的过程中，还需要对数组进行排序,每一次比较的时候</span></span><br><span class="line"><span class="comment"> 都把较大的数字从后面往前复制到一个辅助数组中，确保辅助数组copy中的数字是递增排序的</span></span><br><span class="line"><span class="comment"> 交换copy和data:在每次的操作中，当前传入函数中第一项，比较的结果都存放到第二项中,需要交叉保证下一次是排序的</span></span><br><span class="line"><span class="comment"> 输入[7,5,6,4], 最后的结果copy[4,5,6,7], data[5,7,4,6]</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function"><span class="keyword">int</span> <span class="title">InversePairs</span><span class="params">(<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; data)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">if</span>(data.size()==<span class="number">0</span>) <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">        <span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt;copy(data); <span class="comment">//使用data初始化copy</span></span><br><span class="line">        <span class="keyword">long</span> <span class="keyword">long</span> P = InversePairsCore(data,copy,<span class="number">0</span>,data.size()<span class="number">-1</span>);</span><br><span class="line">        <span class="keyword">return</span> P%<span class="number">1000000007</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="function"><span class="keyword">long</span> <span class="keyword">long</span> <span class="title">InversePairsCore</span><span class="params">(<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; &amp;data,<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; &amp;copy,<span class="keyword">int</span> l,<span class="keyword">int</span> r)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">if</span>(l == r)&#123;</span><br><span class="line">            copy[l] = data[l]; <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">int</span> mid = (l+r)/<span class="number">2</span>;</span><br><span class="line">        <span class="keyword">long</span> <span class="keyword">long</span> left = InversePairsCore(copy,data,l,mid);</span><br><span class="line">        <span class="keyword">long</span> <span class="keyword">long</span> right = InversePairsCore(copy,data,mid+<span class="number">1</span>,r);</span><br><span class="line">        <span class="keyword">int</span> i = mid,j = r;</span><br><span class="line">        <span class="keyword">long</span> <span class="keyword">long</span> count = <span class="number">0</span>; <span class="comment">//需要long long,int的话最后一个例子会溢出测试不通过</span></span><br><span class="line">        <span class="keyword">int</span> cur = r;</span><br><span class="line">        <span class="keyword">while</span>(i&gt;=l &amp;&amp; j&gt;=mid+<span class="number">1</span>)&#123;</span><br><span class="line">            <span class="keyword">if</span>(data[i]&gt;data[j])&#123; <span class="comment">//3 8,4 6  8&gt;6</span></span><br><span class="line">                count += j-mid;</span><br><span class="line">                copy[cur--] = data[i]; i--;</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">else</span>&#123;</span><br><span class="line">                copy[cur--] = data[j]; j--;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">while</span>(i&gt;=l)&#123;</span><br><span class="line">            copy[cur--] = data[i]; i--;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">while</span>(j&gt;=mid+<span class="number">1</span>)&#123;</span><br><span class="line">            copy[cur--] = data[j]; j--;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> left+right+count;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="36、两个链表的第一个公共节点"><a href="#36、两个链表的第一个公共节点" class="headerlink" title="36、两个链表的第一个公共节点"></a>36、两个链表的第一个公共节点</h1><p>输入两个链表，找出它们的第一个公共结点。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment">struct ListNode &#123;</span></span><br><span class="line"><span class="comment">int val;</span></span><br><span class="line"><span class="comment">struct ListNode *next;</span></span><br><span class="line"><span class="comment">ListNode(int x) :</span></span><br><span class="line"><span class="comment">val(x), next(NULL) &#123;</span></span><br><span class="line"><span class="comment">&#125;</span></span><br><span class="line"><span class="comment">&#125;;*/</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function">ListNode* <span class="title">FindFirstCommonNode</span><span class="params">( ListNode* pHead1, ListNode* pHead2)</span> </span>&#123;</span><br><span class="line">        <span class="comment">//找出2个链表的长度，然后让长的先走两个链表的长度差，然后再一起走</span></span><br><span class="line">        <span class="keyword">int</span> len1 = getlen(pHead1);</span><br><span class="line">        <span class="keyword">int</span> len2 = getlen(pHead2);</span><br><span class="line">        <span class="keyword">int</span> dis = len1-len2&gt;<span class="number">0</span>?len1-len2:len2-len1;</span><br><span class="line">        <span class="keyword">while</span>(dis!=<span class="number">0</span>)&#123;</span><br><span class="line">            <span class="keyword">if</span>(len1&gt;len2) pHead1 = pHead1-&gt;next;</span><br><span class="line">            <span class="keyword">else</span> pHead2 = pHead2-&gt;next;</span><br><span class="line">            dis--;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">while</span>(pHead1)&#123;</span><br><span class="line">            <span class="keyword">if</span>(pHead1 == pHead2) <span class="keyword">return</span> pHead1;</span><br><span class="line">            pHead1 = pHead1-&gt;next;</span><br><span class="line">            pHead2 = pHead2-&gt;next;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> <span class="literal">NULL</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="function"><span class="keyword">int</span> <span class="title">getlen</span><span class="params">(ListNode* p)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">int</span> res = <span class="number">0</span>;</span><br><span class="line">        ListNode* root = p;</span><br><span class="line">        <span class="keyword">while</span>(root)&#123;</span><br><span class="line">            res++;</span><br><span class="line">            root = root-&gt;next;</span><br><span class="line">        &#125;</span><br><span class="line">       <span class="keyword">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="37、数字在排序数组中出现的次数"><a href="#37、数字在排序数组中出现的次数" class="headerlink" title="37、数字在排序数组中出现的次数"></a>37、数字在排序数组中出现的次数</h1><p>统计一个数字在排序数组中出现的次数。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function"><span class="keyword">int</span> <span class="title">GetNumberOfK</span><span class="params">(<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; data ,<span class="keyword">int</span> k)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">if</span>(data.empty()) <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">int</span> l=<span class="number">0</span>,r=data.size()<span class="number">-1</span>;</span><br><span class="line">        <span class="keyword">while</span>(l&lt;=r)&#123;</span><br><span class="line">            <span class="keyword">int</span> mid = (l+r)/<span class="number">2</span>;</span><br><span class="line">            <span class="keyword">if</span>(data[mid]==k)&#123; <span class="comment">//计数</span></span><br><span class="line">                <span class="keyword">int</span> res=<span class="number">0</span>,i=mid;</span><br><span class="line">                <span class="keyword">while</span>(i&gt;=l)&#123;</span><br><span class="line">                    <span class="keyword">if</span>(data[i]==k)&#123;</span><br><span class="line">                        i--;</span><br><span class="line">                        res++;</span><br><span class="line">                    &#125;</span><br><span class="line">                    <span class="keyword">else</span> <span class="keyword">break</span>;</span><br><span class="line">                &#125;</span><br><span class="line">                i=mid+<span class="number">1</span>;</span><br><span class="line">                <span class="keyword">while</span>(i&lt;=r)&#123;</span><br><span class="line">                    <span class="keyword">if</span>(data[i]==k)&#123;</span><br><span class="line">                        i++;</span><br><span class="line">                        res++;</span><br><span class="line">                    &#125;</span><br><span class="line">                    <span class="keyword">else</span> <span class="keyword">break</span>;</span><br><span class="line">                &#125;</span><br><span class="line">                <span class="keyword">return</span> res;</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">else</span> <span class="keyword">if</span>(data[mid] &gt; k) r=mid<span class="number">-1</span>;</span><br><span class="line">            <span class="keyword">else</span> l=mid+<span class="number">1</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="38、二叉树的深度"><a href="#38、二叉树的深度" class="headerlink" title="38、二叉树的深度"></a>38、二叉树的深度</h1><p>输入一棵二叉树，求该树的深度。从根结点到叶结点依次经过的结点（含根、叶结点）形成树的一条路径，最长路径的长度为树的深度。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment">struct TreeNode &#123;</span></span><br><span class="line"><span class="comment">int val;</span></span><br><span class="line"><span class="comment">struct TreeNode *left;</span></span><br><span class="line"><span class="comment">struct TreeNode *right;</span></span><br><span class="line"><span class="comment">TreeNode(int x) :</span></span><br><span class="line"><span class="comment">val(x), left(NULL), right(NULL) &#123;</span></span><br><span class="line"><span class="comment">&#125;</span></span><br><span class="line"><span class="comment">&#125;;*/</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function"><span class="keyword">int</span> <span class="title">TreeDepth</span><span class="params">(TreeNode* pRoot)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">if</span>(!pRoot) <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">return</span> max(TreeDepth(pRoot-&gt;left),TreeDepth(pRoot-&gt;right))+<span class="number">1</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="39、平衡二叉树"><a href="#39、平衡二叉树" class="headerlink" title="39、平衡二叉树"></a>39、平衡二叉树</h1><p>输入一棵二叉树，判断该二叉树是否是平衡二叉树。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="comment">//左右子树均为平衡二叉树，且左右子树层高不超过1</span></span><br><span class="line">    <span class="function"><span class="keyword">bool</span> <span class="title">IsBalanced_Solution</span><span class="params">(TreeNode* pRoot)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">if</span>(!pRoot) <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line">        <span class="keyword">return</span> IsBalanced_Solution(pRoot-&gt;left)</span><br><span class="line">            &amp;&amp; IsBalanced_Solution(pRoot-&gt;right)</span><br><span class="line">            &amp;&amp; <span class="built_in">abs</span>(getlen(pRoot-&gt;left)-getlen(pRoot-&gt;right))&lt;=<span class="number">1</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="function"><span class="keyword">int</span> <span class="title">getlen</span><span class="params">(TreeNode* p)</span></span>&#123;</span><br><span class="line">        <span class="keyword">if</span>(!p) <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">return</span> max(getlen(p-&gt;left),getlen(p-&gt;right))+<span class="number">1</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="40、数组中只出现一次的数字"><a href="#40、数组中只出现一次的数字" class="headerlink" title="40、数组中只出现一次的数字"></a>40、数组中只出现一次的数字</h1><p>一个整型数组里除了两个数字之外，其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment"> 异或性质：</span></span><br><span class="line"><span class="comment"> 交换律：a ^ b ^ c  &lt;=&gt; a ^ c ^ b,俩两相同的移到一起</span></span><br><span class="line"><span class="comment"> 相同的数异或为0: n ^ n =&gt; 0</span></span><br><span class="line"><span class="comment"> 任何数于0异或为任何数 0 ^ n =&gt; n</span></span><br><span class="line"><span class="comment"> </span></span><br><span class="line"><span class="comment"> 遍历异或后，只剩下两单个的异或了，结果res的二进制至少有一位为1</span></span><br><span class="line"><span class="comment"> 取第一个1所在的位数index，原数组分成第index位为1和为0</span></span><br><span class="line"><span class="comment"> 相同的数肯定在一个组，两个单的在不同的组</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">FindNumsAppearOnce</span><span class="params">(<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; data,<span class="keyword">int</span>* num1,<span class="keyword">int</span> *num2)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">int</span> add = <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;data.size();i++)&#123;</span><br><span class="line">            add ^= data[i];</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">int</span> index = <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">while</span>((add&amp;<span class="number">1</span>)==<span class="number">0</span>)&#123;</span><br><span class="line">            add = add &gt;&gt; <span class="number">1</span>;</span><br><span class="line">            index++;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;data.size();i++)&#123;</span><br><span class="line">            <span class="keyword">if</span>((data[i]&gt;&gt;index&amp;<span class="number">1</span>)==<span class="number">0</span>) num1[<span class="number">0</span>]^=data[i];</span><br><span class="line">            <span class="keyword">else</span> num2[<span class="number">0</span>]^=data[i];</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="41、和为S的连续正数序列"><a href="#41、和为S的连续正数序列" class="headerlink" title="41、和为S的连续正数序列"></a>41、和为S的连续正数序列</h1><p>小明很喜欢数学,有一天他在做数学作业时,要求计算出9~16的和,他马上就写出了正确答案是100。但是他并不满足于此,他在想究竟有多少种连续的正数序列的和为100(至少包括两个数)。没多久,他就得到另一组连续正数和为100的序列:18,19,20,21,22。现在把问题交给你,你能不能也很快的找出所有和为S的连续正数序列? Good Luck!输出描述:<br>输出所有和为S的连续正数序列。序列内按照从小至大的顺序，序列间按照开始数字从小到大的顺序</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="built_in">vector</span>&lt;<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; &gt; FindContinuousSequence(<span class="keyword">int</span> sum) &#123;</span><br><span class="line">        <span class="built_in">vector</span>&lt;<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; &gt; res;</span><br><span class="line">        <span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; part;</span><br><span class="line">        <span class="keyword">int</span> i = <span class="number">1</span>,j = <span class="number">2</span>;</span><br><span class="line">        <span class="keyword">while</span>(i &lt; j)&#123;</span><br><span class="line">            <span class="keyword">int</span> count = (i+j)*(j-i+<span class="number">1</span>)/<span class="number">2</span>; <span class="comment">//i~j的和</span></span><br><span class="line">            <span class="keyword">if</span>(count == sum)&#123; <span class="comment">//将i~j插入res</span></span><br><span class="line">                part.clear();</span><br><span class="line">                <span class="keyword">for</span>(<span class="keyword">int</span> k=i;k&lt;=j;k++)&#123;</span><br><span class="line">                    part.push_back(k);</span><br><span class="line">                &#125;</span><br><span class="line">                res.push_back(part);</span><br><span class="line">                i++;</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">else</span> <span class="keyword">if</span>(count &lt; sum) j++; <span class="comment">//右窗口右移</span></span><br><span class="line">            <span class="keyword">else</span> i++; <span class="comment">//左窗口右移</span></span><br><span class="line">            </span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="42、和为S的两个数字"><a href="#42、和为S的两个数字" class="headerlink" title="42、和为S的两个数字"></a>42、和为S的两个数字</h1><p>输入一个递增排序的数组和一个数字S，在数组中查找两个数，使得他们的和正好是S，如果有多对数字的和等于S，输出两个数的乘积最小的。<br>输出描述:<br>对应每个测试案例，输出两个数，小的先输出。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; FindNumbersWithSum(<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; <span class="built_in">array</span>,<span class="keyword">int</span> sum) &#123;</span><br><span class="line">        <span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; res;</span><br><span class="line">        <span class="keyword">int</span> i = <span class="number">0</span>, j = <span class="built_in">array</span>.size()<span class="number">-1</span>;</span><br><span class="line">        <span class="keyword">while</span>(i&lt;j)&#123;</span><br><span class="line">            <span class="keyword">if</span>(<span class="built_in">array</span>[i]+<span class="built_in">array</span>[j] == sum)&#123; <span class="comment">//1 3 4 6,1*6&lt;3*4,越边边乘积越小</span></span><br><span class="line">                res.push_back(<span class="built_in">array</span>[i]);</span><br><span class="line">                res.push_back(<span class="built_in">array</span>[j]);</span><br><span class="line">                <span class="keyword">break</span>;</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">else</span> <span class="keyword">if</span>(<span class="built_in">array</span>[i]+<span class="built_in">array</span>[j] &gt; sum) j--;</span><br><span class="line">            <span class="keyword">else</span> i++;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="43、左旋转字符串"><a href="#43、左旋转字符串" class="headerlink" title="43、左旋转字符串"></a>43、左旋转字符串</h1><p>汇编语言中有一种移位指令叫做循环左移（ROL），现在有个简单的任务，就是用字符串模拟这个指令的运算结果。对于一个给定的字符序列S，请你把其循环左移K位后的序列输出。例如，字符序列S=”abcXYZdef”,要求输出循环左移3位后的结果，即“XYZdefabc”。是不是很简单？OK，搞定它！</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function"><span class="built_in">string</span> <span class="title">LeftRotateString</span><span class="params">(<span class="built_in">string</span> str, <span class="keyword">int</span> n)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">if</span>(str.empty()) <span class="keyword">return</span> <span class="string">""</span>;</span><br><span class="line">        n%=str.size();</span><br><span class="line">        <span class="keyword">return</span> str.substr(n)+str.substr(<span class="number">0</span>,n);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="44、翻转单词顺序列"><a href="#44、翻转单词顺序列" class="headerlink" title="44、翻转单词顺序列"></a>44、翻转单词顺序列</h1><p>牛客最近来了一个新员工Fish，每天早晨总是会拿着一本英文杂志，写些句子在本子上。同事Cat对Fish写的内容颇感兴趣，有一天他向Fish借来翻看，但却读不懂它的意思。例如，“student. a am I”。后来才意识到，这家伙原来把句子单词的顺序翻转了，正确的句子应该是“I am a student.”。Cat对一一的翻转这些单词顺序可不在行，你能帮助他么？</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function"><span class="built_in">string</span> <span class="title">ReverseSentence</span><span class="params">(<span class="built_in">string</span> str)</span> </span>&#123;</span><br><span class="line">        <span class="built_in">string</span> res;</span><br><span class="line">        <span class="built_in">stack</span>&lt;<span class="built_in">string</span>&gt; <span class="built_in">stack</span>;</span><br><span class="line">        <span class="built_in">string</span> tmp;</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;str.size();i++)&#123;</span><br><span class="line">            <span class="keyword">if</span>(str[i] == <span class="string">' '</span>)&#123;</span><br><span class="line">                <span class="built_in">stack</span>.push(tmp);</span><br><span class="line">                tmp.clear();</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">else</span> tmp.push_back(str[i]);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="built_in">stack</span>.push(tmp);</span><br><span class="line">        <span class="keyword">while</span>(!<span class="built_in">stack</span>.empty())&#123;</span><br><span class="line">            res += <span class="string">' '</span> + <span class="built_in">stack</span>.top();</span><br><span class="line">            <span class="built_in">stack</span>.pop();</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> res.erase(<span class="number">0</span>,<span class="number">1</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="45、扑克牌顺子"><a href="#45、扑克牌顺子" class="headerlink" title="45、扑克牌顺子"></a>45、扑克牌顺子</h1><p>LL今天心情特别好,因为他去买了一副扑克牌,发现里面居然有2个大王,2个小王(一副牌原本是54张^_^)…他随机从中抽出了5张牌,想测测自己的手气,看看能不能抽到顺子,如果抽到的话,他决定去买体育彩票,嘿嘿！！“红心A,黑桃3,小王,大王,方片5”,“Oh My God!”不是顺子…..LL不高兴了,他想了想,决定大\小 王可以看成任何数字,并且A看作1,J为11,Q为12,K为13。上面的5张牌就可以变成“1,2,3,4,5”(大小王分别看作2和4),“So Lucky!”。LL决定去买体育彩票啦。 现在,要求你使用这幅牌模拟上面的过程,然后告诉我们LL的运气如何， 如果牌能组成顺子就输出true，否则就输出false。为了方便起见,你可以认为大小王是0。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment"> max 记录 最大值,min 记录  最小值,min ,max 都不记0</span></span><br><span class="line"><span class="comment"> 满足条件 max - min &lt;5;除0外没有重复的数字(牌);数组长度 为5</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function"><span class="keyword">bool</span> <span class="title">IsContinuous</span><span class="params">( <span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; numbers )</span> </span>&#123; <span class="comment">// 5张牌</span></span><br><span class="line">        <span class="keyword">if</span>(numbers.size()!=<span class="number">5</span>) <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">        <span class="keyword">int</span> max = <span class="number">-1</span>, min = <span class="number">14</span>;</span><br><span class="line">        <span class="keyword">int</span>* flag = <span class="keyword">new</span> <span class="keyword">int</span>[<span class="number">14</span>](); <span class="comment">//初始化数组全为 0</span></span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;numbers.size();i++)&#123;</span><br><span class="line">            <span class="keyword">if</span>(numbers[i] == <span class="number">0</span>) <span class="keyword">continue</span>;</span><br><span class="line">            <span class="keyword">int</span> tmp = numbers[i];</span><br><span class="line">            <span class="keyword">if</span>(flag[tmp] == <span class="number">1</span>) <span class="keyword">return</span> <span class="literal">false</span>; <span class="comment">//重复</span></span><br><span class="line">            <span class="keyword">else</span>&#123;</span><br><span class="line">                <span class="keyword">if</span>(tmp &lt; min) min = tmp;</span><br><span class="line">                <span class="keyword">if</span>(tmp &gt; max) max = tmp;</span><br><span class="line">                flag[tmp] = <span class="number">1</span>;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">delete</span>[] flag;</span><br><span class="line">        <span class="keyword">return</span> max-min&lt;<span class="number">5</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="46、孩子们的游戏（圆圈中最后剩下的数）"><a href="#46、孩子们的游戏（圆圈中最后剩下的数）" class="headerlink" title="46、孩子们的游戏（圆圈中最后剩下的数）"></a>46、孩子们的游戏（圆圈中最后剩下的数）</h1><p>每年六一儿童节,牛客都会准备一些小礼物去看望孤儿院的小朋友,今年亦是如此。HF作为牛客的资深元老,自然也准备了一些小游戏。其中,有个游戏是这样的:首先,让小朋友们围成一个大圈。然后,他随机指定一个数m,让编号为0的小朋友开始报数。每次喊到m-1的那个小朋友要出列唱首歌,然后可以在礼品箱中任意的挑选礼物,并且不再回到圈中,从他的下一个小朋友开始,继续0…m-1报数….这样下去….直到剩下最后一个小朋友,可以不用表演,并且拿到牛客名贵的“名侦探柯南”典藏版(名额有限哦!!^_^)。请你试着想下,哪个小朋友会得到这份礼品呢？(注：小朋友的编号是从0到n-1)</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function"><span class="keyword">int</span> <span class="title">LastRemaining_Solution</span><span class="params">(<span class="keyword">int</span> n, <span class="keyword">int</span> m)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">if</span> (m == <span class="number">0</span> || n == <span class="number">0</span>) <span class="keyword">return</span> <span class="number">-1</span>;</span><br><span class="line">        <span class="keyword">int</span>* flag = <span class="keyword">new</span> <span class="keyword">int</span>[n]();<span class="comment">//初始化数组全为 0</span></span><br><span class="line">        <span class="keyword">int</span> i = <span class="number">-1</span>,left = n,step = <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">while</span>(left&gt;<span class="number">0</span>)&#123;</span><br><span class="line">            i++; <span class="comment">//0</span></span><br><span class="line">            <span class="keyword">if</span>(i == n) i = <span class="number">0</span>; <span class="comment">//模拟环</span></span><br><span class="line">            <span class="keyword">if</span>(flag[i] == <span class="number">1</span>) <span class="keyword">continue</span>; <span class="comment">//跳过被删除的对象</span></span><br><span class="line">            step++;</span><br><span class="line">            <span class="keyword">if</span>(step == m)&#123;</span><br><span class="line">                step = <span class="number">0</span>;</span><br><span class="line">                flag[i] = <span class="number">1</span>;</span><br><span class="line">                left--;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> i;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="47、求1-2-3-…-n"><a href="#47、求1-2-3-…-n" class="headerlink" title="47、求1+2+3+…+n"></a>47、求1+2+3+…+n</h1><p>求1+2+3+…+n，要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句（A?B:C）。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment"> int Sum_Solution(int n) &#123;</span></span><br><span class="line"><span class="comment">     if(n == 0) return 0;</span></span><br><span class="line"><span class="comment">     return n+Sum_Solution(n-1);</span></span><br><span class="line"><span class="comment"> &#125;</span></span><br><span class="line"><span class="comment"> 将此段代码改写成不使用for、while、if、else、switch、case等关键字及条件判断语句</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function"><span class="keyword">int</span> <span class="title">Sum_Solution</span><span class="params">(<span class="keyword">int</span> n)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">int</span> res = n;</span><br><span class="line">        res &amp;&amp; (res+=Sum_Solution(n<span class="number">-1</span>));</span><br><span class="line">        <span class="comment">//当n==0时，只执行前面的判断，为false，然后直接返回0；</span></span><br><span class="line">        <span class="comment">//当n&gt;0时，执行sum+=Sum_Solution(n-1)，实现递归计算Sum_Solution(n)</span></span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="48、不用加减乘除做加法"><a href="#48、不用加减乘除做加法" class="headerlink" title="48、不用加减乘除做加法"></a>48、不用加减乘除做加法</h1><p>写一个函数，求两个整数之和，要求在函数体内不得使用+、-、*、/四则运算符号。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment"> 两数相与再左移一位，表示相加进位的值 101&amp;111=101 左移1，1010</span></span><br><span class="line"><span class="comment"> 两数异或，表示相加不算进位的值 101^111=010</span></span><br><span class="line"><span class="comment"> 两者相加为和，(101&amp;111)&lt;&lt;1 + 101^111 = 1100,即调用函数本身，直到进位为0</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function"><span class="keyword">int</span> <span class="title">Add</span><span class="params">(<span class="keyword">int</span> num1, <span class="keyword">int</span> num2)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">while</span>(num2!=<span class="number">0</span>)&#123;</span><br><span class="line">            <span class="keyword">int</span> tmp = num1^num2; <span class="comment">//相加不算进位的值</span></span><br><span class="line">            num2 = (num1&amp;num2)&lt;&lt;<span class="number">1</span>; <span class="comment">//相加进位的值</span></span><br><span class="line">            num1 = tmp;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> num1;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="49、把字符串转换成整数"><a href="#49、把字符串转换成整数" class="headerlink" title="49、把字符串转换成整数"></a>49、把字符串转换成整数</h1><p>将一个字符串转换成一个整数(实现Integer.valueOf(string)的功能，但是string不符合数字要求时返回0)，要求不能使用字符串转换整数的库函数。 数值为0或者字符串不是一个合法的数值则返回0。<br>输入描述:<br>输入一个字符串,包括数字字母符号,可以为空<br>输出描述:<br>如果是合法的数值表达则返回该数字，否则返回0</p><p>输入: +2147483647  ,  1a33<br>输出: 2147483647  ,  0<br> <figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment"> 字符"0123456789"的值是连续的，如果c"0123456789"范围内</span></span><br><span class="line"><span class="comment"> int a = c - '0'就是对应整数值</span></span><br><span class="line"><span class="comment"> 从后往前，最后判断符号位</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function"><span class="keyword">int</span> <span class="title">StrToInt</span><span class="params">(<span class="built_in">string</span> str)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">if</span>(str.empty()) <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">int</span> res = <span class="number">0</span>,base = <span class="number">1</span>;</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i = str.size()<span class="number">-1</span>;i&gt;=<span class="number">0</span>;i--)&#123;</span><br><span class="line">            <span class="keyword">if</span>(str[i]&gt;=<span class="string">'0'</span> &amp;&amp; str[i]&lt;=<span class="string">'9'</span>)&#123;</span><br><span class="line">                res += base*(<span class="keyword">int</span>)(str[i]-<span class="string">'0'</span>);</span><br><span class="line">                base *= <span class="number">10</span>;</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">else</span> <span class="keyword">if</span>(str[i] == <span class="string">'-'</span>)&#123;</span><br><span class="line">                <span class="keyword">if</span>(i == <span class="number">0</span>) <span class="keyword">return</span> -res; <span class="comment">//-123</span></span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">else</span> <span class="keyword">if</span>(str[i] == <span class="string">'+'</span>)&#123;</span><br><span class="line">                <span class="keyword">if</span>(i == <span class="number">0</span>) <span class="keyword">return</span> res; <span class="comment">//+123</span></span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">else</span> <span class="keyword">return</span> <span class="number">0</span>; <span class="comment">//1a3</span></span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> res; <span class="comment">//123</span></span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure></p><h1 id="50、数组中重复的数字"><a href="#50、数组中重复的数字" class="headerlink" title="50、数组中重复的数字"></a>50、数组中重复的数字</h1><p>在一个长度为n的数组里的所有数字都在0到n-1的范围内。 数组中某些数字是重复的，但不知道有几个数字是重复的。也不知道每个数字重复几次。请找出数组中任意一个重复的数字。 例如，如果输入长度为7的数组{2,3,1,0,2,5,3}，那么对应的输出是第一个重复的数字2。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment"> 数字的范围保证在0 ~ n-1 之间，所以可以利用现有数组设置标志</span></span><br><span class="line"><span class="comment"> 当一个数字i被访问过后，可以设置对应位上的数numbers[i] += n</span></span><br><span class="line"><span class="comment"> 再次访问i时，发现numbers[i] &gt;=n，直接返回i</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="comment">// Parameters:</span></span><br><span class="line">    <span class="comment">//        numbers:     an array of integers</span></span><br><span class="line">    <span class="comment">//        length:      the length of array numbers</span></span><br><span class="line">    <span class="comment">//        duplication: (Output) the duplicated number in the array number</span></span><br><span class="line">    <span class="comment">// Return value:       true if the input is valid, and there are some duplications in the array number</span></span><br><span class="line">    <span class="comment">//                     otherwise false</span></span><br><span class="line">    <span class="function"><span class="keyword">bool</span> <span class="title">duplicate</span><span class="params">(<span class="keyword">int</span> numbers[], <span class="keyword">int</span> length, <span class="keyword">int</span>* duplication)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;length;i++)&#123; <span class="comment">//2,3,1,0,2,5,3</span></span><br><span class="line">            <span class="keyword">int</span> cur = numbers[i];</span><br><span class="line">            <span class="keyword">if</span>(cur &gt;= length) cur = cur-length;</span><br><span class="line">            <span class="keyword">if</span>(numbers[cur] &gt;= length)&#123;</span><br><span class="line">                *duplication = cur;</span><br><span class="line">                <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line">            &#125;</span><br><span class="line">            numbers[cur] += length;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="51、构建乘积数组"><a href="#51、构建乘积数组" class="headerlink" title="51、构建乘积数组"></a>51、构建乘积数组</h1><p>给定一个数组A[0,1,…,n-1],请构建一个数组B[0,1,…,n-1],其中B中的元素B[i]=A[0]<em>A[1]</em>…<em>A[i-1]</em>A[i+1]<em>…</em>A[n-1]。不能使用除法。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment"> 1                             第一项左侧</span></span><br><span class="line"><span class="comment"> a[0]                          第二项左侧</span></span><br><span class="line"><span class="comment"> a[0]*a[1]</span></span><br><span class="line"><span class="comment"> a[0]*a[1]*a[2]</span></span><br><span class="line"><span class="comment"> a[0]*a[1]*a[2]...*a[n-2]      第n项左侧</span></span><br><span class="line"><span class="comment"> </span></span><br><span class="line"><span class="comment"> 1                             第n项右侧</span></span><br><span class="line"><span class="comment"> a[n-1]</span></span><br><span class="line"><span class="comment"> a[n-1]*a[n-2]</span></span><br><span class="line"><span class="comment"> a[n-1]*a[n-2]*a[n-3]...*a[2]  第二项左侧</span></span><br><span class="line"><span class="comment"> a[n-1]*a[n-2]*a[n-3]...*a[1]  第一项右侧</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; multiply(<span class="keyword">const</span> <span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt;&amp; A) &#123;</span><br><span class="line">        <span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; res;</span><br><span class="line">        <span class="keyword">if</span>(A.empty()) <span class="keyword">return</span> res;</span><br><span class="line">        <span class="keyword">int</span> tmp = <span class="number">1</span>;</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;A.size();i++)&#123; <span class="comment">//左边乘</span></span><br><span class="line">            res.push_back(tmp);</span><br><span class="line">            tmp *= A[i];</span><br><span class="line">        &#125; </span><br><span class="line">        tmp = <span class="number">1</span>;</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i=A.size()<span class="number">-1</span>;i&gt;=<span class="number">0</span>;i--)&#123; <span class="comment">//右边乘</span></span><br><span class="line">            res[i] *= tmp;</span><br><span class="line">            tmp *= A[i];</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="52、正则表达式匹配"><a href="#52、正则表达式匹配" class="headerlink" title="52、正则表达式匹配"></a>52、正则表达式匹配</h1><p>请实现一个函数用来匹配包括’.’和’<em>‘的正则表达式。模式中的字符’.’表示任意一个字符，而’</em>‘表示它前面的字符可以出现任意次（包含0次）。 在本题中，匹配是指字符串的所有字符匹配整个模式。例如，字符串”aaa”与模式”a.a”和”ab<em>ac</em>a”匹配，但是与”aa.a”和”ab*a”均不匹配</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment"> 当第二个字符不是“*”时：</span></span><br><span class="line"><span class="comment"> 1、第一个字符匹配，字符串和模式后移1个字符，继续匹配 </span></span><br><span class="line"><span class="comment"> 2、第一个字符不匹配，返回false</span></span><br><span class="line"><span class="comment"> 当第二个字符是“*”时：</span></span><br><span class="line"><span class="comment"> 1、第一个字符不匹配，模式后移2个字符，继续匹配</span></span><br><span class="line"><span class="comment"> 2、第一个字符匹配，可以有3种情况：</span></span><br><span class="line"><span class="comment">    （1）模式后移2字符，相当于x*被忽略，x出现0次；</span></span><br><span class="line"><span class="comment">    （2）字符串后移1字符，模式后移2字符，相当于x出现一次；</span></span><br><span class="line"><span class="comment">    （3）字符串后移1字符，模式不变，相当于x出现多次次；</span></span><br><span class="line"><span class="comment"> 注：匹配指值相同，或pattern为'.',字符串未到尾</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function"><span class="keyword">bool</span> <span class="title">match</span><span class="params">(<span class="keyword">char</span>* str, <span class="keyword">char</span>* pattern)</span></span></span><br><span class="line"><span class="function">    </span>&#123;</span><br><span class="line">        <span class="keyword">if</span>(*str == <span class="string">'\0'</span> &amp;&amp; *pattern == <span class="string">'\0'</span>) <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line">        <span class="keyword">if</span>(*str != <span class="string">'\0'</span> &amp;&amp; *pattern == <span class="string">'\0'</span>) <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">        <span class="keyword">if</span>(*(pattern+<span class="number">1</span>) != <span class="string">'*'</span>)&#123;</span><br><span class="line">            <span class="keyword">if</span>(*str==*pattern || *pattern==<span class="string">'.'</span>&amp;&amp;*str!=<span class="string">'\0'</span>)&#123;</span><br><span class="line">                <span class="keyword">return</span> match(str+<span class="number">1</span>,pattern+<span class="number">1</span>);</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">else</span> <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">else</span>&#123;</span><br><span class="line">            <span class="keyword">if</span>(*str==*pattern || *pattern==<span class="string">'.'</span>&amp;&amp;*str!=<span class="string">'\0'</span>)&#123;</span><br><span class="line">                <span class="keyword">return</span> match(str,pattern+<span class="number">2</span>)|| match(str+<span class="number">1</span>,pattern+<span class="number">2</span>)|| match(str+<span class="number">1</span>,pattern);</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">else</span> <span class="keyword">return</span> match(str,pattern+<span class="number">2</span>);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="53、表示数值的字符串"><a href="#53、表示数值的字符串" class="headerlink" title="53、表示数值的字符串"></a>53、表示数值的字符串</h1><p>请实现一个函数用来判断字符串是否表示数值（包括整数和小数）。例如，字符串”+100”,”5e2”,”-123”,”3.1416”和”-1E-16”都表示数值。 但是”12e”,”1a3.14”,”1.2.3”,”+-5”和”12e+4.3”都不是。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment"> 1、+、-</span></span><br><span class="line"><span class="comment">  第一次出现+-符号，且不在首位，必须紧接在e之后</span></span><br><span class="line"><span class="comment">  第二次出现+-符号，必须紧接在e之后</span></span><br><span class="line"><span class="comment"> 2、e、E</span></span><br><span class="line"><span class="comment">  e后不为空</span></span><br><span class="line"><span class="comment">  不能双e</span></span><br><span class="line"><span class="comment"> 3、.</span></span><br><span class="line"><span class="comment">  .前不能有.或e</span></span><br><span class="line"><span class="comment"> 4、其他</span></span><br><span class="line"><span class="comment">  return false</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function"><span class="keyword">bool</span> <span class="title">isNumeric</span><span class="params">(<span class="keyword">char</span>* <span class="built_in">string</span>)</span> </span>&#123;</span><br><span class="line">        <span class="comment">// 标记符号、小数点、e是否出现过</span></span><br><span class="line">        <span class="keyword">bool</span> hasSign = <span class="literal">false</span>, hasPoint = <span class="literal">false</span>, hasE = <span class="literal">false</span>; </span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">0</span>;<span class="built_in">string</span>[i];i++)&#123;</span><br><span class="line">            <span class="keyword">if</span>(<span class="built_in">string</span>[i] == <span class="string">'+'</span> || <span class="built_in">string</span>[i] == <span class="string">'-'</span>)&#123;</span><br><span class="line">                <span class="keyword">if</span>(!hasSign &amp;&amp; i&gt;<span class="number">0</span> &amp;&amp; <span class="built_in">string</span>[i<span class="number">-1</span>]!=<span class="string">'e'</span> &amp;&amp; <span class="built_in">string</span>[i<span class="number">-1</span>]!=<span class="string">'E'</span>) <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">                <span class="keyword">if</span>(hasSign &amp;&amp; <span class="built_in">string</span>[i<span class="number">-1</span>]!=<span class="string">'e'</span> &amp;&amp; <span class="built_in">string</span>[i<span class="number">-1</span>]!=<span class="string">'E'</span>) <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">                hasSign = <span class="literal">true</span>;</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">else</span> <span class="keyword">if</span>(<span class="built_in">string</span>[i] == <span class="string">'e'</span> || <span class="built_in">string</span>[i] == <span class="string">'E'</span>)&#123;</span><br><span class="line">                <span class="keyword">if</span>(<span class="built_in">string</span>[i+<span class="number">1</span>] == <span class="string">'\0'</span> || hasE) <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">                hasE = <span class="literal">true</span>;</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">else</span> <span class="keyword">if</span>(<span class="built_in">string</span>[i] == <span class="string">'.'</span>)&#123;</span><br><span class="line">                <span class="keyword">if</span>(hasPoint || hasE) <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">                hasPoint = <span class="literal">true</span>;</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">else</span> <span class="keyword">if</span>(<span class="built_in">string</span>[i] &lt; <span class="string">'0'</span> || <span class="built_in">string</span>[i] &gt; <span class="string">'9'</span>) <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="54、字符流中第一个不重复的字符"><a href="#54、字符流中第一个不重复的字符" class="headerlink" title="54、字符流中第一个不重复的字符"></a>54、字符流中第一个不重复的字符</h1><p>请实现一个函数用来找出字符流中第一个只出现一次的字符。例如，当从字符流中只读出前两个字符”go”时，第一个只出现一次的字符是”g”。当从该字符流中读出前六个字符“google”时，第一个只出现一次的字符是”l”。<br>输出描述:<br>如果当前字符流没有存在出现一次的字符，返回#字符。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment"> 字符在计算机中以ASCII码的形式存储，当字符作为数组下标时，其表示的下标值为该字符的ASCII码的十进制值</span></span><br><span class="line"><span class="comment"> 0-9:  48-57  ,A-Z:  65-90  ,a-z:  97-122   ASCII码:0~127</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span></span></span><br><span class="line"><span class="class">&#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="built_in">string</span> s;</span><br><span class="line">    <span class="keyword">char</span> flag[<span class="number">128</span>] = &#123;<span class="number">0</span>&#125;; </span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">Insert</span><span class="params">(<span class="keyword">char</span> ch)</span> </span>&#123;</span><br><span class="line">        s += ch;</span><br><span class="line">        flag[ch]++;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="function"><span class="keyword">char</span> <span class="title">FirstAppearingOnce</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;s.size();i++)&#123;</span><br><span class="line">            <span class="keyword">if</span>(flag[s[i]] == <span class="number">1</span>) <span class="keyword">return</span> s[i];</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> <span class="string">'#'</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="55、链表中环的入口结点"><a href="#55、链表中环的入口结点" class="headerlink" title="55、链表中环的入口结点"></a>55、链表中环的入口结点</h1><p>给一个链表，若其中包含环，请找出该链表的环的入口结点，否则，输出null。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment"> 如果有环，快慢指针总会相遇</span></span><br><span class="line"><span class="comment"> 1——2——3——4——5——6</span></span><br><span class="line"><span class="comment">          |     |</span></span><br><span class="line"><span class="comment">          9——8——7</span></span><br><span class="line"><span class="comment"> 假设快慢指针相遇在6，有1~6走的=6~6走的</span></span><br><span class="line"><span class="comment"> 1~6走的 = 1~入环点+入环点~6</span></span><br><span class="line"><span class="comment"> 6~6走的 = 6~入环点+入环点~6</span></span><br><span class="line"><span class="comment"> 则当快指针从1重新开始，两指针速度相同，再次相遇即为入口节点</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment">struct ListNode &#123;</span></span><br><span class="line"><span class="comment">    int val;</span></span><br><span class="line"><span class="comment">    struct ListNode *next;</span></span><br><span class="line"><span class="comment">    ListNode(int x) :</span></span><br><span class="line"><span class="comment">        val(x), next(NULL) &#123;</span></span><br><span class="line"><span class="comment">    &#125;</span></span><br><span class="line"><span class="comment">&#125;;</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function">ListNode* <span class="title">EntryNodeOfLoop</span><span class="params">(ListNode* pHead)</span> </span>&#123;</span><br><span class="line">        <span class="comment">//快慢指针，判断是否有环</span></span><br><span class="line">        <span class="keyword">bool</span> hasLoop = <span class="literal">false</span>;</span><br><span class="line">        ListNode* fast = pHead;</span><br><span class="line">        ListNode* slow = pHead;</span><br><span class="line">        <span class="keyword">while</span>(fast &amp;&amp; fast-&gt;next)&#123;</span><br><span class="line">            fast = fast-&gt;next-&gt;next;</span><br><span class="line">            slow = slow-&gt;next;</span><br><span class="line">            <span class="keyword">if</span>(fast == slow)&#123;</span><br><span class="line">                hasLoop = <span class="literal">true</span>;</span><br><span class="line">                <span class="keyword">break</span>;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="comment">//寻找环的入口节点</span></span><br><span class="line">        <span class="keyword">if</span>(hasLoop)&#123;</span><br><span class="line">            fast = pHead;</span><br><span class="line">            <span class="keyword">while</span>(fast != slow)&#123;</span><br><span class="line">                fast = fast-&gt;next;</span><br><span class="line">                slow = slow-&gt;next;</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">return</span> slow;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> <span class="literal">NULL</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="56、删除链表中重复的结点"><a href="#56、删除链表中重复的结点" class="headerlink" title="56、删除链表中重复的结点"></a>56、删除链表中重复的结点</h1><p>在一个排序的链表中，存在重复的结点，请删除该链表中重复的结点，重复的结点不保留，返回链表头指针。 例如，链表1-&gt;2-&gt;3-&gt;3-&gt;4-&gt;4-&gt;5 处理后为 1-&gt;2-&gt;5</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment">struct ListNode &#123;</span></span><br><span class="line"><span class="comment">    int val;</span></span><br><span class="line"><span class="comment">    struct ListNode *next;</span></span><br><span class="line"><span class="comment">    ListNode(int x) :</span></span><br><span class="line"><span class="comment">        val(x), next(NULL) &#123;</span></span><br><span class="line"><span class="comment">    &#125;</span></span><br><span class="line"><span class="comment">&#125;;</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function">ListNode* <span class="title">deleteDuplication</span><span class="params">(ListNode* pHead)</span> </span>&#123;</span><br><span class="line">        ListNode* root = <span class="keyword">new</span> ListNode(<span class="number">0</span>);<span class="comment">//设为几无所谓</span></span><br><span class="line">        ListNode* h = root; <span class="comment">//标记当前位置</span></span><br><span class="line">        h-&gt;next = pHead;</span><br><span class="line">        <span class="keyword">while</span>(h-&gt;next &amp;&amp; h-&gt;next-&gt;next)&#123;<span class="comment">//至少两个节点</span></span><br><span class="line">            ListNode* tmp = h-&gt;next-&gt;next;</span><br><span class="line">            <span class="keyword">if</span>(h-&gt;next-&gt;val == tmp-&gt;val)&#123;<span class="comment">//两节点相同</span></span><br><span class="line">                <span class="keyword">while</span>(tmp &amp;&amp; h-&gt;next-&gt;val == tmp-&gt;val)&#123;</span><br><span class="line">                    tmp = tmp-&gt;next;</span><br><span class="line">                &#125;</span><br><span class="line">                h-&gt;next = tmp; <span class="comment">//删除操作</span></span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">else</span> h = h-&gt;next;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> root-&gt;next;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="57、二叉树的下一个结点"><a href="#57、二叉树的下一个结点" class="headerlink" title="57、二叉树的下一个结点"></a>57、二叉树的下一个结点</h1><p>给定一个二叉树和其中的一个结点，请找出中序遍历顺序的下一个结点并且返回。注意，树中的结点不仅包含左右子结点，同时包含指向父结点的指针。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment"> 3种情况：</span></span><br><span class="line"><span class="comment">       1              1              1</span></span><br><span class="line"><span class="comment">      / \            / \            / \</span></span><br><span class="line"><span class="comment">     2   3          2   4          2   5</span></span><br><span class="line"><span class="comment">        / \        /              / \</span></span><br><span class="line"><span class="comment">       4   5      3              3   4</span></span><br><span class="line"><span class="comment">  cur=1,next=4   cur=2,next=1   cur=4,next=1</span></span><br><span class="line"><span class="comment"> 情况1，有右子树，返回右子树的左下角</span></span><br><span class="line"><span class="comment"> 情况2，无右子树，且是父结点的左子树，返回父结点</span></span><br><span class="line"><span class="comment"> 情况3，无右子树，且是父结点的右子树，返回父结点的左上角的父结点</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment">struct TreeLinkNode &#123;</span></span><br><span class="line"><span class="comment">    int val;</span></span><br><span class="line"><span class="comment">    struct TreeLinkNode *left;</span></span><br><span class="line"><span class="comment">    struct TreeLinkNode *right;</span></span><br><span class="line"><span class="comment">    struct TreeLinkNode *next;</span></span><br><span class="line"><span class="comment">    TreeLinkNode(int x) :val(x), left(NULL), right(NULL), next(NULL) &#123;</span></span><br><span class="line"><span class="comment">        </span></span><br><span class="line"><span class="comment">    &#125;</span></span><br><span class="line"><span class="comment">&#125;;</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span>   </span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function">TreeLinkNode* <span class="title">GetNext</span><span class="params">(TreeLinkNode* pNode)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">if</span>(pNode-&gt;right)&#123;</span><br><span class="line">            TreeLinkNode* res = pNode-&gt;right;</span><br><span class="line">            <span class="keyword">while</span>(res-&gt;left)&#123;</span><br><span class="line">                res = res-&gt;left;</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">return</span> res;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">else</span>&#123;  </span><br><span class="line">            <span class="keyword">while</span>(pNode-&gt;next &amp;&amp; pNode-&gt;next-&gt;right == pNode)&#123;</span><br><span class="line">                pNode = pNode-&gt;next;</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">return</span> pNode-&gt;next;</span><br><span class="line">        &#125;</span><br><span class="line">        </span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="58、对称的二叉树"><a href="#58、对称的二叉树" class="headerlink" title="58、对称的二叉树"></a>58、对称的二叉树</h1><p>请实现一个函数，用来判断一颗二叉树是不是对称的。注意，如果一个二叉树同此二叉树的镜像是同样的，定义其为对称的。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment">struct TreeNode &#123;</span></span><br><span class="line"><span class="comment">    int val;</span></span><br><span class="line"><span class="comment">    struct TreeNode *left;</span></span><br><span class="line"><span class="comment">    struct TreeNode *right;</span></span><br><span class="line"><span class="comment">    TreeNode(int x) :</span></span><br><span class="line"><span class="comment">            val(x), left(NULL), right(NUL L) &#123;</span></span><br><span class="line"><span class="comment">    &#125;</span></span><br><span class="line"><span class="comment">&#125;;</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function"><span class="keyword">bool</span> <span class="title">isSymmetrical</span><span class="params">(TreeNode* pRoot)</span></span>&#123;</span><br><span class="line">        <span class="keyword">if</span>(!pRoot) <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line">        <span class="keyword">return</span> ismoir(pRoot-&gt;left,pRoot-&gt;right);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="function"><span class="keyword">bool</span> <span class="title">ismoir</span><span class="params">(TreeNode* l,TreeNode* r)</span></span>&#123;<span class="comment">//是镜像的</span></span><br><span class="line">        <span class="keyword">if</span>(!l &amp;&amp; !r) <span class="keyword">return</span> <span class="literal">true</span>;<span class="comment">//都不存在</span></span><br><span class="line">        <span class="keyword">if</span>(l &amp;&amp; r) <span class="keyword">return</span> l-&gt;val==r-&gt;val &amp;&amp; ismoir(l-&gt;left,r-&gt;right) &amp;&amp; ismoir(r-&gt;left,l-&gt;right);</span><br><span class="line">        <span class="keyword">return</span> <span class="literal">false</span>;<span class="comment">// 有且仅有1个存在</span></span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="59、按之字形顺序打印二叉树"><a href="#59、按之字形顺序打印二叉树" class="headerlink" title="59、按之字形顺序打印二叉树"></a>59、按之字形顺序打印二叉树</h1><p>请实现一个函数按照之字形打印二叉树，即第一行按照从左到右的顺序打印，第二层按照从右至左的顺序打印，第三行按照从左到右的顺序打印，其他行以此类推。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment">        1         ——&gt; stack1 存奇数层，顺序</span></span><br><span class="line"><span class="comment">       / \</span></span><br><span class="line"><span class="comment">      2   3       &lt;—— stack2 存偶数层，逆序,先left后right</span></span><br><span class="line"><span class="comment">     / \  / \</span></span><br><span class="line"><span class="comment">    4  5 6   7    ——&gt; stack1 存奇数层，顺序,先right后left</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment">struct TreeNode &#123;</span></span><br><span class="line"><span class="comment">    int val;</span></span><br><span class="line"><span class="comment">    struct TreeNode *left;</span></span><br><span class="line"><span class="comment">    struct TreeNode *right;</span></span><br><span class="line"><span class="comment">    TreeNode(int x) :</span></span><br><span class="line"><span class="comment">            val(x), left(NULL), right(NULL) &#123;</span></span><br><span class="line"><span class="comment">    &#125;</span></span><br><span class="line"><span class="comment">&#125;;</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="built_in">vector</span>&lt;<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; &gt; Print(TreeNode* pRoot) &#123;</span><br><span class="line">        <span class="built_in">vector</span>&lt;<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; &gt; res;</span><br><span class="line">        <span class="keyword">if</span>(!pRoot) <span class="keyword">return</span> res;</span><br><span class="line">        <span class="built_in">stack</span>&lt;TreeNode*&gt; stack1,stack2;</span><br><span class="line">        stack1.push(pRoot);</span><br><span class="line">        <span class="keyword">while</span>(!stack1.empty() || !stack2.empty())&#123;</span><br><span class="line">            <span class="keyword">if</span>(!stack1.empty())&#123;</span><br><span class="line">                <span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; tmp;</span><br><span class="line">                <span class="keyword">while</span>(!stack1.empty())&#123;</span><br><span class="line">                    <span class="keyword">if</span>(stack1.top()-&gt;left) stack2.push(stack1.top()-&gt;left);</span><br><span class="line">                    <span class="keyword">if</span>(stack1.top()-&gt;right) stack2.push(stack1.top()-&gt;right);</span><br><span class="line">                    tmp.push_back(stack1.top()-&gt;val);</span><br><span class="line">                    stack1.pop();</span><br><span class="line">                &#125;</span><br><span class="line">                res.push_back(tmp);</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">if</span>(!stack2.empty())&#123;</span><br><span class="line">                <span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; tmp;</span><br><span class="line">                <span class="keyword">while</span>(!stack2.empty())&#123;</span><br><span class="line">                    <span class="keyword">if</span>(stack2.top()-&gt;right) stack1.push(stack2.top()-&gt;right);</span><br><span class="line">                    <span class="keyword">if</span>(stack2.top()-&gt;left) stack1.push(stack2.top()-&gt;left);</span><br><span class="line">                    tmp.push_back(stack2.top()-&gt;val);</span><br><span class="line">                    stack2.pop();</span><br><span class="line">                &#125;</span><br><span class="line">                res.push_back(tmp);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="60、把二叉树打印成多行"><a href="#60、把二叉树打印成多行" class="headerlink" title="60、把二叉树打印成多行"></a>60、把二叉树打印成多行</h1><p>从上到下按层打印二叉树，同一层结点从左至右输出。每一层输出一行。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment">struct TreeNode &#123;</span></span><br><span class="line"><span class="comment">    int val;</span></span><br><span class="line"><span class="comment">    struct TreeNode *left;</span></span><br><span class="line"><span class="comment">    struct TreeNode *right;</span></span><br><span class="line"><span class="comment">    TreeNode(int x) :</span></span><br><span class="line"><span class="comment">            val(x), left(NULL), right(NULL) &#123;</span></span><br><span class="line"><span class="comment">    &#125;</span></span><br><span class="line"><span class="comment">&#125;;</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">        <span class="built_in">vector</span>&lt;<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; &gt; Print(TreeNode* pRoot) &#123;</span><br><span class="line">            <span class="built_in">vector</span>&lt;<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; &gt; res;</span><br><span class="line">            <span class="keyword">if</span>(!pRoot) <span class="keyword">return</span> res;</span><br><span class="line">            <span class="built_in">queue</span>&lt;TreeNode*&gt; <span class="built_in">queue</span>;</span><br><span class="line">            <span class="built_in">queue</span>.push(pRoot);</span><br><span class="line">            <span class="keyword">while</span>(!<span class="built_in">queue</span>.empty())&#123;</span><br><span class="line">                <span class="keyword">int</span> num = <span class="built_in">queue</span>.size();</span><br><span class="line">                <span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; tmp;</span><br><span class="line">                <span class="keyword">while</span>(num!=<span class="number">0</span>)&#123;</span><br><span class="line">                    <span class="keyword">if</span>(<span class="built_in">queue</span>.front()-&gt;left) <span class="built_in">queue</span>.push(<span class="built_in">queue</span>.front()-&gt;left);</span><br><span class="line">                    <span class="keyword">if</span>(<span class="built_in">queue</span>.front()-&gt;right) <span class="built_in">queue</span>.push(<span class="built_in">queue</span>.front()-&gt;right);</span><br><span class="line">                    tmp.push_back(<span class="built_in">queue</span>.front()-&gt;val);</span><br><span class="line">                    <span class="built_in">queue</span>.pop();</span><br><span class="line">                    num--;</span><br><span class="line">                &#125;</span><br><span class="line">                res.push_back(tmp);</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">return</span> res;</span><br><span class="line">        &#125;</span><br><span class="line">    </span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="61、序列化二叉树"><a href="#61、序列化二叉树" class="headerlink" title="61、序列化二叉树"></a>61、序列化二叉树</h1><p>请实现两个函数，分别用来序列化和反序列化二叉树</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment">struct TreeNode &#123;</span></span><br><span class="line"><span class="comment">    int val;</span></span><br><span class="line"><span class="comment">    struct TreeNode *left;</span></span><br><span class="line"><span class="comment">    struct TreeNode *right;</span></span><br><span class="line"><span class="comment">    TreeNode(int x) :</span></span><br><span class="line"><span class="comment">            val(x), left(NULL), right(NULL) &#123;</span></span><br><span class="line"><span class="comment">    &#125;</span></span><br><span class="line"><span class="comment">&#125;;</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function"><span class="keyword">char</span>* <span class="title">Serialize</span><span class="params">(TreeNode *root)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">if</span>(!root) <span class="keyword">return</span> <span class="literal">NULL</span>;</span><br><span class="line">        <span class="built_in">string</span> s;</span><br><span class="line">        <span class="built_in">queue</span>&lt;TreeNode*&gt; <span class="built_in">queue</span>;</span><br><span class="line">        <span class="built_in">queue</span>.push(root);</span><br><span class="line">        <span class="keyword">while</span>(!<span class="built_in">queue</span>.empty())&#123;</span><br><span class="line">            <span class="keyword">if</span>(<span class="built_in">queue</span>.front())&#123;</span><br><span class="line">                <span class="built_in">queue</span>.push(<span class="built_in">queue</span>.front()-&gt;left);</span><br><span class="line">                <span class="built_in">queue</span>.push(<span class="built_in">queue</span>.front()-&gt;right);</span><br><span class="line">                s += to_string(<span class="built_in">queue</span>.front()-&gt;val)+<span class="string">","</span>;</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">else</span> s += <span class="string">"#,"</span>;</span><br><span class="line">            <span class="built_in">queue</span>.pop();</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">char</span>* res = strdup(s.c_str());</span><br><span class="line">        <span class="comment">/* 另一种写法，不用strdup()</span></span><br><span class="line"><span class="comment">        char* res = new char[s.size() + 1];</span></span><br><span class="line"><span class="comment">        int i;</span></span><br><span class="line"><span class="comment">        for(i=0;i&lt;s.size();i++) res[i]=s[i];</span></span><br><span class="line"><span class="comment">        res[i] = '\0';</span></span><br><span class="line"><span class="comment">        */</span></span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="function">TreeNode* <span class="title">Deserialize</span><span class="params">(<span class="keyword">char</span> *str)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">if</span>(!str) <span class="keyword">return</span> <span class="literal">NULL</span>;</span><br><span class="line">        <span class="keyword">int</span> i = <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">auto</span> head = getnode(str,i);</span><br><span class="line">        <span class="built_in">queue</span>&lt;TreeNode*&gt; <span class="built_in">queue</span>;</span><br><span class="line">        <span class="built_in">queue</span>.push(head);</span><br><span class="line">        <span class="keyword">while</span>(!<span class="built_in">queue</span>.empty())&#123;</span><br><span class="line">            <span class="built_in">queue</span>.front()-&gt;left = getnode(str,i);</span><br><span class="line">            <span class="built_in">queue</span>.front()-&gt;right = getnode(str,i);</span><br><span class="line">            <span class="keyword">if</span>(<span class="built_in">queue</span>.front()-&gt;left) <span class="built_in">queue</span>.push(<span class="built_in">queue</span>.front()-&gt;left);</span><br><span class="line">            <span class="keyword">if</span>(<span class="built_in">queue</span>.front()-&gt;right) <span class="built_in">queue</span>.push(<span class="built_in">queue</span>.front()-&gt;right);</span><br><span class="line">            <span class="built_in">queue</span>.pop();</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> head;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="function">TreeNode* <span class="title">getnode</span><span class="params">(<span class="keyword">char</span> *str,<span class="keyword">int</span> &amp;i)</span></span>&#123;</span><br><span class="line">        <span class="keyword">if</span>(str[i] == <span class="string">','</span>) i++;</span><br><span class="line">        <span class="keyword">if</span>(str[i] == <span class="string">'#'</span>)&#123;</span><br><span class="line">            i += <span class="number">2</span>;</span><br><span class="line">            <span class="keyword">return</span> <span class="literal">NULL</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="built_in">string</span> s;</span><br><span class="line">        <span class="keyword">while</span>(str[i] != <span class="string">','</span> &amp;&amp; str[i] != <span class="string">'\0'</span>)&#123;</span><br><span class="line">            s += str[i];</span><br><span class="line">            i++;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span>(!s.empty()) <span class="keyword">return</span> <span class="keyword">new</span> TreeNode(stoi(s));</span><br><span class="line">        <span class="keyword">return</span> <span class="literal">NULL</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="62、二叉搜索树的第k个结点"><a href="#62、二叉搜索树的第k个结点" class="headerlink" title="62、二叉搜索树的第k个结点"></a>62、二叉搜索树的第k个结点</h1><p>给定一棵二叉搜索树，请找出其中的第k小的结点。例如， （5，3，7，2，4，6，8）    中，按结点数值大小顺序第三小结点的值为4。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment"> 二叉搜索树：左子树上所有结点的值均小于它的根结点的值,右子树上所有结点的值均大于它的根结点的值</span></span><br><span class="line"><span class="comment"> 二叉搜索树按照中序遍历得到递增的顺序，压入栈，第k个结点就是结果</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment">struct TreeNode &#123;</span></span><br><span class="line"><span class="comment">    int val;</span></span><br><span class="line"><span class="comment">    struct TreeNode *left;</span></span><br><span class="line"><span class="comment">    struct TreeNode *right;</span></span><br><span class="line"><span class="comment">    TreeNode(int x) :</span></span><br><span class="line"><span class="comment">            val(x), left(NULL), right(NULL) &#123;</span></span><br><span class="line"><span class="comment">    &#125;</span></span><br><span class="line"><span class="comment">&#125;;</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="built_in">stack</span>&lt;TreeNode*&gt; <span class="built_in">stack</span>;</span><br><span class="line">    <span class="function">TreeNode* <span class="title">KthNode</span><span class="params">(TreeNode* pRoot, <span class="keyword">int</span> k)</span></span>&#123;</span><br><span class="line">        <span class="keyword">if</span>(k &lt;= <span class="number">0</span>) <span class="keyword">return</span> <span class="literal">NULL</span>;</span><br><span class="line">        sortmid(pRoot,k);</span><br><span class="line">        <span class="keyword">if</span>(<span class="built_in">stack</span>.size() &lt; k) <span class="keyword">return</span> <span class="literal">NULL</span>; <span class="comment">//k大于节点数</span></span><br><span class="line">        <span class="keyword">return</span> <span class="built_in">stack</span>.top();</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">sortmid</span><span class="params">(TreeNode* pRoot, <span class="keyword">int</span> k)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">if</span>(!pRoot) <span class="keyword">return</span>;</span><br><span class="line">        <span class="keyword">if</span>(<span class="built_in">stack</span>.size()!=k) sortmid(pRoot-&gt;left,k);</span><br><span class="line">        <span class="keyword">if</span>(<span class="built_in">stack</span>.size()!=k) <span class="built_in">stack</span>.push(pRoot);</span><br><span class="line">        <span class="keyword">if</span>(<span class="built_in">stack</span>.size()!=k) sortmid(pRoot-&gt;right,k);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="63、数据流中的中位数"><a href="#63、数据流中的中位数" class="headerlink" title="63、数据流中的中位数"></a>63、数据流中的中位数</h1><p>如何得到一个数据流中的中位数？如果从数据流中读出奇数个数值，那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值，那么中位数就是所有数值排序之后中间两个数的平均值。我们使用Insert()方法读取数据流，使用GetMedian()方法获取当前读取数据的中位数。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment"> 使用大小顶堆，中位数是大顶堆的根节点与小顶堆的根节点和的平均数</span></span><br><span class="line"><span class="comment"> 大顶堆,由大到小，存较小的数 7 6 5</span></span><br><span class="line"><span class="comment"> 小顶堆,由小到大，存较大的数 8 9 10</span></span><br><span class="line"><span class="comment"> 步骤：</span></span><br><span class="line"><span class="comment"> 第一个插入的元素装大顶堆</span></span><br><span class="line"><span class="comment"> 1、每来一个插入的元素，比大顶堆堆顶元素小的装大顶堆，否则装小顶堆（保证大顶堆的数都比小顶堆的数小）</span></span><br><span class="line"><span class="comment"> 2、判断是否大顶堆装多了，大顶堆最多比小顶堆多一个，如果是，将大顶堆堆顶元素插入小顶堆</span></span><br><span class="line"><span class="comment"> 3、判断是否小顶堆装多了，小顶堆小于等于大顶堆，如果是，将小顶堆堆顶元素插入大顶堆</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    priority_queue&lt;<span class="keyword">int</span>,<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt;,less&lt;<span class="keyword">int</span>&gt; &gt; big_heap;</span><br><span class="line">    priority_queue&lt;<span class="keyword">int</span>,<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt;,greater&lt;<span class="keyword">int</span>&gt; &gt; small_heap;</span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">Insert</span><span class="params">(<span class="keyword">int</span> num)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">if</span>(big_heap.empty() || num &lt; big_heap.top()) big_heap.push(num);</span><br><span class="line">        <span class="keyword">else</span> small_heap.push(num);</span><br><span class="line">        <span class="keyword">if</span>(big_heap.size() == small_heap.size()+<span class="number">2</span>)&#123;</span><br><span class="line">            small_heap.push(big_heap.top());</span><br><span class="line">            big_heap.pop();</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span>(big_heap.size() == small_heap.size()<span class="number">-1</span>)&#123;</span><br><span class="line">            big_heap.push(small_heap.top());</span><br><span class="line">            small_heap.pop();</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">double</span> <span class="title">GetMedian</span><span class="params">()</span> </span>&#123; </span><br><span class="line">        <span class="keyword">return</span> small_heap.size()==big_heap.size()?(small_heap.top()+big_heap.top())/<span class="number">2.0</span>:big_heap.top();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="64、滑动窗口的最大值"><a href="#64、滑动窗口的最大值" class="headerlink" title="64、滑动窗口的最大值"></a>64、滑动窗口的最大值</h1><p>给定一个数组和滑动窗口的大小，找出所有滑动窗口里数值的最大值。例如，如果输入数组{2,3,4,2,6,2,5,1}及滑动窗口的大小3，那么一共存在6个滑动窗口，他们的最大值分别为{4,4,6,6,6,5}； 针对数组{2,3,4,2,6,2,5,1}的滑动窗口有以下6个： {[2,3,4],2,6,2,5,1}， {2,[3,4,2],6,2,5,1}， {2,3,[4,2,6],2,5,1}， {2,3,4,[2,6,2],5,1}， {2,3,4,2,[6,2,5],1}， {2,3,4,2,6,[2,5,1]}。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; maxInWindows(<span class="keyword">const</span> <span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt;&amp; num, <span class="keyword">unsigned</span> <span class="keyword">int</span> size)</span><br><span class="line">    &#123;</span><br><span class="line">        <span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; res;</span><br><span class="line">        <span class="built_in">deque</span>&lt;<span class="keyword">int</span>&gt; q;<span class="comment">//队首为当前窗口下最大值下标</span></span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">unsigned</span> <span class="keyword">int</span> i=<span class="number">0</span>;i&lt;num.size();i++)&#123;</span><br><span class="line">            <span class="keyword">while</span>(!q.empty() &amp;&amp; num[i]&gt;num[q.back()])&#123;<span class="comment">//q删掉所有比当前元素小的，保证q降序</span></span><br><span class="line">                q.pop_back();</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">if</span>(!q.empty() &amp;&amp; q.front()+size == i)&#123; <span class="comment">//若队首超过窗口位置,删掉</span></span><br><span class="line">                q.pop_front();</span><br><span class="line">            &#125;</span><br><span class="line">            q.push_back(i);</span><br><span class="line">            <span class="keyword">if</span>(size &amp;&amp; i+<span class="number">1</span>&gt;=size) res.push_back(num[q.front()]); <span class="comment">//防止size=0</span></span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="65、矩阵中的路径"><a href="#65、矩阵中的路径" class="headerlink" title="65、矩阵中的路径"></a>65、矩阵中的路径</h1><p>请设计一个函数，用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一个格子开始，每一步可以在矩阵中向左，向右，向上，向下移动一个格子。如果一条路径经过了矩阵中的某一个格子，则之后不能再次进入这个格子。 例如 a b c e s f c s a d e e 这样的3 X 4 矩阵中包含一条字符串”bcced”的路径，但是矩阵中不包含”abcb”路径，因为字符串的第一个字符b占据了矩阵中的第一行第二个格子之后，路径不能再次进入该格子。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function"><span class="keyword">bool</span> <span class="title">hasPath</span><span class="params">(<span class="keyword">char</span>* matrix, <span class="keyword">int</span> rows, <span class="keyword">int</span> cols, <span class="keyword">char</span>* str)</span></span></span><br><span class="line"><span class="function">    </span>&#123;</span><br><span class="line">        <span class="comment">//if(!matrix || rows&lt;=0 || cols&lt;=0 || !str) return false;</span></span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;rows;i++)&#123;</span><br><span class="line">            <span class="keyword">for</span>(<span class="keyword">int</span> j=<span class="number">0</span>;j&lt;cols;j++)&#123;</span><br><span class="line">                <span class="keyword">if</span>(help(matrix,i,j,str,<span class="number">0</span>,rows,cols)) <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="function"><span class="keyword">bool</span> <span class="title">help</span><span class="params">(<span class="keyword">char</span>* matrix, <span class="keyword">int</span> i, <span class="keyword">int</span> j, <span class="keyword">char</span>* str, <span class="keyword">int</span> k, <span class="keyword">int</span> rows, <span class="keyword">int</span> cols)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">int</span> index = i*cols+j;</span><br><span class="line">        <span class="keyword">if</span>(i&lt;<span class="number">0</span>||i&gt;=rows||j&lt;<span class="number">0</span>||j&gt;=cols||matrix[index]==<span class="string">'#'</span>||str[k]!=matrix[index]) <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">        <span class="keyword">if</span>(str[k+<span class="number">1</span>]==<span class="string">'\0'</span>) <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line">        <span class="keyword">char</span> tmp = matrix[index];</span><br><span class="line">        matrix[index] = <span class="string">'#'</span>;</span><br><span class="line">        <span class="keyword">if</span>(help(matrix,i+<span class="number">1</span>,j,str,k+<span class="number">1</span>,rows,cols) </span><br><span class="line">           || help(matrix,i<span class="number">-1</span>,j,str,k+<span class="number">1</span>,rows,cols)</span><br><span class="line">           || help(matrix,i,j+<span class="number">1</span>,str,k+<span class="number">1</span>,rows,cols) </span><br><span class="line">           || help(matrix,i,j<span class="number">-1</span>,str,k+<span class="number">1</span>,rows,cols))&#123;</span><br><span class="line">            <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        matrix[index] = tmp;</span><br><span class="line">        <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h1 id="66、机器人的运动范围"><a href="#66、机器人的运动范围" class="headerlink" title="66、机器人的运动范围"></a>66、机器人的运动范围</h1><p>地上有一个m行和n列的方格。一个机器人从坐标0,0的格子开始移动，每一次只能向左，右，上，下四个方向移动一格，但是不能进入行坐标和列坐标的数位之和大于k的格子。 例如，当k为18时，机器人能够进入方格（35,37），因为3+5+3+7 = 18。但是，它不能进入方格（35,38），因为3+5+3+8 = 19。请问该机器人能够达到多少个格子？</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function"><span class="keyword">int</span> <span class="title">movingCount</span><span class="params">(<span class="keyword">int</span> threshold, <span class="keyword">int</span> rows, <span class="keyword">int</span> cols)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">if</span>(rows&lt;=<span class="number">0</span> || cols&lt;=<span class="number">0</span> || threshold&lt;<span class="number">0</span>) <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">bool</span>* flag = <span class="keyword">new</span> <span class="keyword">bool</span>[rows*cols];</span><br><span class="line">        <span class="built_in">memset</span>(flag,<span class="literal">false</span>,rows*cols);</span><br><span class="line">        <span class="keyword">return</span> helper(threshold,rows,cols,<span class="number">0</span>,<span class="number">0</span>,flag);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="function"><span class="keyword">int</span> <span class="title">helper</span><span class="params">(<span class="keyword">int</span> threshold, <span class="keyword">int</span> rows, <span class="keyword">int</span> cols,<span class="keyword">int</span> i, <span class="keyword">int</span> j, <span class="keyword">bool</span>* flag)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">int</span> index = i*cols+j;</span><br><span class="line">        <span class="keyword">if</span>(i&lt;<span class="number">0</span>||i&gt;=rows||j&lt;<span class="number">0</span>||j&gt;=cols||flag[index]||count(i)+count(j)&gt;threshold) <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">        flag[index] = <span class="literal">true</span>;</span><br><span class="line">        <span class="keyword">return</span> helper(threshold,rows,cols,i<span class="number">-1</span>,j,flag)+</span><br><span class="line">               helper(threshold,rows,cols,i+<span class="number">1</span>,j,flag)+</span><br><span class="line">               helper(threshold,rows,cols,i,j<span class="number">-1</span>,flag)+</span><br><span class="line">               helper(threshold,rows,cols,i,j+<span class="number">1</span>,flag)+<span class="number">1</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="function"><span class="keyword">int</span> <span class="title">count</span><span class="params">(<span class="keyword">int</span> n)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">int</span> res = <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">while</span>(n!=<span class="number">0</span>)&#123;</span><br><span class="line">            res += n%<span class="number">10</span>;</span><br><span class="line">            n /= <span class="number">10</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure>]]></content>
    
    <summary type="html">
    
      &lt;h3 id=&quot;题目来源&quot;&gt;&lt;a href=&quot;#题目来源&quot; class=&quot;headerlink&quot; title=&quot;题目来源&quot;&gt;&lt;/a&gt;题目来源&lt;/h3&gt;&lt;p&gt; &lt;a href=&quot;https://www.nowcoder.com/ta/coding-interviews?page=1&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;剑指Offer 66题&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;相关：&lt;br&gt;&lt;a href=&quot;https://blog.csdn.net/ffcjjhv/article/details/88409676&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;刷题汇总（一）leetcode 精选50题 JavaScript答案总结&lt;/a&gt;&lt;br&gt;&lt;a href=&quot;https://blog.csdn.net/ffcjjhv/article/details/100104411&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;刷题汇总（三）leetcode 精选50题 C++答案总结&lt;/a&gt;&lt;br&gt;&lt;a href=&quot;https://blog.csdn.net/ffcjjhv/article/details/103195691&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;刷题汇总（四）技术类编程题汇总 C++&lt;/a&gt;&lt;br&gt;&lt;a href=&quot;https://blog.csdn.net/ffcjjhv/article/details/103381516&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;刷题汇总（五）leetcode 热题 HOT 100 C++ 答案总结&lt;/a&gt;&lt;br&gt;&lt;a href=&quot;https://blog.csdn.net/ffcjjhv/article/details/103503745&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;刷题汇总（六）leetcode 多线程 / Shell&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://pan.baidu.com/s/1fHto2ckVlwQzgUi8TxYReA&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;PDF版 code&lt;/a&gt;  （提取码：0wxr ）&lt;/p&gt;
&lt;h1 id=&quot;1、二维数组中的查找&quot;&gt;&lt;a href=&quot;#1、二维数组中的查找&quot; class=&quot;headerlink&quot; title=&quot;1、二维数组中的查找&quot;&gt;&lt;/a&gt;1、二维数组中的查找&lt;/h1&gt;&lt;p&gt;在一个二维数组中（每个一维数组的长度相同），每一行都按照从左到右递增的顺序排序，每一列都按照从上到下递增的顺序排序。请完成一个函数，输入这样的一个二维数组和一个整数，判断数组中是否含有该整数。&lt;/p&gt;
    
    </summary>
    
      <category term="C++" scheme="http://yoursite.com/categories/C/"/>
    
      <category term="后台开发" scheme="http://yoursite.com/categories/%E5%90%8E%E5%8F%B0%E5%BC%80%E5%8F%91/"/>
    
      <category term="CodeCode" scheme="http://yoursite.com/categories/CodeCode/"/>
    
    
      <category term="C++" scheme="http://yoursite.com/tags/C/"/>
    
      <category term="剑指Offer" scheme="http://yoursite.com/tags/%E5%89%91%E6%8C%87Offer/"/>
    
  </entry>
  
  <entry>
    <title>基于RGBD相机的人脸实时三维重建过程解析（ElasticFusion实现）</title>
    <link href="http://yoursite.com/2019/06/17/18/"/>
    <id>http://yoursite.com/2019/06/17/18/</id>
    <published>2019-06-17T03:36:20.000Z</published>
    <updated>2019-12-18T04:14:28.239Z</updated>
    
    <content type="html"><![CDATA[<p><img src="https://img-blog.csdnimg.cn/20190617110733452.JPG?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZmY2pqaHY=,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"></p><a id="more"></a><p><img src="https://img-blog.csdnimg.cn/20190617110750587.JPG?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZmY2pqaHY=,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"><br><img src="https://img-blog.csdnimg.cn/20190617110803839.JPG?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZmY2pqaHY=,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"><br><img src="https://img-blog.csdnimg.cn/20190617110815847.JPG?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZmY2pqaHY=,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"><br><img src="https://img-blog.csdnimg.cn/20190617110827407.JPG?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZmY2pqaHY=,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"><br><img src="https://img-blog.csdnimg.cn/20190617110838240.JPG?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZmY2pqaHY=,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"><br><img src="https://img-blog.csdnimg.cn/20190617110852240.JPG?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZmY2pqaHY=,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"><br><img src="https://img-blog.csdnimg.cn/20190617110903395.JPG?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZmY2pqaHY=,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"><br><img src="https://img-blog.csdnimg.cn/20190617110915324.JPG?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZmY2pqaHY=,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"><br><img src="https://img-blog.csdnimg.cn/20190617110925918.JPG?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZmY2pqaHY=,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"><br><img src="https://img-blog.csdnimg.cn/20190617110936331.JPG?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZmY2pqaHY=,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"><br><img src="https://img-blog.csdnimg.cn/20190617110948477.JPG?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZmY2pqaHY=,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"><br><img src="https://img-blog.csdnimg.cn/20190617111000826.JPG?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZmY2pqaHY=,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"><br>主要是在ElasticFusion基础上做了部分修改，进行人脸实时重建。<br>PPT及相关论文地址：<a href="https://pan.baidu.com/s/1Zr1uCFj7YqgEWWof2gp-Lw" target="_blank" rel="noopener">https://pan.baidu.com/s/1Zr1uCFj7YqgEWWof2gp-Lw</a>  ，提取码：7fnw<br>相关算法实现链接：<br><a href="https://blog.csdn.net/ffcjjhv/article/details/89221992" target="_blank" rel="noopener">BundleFusion在win10+vs2013+cuda8.0上的实现</a><br><a href="https://blog.csdn.net/ffcjjhv/article/details/89151382" target="_blank" rel="noopener">DynamicFusion在ubuntu16.04+显卡GT740+cuda8.0上的实现</a><br><a href="https://blog.csdn.net/ffcjjhv/article/details/89258224" target="_blank" rel="noopener">ElasticFusion在ubuntu16.04+cuda8.0上的实现</a></p><p>参考链接：<br><a href="https://blog.csdn.net/fuxingyin/article/details/51417822" target="_blank" rel="noopener">KinectFusion 解析</a><br><a href="https://www.jianshu.com/p/7a447c633ae9" target="_blank" rel="noopener">KinectFusion 论文精析</a><br><a href="https://blog.csdn.net/xiaohu50/article/details/51592503" target="_blank" rel="noopener">kinect fusion 3D重建基本算法</a><br><a href="https://blog.csdn.net/qq_31785865/article/details/78524429" target="_blank" rel="noopener">KinectFusion中用到的TSDF Fusion</a><br><a href="https://blog.csdn.net/fuxingyin/article/details/52921958" target="_blank" rel="noopener">BundleFusion 解析</a><br><a href="https://blog.csdn.net/fuxingyin/article/details/51433793" target="_blank" rel="noopener">ElasticFusion 解析</a> （这个博主其他文章也非常值得参考）<br><a href="https://blog.csdn.net/datase/article/details/80961668" target="_blank" rel="noopener">ElasticFusion</a></p>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;&lt;img src=&quot;https://img-blog.csdnimg.cn/20190617110733452.JPG?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZmY2pqaHY=,size_16,color_FFFFFF,t_70&quot; alt=&quot;在这里插入图片描述&quot;&gt;&lt;/p&gt;
    
    </summary>
    
      <category term="深度相机" scheme="http://yoursite.com/categories/%E6%B7%B1%E5%BA%A6%E7%9B%B8%E6%9C%BA/"/>
    
      <category term="C++" scheme="http://yoursite.com/categories/C/"/>
    
    
      <category term="RGBD" scheme="http://yoursite.com/tags/RGBD/"/>
    
      <category term="ElasticFusion" scheme="http://yoursite.com/tags/ElasticFusion/"/>
    
      <category term="人脸实时三维重建" scheme="http://yoursite.com/tags/%E4%BA%BA%E8%84%B8%E5%AE%9E%E6%97%B6%E4%B8%89%E7%BB%B4%E9%87%8D%E5%BB%BA/"/>
    
  </entry>
  
  <entry>
    <title>Vue+iview+Echarts+electron 桌面应用</title>
    <link href="http://yoursite.com/2019/04/29/17/"/>
    <id>http://yoursite.com/2019/04/29/17/</id>
    <published>2019-04-29T12:01:15.000Z</published>
    <updated>2019-12-18T04:13:58.258Z</updated>
    
    <content type="html"><![CDATA[<h1 id="一、Vue项目创建"><a href="#一、Vue项目创建" class="headerlink" title="一、Vue项目创建"></a>一、Vue项目创建</h1><h2 id="1、安装node-js"><a href="#1、安装node-js" class="headerlink" title="1、安装node.js"></a>1、安装node.js</h2><p>#下载安装包：<a href="https://nodejs.org/en/" target="_blank" rel="noopener">https://nodejs.org/en/</a><br>cmd输入<code>node -v</code> 和<code>npm -v</code>查看是否安装成功</p><a id="more"></a><p><img src="https://img-blog.csdnimg.cn/20190429103700396.JPG" alt="在这里插入图片描述"></p><h2 id="2、Vue开发环境"><a href="#2、Vue开发环境" class="headerlink" title="2、Vue开发环境"></a>2、Vue开发环境</h2><p>#命令行下载淘宝镜像命令工具 <code>cnpm</code></p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm install cnpm -g --registry=http:<span class="comment">//registry.npm.taobao.org</span></span><br></pre></td></tr></table></figure><p>#用 cnpm 命令全局安装vue-cli脚手架</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">cnpm install --global vue-cli</span><br></pre></td></tr></table></figure><p>输入vue，出来vue的信息说明安装成功<br><img src="https://img-blog.csdnimg.cn/2019042910425040.JPG?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZmY2pqaHY=,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"></p><h2 id="3、搭建Vue项目"><a href="#3、搭建Vue项目" class="headerlink" title="3、搭建Vue项目"></a>3、搭建Vue项目</h2><h3 id="（1）项目初始化"><a href="#（1）项目初始化" class="headerlink" title="（1）项目初始化"></a>（1）项目初始化</h3><p> 使用命令创建项目，一步步选择之后开始等等项目创建完成<br> <figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">vue init webpack app</span><br></pre></td></tr></table></figure></p><p><img src="https://img-blog.csdnimg.cn/20190429104503876.JPG?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZmY2pqaHY=,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"></p><h3 id="（2）项目预览"><a href="#（2）项目预览" class="headerlink" title="（2）项目预览"></a>（2）项目预览</h3><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">cd demo</span><br><span class="line">npm run dev</span><br></pre></td></tr></table></figure><p><img src="https://img-blog.csdnimg.cn/20190429105341255.JPG?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZmY2pqaHY=,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"><br>打开浏览器，复制粘贴命令行显示的地址（ <a href="http://localhost:8080），跳出页面" target="_blank" rel="noopener">http://localhost:8080），跳出页面</a><br><img src="https://img-blog.csdnimg.cn/20190429105244906.JPG?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZmY2pqaHY=,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"></p><h1 id="二、引入ivew-Echarts"><a href="#二、引入ivew-Echarts" class="headerlink" title="二、引入ivew+Echarts"></a>二、引入ivew+Echarts</h1><h2 id="1、ivew-Echarts安装"><a href="#1、ivew-Echarts安装" class="headerlink" title="1、ivew+Echarts安装"></a>1、ivew+Echarts安装</h2><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">cnpm install ivew -save</span><br></pre></td></tr></table></figure><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">cnpm install echarts -save</span><br></pre></td></tr></table></figure><h2 id="2、引入ivew-Echarts"><a href="#2、引入ivew-Echarts" class="headerlink" title="2、引入ivew+Echarts"></a>2、引入ivew+Echarts</h2><p>项目<code>src/main.js</code>中引入ivew+Echarts</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">import iView from 'iview';</span><br><span class="line">import 'iview/dist/styles/iview.css';</span><br><span class="line"></span><br><span class="line">Vue.use(iView);</span><br></pre></td></tr></table></figure><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">import Echarts from 'echarts'</span><br><span class="line">Vue.prototype.echarts = Echarts</span><br></pre></td></tr></table></figure><p><img src="https://img-blog.csdnimg.cn/20190530103057482.JPG?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZmY2pqaHY=,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"></p><h2 id="3、Echarts组件"><a href="#3、Echarts组件" class="headerlink" title="3、Echarts组件"></a>3、Echarts组件</h2><p>将<code>src/components/HelloWorld</code>修改为如下内容</p><figure class="highlight"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br><span class="line">180</span><br><span class="line">181</span><br><span class="line">182</span><br><span class="line">183</span><br><span class="line">184</span><br><span class="line">185</span><br><span class="line">186</span><br><span class="line">187</span><br><span class="line">188</span><br><span class="line">189</span><br><span class="line">190</span><br><span class="line">191</span><br><span class="line">192</span><br></pre></td><td class="code"><pre><span class="line">&lt;style scoped&gt;</span><br><span class="line">.layout&#123;</span><br><span class="line">    border: <span class="number">1</span>px solid #d7dde4;</span><br><span class="line">    background: #f5f7f9;</span><br><span class="line">    position: relative;</span><br><span class="line">    border-radius: <span class="number">4</span>px;</span><br><span class="line">    overflow: hidden;</span><br><span class="line">&#125;</span><br><span class="line">.layout-logo&#123;</span><br><span class="line">    width: <span class="number">100</span>px;</span><br><span class="line">    height: <span class="number">30</span>px;</span><br><span class="line">    background: #<span class="number">5b</span>6270;</span><br><span class="line">    border-radius: <span class="number">3</span>px;</span><br><span class="line">    <span class="keyword">float</span>: left;</span><br><span class="line">    position: relative;</span><br><span class="line">    top: <span class="number">15</span>px;</span><br><span class="line">    left: <span class="number">20</span>px;</span><br><span class="line">&#125;</span><br><span class="line">.layout-nav&#123;</span><br><span class="line">    width: <span class="number">420</span>px;</span><br><span class="line">    margin: <span class="number">0</span> <span class="keyword">auto</span>;</span><br><span class="line">    margin-right: <span class="number">20</span>px;</span><br><span class="line">&#125;</span><br><span class="line">&lt;/style&gt;</span><br><span class="line">&lt;<span class="keyword">template</span>&gt;</span><br><span class="line">    &lt;div <span class="class"><span class="keyword">class</span>="<span class="title">layout</span>"&gt;</span></span><br><span class="line"><span class="class">        &lt;Layout&gt;</span></span><br><span class="line"><span class="class">            &lt;Header&gt;</span></span><br><span class="line"><span class="class">                &lt;Menu mode="horizontal" theme="dark" active-name="1"&gt;</span></span><br><span class="line"><span class="class">                    &lt;div class="layout-logo"&gt;&lt;/div&gt;</span></span><br><span class="line"><span class="class">                    &lt;div class="layout-nav"&gt;</span></span><br><span class="line"><span class="class">                        &lt;MenuItem name="1"&gt;</span></span><br><span class="line"><span class="class">                            &lt;Icon type="ios-navigate"&gt;&lt;/Icon&gt;</span></span><br><span class="line"><span class="class">                            <span class="title">Item</span> 1</span></span><br><span class="line"><span class="class">                        &lt;/MenuItem&gt;</span></span><br><span class="line"><span class="class">                        &lt;MenuItem name="2"&gt;</span></span><br><span class="line"><span class="class">                            &lt;Icon type="ios-keypad"&gt;&lt;/Icon&gt;</span></span><br><span class="line"><span class="class">                            <span class="title">Item</span> 2</span></span><br><span class="line"><span class="class">                        &lt;/MenuItem&gt;</span></span><br><span class="line"><span class="class">                        &lt;MenuItem name="3"&gt;</span></span><br><span class="line"><span class="class">                            &lt;Icon type="ios-analytics"&gt;&lt;/Icon&gt;</span></span><br><span class="line"><span class="class">                            <span class="title">Item</span> 3</span></span><br><span class="line"><span class="class">                        &lt;/MenuItem&gt;</span></span><br><span class="line"><span class="class">                        &lt;MenuItem name="4"&gt;</span></span><br><span class="line"><span class="class">                            &lt;Icon type="ios-paper"&gt;&lt;/Icon&gt;</span></span><br><span class="line"><span class="class">                            <span class="title">Item</span> 4</span></span><br><span class="line"><span class="class">                        &lt;/MenuItem&gt;</span></span><br><span class="line"><span class="class">                    &lt;/div&gt;</span></span><br><span class="line"><span class="class">                &lt;/Menu&gt;</span></span><br><span class="line"><span class="class">            &lt;/Header&gt;</span></span><br><span class="line"><span class="class">            &lt;Layout&gt;</span></span><br><span class="line"><span class="class">                &lt;Sider hide-trigger :style="&#123;background: '#fff'&#125;"&gt;</span></span><br><span class="line"><span class="class">                    &lt;Menu active-name="1-2" theme="light" width="auto" :open-names="['1']"&gt;</span></span><br><span class="line"><span class="class">                        &lt;Submenu name="1"&gt;</span></span><br><span class="line"><span class="class">                            &lt;template slot="title"&gt;</span></span><br><span class="line"><span class="class">                                &lt;Icon type="ios-navigate"&gt;&lt;/Icon&gt;</span></span><br><span class="line"><span class="class">                                <span class="title">Item</span> 1</span></span><br><span class="line"><span class="class">                            &lt;/template&gt;</span></span><br><span class="line"><span class="class">                            &lt;MenuItem name="1-1"&gt;<span class="title">Option</span> 1&lt;/MenuItem&gt;</span></span><br><span class="line"><span class="class">                            &lt;MenuItem name="1-2"&gt;<span class="title">Option</span> 2&lt;/MenuItem&gt;</span></span><br><span class="line"><span class="class">                            &lt;MenuItem name="1-3"&gt;<span class="title">Option</span> 3&lt;/MenuItem&gt;</span></span><br><span class="line"><span class="class">                        &lt;/Submenu&gt;</span></span><br><span class="line"><span class="class">                        &lt;Submenu name="2"&gt;</span></span><br><span class="line"><span class="class">                            &lt;template slot="title"&gt;</span></span><br><span class="line"><span class="class">                                &lt;Icon type="ios-keypad"&gt;&lt;/Icon&gt;</span></span><br><span class="line"><span class="class">                                <span class="title">Item</span> 2</span></span><br><span class="line"><span class="class">                            &lt;/template&gt;</span></span><br><span class="line"><span class="class">                            &lt;MenuItem name="2-1"&gt;<span class="title">Option</span> 1&lt;/MenuItem&gt;</span></span><br><span class="line"><span class="class">                            &lt;MenuItem name="2-2"&gt;<span class="title">Option</span> 2&lt;/MenuItem&gt;</span></span><br><span class="line"><span class="class">                        &lt;/Submenu&gt;</span></span><br><span class="line"><span class="class">                        &lt;Submenu name="3"&gt;</span></span><br><span class="line"><span class="class">                            &lt;template slot="title"&gt;</span></span><br><span class="line"><span class="class">                                &lt;Icon type="ios-analytics"&gt;&lt;/Icon&gt;</span></span><br><span class="line"><span class="class">                                <span class="title">Item</span> 3</span></span><br><span class="line"><span class="class">                            &lt;/template&gt;</span></span><br><span class="line"><span class="class">                            &lt;MenuItem name="3-1"&gt;<span class="title">Option</span> 1&lt;/MenuItem&gt;</span></span><br><span class="line"><span class="class">                            &lt;MenuItem name="3-2"&gt;<span class="title">Option</span> 2&lt;/MenuItem&gt;</span></span><br><span class="line"><span class="class">                        &lt;/Submenu&gt;</span></span><br><span class="line"><span class="class">                    &lt;/Menu&gt;</span></span><br><span class="line"><span class="class">                &lt;/Sider&gt;</span></span><br><span class="line"><span class="class">                &lt;Layout :style="&#123;padding: '0 24px 24px'&#125;"&gt;</span></span><br><span class="line"><span class="class">                    &lt;Breadcrumb :style="&#123;margin: '24px 0'&#125;"&gt;</span></span><br><span class="line"><span class="class">                        &lt;BreadcrumbItem&gt;<span class="title">Home</span>&lt;/BreadcrumbItem&gt;</span></span><br><span class="line"><span class="class">                        &lt;BreadcrumbItem&gt;<span class="title">Components</span>&lt;/BreadcrumbItem&gt;</span></span><br><span class="line"><span class="class">                        &lt;BreadcrumbItem&gt;<span class="title">Layout</span>&lt;/BreadcrumbItem&gt;</span></span><br><span class="line"><span class="class">                    &lt;/Breadcrumb&gt;</span></span><br><span class="line"><span class="class">                    &lt;Content :style="&#123;padding: '24px', minHeight: '280px', background: '#fff'&#125;"&gt;</span></span><br><span class="line"><span class="class">                        &lt;div id="echart" style="width: 940px;height:500px;"&gt;&lt;/div&gt;</span></span><br><span class="line"><span class="class">                    &lt;/Content&gt;</span></span><br><span class="line"><span class="class">                &lt;/Layout&gt;</span></span><br><span class="line"><span class="class">            &lt;/Layout&gt;</span></span><br><span class="line"><span class="class">        &lt;/Layout&gt;</span></span><br><span class="line"><span class="class">    &lt;/div&gt;</span></span><br><span class="line"><span class="class">&lt;/template&gt;</span></span><br><span class="line"><span class="class">&lt;script&gt;</span></span><br><span class="line"><span class="class">    <span class="title">import</span> <span class="title">echarts</span> <span class="title">from</span> '<span class="title">echarts</span>'</span></span><br><span class="line"><span class="class">    <span class="title">export</span> <span class="title">default</span> &#123;</span></span><br><span class="line">      data() &#123;</span><br><span class="line">        <span class="keyword">return</span> &#123;&#125;</span><br><span class="line">      &#125;,</span><br><span class="line">      mounted() &#123;</span><br><span class="line">        <span class="comment">// 基于准备好的dom，初始化echarts实例</span></span><br><span class="line">        var myChart = echarts.init(document.getElementById('echart'));</span><br><span class="line">        <span class="comment">// 绘制图表</span></span><br><span class="line">        var option = &#123;</span><br><span class="line">          title : &#123;</span><br><span class="line">              text: '保有储量变化图',</span><br><span class="line">              subtext: '一次能源'</span><br><span class="line">          &#125;,</span><br><span class="line">          tooltip : &#123;</span><br><span class="line">              trigger: 'axis'</span><br><span class="line">          &#125;,</span><br><span class="line">          legend: &#123;</span><br><span class="line">              data:['煤','石油','天然气']</span><br><span class="line">          &#125;,</span><br><span class="line">          toolbox: &#123;</span><br><span class="line">              show : <span class="literal">true</span>,</span><br><span class="line">              feature : &#123;</span><br><span class="line">                  dataView : &#123;show: <span class="literal">true</span>, readOnly: <span class="literal">false</span>&#125;,</span><br><span class="line">                  magicType : &#123;show: true, type: ['line', 'bar']&#125;,</span><br><span class="line">                  restore : &#123;show: <span class="literal">true</span>&#125;,</span><br><span class="line">                  saveAsImage : &#123;show: <span class="literal">true</span>&#125;</span><br><span class="line">              &#125;</span><br><span class="line">          &#125;,</span><br><span class="line">          calculable : <span class="literal">true</span>,</span><br><span class="line">          xAxis : [</span><br><span class="line">              &#123;</span><br><span class="line">                  type : 'category',</span><br><span class="line">                  data : ['2009','2010','2011','2012','2013','2014','2015','2016','2017'],</span><br><span class="line">                  splitNumber: <span class="number">10</span></span><br><span class="line">              &#125;</span><br><span class="line">          ],</span><br><span class="line">          yAxis : [</span><br><span class="line">              &#123;</span><br><span class="line">                  type : 'value'</span><br><span class="line">              &#125;</span><br><span class="line">          ],</span><br><span class="line">          series : [</span><br><span class="line">              &#123;</span><br><span class="line">                  name:<span class="string">'煤'</span>,</span><br><span class="line">                  type:'bar',</span><br><span class="line">                  data:[<span class="number">1683.47</span>,<span class="number">1654.23</span>,<span class="number">1640.12</span>,<span class="number">1641.6</span>,<span class="number">1639.68</span>,<span class="number">1642.7</span>,<span class="number">1610.41</span>,<span class="number">1639.45</span>,<span class="number">1722.2</span>],</span><br><span class="line">                  markPoint : &#123;</span><br><span class="line">                      data : [</span><br><span class="line">                          &#123;type : 'max', name: '最大值'&#125;,</span><br><span class="line">                          &#123;type : 'min', name: '最小值'&#125;</span><br><span class="line">                      ]</span><br><span class="line">                  &#125;,</span><br><span class="line">                  markLine : &#123;</span><br><span class="line">                      data : [</span><br><span class="line">                          &#123;type : 'average', name: '平均值'&#125;</span><br><span class="line">                      ]</span><br><span class="line">                  &#125;</span><br><span class="line">              &#125;,</span><br><span class="line">              &#123;</span><br><span class="line">                  name:'石油',</span><br><span class="line">                  type:'bar',</span><br><span class="line">                  data:[<span class="number">22490.2</span>,<span class="number">24947.67</span>,<span class="number">29844.34</span>,<span class="number">31397.94</span>,<span class="number">33713</span>,<span class="number">36300.8</span>,<span class="number">38445.3</span>,<span class="number">38375.6</span>,<span class="number">38158.7</span>],</span><br><span class="line">                  markPoint : &#123;</span><br><span class="line">                      data : [</span><br><span class="line">                          &#123;type : 'max', name: '最大值'&#125;,</span><br><span class="line">                          &#123;type : 'min', name: '最小值'&#125;</span><br><span class="line">                      ]</span><br><span class="line">                  &#125;,</span><br><span class="line">                  markLine : &#123;</span><br><span class="line">                      data : [</span><br><span class="line">                          &#123;type : 'average', name : '平均值'&#125;</span><br><span class="line">                      ]</span><br><span class="line">                  &#125;</span><br><span class="line">              &#125;,</span><br><span class="line">              &#123;</span><br><span class="line">                  name:'天然气',</span><br><span class="line">                  type:'bar',</span><br><span class="line">                  data:[<span class="number">5502.54</span>,<span class="number">5628.11</span>,<span class="number">5478</span>,<span class="number">6376.26</span>,<span class="number">6231.14</span>,<span class="number">8047.88</span>,<span class="number">7857.1</span>,<span class="number">7802.5</span>,<span class="number">8695.01</span>],</span><br><span class="line">                  markPoint : &#123;</span><br><span class="line">                      data : [</span><br><span class="line">                          &#123;type : 'max', name: '最大值'&#125;,</span><br><span class="line">                          &#123;type : 'min', name: '最小值'&#125;</span><br><span class="line">                      ]</span><br><span class="line">                  &#125;,</span><br><span class="line">                  markLine : &#123;</span><br><span class="line">                      data : [</span><br><span class="line">                          &#123;type : 'average', name : '平均值'&#125;</span><br><span class="line">                      ]</span><br><span class="line">                  &#125;</span><br><span class="line">              &#125;  </span><br><span class="line">          ]</span><br><span class="line">        &#125;;</span><br><span class="line">        myChart.setOption(option);</span><br><span class="line">      &#125; </span><br><span class="line">    &#125; </span><br><span class="line">&lt;/script&gt;</span><br></pre></td></tr></table></figure><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm run dev</span><br></pre></td></tr></table></figure><p>打开<a href="http://localhost:8080" target="_blank" rel="noopener">http://localhost:8080</a> ，显示页面<br><img src="https://img-blog.csdnimg.cn/2019053010333712.JPG?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZmY2pqaHY=,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"></p><h2 id="4、生成项目"><a href="#4、生成项目" class="headerlink" title="4、生成项目"></a>4、生成项目</h2><p>执行生成命令</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm run build</span><br></pre></td></tr></table></figure><p>出现如下效果<br><img src="https://img-blog.csdnimg.cn/20190429111214467.JPG?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZmY2pqaHY=,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"><br>项目下回多出一个dist的文件夹，里面是打包好的东西，双击index.html显示网页内容则证明生成成功<br><img src="https://img-blog.csdnimg.cn/20190429111253648.JPG" alt="在这里插入图片描述"></p><h3 id="（1）打包页面显示空白"><a href="#（1）打包页面显示空白" class="headerlink" title="（1）打包页面显示空白"></a>（1）打包页面显示空白</h3><p>修改index.js 中的生成路径，第46行改为<code>assetsPublicPath: &#39;./&#39;,</code>，否则后面程序运行打包页面会显示空白，找不到路径<br><img src="https://img-blog.csdnimg.cn/20190530094646185.JPG?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZmY2pqaHY=,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"></p><h3 id="（2）页面部分空白，router-view内容无法显示"><a href="#（2）页面部分空白，router-view内容无法显示" class="headerlink" title="（2）页面部分空白，router-view内容无法显示"></a>（2）页面部分空白，router-view内容无法显示</h3><p>// mode: ‘history’,//将这个模式关闭就好<br><img src="https://img-blog.csdnimg.cn/20190530095136965.JPG?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZmY2pqaHY=,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"></p><h3 id="（3）iview-打包之后，图标无法显示"><a href="#（3）iview-打包之后，图标无法显示" class="headerlink" title="（3）iview 打包之后，图标无法显示"></a>（3）iview 打包之后，图标无法显示</h3><p>在 <code>build/webpack.prod.conf.js</code> 中,将extract改为false<br><img src="https://img-blog.csdnimg.cn/20190530095429841.JPG" alt="在这里插入图片描述"><br>接下来一切操作都在<code>dist文件夹</code>目录下。</p><h1 id="三、electron打包"><a href="#三、electron打包" class="headerlink" title="三、electron打包"></a>三、electron打包</h1><h2 id="1、安装-electron"><a href="#1、安装-electron" class="headerlink" title="1、安装 electron"></a>1、安装 electron</h2><p>用 cnpm 命令安装 electron</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">cnpm install electron -g</span><br></pre></td></tr></table></figure><p>cmd输入electron -v查看是否安装成功<br><img src="https://img-blog.csdnimg.cn/20190429195032186.JPG" alt="在这里插入图片描述"></p><h2 id="2、-package-json-和-main-js"><a href="#2、-package-json-和-main-js" class="headerlink" title="2、 package.json 和 main.js"></a>2、 package.json 和 main.js</h2><p>在dist文件夹下，复制粘贴下面的 package.json 和 main.js文件，最终目录如图<br><img src="https://img-blog.csdnimg.cn/20190429194331359.JPG" alt="在这里插入图片描述"><br>在<code>package.json</code>中：</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">&#123;</span><br><span class="line">  <span class="string">"name"</span>    : <span class="string">"your-app"</span>,</span><br><span class="line">  <span class="string">"version"</span> : <span class="string">"0.1.0"</span>,</span><br><span class="line">  <span class="string">"main"</span>    : <span class="string">"main.js"</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>在<code>main.js</code>中</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br></pre></td><td class="code"><pre><span class="line">const &#123;app, BrowserWindow&#125; = require('electron')</span><br><span class="line">const path = require('path')</span><br><span class="line">const url = require('url')</span><br><span class="line"></span><br><span class="line"><span class="comment">// Keep a global reference of the window object, if you don't, the window will</span></span><br><span class="line"><span class="comment">// be closed automatically when the JavaScript object is garbage collected.</span></span><br><span class="line">let win</span><br><span class="line"></span><br><span class="line"><span class="function">function <span class="title">createWindow</span> <span class="params">()</span> </span>&#123;</span><br><span class="line">  <span class="comment">// Create the browser window.</span></span><br><span class="line">  win = <span class="keyword">new</span> BrowserWindow(&#123;width: <span class="number">800</span>, height: <span class="number">600</span>&#125;)</span><br><span class="line"></span><br><span class="line">  <span class="comment">// and load the index.html of the app.</span></span><br><span class="line">  win.loadURL(url.format(&#123;</span><br><span class="line">    pathname: path.join(__dirname, 'index.html'),</span><br><span class="line">    protocol: 'file:',</span><br><span class="line">    slashes: <span class="literal">true</span></span><br><span class="line">  &#125;))</span><br><span class="line"></span><br><span class="line">  <span class="comment">// Open the DevTools.</span></span><br><span class="line">  <span class="comment">// win.webContents.openDevTools()</span></span><br><span class="line"></span><br><span class="line">  <span class="comment">// Emitted when the window is closed.</span></span><br><span class="line">  win.on('closed', () =&gt; &#123;</span><br><span class="line">    <span class="comment">// Dereference the window object, usually you would store windows</span></span><br><span class="line">    <span class="comment">// in an array if your app supports multi windows, this is the time</span></span><br><span class="line">    <span class="comment">// when you should delete the corresponding element.</span></span><br><span class="line">    win = null</span><br><span class="line">  &#125;)</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// This method will be called when Electron has finished</span></span><br><span class="line"><span class="comment">// initialization and is ready to create browser windows.</span></span><br><span class="line"><span class="comment">// Some APIs can only be used after this event occurs.</span></span><br><span class="line">app.on('ready', createWindow)</span><br><span class="line"></span><br><span class="line"><span class="comment">// Quit when all windows are closed.</span></span><br><span class="line">app.on('window-all-closed', () =&gt; &#123;</span><br><span class="line">  <span class="comment">// On macOS it is common for applications and their menu bar</span></span><br><span class="line">  <span class="comment">// to stay active until the user quits explicitly with Cmd + Q</span></span><br><span class="line">  if (process.platform !== 'darwin') &#123;</span><br><span class="line">    app.quit()</span><br><span class="line">  &#125;</span><br><span class="line">&#125;)</span><br><span class="line"></span><br><span class="line">app.on('activate', () =&gt; &#123;</span><br><span class="line">  <span class="comment">// On macOS it's common to re-create a window in the app when the</span></span><br><span class="line">  <span class="comment">// dock icon is clicked and there are no other windows open.</span></span><br><span class="line">  <span class="keyword">if</span> (win === null) &#123;</span><br><span class="line">    createWindow()</span><br><span class="line">  &#125;</span><br><span class="line">&#125;)</span><br><span class="line"></span><br><span class="line"><span class="comment">// In this file you can include the rest of your app's specific main process</span></span><br><span class="line"><span class="comment">// code. You can also put them in separate files and require them here.</span></span><br></pre></td></tr></table></figure><p>运行</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">electron .</span><br></pre></td></tr></table></figure><h2 id="3、electron-packager打包"><a href="#3、electron-packager打包" class="headerlink" title="3、electron-packager打包"></a>3、electron-packager打包</h2><h3 id="（1）全局安装electron-packager"><a href="#（1）全局安装electron-packager" class="headerlink" title="（1）全局安装electron-packager"></a>（1）全局安装<code>electron-packager</code></h3><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm install electron-packager -g</span><br></pre></td></tr></table></figure><h3 id="（2）运行打包命令"><a href="#（2）运行打包命令" class="headerlink" title="（2）运行打包命令"></a>（2）运行打包命令</h3><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">electron-packager . demo --win --out outApp --arch=x64 --app-version <span class="number">1.0</span><span class="number">.0</span> --electron-version <span class="number">5.0</span><span class="number">.0</span> --overwrite --ignore=node_modules</span><br></pre></td></tr></table></figure><p><img src="https://img-blog.csdnimg.cn/20190429195228387.JPG" alt="在这里插入图片描述"><br>在<code>dist\outApp\demo-win32-x64</code>文件夹下生成可执行文件<code>demo.exe</code>,双击运行程序<br><img src="https://img-blog.csdnimg.cn/20190429195349765.JPG?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZmY2pqaHY=,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"><br>嫌每次输入太长，可以将在<code>package.json</code>中添加</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="string">"scripts"</span>: &#123;</span><br><span class="line">        <span class="string">"start"</span>: <span class="string">"electron ."</span>,</span><br><span class="line">        <span class="string">"build"</span>: <span class="string">"electron-packager . myApp --win --out outApp --arch=x64 --app-version 1.0.0 --electron-version 5.0.0 --overwrite --ignore=node_modules"</span></span><br><span class="line">      &#125;</span><br></pre></td></tr></table></figure><p><img src="https://img-blog.csdnimg.cn/20190605162356685.JPG?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZmY2pqaHY=,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"><br>这样输入<code>npm run start</code>相当于执行了<code>electron .</code>,测试打包效果<br>输入<code>npm run build</code>相当于执行了打包命令，在<code>dist\outApp\myApp-win32-x64</code>文件夹下生成可执行文件<code>myApp.exe</code></p><h2 id="4、源码加密"><a href="#4、源码加密" class="headerlink" title="4、源码加密"></a>4、源码加密</h2><p>在<code>outApp\demo-win32-x64\resources\app</code>里有写的源码。写的代码完全暴露在用户电脑上是非常不安全的，可以通过electron 自带的加密功能解决这个问题。</p><h3 id="（1）全局安装-asar"><a href="#（1）全局安装-asar" class="headerlink" title="（1）全局安装 asar"></a>（1）全局安装 asar</h3><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm install asar -g</span><br></pre></td></tr></table></figure><h3 id="（2）使用asar指令进行加密"><a href="#（2）使用asar指令进行加密" class="headerlink" title="（2）使用asar指令进行加密"></a>（2）使用asar指令进行加密</h3><p>在<code>resources</code>目录下使用<code>asar</code>指令进行加密</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">asar pack ./app app.asar</span><br></pre></td></tr></table></figure><p><img src="https://img-blog.csdnimg.cn/20190429195615524.JPG" alt="在这里插入图片描述"><br>将原来的app文件夹删除，这样生成的<code>app.asar</code>就加密了之前的源代码<br>双击<code>demo.exe</code>重新运行程序</p>]]></content>
    
    <summary type="html">
    
      &lt;h1 id=&quot;一、Vue项目创建&quot;&gt;&lt;a href=&quot;#一、Vue项目创建&quot; class=&quot;headerlink&quot; title=&quot;一、Vue项目创建&quot;&gt;&lt;/a&gt;一、Vue项目创建&lt;/h1&gt;&lt;h2 id=&quot;1、安装node-js&quot;&gt;&lt;a href=&quot;#1、安装node-js&quot; class=&quot;headerlink&quot; title=&quot;1、安装node.js&quot;&gt;&lt;/a&gt;1、安装node.js&lt;/h2&gt;&lt;p&gt;#下载安装包：&lt;a href=&quot;https://nodejs.org/en/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://nodejs.org/en/&lt;/a&gt;&lt;br&gt;cmd输入&lt;code&gt;node -v&lt;/code&gt; 和&lt;code&gt;npm -v&lt;/code&gt;查看是否安装成功&lt;/p&gt;
    
    </summary>
    
      <category term="前端" scheme="http://yoursite.com/categories/%E5%89%8D%E7%AB%AF/"/>
    
    
      <category term="Electron" scheme="http://yoursite.com/tags/Electron/"/>
    
      <category term="Vue" scheme="http://yoursite.com/tags/Vue/"/>
    
      <category term="iview" scheme="http://yoursite.com/tags/iview/"/>
    
      <category term="Echarts" scheme="http://yoursite.com/tags/Echarts/"/>
    
      <category term="桌面应用" scheme="http://yoursite.com/tags/%E6%A1%8C%E9%9D%A2%E5%BA%94%E7%94%A8/"/>
    
  </entry>
  
  <entry>
    <title>一步步配置腾讯云服务器Ubuntu 通过域名访问自己的网页tomcat（详细基础）</title>
    <link href="http://yoursite.com/2019/04/26/22/"/>
    <id>http://yoursite.com/2019/04/26/22/</id>
    <published>2019-04-26T08:32:46.000Z</published>
    <updated>2019-12-18T04:17:49.267Z</updated>
    
    <content type="html"><![CDATA[<h1 id="STEP1-云服务器-域名"><a href="#STEP1-云服务器-域名" class="headerlink" title="STEP1:云服务器+域名"></a>STEP1:云服务器+域名</h1><h2 id="1、购买云服务器、域名"><a href="#1、购买云服务器、域名" class="headerlink" title="1、购买云服务器、域名"></a>1、购买云服务器、域名</h2><p>购买学生优惠套餐 10元/月：<a href="https://cloud.tencent.com/act/campus?fromSource=gwzcw.1088196.1088196.1088196" target="_blank" rel="noopener">https://cloud.tencent.com/act/campus?fromSource=gwzcw.1088196.1088196.1088196</a><br>系统选ubuntu，购买3个月加购域名共38元（3个月以下没法添加域名解析），买了域名以后可以直接通过域名访问</p><a id="more"></a><p><img src="https://img-blog.csdnimg.cn/20181220201420186.JPG?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZmY2pqaHY=,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"><br>收到服务器信息，最好把这些复制到一个txt里，以后会经常用。</p><h2 id="2、添加解析"><a href="#2、添加解析" class="headerlink" title="2、添加解析"></a>2、添加解析</h2><p>在控制台进入云解析，添加解析，填域名，点新手快速添加， 网站解析，输入公网ip（无需备案）<br>完成后：<br><img src="https://img-blog.csdnimg.cn/20181220200632602.JPG?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZmY2pqaHY=,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"></p><h2 id="3、设置安全组"><a href="#3、设置安全组" class="headerlink" title="3、设置安全组"></a>3、设置安全组</h2><p>控制台-云服务器-安全组-新建，选择 放通22，80，443，3389端口和ICMP协议，新建安全组<br>点击关联实例数，新增关联与自己的服务器进行关联，<br>点击修改规则，放通8080端口（tomcat要用）<img src="https://img-blog.csdnimg.cn/20181220212224635.JPG?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZmY2pqaHY=,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"></p><h1 id="STEP2-连接服务器，配置JDK-tomcat"><a href="#STEP2-连接服务器，配置JDK-tomcat" class="headerlink" title="STEP2:连接服务器，配置JDK+tomcat"></a>STEP2:连接服务器，配置JDK+tomcat</h1><h2 id="1、连接服务器"><a href="#1、连接服务器" class="headerlink" title="1、连接服务器"></a>1、连接服务器</h2><p>下载安装PuTTY：<a href="https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html" target="_blank" rel="noopener">https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html</a><br>下载安装WinSCP：<a href="https://winscp.net/eng/download.php" target="_blank" rel="noopener">https://winscp.net/eng/download.php</a></p><h3 id="（1）PuTTY连接服务器"><a href="#（1）PuTTY连接服务器" class="headerlink" title="（1）PuTTY连接服务器"></a>（1）PuTTY连接服务器</h3><p>输入公网ip<br><img src="https://img-blog.csdnimg.cn/20181220201826146.JPG?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZmY2pqaHY=,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"><br>输入默认账户ubuntu，输入初始密码<strong><strong>**</strong></strong>，登陆成功如上图。</p><h4 id="putty的复制粘贴技巧"><a href="#putty的复制粘贴技巧" class="headerlink" title="putty的复制粘贴技巧"></a>putty的复制粘贴技巧</h4><p>复制密码后，在putty直接右键就是粘贴，密码不显示注意不要多复制。（如果想复制putty中的文字，左键选取就已经复制上了）<br><img src="https://img-blog.csdnimg.cn/20181220202551470.JPG?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZmY2pqaHY=,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"></p><h4 id="创建root账号"><a href="#创建root账号" class="headerlink" title="创建root账号"></a>创建root账号</h4><p>1、设置root密码<br>sudo passwd root<br>输入密码<br>2、获取root权限<br>输入su<br>输入密码<br>以后再次登录，输入su再输入密码就可以了，成功后：</p><blockquote><p>root@VM-0-16-ubuntu:/home/ubuntu#</p></blockquote><h3 id="（2）winSCP连接服务器"><a href="#（2）winSCP连接服务器" class="headerlink" title="（2）winSCP连接服务器"></a>（2）winSCP连接服务器</h3><p>主机名为公网ip，点击登录<br><img src="https://img-blog.csdnimg.cn/20181220203010452.JPG?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZmY2pqaHY=,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"></p><p>尝试新建文件夹test，提示permission denied<br><img src="https://img-blog.csdnimg.cn/2018122020325485.JPG?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZmY2pqaHY=,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"></p><h4 id="使用root登录winSCP："><a href="#使用root登录winSCP：" class="headerlink" title="使用root登录winSCP："></a>使用root登录winSCP：</h4><p>打开winSCP填写登录信息 ，点击高级，设置SFTP如下：<br><code>sudo /usr/lib/openssh/sftp-server</code><br><img src="https://img-blog.csdnimg.cn/20181220204051332.JPG?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZmY2pqaHY=,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"><br>重新登录后，就可以将本地文件拖到服务器中了。</p><h2 id="2、配置JDK-tomcat（ubuntu云服务器）"><a href="#2、配置JDK-tomcat（ubuntu云服务器）" class="headerlink" title="2、配置JDK+tomcat（ubuntu云服务器）"></a>2、配置JDK+tomcat（ubuntu云服务器）</h2><p>下载jdk8：<a href="http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html" target="_blank" rel="noopener">http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html</a><br>下载Tomcat：<a href="https://tomcat.apache.org/download-90.cgi" target="_blank" rel="noopener">https://tomcat.apache.org/download-90.cgi</a><br>root登录winSCP后，将下载的 jdk-8u191-linux-x64.tar.gz 和 jdk-11.0.1_linux-x64_bin.tar.gz拖到/usr/local/src/目录下   </p><h3 id="（1）安装JDK1-8"><a href="#（1）安装JDK1-8" class="headerlink" title="（1）安装JDK1.8"></a>（1）安装JDK1.8</h3><p>root登录putty后，输入<br><code>cd /usr/local/src/</code> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 进入存放安装包的位置<br><code>tar zxvf jdk-8u144-linux-x64.tar.gz</code> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 解压下载的数据包<br><code>mv jdk1.8.0_144 /usr/local/jdk1.8</code> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 给解压完成后的数据包更换一个其他目录并且改名<br><code>vi /etc/profile</code>  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 编辑/etc/profile  环境变量文件<br>在最后面添加</p><blockquote><p>JAVA_HOME=/usr/local/jdk1.8<br>JAVA_BIN=/usr/local/jdk1.8/bin<br>JRE_HOME=/usr/local/jdk1.8/jre<br>PATH=$PATH:/usr/local/jdk1.8/bin:/usr/local/jdk1.8/jre/bin<br>CLASSPATH=/usr/local/jdk1.8/jre/lib:/usr/local/jdk1.8/lib:/usr/local/jdk1.8/jre/lib/charsets.jar</p></blockquote><h4 id="vi使用技巧"><a href="#vi使用技巧" class="headerlink" title="vi使用技巧"></a>vi使用技巧</h4><p>输入 i ，退出命令模式，进入INSERT模式<br>开始修改内容……<br>按 esc 键，退出INSERT模式，进入命令模式<br>再输入 :wq，保存文件，退出vi编辑器</p><p>键 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 功能<br>:wq &nbsp;&nbsp;&nbsp;&nbsp;     保存文件，退出vi编辑器<br>:w  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;    保存文件，但不退出vi编辑器<br>:q  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;     退出vi编辑器<br>:q! &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;    不保存文件，退出vi编辑器<br>ZZ  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;    保存文件，退出vi编辑器<br>或者在winSCP中直接打开/etc/profile文件，修改后保存。</p><p>putty中输入<br><code>source /etc/profile</code> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // source重启环境变量配置文件<br><code>java -version</code>  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 检测jdk环境是否配置好<br><img src="https://img-blog.csdnimg.cn/20181220210757797.JPG?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZmY2pqaHY=,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"><br>注：每次登录，碰到java -version不显示版本号就，先<code>source /etc/profile</code>，再<code>java -version</code>，就好了。</p><h3 id="（2）安装Tomcat9"><a href="#（2）安装Tomcat9" class="headerlink" title="（2）安装Tomcat9"></a>（2）安装Tomcat9</h3><p>root登录putty后，输入<br><code>cd /usr/local/src/</code> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 进入存放安装包的位置<br><code>tar zxvf apache-tomcat-9.0.14.tar.gz</code> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 解压下载的数据包<br><code>mv apache-tomcat-9.0.14 /usr/local/tomcat</code> &nbsp;&nbsp; // 给解压完成后的数据包更换一个其他目录并且改名<br><code>/usr/local/tomcat/bin/startup.sh</code> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 启动Tomcat</p><p>Tomcat启用成功了显示：</p><blockquote><p>Using CATALINA_BASE:   /usr/local/tomcat<br>Using CATALINA_HOME:   /usr/local/tomcat<br>Using CATALINA_TMPDIR: /usr/local/tomcat/temp<br>Using JRE_HOME:        /usr/local/jdk1.8<br>Using CLASSPATH:       /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar<br>Tomcat started.</p></blockquote><p>如果要关闭Tomcat<br><code>/usr/local/tomcat/bin/shutdown.sh</code><br>启动Tomcat后，确定服务器8080端口放通，则在浏览器输入 服务器公网ip:8080，一只熟悉的猫出现了~注：如果添加了域名解析，可以用域名代替ip</p><h1 id="STEP3-本地网页布置到tomcat"><a href="#STEP3-本地网页布置到tomcat" class="headerlink" title="STEP3:本地网页布置到tomcat"></a>STEP3:本地网页布置到tomcat</h1><p>希望ip:8080访问自己的网页<br>首先有自己的网页，如自己写的跳一跳网页，下载地址：<a href="https://github.com/zj19941113/You_Jump_I_Jump" target="_blank" rel="noopener">https://github.com/zj19941113/You_Jump_I_Jump</a><br>将项目文件夹zjgame放到tomcat/webapps/文件夹中，从ROOT中将WEB-INF文件夹复制到zjgame，访问ip:8080/zjgame/zjtest.html，就能看到项目了<br>如果添加了域名解析，可以访问 域名:8080/zjgame/zjtest.html<br><img src="https://img-blog.csdnimg.cn/20181220213248797.JPG?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZmY2pqaHY=,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"></p><h3 id="（1）去掉项目名"><a href="#（1）去掉项目名" class="headerlink" title="（1）去掉项目名"></a>（1）去掉项目名</h3><p>a. 将zjgame中的网页和资源文件复制到ROOT中，zjtest.html重命名为index.html<br>浏览器输入 ip:8080 就能访问了<br>或者</p><p>b. 修改 /usr/local/tomcat/conf/server.xml 文件<br><img src="https://img-blog.csdnimg.cn/20181224161700100.JPG?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZmY2pqaHY=,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"><br>在&lt;Host&gt;&lt;/Host&gt;里加上 &lt;Context path=”” docBase=”项目名” reloadable=”true” /&gt;</p><h3 id="（2）去掉-8080"><a href="#（2）去掉-8080" class="headerlink" title="（2）去掉:8080"></a>（2）去掉:8080</h3><p>修改 /usr/local/tomcat/conf/server.xml 文件，将默认端口port=”8080”改为”80”</p><blockquote><p>Connector port=”80” protocol=”HTTP/1.1” connectionTimeout=”20000”  redirectPort=”8443” /&gt;</p></blockquote><p>关闭Tomcat<br><code>/usr/local/tomcat/bin/shutdown.sh</code><br>过一会再重启<br><code>/usr/local/tomcat/bin/startup.sh</code><br>因为之前已经进行过域名解析，所以直接访问 <a href="http://zhoujie1994.cn" target="_blank" rel="noopener">http://zhoujie1994.cn</a> 就能看到自己的网页了<br><img src="https://img-blog.csdnimg.cn/2018122019554673.JPG?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZmY2pqaHY=,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"><br>备案后不会再提示不安全：<a href="https://zhoujie1994.cn/three/" target="_blank" rel="noopener">https://zhoujie1994.cn/three/</a><br><img src="https://img-blog.csdnimg.cn/20190123095759145.JPG?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZmY2pqaHY=,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"></p>]]></content>
    
    <summary type="html">
    
      &lt;h1 id=&quot;STEP1-云服务器-域名&quot;&gt;&lt;a href=&quot;#STEP1-云服务器-域名&quot; class=&quot;headerlink&quot; title=&quot;STEP1:云服务器+域名&quot;&gt;&lt;/a&gt;STEP1:云服务器+域名&lt;/h1&gt;&lt;h2 id=&quot;1、购买云服务器、域名&quot;&gt;&lt;a href=&quot;#1、购买云服务器、域名&quot; class=&quot;headerlink&quot; title=&quot;1、购买云服务器、域名&quot;&gt;&lt;/a&gt;1、购买云服务器、域名&lt;/h2&gt;&lt;p&gt;购买学生优惠套餐 10元/月：&lt;a href=&quot;https://cloud.tencent.com/act/campus?fromSource=gwzcw.1088196.1088196.1088196&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://cloud.tencent.com/act/campus?fromSource=gwzcw.1088196.1088196.1088196&lt;/a&gt;&lt;br&gt;系统选ubuntu，购买3个月加购域名共38元（3个月以下没法添加域名解析），买了域名以后可以直接通过域名访问&lt;/p&gt;
    
    </summary>
    
      <category term="前端" scheme="http://yoursite.com/categories/%E5%89%8D%E7%AB%AF/"/>
    
      <category term="后台开发" scheme="http://yoursite.com/categories/%E5%90%8E%E5%8F%B0%E5%BC%80%E5%8F%91/"/>
    
    
      <category term="腾讯云服务器" scheme="http://yoursite.com/tags/%E8%85%BE%E8%AE%AF%E4%BA%91%E6%9C%8D%E5%8A%A1%E5%99%A8/"/>
    
      <category term="Tomcat" scheme="http://yoursite.com/tags/Tomcat/"/>
    
  </entry>
  
  <entry>
    <title>Kinect v1实时dlib(GPU版)人脸识别与活体检测</title>
    <link href="http://yoursite.com/2019/04/22/16/"/>
    <id>http://yoursite.com/2019/04/22/16/</id>
    <published>2019-04-22T11:39:33.000Z</published>
    <updated>2019-12-18T04:13:02.054Z</updated>
    
    <content type="html"><![CDATA[<h1 id="一、配置"><a href="#一、配置" class="headerlink" title="一、配置"></a>一、配置</h1><h2 id="1、opencv"><a href="#1、opencv" class="headerlink" title="1、opencv"></a>1、opencv</h2><p>#安装依赖</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">sudo apt-get install libvtk5-dev</span><br><span class="line">sudo apt-get install libgtk2<span class="number">.0</span>-dev</span><br></pre></td></tr></table></figure><a id="more"></a><p>#安装OpenCV 2.4.13</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">git clone https:<span class="comment">//github.com/opencv/opencv</span></span><br><span class="line">cd opencv/</span><br><span class="line">git checkout <span class="number">2.4</span><span class="number">.13</span><span class="number">.3</span></span><br><span class="line">mkdir -p build &amp;&amp; cd build</span><br><span class="line">cmake -DWITH_VTK=ON -DWITH_GTK=ON -DBUILD_opencv_calib3d=ON -DBUILD_opencv_imgproc=ON -DWITH_CUDA=OFF ..</span><br><span class="line">make -j4</span><br><span class="line">sudo make install</span><br></pre></td></tr></table></figure><p>注：opencv的下载过程非常慢</p><h2 id="2、dlib（GPU版）"><a href="#2、dlib（GPU版）" class="headerlink" title="2、dlib（GPU版）"></a>2、dlib（GPU版）</h2><p>需要提前安装<code>驱动、cuda 与 cudnn</code><br>进入官网：<a href="http://dlib.net/" target="_blank" rel="noopener">http://dlib.net/</a> ，点击左下角<code>Download dlib ver.19.17</code> ，下载后解压。<br>进入dlib根目录下</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">mkdir build &amp;&amp; cd build</span><br><span class="line">cmake .. </span><br><span class="line">cmake --build . --config Release</span><br><span class="line">sudo make install</span><br></pre></td></tr></table></figure><p>注：会自动检查满足安装gpu版条件，注意命令行提示信息</p><h1 id="二、Kinect-v1接入"><a href="#二、Kinect-v1接入" class="headerlink" title="二、Kinect v1接入"></a>二、Kinect v1接入</h1><h2 id="1、安装OpenNI2"><a href="#1、安装OpenNI2" class="headerlink" title="1、安装OpenNI2"></a>1、安装OpenNI2</h2><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">git clone https:<span class="comment">//github.com/occipital/OpenNI2.git</span></span><br><span class="line">cd OpenNI2</span><br><span class="line">make -j4</span><br></pre></td></tr></table></figure><h2 id="2、安装libFreenect"><a href="#2、安装libFreenect" class="headerlink" title="2、安装libFreenect"></a>2、安装libFreenect</h2><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">git clone https:<span class="comment">//github.com/OpenKinect/libfreenect</span></span><br><span class="line">cd libfreenect</span><br></pre></td></tr></table></figure><p>打开<code>libfreenect/CMakeLists.txt</code>，在33行<code>cmake_minimum_required(VERSION 2.8.12)</code>下一行添加</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">add_definitions(-<span class="built_in">std</span>=c++<span class="number">11</span>)</span><br></pre></td></tr></table></figure><p>保存后关闭，命令行继续执行</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">mkdir build &amp;&amp; cd build  </span><br><span class="line">cmake .. -DBUILD_OPENNI2_DRIVER=ON  </span><br><span class="line">make -j4</span><br><span class="line">cp -L lib/OpenNI2-FreenectDriver/libFreenectDriver.so $&#123;OPENNI2_DIR&#125;/Bin/x64-Release/OpenNI2/Drivers   #OPENNI2_DIR需要修改</span><br></pre></td></tr></table></figure><p>注：<code>${OPENNI2_DIR}</code>是OpenNI2的解压文件夹，比如我的在ElasticFusion文件夹，则<br><img src="https://img-blog.csdnimg.cn/2019041516412934.png" alt="在这里插入图片描述"><br>打开<code>libfreenect</code>文件夹，运行</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo cp platform/linux/udev/<span class="number">51</span>-kinect.rules /etc/udev/rules.d</span><br></pre></td></tr></table></figure><p>重启后，插上kinect后，命令行运行<code>clsusb</code>，查看是否包含：Xbox camera，Xbox motor，Xbox audio<br><img src="https://img-blog.csdnimg.cn/20190415165040377.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZmY2pqaHY=,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"></p><h1 id="二、代码运行"><a href="#二、代码运行" class="headerlink" title="二、代码运行"></a>二、代码运行</h1><h2 id="1、CMakeList-txt修改"><a href="#1、CMakeList-txt修改" class="headerlink" title="1、CMakeList.txt修改"></a>1、CMakeList.txt修改</h2><p>#CMakeList.txt</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br></pre></td><td class="code"><pre><span class="line">cmake_minimum_required(VERSION <span class="number">2.8</span><span class="number">.4</span>) </span><br><span class="line"></span><br><span class="line">project(face_dlib) </span><br><span class="line"></span><br><span class="line"></span><br><span class="line">SET(CMAKE_CXX_FLAGS <span class="string">"$&#123;CMAKE_CXX_FLAGS&#125; -O2 -DDLIB_JPEG_SUPPORT"</span>)</span><br><span class="line"></span><br><span class="line">IF(CMAKE_CXX_COMPILER_ID STREQUAL <span class="string">"Clang"</span>)</span><br><span class="line">  SET(CMAKE_CXX_FLAGS <span class="string">"$&#123;CMAKE_CXX_FLAGS&#125; -Weverything"</span>)</span><br><span class="line">ELSEIF(CMAKE_CXX_COMPILER_ID STREQUAL <span class="string">"GNU"</span>)</span><br><span class="line">  SET(CMAKE_CXX_FLAGS <span class="string">"$&#123;CMAKE_CXX_FLAGS&#125; -Wall -Wextra"</span>)</span><br><span class="line">ENDIF()</span><br><span class="line"></span><br><span class="line"><span class="meta"># opencv</span></span><br><span class="line">find_package(OpenCV REQUIRED)</span><br><span class="line">include_directories($&#123;OpenCV_INCLUDE_DIRS&#125;)</span><br><span class="line"></span><br><span class="line"># OpenNI2</span><br><span class="line"><span class="built_in">set</span>(OPENNI2_PATH <span class="string">"/home/zhoujie/fusion/ElasticFusion/OpenNI2"</span>) </span><br><span class="line"></span><br><span class="line"><span class="built_in">set</span>(OPENNI2_INCLUDE_DIR $&#123;OPENNI2_PATH&#125;/Include)</span><br><span class="line"><span class="built_in">set</span>(OPENNI2_LIBRARY $&#123;OPENNI2_PATH&#125;/Bin/x64-Release)</span><br><span class="line">include_directories ($&#123;OPENNI2_INCLUDE_DIR&#125;)</span><br><span class="line">link_directories ($&#123;OPENNI2_LIBRARY&#125;)</span><br><span class="line"></span><br><span class="line"><span class="meta"># dlib</span></span><br><span class="line">include(/home/zhoujie/dlib<span class="number">-19.17</span>/dlib/cmake)</span><br><span class="line"></span><br><span class="line">add_executable(this_is_who_kinect_one src/this_is_who_kinect_one.cpp)</span><br><span class="line">target_link_libraries(this_is_who_kinect_one dlib $&#123;OpenCV_LIBS&#125; libOpenNI2.so)</span><br><span class="line"></span><br><span class="line">macro(add_face_dlib name)</span><br><span class="line">   add_executable($&#123;name&#125; src/$&#123;name&#125;.cpp)</span><br><span class="line">   target_link_libraries($&#123;name&#125; dlib )</span><br><span class="line">endmacro()</span><br><span class="line"></span><br><span class="line">add_face_dlib(train_candidate)</span><br><span class="line">add_face_dlib(this_is_who)</span><br></pre></td></tr></table></figure><p>将<code>OPENNI2_PATH</code>与<code>dlib</code>路径修改为自己的。</p><h2 id="2、数据-模型下载"><a href="#2、数据-模型下载" class="headerlink" title="2、数据+模型下载"></a>2、数据+模型下载</h2><p>下载 <code>shape_predictor_68_face_landmarks.dat</code> 和 <code>dlib_face_recognition_resnet_model_v1.dat</code> 放置到<code>model</code>文件夹中</p><p>链接：<a href="https://pan.baidu.com/s/1jIoW6BSa5nkGWNipL7sxVQ" target="_blank" rel="noopener">https://pan.baidu.com/s/1jIoW6BSa5nkGWNipL7sxVQ</a><br>其中包括：</p><ul><li>candidate-face.zip（人脸库：包含29个正面人脸红外图）</li><li>allface.zip（测试人脸集：包括29个人，每人13种脸部姿态下的红外图与深度图）</li><li>shape_predictor_68_face_landmarks.dat（人脸68关键点检测器）</li><li>dlib_face_recognition_resnet_model_v1.dat（人脸识别模型）<br><img src="https://img-blog.csdnimg.cn/20190123122918821.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZmY2pqaHY=,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"></li></ul><h2 id="3、代码运行"><a href="#3、代码运行" class="headerlink" title="3、代码运行"></a>3、代码运行</h2><p><img src="https://img-blog.csdnimg.cn/20190422194030399.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZmY2pqaHY=,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"><br>将<code>train_candidate.cpp</code> 、<code>this_is_who</code> 和 <code>this_is_who_kinect_one.cpp</code>置于<code>src</code>文件夹中。</p><p>#build</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">mkdir build &amp;&amp; cd build</span><br><span class="line">cmake ..</span><br><span class="line">make -j4</span><br></pre></td></tr></table></figure><p>cmake时检查是否适用dlib(GPU)版<br><img src="https://img-blog.csdnimg.cn/20190423104534219.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZmY2pqaHY=,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"><img src="https://img-blog.csdnimg.cn/20190423104605942.png" alt="在这里插入图片描述"><br>最终在<code>build</code>文件夹中生成多个可执行文件<br><img src="https://img-blog.csdnimg.cn/20190423104548489.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZmY2pqaHY=,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"><br>将人脸图片重命名为人的名字，放在<code>data</code>文件夹中。</p><p>1、运行<code>train_candidate</code> 获得人脸库特征信息，存储在<code>candidates_descriptors.dat</code> 与 <code>candidates.dat</code> 中，同时生成<code>candidates.txt</code>，便于查看候选人信息。每次修改人脸库，只需运行<code>train_candidate</code>，完成人脸信息的更新。<br><img src="https://img-blog.csdnimg.cn/20190423102438856.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZmY2pqaHY=,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"></p><p>2、运行<code>this_is_who_kinect_one</code>,实时获取Kinect深度图与彩色图，并进行人脸识别与活体检测。<br><img src="https://img-blog.csdnimg.cn/20190422193123321.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZmY2pqaHY=,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"><br>3、 不使用kinect v1实时接入，在离线数据上测试，运行<code>this_is_who</code>,使用<code>data/allface</code>中的深度图与红外图，并进行人脸识别与活体检测。<br><img src="https://img-blog.csdnimg.cn/20190423103125141.png" alt="在这里插入图片描述"><br>代码部分：</p><p>#train_candidate</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;dlib/dnn.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;dlib/image_processing/frontal_face_detector.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;dlib/image_processing.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;dlib/gui_widgets.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;dlib/image_io.h&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;iostream&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;fstream&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;time.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;dirent.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;string.h&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> dlib;</span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> <span class="built_in">std</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">/* 函数声明 */</span></span><br><span class="line"><span class="comment">/* 人脸库训练 */</span></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">candidates_train</span><span class="params">(<span class="keyword">const</span> <span class="keyword">char</span> *facesFile,<span class="built_in">std</span>::<span class="built_in">vector</span>&lt;matrix&lt;<span class="keyword">float</span>,<span class="number">0</span>,<span class="number">1</span>&gt;&gt;&amp;candidates_descriptors,<span class="built_in">std</span>::<span class="built_in">vector</span>&lt;<span class="built_in">string</span>&gt;&amp;candidates)</span></span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">template</span> &lt;<span class="keyword">template</span> &lt;<span class="keyword">int</span>,<span class="keyword">template</span>&lt;<span class="keyword">typename</span>&gt;<span class="class"><span class="keyword">class</span>,<span class="title">int</span>,<span class="title">typename</span>&gt; <span class="title">class</span> <span class="title">block</span>, <span class="title">int</span> <span class="title">N</span>, <span class="title">template</span>&lt;typename&gt;<span class="title">class</span> <span class="title">BN</span>, <span class="title">typename</span> <span class="title">SUBNET</span>&gt;</span></span><br><span class="line"><span class="class"><span class="title">using</span> <span class="title">residual</span> = <span class="title">add_prev1</span>&lt;block&lt;N,BN,1,tag1&lt;SUBNET&gt;&gt;&gt;;</span></span><br><span class="line"><span class="keyword">template</span> &lt;<span class="keyword">template</span> &lt;<span class="keyword">int</span>,<span class="keyword">template</span>&lt;<span class="keyword">typename</span>&gt;<span class="class"><span class="keyword">class</span>,<span class="title">int</span>,<span class="title">typename</span>&gt; <span class="title">class</span> <span class="title">block</span>, <span class="title">int</span> <span class="title">N</span>, <span class="title">template</span>&lt;typename&gt;<span class="title">class</span> <span class="title">BN</span>, <span class="title">typename</span> <span class="title">SUBNET</span>&gt;</span></span><br><span class="line"><span class="class"><span class="title">using</span> <span class="title">residual_down</span> = <span class="title">add_prev2</span>&lt;avg_pool&lt;2,2,2,2,skip1&lt;tag2&lt;block&lt;N,BN,2,tag1&lt;SUBNET&gt;&gt;&gt;&gt;&gt;&gt;;</span></span><br><span class="line"><span class="keyword">template</span> &lt;<span class="keyword">int</span> N, <span class="keyword">template</span> &lt;<span class="keyword">typename</span>&gt; <span class="class"><span class="keyword">class</span> <span class="title">BN</span>, <span class="title">int</span> <span class="title">stride</span>, <span class="title">typename</span> <span class="title">SUBNET</span>&gt; </span></span><br><span class="line"><span class="class"><span class="title">using</span> <span class="title">block</span>  = <span class="title">BN</span>&lt;con&lt;N,3,3,1,1,relu&lt;BN&lt;con&lt;N,3,3,stride,stride,SUBNET&gt;&gt;&gt;&gt;&gt;;</span></span><br><span class="line"><span class="keyword">template</span> &lt;<span class="keyword">int</span> N, <span class="keyword">typename</span> SUBNET&gt; <span class="keyword">using</span> ares      = relu&lt;residual&lt;block,N,affine,SUBNET&gt;&gt;;</span><br><span class="line"><span class="keyword">template</span> &lt;<span class="keyword">int</span> N, <span class="keyword">typename</span> SUBNET&gt; <span class="keyword">using</span> ares_down = relu&lt;residual_down&lt;block,N,affine,SUBNET&gt;&gt;;</span><br><span class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> SUBNET&gt; <span class="keyword">using</span> alevel0 = ares_down&lt;<span class="number">256</span>,SUBNET&gt;;</span><br><span class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> SUBNET&gt; <span class="keyword">using</span> alevel1 = ares&lt;<span class="number">256</span>,ares&lt;<span class="number">256</span>,ares_down&lt;<span class="number">256</span>,SUBNET&gt;&gt;&gt;;</span><br><span class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> SUBNET&gt; <span class="keyword">using</span> alevel2 = ares&lt;<span class="number">128</span>,ares&lt;<span class="number">128</span>,ares_down&lt;<span class="number">128</span>,SUBNET&gt;&gt;&gt;;</span><br><span class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> SUBNET&gt; <span class="keyword">using</span> alevel3 = ares&lt;<span class="number">64</span>,ares&lt;<span class="number">64</span>,ares&lt;<span class="number">64</span>,ares_down&lt;<span class="number">64</span>,SUBNET&gt;&gt;&gt;&gt;;</span><br><span class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> SUBNET&gt; <span class="keyword">using</span> alevel4 = ares&lt;<span class="number">32</span>,ares&lt;<span class="number">32</span>,ares&lt;<span class="number">32</span>,SUBNET&gt;&gt;&gt;;</span><br><span class="line"><span class="keyword">using</span> anet_type = loss_metric&lt;fc_no_bias&lt;<span class="number">128</span>,avg_pool_everything&lt;</span><br><span class="line">    alevel0&lt;</span><br><span class="line">    alevel1&lt;</span><br><span class="line">    alevel2&lt;</span><br><span class="line">    alevel3&lt;</span><br><span class="line">    alevel4&lt;</span><br><span class="line">    max_pool&lt;<span class="number">3</span>,<span class="number">3</span>,<span class="number">2</span>,<span class="number">2</span>,relu&lt;affine&lt;con&lt;<span class="number">32</span>,<span class="number">7</span>,<span class="number">7</span>,<span class="number">2</span>,<span class="number">2</span>,</span><br><span class="line">    input_rgb_image_sized&lt;<span class="number">150</span>&gt;</span><br><span class="line">    &gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">(<span class="keyword">int</span> argc, <span class="keyword">char</span>** argv)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (argc == <span class="number">1</span>)</span><br><span class="line">        &#123;</span><br><span class="line">            <span class="built_in">cout</span> &lt;&lt; <span class="string">"\nCall this program like this:"</span> &lt;&lt; <span class="built_in">endl</span>;</span><br><span class="line">            <span class="built_in">cout</span> &lt;&lt; <span class="string">"./train_candidate ../data/candidate-face/"</span> &lt;&lt; <span class="built_in">endl</span>;</span><br><span class="line">            <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="keyword">const</span> <span class="keyword">char</span> *facesFile = argv[<span class="number">1</span>];</span><br><span class="line"></span><br><span class="line">    <span class="built_in">std</span>::<span class="built_in">vector</span>&lt;matrix&lt;<span class="keyword">float</span>,0,1&gt;&gt; candidates_descriptors;</span><br><span class="line">    <span class="built_in">std</span>::<span class="built_in">vector</span>&lt;<span class="built_in">string</span>&gt; candidates;</span><br><span class="line">    </span><br><span class="line">    <span class="comment">/* 人脸库训练 */</span></span><br><span class="line">    candidates_train(facesFile,candidates_descriptors,candidates);</span><br><span class="line"></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">/* 人脸库训练 */</span></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">candidates_train</span><span class="params">(<span class="keyword">const</span> <span class="keyword">char</span> *facesFile,<span class="built_in">std</span>::<span class="built_in">vector</span>&lt;matrix&lt;<span class="keyword">float</span>,<span class="number">0</span>,<span class="number">1</span>&gt;&gt;&amp;candidates_descriptors,<span class="built_in">std</span>::<span class="built_in">vector</span>&lt;<span class="built_in">string</span>&gt;&amp;candidates)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    DIR *dir;</span><br><span class="line">    <span class="class"><span class="keyword">struct</span> <span class="title">dirent</span> *<span class="title">ptr</span>;</span> </span><br><span class="line">    <span class="keyword">char</span> base[<span class="number">30</span>]; </span><br><span class="line">    <span class="keyword">const</span> <span class="keyword">char</span> *pick=<span class="string">".jpg"</span>; <span class="comment">//需要的子串;</span></span><br><span class="line">    <span class="keyword">char</span> IRfile[<span class="number">100</span>];</span><br><span class="line">    <span class="keyword">char</span> *name;</span><br><span class="line">    <span class="keyword">int</span> face_num = <span class="number">0</span>;</span><br><span class="line">    <span class="built_in">std</span>::<span class="built_in">vector</span>&lt;matrix&lt;rgb_pixel&gt;&gt; faces;</span><br><span class="line"></span><br><span class="line">    frontal_face_detector detector = get_frontal_face_detector(); <span class="comment">// 人脸正脸检测器</span></span><br><span class="line">    shape_predictor sp; <span class="comment">//人脸关键点检测器</span></span><br><span class="line">    anet_type net;  <span class="comment">// 人脸识别模型</span></span><br><span class="line"></span><br><span class="line">    deserialize(<span class="string">"../model/shape_predictor_68_face_landmarks.dat"</span>) &gt;&gt; sp;</span><br><span class="line">    deserialize(<span class="string">"../model/dlib_face_recognition_resnet_model_v1.dat"</span>) &gt;&gt; net;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">clock_t</span> start,finish;</span><br><span class="line">    <span class="keyword">double</span> totaltime;</span><br><span class="line">    start=clock();</span><br><span class="line"></span><br><span class="line">    <span class="function">ofstream <span class="title">mycout</span><span class="params">(<span class="string">"../candidates.txt"</span>)</span></span>;</span><br><span class="line"></span><br><span class="line">    <span class="built_in">cout</span> &lt;&lt; <span class="string">"TRAINING START！"</span> &lt;&lt; <span class="built_in">endl</span>;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> ((dir=opendir(facesFile)) == <span class="literal">NULL</span>)</span><br><span class="line">    &#123;</span><br><span class="line">        perror(<span class="string">"Open dir error..."</span>);</span><br><span class="line">        <span class="built_in">exit</span>(<span class="number">1</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">while</span> ((ptr=readdir(dir)) != <span class="literal">NULL</span>)</span><br><span class="line">    &#123;</span><br><span class="line">        <span class="built_in">strcpy</span>(base, ptr-&gt;d_name);</span><br><span class="line">        <span class="keyword">if</span>(<span class="built_in">strstr</span>(base,pick)) </span><br><span class="line">        &#123;</span><br><span class="line">            <span class="built_in">cout</span> &lt;&lt; <span class="string">"training image:"</span> &lt;&lt; base &lt;&lt; <span class="built_in">endl</span>;</span><br><span class="line">            <span class="built_in">strcpy</span>(IRfile, facesFile);</span><br><span class="line">            <span class="built_in">strcat</span>(IRfile, base);</span><br><span class="line">            name = strtok(base, <span class="string">"_"</span>);</span><br><span class="line">            <span class="built_in">string</span> candidate = name;</span><br><span class="line">            <span class="built_in">cout</span> &lt;&lt; <span class="string">"candidate: "</span> &lt;&lt; candidate &lt;&lt; <span class="built_in">endl</span>;</span><br><span class="line"></span><br><span class="line">            mycout  &lt;&lt; candidate &lt;&lt; <span class="built_in">endl</span>;</span><br><span class="line"></span><br><span class="line">            candidates.push_back(candidate);</span><br><span class="line">            matrix&lt;rgb_pixel&gt; img;</span><br><span class="line">            load_image(img, IRfile);</span><br><span class="line">            <span class="built_in">std</span>::<span class="built_in">vector</span>&lt;rectangle&gt; dets = detector(img);</span><br><span class="line">            full_object_detection shape = sp(img, dets[<span class="number">0</span>]);</span><br><span class="line">            matrix&lt;rgb_pixel&gt; face_chip;</span><br><span class="line">            extract_image_chip(img, get_face_chip_details(shape,<span class="number">150</span>,<span class="number">0.25</span>), face_chip);</span><br><span class="line">            faces.push_back(move(face_chip));</span><br><span class="line">            face_num += <span class="number">1</span>;</span><br><span class="line">        &#125;  </span><br><span class="line">    &#125;</span><br><span class="line">    candidates_descriptors = net(faces);</span><br><span class="line"></span><br><span class="line">    mycout.close();</span><br><span class="line">    <span class="built_in">cout</span> &lt;&lt; <span class="string">"TRAINING END！"</span> &lt;&lt; <span class="built_in">endl</span>;</span><br><span class="line">    <span class="built_in">cout</span> &lt;&lt; <span class="string">"\nTRAIN RESULT："</span> &lt;&lt; <span class="built_in">endl</span>;</span><br><span class="line">    <span class="built_in">cout</span> &lt;&lt; <span class="string">"Training "</span> &lt;&lt; face_num &lt;&lt;  <span class="string">" face(s)！"</span> &lt;&lt; <span class="built_in">endl</span>;</span><br><span class="line"></span><br><span class="line">    finish=clock();</span><br><span class="line">    totaltime=(<span class="keyword">double</span>)(finish-start)/CLOCKS_PER_SEC;</span><br><span class="line">    <span class="built_in">cout</span>&lt;&lt;<span class="string">"TRAINING TIME： "</span> &lt;&lt; totaltime &lt;&lt; <span class="string">" S！"</span>&lt;&lt;<span class="built_in">endl</span>;</span><br><span class="line"></span><br><span class="line">    <span class="built_in">cout</span> &lt;&lt; <span class="string">"\nFace database updating……"</span> &lt;&lt; <span class="built_in">endl</span>;</span><br><span class="line">    serialize(<span class="string">"../candidates_descriptors.dat"</span>) &lt;&lt; candidates_descriptors;</span><br><span class="line">    serialize(<span class="string">"../candidates.dat"</span>) &lt;&lt; candidates;</span><br><span class="line">    <span class="built_in">cout</span> &lt;&lt; <span class="string">"Face has been updated！"</span> &lt;&lt; <span class="built_in">endl</span>;</span><br><span class="line">    </span><br><span class="line">    closedir(dir);</span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>#this_is_who_kinect_one.cpp</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br><span class="line">180</span><br><span class="line">181</span><br><span class="line">182</span><br><span class="line">183</span><br><span class="line">184</span><br><span class="line">185</span><br><span class="line">186</span><br><span class="line">187</span><br><span class="line">188</span><br><span class="line">189</span><br><span class="line">190</span><br><span class="line">191</span><br><span class="line">192</span><br><span class="line">193</span><br><span class="line">194</span><br><span class="line">195</span><br><span class="line">196</span><br><span class="line">197</span><br><span class="line">198</span><br><span class="line">199</span><br><span class="line">200</span><br><span class="line">201</span><br><span class="line">202</span><br><span class="line">203</span><br><span class="line">204</span><br><span class="line">205</span><br><span class="line">206</span><br><span class="line">207</span><br><span class="line">208</span><br><span class="line">209</span><br><span class="line">210</span><br><span class="line">211</span><br><span class="line">212</span><br><span class="line">213</span><br><span class="line">214</span><br><span class="line">215</span><br><span class="line">216</span><br><span class="line">217</span><br><span class="line">218</span><br><span class="line">219</span><br><span class="line">220</span><br><span class="line">221</span><br><span class="line">222</span><br><span class="line">223</span><br><span class="line">224</span><br><span class="line">225</span><br><span class="line">226</span><br><span class="line">227</span><br><span class="line">228</span><br><span class="line">229</span><br><span class="line">230</span><br><span class="line">231</span><br><span class="line">232</span><br><span class="line">233</span><br><span class="line">234</span><br><span class="line">235</span><br><span class="line">236</span><br><span class="line">237</span><br><span class="line">238</span><br><span class="line">239</span><br><span class="line">240</span><br><span class="line">241</span><br><span class="line">242</span><br><span class="line">243</span><br><span class="line">244</span><br><span class="line">245</span><br><span class="line">246</span><br><span class="line">247</span><br><span class="line">248</span><br><span class="line">249</span><br><span class="line">250</span><br><span class="line">251</span><br><span class="line">252</span><br><span class="line">253</span><br><span class="line">254</span><br><span class="line">255</span><br><span class="line">256</span><br><span class="line">257</span><br><span class="line">258</span><br><span class="line">259</span><br><span class="line">260</span><br><span class="line">261</span><br><span class="line">262</span><br><span class="line">263</span><br><span class="line">264</span><br><span class="line">265</span><br><span class="line">266</span><br><span class="line">267</span><br><span class="line">268</span><br><span class="line">269</span><br><span class="line">270</span><br><span class="line">271</span><br><span class="line">272</span><br><span class="line">273</span><br><span class="line">274</span><br><span class="line">275</span><br><span class="line">276</span><br><span class="line">277</span><br><span class="line">278</span><br><span class="line">279</span><br><span class="line">280</span><br><span class="line">281</span><br><span class="line">282</span><br><span class="line">283</span><br><span class="line">284</span><br><span class="line">285</span><br><span class="line">286</span><br><span class="line">287</span><br><span class="line">288</span><br><span class="line">289</span><br><span class="line">290</span><br><span class="line">291</span><br><span class="line">292</span><br><span class="line">293</span><br><span class="line">294</span><br><span class="line">295</span><br><span class="line">296</span><br><span class="line">297</span><br><span class="line">298</span><br><span class="line">299</span><br><span class="line">300</span><br><span class="line">301</span><br><span class="line">302</span><br><span class="line">303</span><br><span class="line">304</span><br><span class="line">305</span><br><span class="line">306</span><br><span class="line">307</span><br><span class="line">308</span><br><span class="line">309</span><br><span class="line">310</span><br><span class="line">311</span><br><span class="line">312</span><br><span class="line">313</span><br><span class="line">314</span><br><span class="line">315</span><br><span class="line">316</span><br><span class="line">317</span><br><span class="line">318</span><br><span class="line">319</span><br><span class="line">320</span><br><span class="line">321</span><br><span class="line">322</span><br><span class="line">323</span><br><span class="line">324</span><br><span class="line">325</span><br><span class="line">326</span><br><span class="line">327</span><br><span class="line">328</span><br><span class="line">329</span><br><span class="line">330</span><br><span class="line">331</span><br><span class="line">332</span><br><span class="line">333</span><br><span class="line">334</span><br><span class="line">335</span><br><span class="line">336</span><br><span class="line">337</span><br><span class="line">338</span><br><span class="line">339</span><br><span class="line">340</span><br><span class="line">341</span><br><span class="line">342</span><br><span class="line">343</span><br><span class="line">344</span><br><span class="line">345</span><br><span class="line">346</span><br><span class="line">347</span><br><span class="line">348</span><br><span class="line">349</span><br><span class="line">350</span><br><span class="line">351</span><br><span class="line">352</span><br><span class="line">353</span><br><span class="line">354</span><br><span class="line">355</span><br><span class="line">356</span><br><span class="line">357</span><br><span class="line">358</span><br><span class="line">359</span><br><span class="line">360</span><br><span class="line">361</span><br><span class="line">362</span><br><span class="line">363</span><br><span class="line">364</span><br><span class="line">365</span><br><span class="line">366</span><br><span class="line">367</span><br><span class="line">368</span><br><span class="line">369</span><br><span class="line">370</span><br><span class="line">371</span><br><span class="line">372</span><br><span class="line">373</span><br><span class="line">374</span><br><span class="line">375</span><br><span class="line">376</span><br><span class="line">377</span><br><span class="line">378</span><br><span class="line">379</span><br><span class="line">380</span><br><span class="line">381</span><br><span class="line">382</span><br><span class="line">383</span><br><span class="line">384</span><br><span class="line">385</span><br><span class="line">386</span><br><span class="line">387</span><br><span class="line">388</span><br><span class="line">389</span><br><span class="line">390</span><br><span class="line">391</span><br><span class="line">392</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;iostream&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;opencv2/core.hpp&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;opencv2/imgproc.hpp&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;opencv2/highgui.hpp&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;opencv2/opencv.hpp&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;OpenNI.h&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;dlib/dnn.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;dlib/image_processing/frontal_face_detector.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;dlib/image_processing/render_face_detections.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;dlib/image_processing.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;dlib/gui_widgets.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;dlib/image_io.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;dlib/opencv.h&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;time.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;dirent.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;string.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;math.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;sstream&gt; </span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> <span class="built_in">std</span>;</span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> openni;</span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> dlib;</span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> cv;</span><br><span class="line"></span><br><span class="line"><span class="keyword">template</span> &lt;<span class="keyword">template</span> &lt;<span class="keyword">int</span>,<span class="keyword">template</span>&lt;<span class="keyword">typename</span>&gt;<span class="class"><span class="keyword">class</span>,<span class="title">int</span>,<span class="title">typename</span>&gt; <span class="title">class</span> <span class="title">block</span>, <span class="title">int</span> <span class="title">N</span>, <span class="title">template</span>&lt;typename&gt;<span class="title">class</span> <span class="title">BN</span>, <span class="title">typename</span> <span class="title">SUBNET</span>&gt;</span></span><br><span class="line"><span class="class"><span class="title">using</span> <span class="title">residual</span> = <span class="title">add_prev1</span>&lt;block&lt;N,BN,1,tag1&lt;SUBNET&gt;&gt;&gt;;</span></span><br><span class="line"><span class="keyword">template</span> &lt;<span class="keyword">template</span> &lt;<span class="keyword">int</span>,<span class="keyword">template</span>&lt;<span class="keyword">typename</span>&gt;<span class="class"><span class="keyword">class</span>,<span class="title">int</span>,<span class="title">typename</span>&gt; <span class="title">class</span> <span class="title">block</span>, <span class="title">int</span> <span class="title">N</span>, <span class="title">template</span>&lt;typename&gt;<span class="title">class</span> <span class="title">BN</span>, <span class="title">typename</span> <span class="title">SUBNET</span>&gt;</span></span><br><span class="line"><span class="class"><span class="title">using</span> <span class="title">residual_down</span> = <span class="title">add_prev2</span>&lt;avg_pool&lt;2,2,2,2,skip1&lt;tag2&lt;block&lt;N,BN,2,tag1&lt;SUBNET&gt;&gt;&gt;&gt;&gt;&gt;;</span></span><br><span class="line"><span class="keyword">template</span> &lt;<span class="keyword">int</span> N, <span class="keyword">template</span> &lt;<span class="keyword">typename</span>&gt; <span class="class"><span class="keyword">class</span> <span class="title">BN</span>, <span class="title">int</span> <span class="title">stride</span>, <span class="title">typename</span> <span class="title">SUBNET</span>&gt; </span></span><br><span class="line"><span class="class"><span class="title">using</span> <span class="title">block</span>  = <span class="title">BN</span>&lt;con&lt;N,3,3,1,1,relu&lt;BN&lt;con&lt;N,3,3,stride,stride,SUBNET&gt;&gt;&gt;&gt;&gt;;</span></span><br><span class="line"><span class="keyword">template</span> &lt;<span class="keyword">int</span> N, <span class="keyword">typename</span> SUBNET&gt; <span class="keyword">using</span> ares      = relu&lt;residual&lt;block,N,affine,SUBNET&gt;&gt;;</span><br><span class="line"><span class="keyword">template</span> &lt;<span class="keyword">int</span> N, <span class="keyword">typename</span> SUBNET&gt; <span class="keyword">using</span> ares_down = relu&lt;residual_down&lt;block,N,affine,SUBNET&gt;&gt;;</span><br><span class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> SUBNET&gt; <span class="keyword">using</span> alevel0 = ares_down&lt;<span class="number">256</span>,SUBNET&gt;;</span><br><span class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> SUBNET&gt; <span class="keyword">using</span> alevel1 = ares&lt;<span class="number">256</span>,ares&lt;<span class="number">256</span>,ares_down&lt;<span class="number">256</span>,SUBNET&gt;&gt;&gt;;</span><br><span class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> SUBNET&gt; <span class="keyword">using</span> alevel2 = ares&lt;<span class="number">128</span>,ares&lt;<span class="number">128</span>,ares_down&lt;<span class="number">128</span>,SUBNET&gt;&gt;&gt;;</span><br><span class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> SUBNET&gt; <span class="keyword">using</span> alevel3 = ares&lt;<span class="number">64</span>,ares&lt;<span class="number">64</span>,ares&lt;<span class="number">64</span>,ares_down&lt;<span class="number">64</span>,SUBNET&gt;&gt;&gt;&gt;;</span><br><span class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> SUBNET&gt; <span class="keyword">using</span> alevel4 = ares&lt;<span class="number">32</span>,ares&lt;<span class="number">32</span>,ares&lt;<span class="number">32</span>,SUBNET&gt;&gt;&gt;;</span><br><span class="line"><span class="keyword">using</span> anet_type = loss_metric&lt;fc_no_bias&lt;<span class="number">128</span>,avg_pool_everything&lt;</span><br><span class="line">    alevel0&lt;</span><br><span class="line">    alevel1&lt;</span><br><span class="line">    alevel2&lt;</span><br><span class="line">    alevel3&lt;</span><br><span class="line">    alevel4&lt;</span><br><span class="line">    max_pool&lt;<span class="number">3</span>,<span class="number">3</span>,<span class="number">2</span>,<span class="number">2</span>,relu&lt;affine&lt;con&lt;<span class="number">32</span>,<span class="number">7</span>,<span class="number">7</span>,<span class="number">2</span>,<span class="number">2</span>,</span><br><span class="line">    input_rgb_image_sized&lt;<span class="number">150</span>&gt;</span><br><span class="line">    &gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;;</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> <span class="keyword">int</span> ITER = <span class="number">5000</span>; <span class="comment">// 随机取点次数</span></span><br><span class="line"><span class="keyword">const</span> <span class="keyword">float</span> PLANE_OR_NOT = <span class="number">0.2</span>; <span class="comment">// 判断是否为平面的分界线</span></span><br><span class="line"><span class="keyword">const</span> <span class="keyword">int</span> SIGMA = <span class="number">1</span>;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">  frontal_face_detector detector = get_frontal_face_detector(); <span class="comment">// 人脸正脸检测器</span></span><br><span class="line">  shape_predictor sp; <span class="comment">//人脸关键点检测器</span></span><br><span class="line">  anet_type net;  <span class="comment">// 人脸识别模型</span></span><br><span class="line"></span><br><span class="line">  deserialize(<span class="string">"../model/shape_predictor_68_face_landmarks.dat"</span>) &gt;&gt; sp;</span><br><span class="line">  deserialize(<span class="string">"../model/dlib_face_recognition_resnet_model_v1.dat"</span>) &gt;&gt; net;</span><br><span class="line"></span><br><span class="line">  <span class="built_in">std</span>::<span class="built_in">vector</span>&lt;matrix&lt;<span class="keyword">float</span>,0,1&gt;&gt; candidates_descriptors;</span><br><span class="line">  deserialize(<span class="string">"../candidates_descriptors.dat"</span>) &gt;&gt; candidates_descriptors;</span><br><span class="line"></span><br><span class="line">  <span class="built_in">std</span>::<span class="built_in">vector</span>&lt;<span class="built_in">string</span>&gt; candidates;</span><br><span class="line">  deserialize(<span class="string">"../candidates.dat"</span>) &gt;&gt; candidates;</span><br><span class="line">  </span><br><span class="line">  <span class="comment">// 1. Initial OpenNI</span></span><br><span class="line">  <span class="keyword">if</span>( OpenNI::initialize() != STATUS_OK )</span><br><span class="line">  &#123;</span><br><span class="line">    <span class="built_in">cerr</span> &lt;&lt; <span class="string">"OpenNI Initial Error: "</span> </span><br><span class="line">         &lt;&lt; OpenNI::getExtendedError() &lt;&lt; <span class="built_in">endl</span>;</span><br><span class="line">    <span class="keyword">return</span> <span class="number">-1</span>;</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 2. Open Device</span></span><br><span class="line">  Device mDevice;</span><br><span class="line">  <span class="keyword">if</span>( mDevice.open( ANY_DEVICE ) != STATUS_OK )</span><br><span class="line">  &#123;</span><br><span class="line">    <span class="built_in">cerr</span> &lt;&lt; <span class="string">"Can't Open Device: "</span> </span><br><span class="line">         &lt;&lt; OpenNI::getExtendedError() &lt;&lt; <span class="built_in">endl</span>;</span><br><span class="line">    <span class="keyword">return</span> <span class="number">-1</span>;</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 3. Create depth stream</span></span><br><span class="line">  VideoStream mDepthStream;</span><br><span class="line">  <span class="keyword">if</span>( mDevice.hasSensor( SENSOR_DEPTH ) )</span><br><span class="line">  &#123;</span><br><span class="line">    <span class="keyword">if</span>( mDepthStream.create( mDevice, SENSOR_DEPTH ) == STATUS_OK )</span><br><span class="line">    &#123;</span><br><span class="line">      <span class="comment">// 3a. set video mode</span></span><br><span class="line">      VideoMode mMode;</span><br><span class="line">      mMode.setResolution( <span class="number">640</span>, <span class="number">480</span> );</span><br><span class="line">      mMode.setFps( <span class="number">30</span> );</span><br><span class="line">      mMode.setPixelFormat( PIXEL_FORMAT_DEPTH_1_MM );</span><br><span class="line"></span><br><span class="line">      <span class="keyword">if</span>( mDepthStream.setVideoMode( mMode) != STATUS_OK )</span><br><span class="line">      &#123;</span><br><span class="line">        <span class="built_in">cout</span> &lt;&lt; <span class="string">"Can't apply VideoMode: "</span></span><br><span class="line">             &lt;&lt; OpenNI::getExtendedError() &lt;&lt; <span class="built_in">endl</span>;</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">else</span></span><br><span class="line">    &#123;</span><br><span class="line">      <span class="built_in">cerr</span> &lt;&lt; <span class="string">"Can't create depth stream on device: "</span></span><br><span class="line">           &lt;&lt; OpenNI::getExtendedError() &lt;&lt; <span class="built_in">endl</span>;</span><br><span class="line">      <span class="keyword">return</span> <span class="number">-1</span>;</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">else</span></span><br><span class="line">  &#123;</span><br><span class="line">    <span class="built_in">cerr</span> &lt;&lt; <span class="string">"ERROR: This device does not have depth sensor"</span> &lt;&lt; <span class="built_in">endl</span>;</span><br><span class="line">    <span class="keyword">return</span> <span class="number">-1</span>;</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 4. Create color stream</span></span><br><span class="line">  VideoStream mColorStream;</span><br><span class="line">  <span class="keyword">if</span>( mDevice.hasSensor( SENSOR_COLOR ) )</span><br><span class="line">  &#123;</span><br><span class="line">    <span class="keyword">if</span>( mColorStream.create( mDevice, SENSOR_COLOR ) == STATUS_OK )</span><br><span class="line">    &#123;</span><br><span class="line">      <span class="comment">// 4a. set video mode</span></span><br><span class="line">      VideoMode mMode;</span><br><span class="line">      mMode.setResolution( <span class="number">640</span>, <span class="number">480</span> );</span><br><span class="line">      mMode.setFps( <span class="number">30</span> );</span><br><span class="line">      mMode.setPixelFormat( PIXEL_FORMAT_RGB888 );</span><br><span class="line"></span><br><span class="line">      <span class="keyword">if</span>( mColorStream.setVideoMode( mMode) != STATUS_OK )</span><br><span class="line">      &#123;</span><br><span class="line">        <span class="built_in">cout</span> &lt;&lt; <span class="string">"Can't apply VideoMode: "</span> </span><br><span class="line">             &lt;&lt; OpenNI::getExtendedError() &lt;&lt; <span class="built_in">endl</span>;</span><br><span class="line">      &#125;</span><br><span class="line"></span><br><span class="line">      <span class="comment">// 4b. image registration</span></span><br><span class="line">      <span class="keyword">if</span>( mDevice.isImageRegistrationModeSupported(</span><br><span class="line">              IMAGE_REGISTRATION_DEPTH_TO_COLOR ) )</span><br><span class="line">      &#123;</span><br><span class="line">        mDevice.setImageRegistrationMode( IMAGE_REGISTRATION_DEPTH_TO_COLOR );</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">else</span></span><br><span class="line">    &#123;</span><br><span class="line">      <span class="built_in">cerr</span> &lt;&lt; <span class="string">"Can't create color stream on device: "</span></span><br><span class="line">           &lt;&lt; OpenNI::getExtendedError() &lt;&lt; <span class="built_in">endl</span>;</span><br><span class="line">      <span class="keyword">return</span> <span class="number">-1</span>;</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 5. create OpenCV Window</span></span><br><span class="line">  cv::namedWindow( <span class="string">"Depth Image"</span>, CV_WINDOW_AUTOSIZE);</span><br><span class="line">  cv::namedWindow( <span class="string">"Color Image"</span>, CV_WINDOW_AUTOSIZE);</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 6. start</span></span><br><span class="line">  VideoFrameRef  mColorFrame;</span><br><span class="line">  VideoFrameRef  mDepthFrame;</span><br><span class="line"></span><br><span class="line">  mDepthStream.start();</span><br><span class="line">  mColorStream.start();</span><br><span class="line"></span><br><span class="line">  cv::Mat cImageBGR;</span><br><span class="line">  cv::Mat DepthMat;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">int</span> iMaxDepth = mDepthStream.getMaxPixelValue();</span><br><span class="line">  <span class="keyword">while</span>( <span class="literal">true</span> )</span><br><span class="line">  &#123;</span><br><span class="line">    <span class="comment">// 8a. get depth frame</span></span><br><span class="line">    <span class="keyword">if</span>( mDepthStream.readFrame( &amp;mDepthFrame ) == STATUS_OK )</span><br><span class="line">    &#123;</span><br><span class="line">      <span class="comment">// 8b. convert data to OpenCV format</span></span><br><span class="line">      <span class="keyword">const</span> cv::<span class="function">Mat <span class="title">mImageDepth</span><span class="params">(</span></span></span><br><span class="line"><span class="function"><span class="params">                mDepthFrame.getHeight(), mDepthFrame.getWidth(),</span></span></span><br><span class="line"><span class="function"><span class="params">                CV_16UC1, (<span class="keyword">void</span>*)mDepthFrame.getData() )</span></span>;</span><br><span class="line"></span><br><span class="line">      DepthMat = mImageDepth.clone();</span><br><span class="line"></span><br><span class="line">      <span class="comment">// 8c. re-map depth data [0,Max] to [0,255]</span></span><br><span class="line">      cv::Mat mScaledDepth;</span><br><span class="line">      mImageDepth.convertTo( mScaledDepth, CV_8U, <span class="number">255.0</span> / iMaxDepth );</span><br><span class="line"></span><br><span class="line">      <span class="comment">// 8d. show image</span></span><br><span class="line">      cv::imshow( <span class="string">"Depth Image"</span>, mScaledDepth );</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 7a. get color frame</span></span><br><span class="line">    <span class="keyword">if</span>( mColorStream.readFrame( &amp;mColorFrame ) == STATUS_OK )</span><br><span class="line">    &#123;</span><br><span class="line">      <span class="comment">// 7b. convert data to OpenCV format</span></span><br><span class="line">      <span class="keyword">const</span> cv::<span class="function">Mat <span class="title">mImageRGB</span><span class="params">(</span></span></span><br><span class="line"><span class="function"><span class="params">              mColorFrame.getHeight(), mColorFrame.getWidth(),</span></span></span><br><span class="line"><span class="function"><span class="params">              CV_8UC3, (<span class="keyword">void</span>*)mColorFrame.getData() )</span></span>;</span><br><span class="line">      <span class="comment">// 7c. convert form RGB to BGR</span></span><br><span class="line">      </span><br><span class="line">      </span><br><span class="line">      cv::cvtColor( mImageRGB, cImageBGR, CV_RGB2BGR );</span><br><span class="line">      <span class="comment">// 7d. show image</span></span><br><span class="line"></span><br><span class="line">      <span class="comment">//dlib</span></span><br><span class="line">      cv_image&lt;bgr_pixel&gt; cimg(cImageBGR);</span><br><span class="line"></span><br><span class="line">      <span class="comment">// Detect faces </span></span><br><span class="line">      <span class="built_in">std</span>::<span class="built_in">vector</span>&lt;dlib::rectangle&gt; dets = detector(cimg);</span><br><span class="line"></span><br><span class="line">      <span class="keyword">if</span>(dets.size() != <span class="number">0</span>)&#123;</span><br><span class="line">        <span class="keyword">int</span> livedetector;</span><br><span class="line">        <span class="built_in">string</span> who,isface;</span><br><span class="line">        <span class="keyword">float</span> who_probability;</span><br><span class="line">        <span class="keyword">float</span> pretotal_ary;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">if</span>(dets.size() != <span class="number">1</span>)&#123;</span><br><span class="line">          livedetector = <span class="number">-1</span>;</span><br><span class="line">          <span class="keyword">for</span> (<span class="keyword">unsigned</span> <span class="keyword">long</span> j = <span class="number">0</span>; j &lt; dets.size(); ++j)&#123;</span><br><span class="line">            <span class="function">Rect <span class="title">rect</span><span class="params">(dets[j].left(),dets[j].top(),dets[j].right() -dets[j].left(), dets[j].bottom() -dets[j].top())</span></span>;<span class="comment">//左上坐标（x,y）和矩形的长(x)宽(y)</span></span><br><span class="line">            cv::rectangle(cImageBGR, rect, Scalar(<span class="number">0</span>, <span class="number">255</span>, <span class="number">0</span>),<span class="number">1</span>,<span class="number">8</span>,<span class="number">0</span>);</span><br><span class="line">          &#125;</span><br><span class="line"></span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">else</span>&#123;</span><br><span class="line">          Rect rect(dets[<span class="number">0</span>].left(),dets[<span class="number">0</span>].top(),dets[<span class="number">0</span>].right() -dets[<span class="number">0</span>].left(), dets[<span class="number">0</span>].bottom() -dets[<span class="number">0</span>].top());<span class="comment">//左上坐标（x,y）和矩形的长(x)宽(y)</span></span><br><span class="line">          cv::rectangle(cImageBGR, rect, Scalar(<span class="number">0</span>, <span class="number">255</span>, <span class="number">0</span>),<span class="number">1</span>,<span class="number">8</span>,<span class="number">0</span>);</span><br><span class="line"></span><br><span class="line">          full_object_detection shape = sp(cimg, dets[<span class="number">0</span>]);</span><br><span class="line">          <span class="built_in">std</span>::<span class="built_in">vector</span>&lt;matrix&lt;rgb_pixel&gt;&gt; faces;</span><br><span class="line">          matrix&lt;rgb_pixel&gt; face_chip;</span><br><span class="line">          extract_image_chip(cimg, get_face_chip_details(shape,<span class="number">150</span>,<span class="number">0.25</span>), face_chip);</span><br><span class="line">          faces.push_back(move(face_chip));</span><br><span class="line">          <span class="built_in">std</span>::<span class="built_in">vector</span>&lt;matrix&lt;<span class="keyword">float</span>,0,1&gt;&gt; face_descriptors = net(faces);</span><br><span class="line"></span><br><span class="line">          <span class="keyword">float</span> distance;</span><br><span class="line">          <span class="keyword">float</span> best_distance = length(face_descriptors[<span class="number">0</span>]-candidates_descriptors[<span class="number">0</span>]);</span><br><span class="line">          <span class="keyword">size_t</span> candidates_num = candidates_descriptors.size();</span><br><span class="line">          <span class="keyword">int</span> candidates_num_int = <span class="keyword">static_cast</span>&lt;<span class="keyword">int</span>&gt;(candidates_num);</span><br><span class="line">          <span class="keyword">int</span> best_k = <span class="number">0</span>;</span><br><span class="line">          <span class="keyword">for</span> (<span class="keyword">int</span> k = <span class="number">1</span>; k &lt; candidates_num_int; k++)</span><br><span class="line">          &#123;</span><br><span class="line">              distance = length(face_descriptors[<span class="number">0</span>]-candidates_descriptors[k]);</span><br><span class="line">              <span class="keyword">if</span> (distance &lt; best_distance) </span><br><span class="line">              &#123;</span><br><span class="line">                  best_distance = distance;</span><br><span class="line">                  best_k = k;</span><br><span class="line">              &#125;</span><br><span class="line">          &#125;</span><br><span class="line">          <span class="keyword">if</span> (best_distance &lt; <span class="number">0.6</span>) &#123;</span><br><span class="line">              who = candidates[best_k];</span><br><span class="line">              who_probability =  (<span class="number">1.05</span><span class="number">-0.66</span>*best_distance)*<span class="number">100</span> &lt; <span class="number">100</span>?(<span class="number">1.05</span><span class="number">-0.66</span>*best_distance)*<span class="number">100</span>:<span class="number">99</span>;</span><br><span class="line">          &#125;</span><br><span class="line">          <span class="keyword">else</span>&#123;</span><br><span class="line">              who = <span class="string">"Unknow"</span>;</span><br><span class="line">          &#125;</span><br><span class="line"></span><br><span class="line">          <span class="comment">// liveness_detection(DepthMat,locates,livedetector);</span></span><br><span class="line">          <span class="keyword">int</span> COL ,ROW ,FACE_WIDTH ,FACE_HEIGHT; </span><br><span class="line">          <span class="keyword">int</span> faceno0_num;</span><br><span class="line">          <span class="keyword">int</span> FaceDATA[<span class="number">3</span>][<span class="number">100000</span>];</span><br><span class="line">          <span class="keyword">int</span> k;</span><br><span class="line">          <span class="keyword">int</span> pretotal;</span><br><span class="line">          <span class="keyword">int</span> x[<span class="number">3</span>],y[<span class="number">3</span>],z[<span class="number">3</span>];  <span class="comment">// 随机取三个点 </span></span><br><span class="line">          <span class="keyword">float</span> a,b,c;  <span class="comment">// 拟合平面方程 z=ax+by+c</span></span><br><span class="line">          <span class="keyword">int</span> rand_num[<span class="number">3</span>];</span><br><span class="line">          <span class="keyword">float</span> check,distance2;</span><br><span class="line">          <span class="keyword">int</span> total;</span><br><span class="line"></span><br><span class="line">          COL = rect.x;</span><br><span class="line">          ROW = rect.y;</span><br><span class="line">          FACE_WIDTH = rect.width;</span><br><span class="line">          FACE_HEIGHT = rect.height; </span><br><span class="line">          faceno0_num = FACE_HEIGHT*FACE_WIDTH <span class="number">-1</span>; </span><br><span class="line">          k = <span class="number">0</span>;</span><br><span class="line">          <span class="keyword">for</span>(<span class="keyword">int</span> m = <span class="number">1</span>;m&lt; FACE_HEIGHT+<span class="number">1</span>;m++)</span><br><span class="line">          &#123;</span><br><span class="line">              <span class="keyword">for</span>(<span class="keyword">int</span> n= <span class="number">1</span>;n&lt; FACE_WIDTH+<span class="number">1</span>;n++) </span><br><span class="line">              &#123; </span><br><span class="line">                  ushort tmp = DepthMat.at&lt;ushort&gt;(COL+n<span class="number">-1</span>,ROW+m<span class="number">-1</span>);</span><br><span class="line">                  <span class="keyword">if</span> (tmp == <span class="number">0</span>)</span><br><span class="line">                  &#123;</span><br><span class="line">                      faceno0_num -= <span class="number">1</span>; <span class="comment">// 非零深度点个数为 faceno0_num+1</span></span><br><span class="line">                      <span class="keyword">continue</span>;</span><br><span class="line">                  &#125;</span><br><span class="line">                  FaceDATA[<span class="number">0</span>][k] = n; </span><br><span class="line">                  FaceDATA[<span class="number">1</span>][k] = m;</span><br><span class="line">                  FaceDATA[<span class="number">2</span>][k] = tmp;</span><br><span class="line">                  k += <span class="number">1</span>;</span><br><span class="line">              &#125; </span><br><span class="line">          &#125; </span><br><span class="line"></span><br><span class="line">          <span class="keyword">if</span>(faceno0_num &gt; <span class="number">2000</span>)&#123;</span><br><span class="line">            pretotal = <span class="number">0</span>;  <span class="comment">// 符合拟合模型的数据的个数 </span></span><br><span class="line">            srand((<span class="keyword">unsigned</span>)time(<span class="literal">NULL</span>));</span><br><span class="line">            total = <span class="number">0</span>;</span><br><span class="line">            <span class="keyword">for</span>(k = <span class="number">0</span>; k &lt; ITER; k++)</span><br><span class="line">            &#123;</span><br><span class="line">              <span class="keyword">do</span>&#123;</span><br><span class="line">                  rand_num[<span class="number">0</span>] = <span class="built_in">std</span>::rand()%faceno0_num; </span><br><span class="line">                  rand_num[<span class="number">1</span>] = <span class="built_in">std</span>::rand()%faceno0_num; </span><br><span class="line">                  rand_num[<span class="number">2</span>] = <span class="built_in">std</span>::rand()%faceno0_num; </span><br><span class="line">              &#125;<span class="keyword">while</span>(rand_num[<span class="number">0</span>] == rand_num[<span class="number">1</span>] || rand_num[<span class="number">0</span>] == rand_num[<span class="number">2</span>] || rand_num[<span class="number">1</span>] == rand_num[<span class="number">2</span>]);</span><br><span class="line">              <span class="keyword">for</span>(<span class="keyword">int</span> n = <span class="number">0</span>; n &lt; <span class="number">3</span>; n++ )</span><br><span class="line">              &#123;</span><br><span class="line">                  x[n] = FaceDATA[<span class="number">0</span>][rand_num[n]];</span><br><span class="line">                  y[n] = FaceDATA[<span class="number">1</span>][rand_num[n]];</span><br><span class="line">                  z[n] = FaceDATA[<span class="number">2</span>][rand_num[n]];</span><br><span class="line">              &#125;</span><br><span class="line">              check = (x[<span class="number">0</span>]-x[<span class="number">1</span>])*(y[<span class="number">0</span>]-y[<span class="number">2</span>]) - (x[<span class="number">0</span>]-x[<span class="number">2</span>])*(y[<span class="number">0</span>]-y[<span class="number">1</span>]);</span><br><span class="line">              <span class="keyword">if</span> ( check == <span class="number">0</span>)  <span class="comment">// 防止提示浮点数例外 (核心已转储)</span></span><br><span class="line">              &#123;</span><br><span class="line">                  k -= <span class="number">1</span>;</span><br><span class="line">                  <span class="keyword">continue</span>;</span><br><span class="line">              &#125;</span><br><span class="line">              a = ( (z[<span class="number">0</span>]-z[<span class="number">1</span>])*(y[<span class="number">0</span>]-y[<span class="number">2</span>]) - (z[<span class="number">0</span>]-z[<span class="number">2</span>])*(y[<span class="number">0</span>]-y[<span class="number">1</span>]) )*<span class="number">1.0</span>/( (x[<span class="number">0</span>]-x[<span class="number">1</span>])*(y[<span class="number">0</span>]-y[<span class="number">2</span>]) - (x[<span class="number">0</span>]-x[<span class="number">2</span>])*(y[<span class="number">0</span>]-y[<span class="number">1</span>]) );</span><br><span class="line">              <span class="keyword">if</span> (y[<span class="number">0</span>] == y[<span class="number">2</span>])  <span class="comment">// 防止提示浮点数例外 (核心已转储)</span></span><br><span class="line">              &#123;</span><br><span class="line">                  k -= <span class="number">1</span>;</span><br><span class="line">                  <span class="keyword">continue</span>;</span><br><span class="line">              &#125;</span><br><span class="line">              b = ((z[<span class="number">0</span>] - z[<span class="number">2</span>]) - a * (x[<span class="number">0</span>] - x[<span class="number">2</span>]))*<span class="number">1.0</span>/(y[<span class="number">0</span>]-y[<span class="number">2</span>]);</span><br><span class="line">              c = z[<span class="number">0</span>]- a * x[<span class="number">0</span>] - b * y[<span class="number">0</span>];</span><br><span class="line">              total = <span class="number">0</span>;</span><br><span class="line">              <span class="keyword">for</span>(<span class="keyword">int</span> n = <span class="number">0</span>; n &lt; faceno0_num +<span class="number">1</span> ; n++ )</span><br><span class="line">              &#123;</span><br><span class="line">                  distance2 = <span class="built_in">fabs</span>(a*FaceDATA[<span class="number">0</span>][n] + b*FaceDATA[<span class="number">1</span>][n] - <span class="number">1</span>*FaceDATA[<span class="number">2</span>][n] + c*<span class="number">1</span>);</span><br><span class="line">                  <span class="keyword">if</span> (distance2 &lt; SIGMA)</span><br><span class="line">                  &#123;</span><br><span class="line">                      total +=<span class="number">1</span>;</span><br><span class="line">                  &#125;</span><br><span class="line">              &#125;</span><br><span class="line">              <span class="keyword">if</span> (total &gt; pretotal)  <span class="comment">// 找到符合拟合平面数据最多的拟合平面</span></span><br><span class="line">              &#123;</span><br><span class="line">                  pretotal=total;</span><br><span class="line">              &#125;   </span><br><span class="line">            &#125;</span><br><span class="line"></span><br><span class="line">            pretotal_ary = pretotal *<span class="number">1.0</span>/ faceno0_num;</span><br><span class="line">            <span class="keyword">if</span> (pretotal_ary &lt; PLANE_OR_NOT)&#123;</span><br><span class="line">              livedetector = <span class="number">1</span>;</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">else</span>&#123;</span><br><span class="line">              livedetector = <span class="number">0</span>;</span><br><span class="line">            &#125;</span><br><span class="line">          </span><br><span class="line">          &#125;</span><br><span class="line">          <span class="keyword">else</span>&#123;</span><br><span class="line">            livedetector = <span class="number">-2</span>;</span><br><span class="line">          &#125;</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">if</span>(livedetector == <span class="number">-1</span>)&#123;</span><br><span class="line">          who = <span class="string">"More than one face"</span>;</span><br><span class="line">          isface = <span class="string">"Please detect one face"</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span>(livedetector == <span class="number">1</span>)&#123;</span><br><span class="line">          isface = <span class="string">"Is FACE"</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span>(livedetector == <span class="number">0</span>)&#123;</span><br><span class="line">          isface = <span class="string">"Is not FACE"</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span>(livedetector == <span class="number">-2</span>)&#123;</span><br><span class="line">          isface = <span class="string">"Lack of depth information"</span>;</span><br><span class="line">          pretotal_ary = <span class="number">0</span>;</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="built_in">stringstream</span> strStream1; </span><br><span class="line">        strStream1 &lt;&lt; who &lt;&lt; <span class="string">" , "</span> &lt;&lt; who_probability &lt;&lt; <span class="string">"%"</span>; </span><br><span class="line">        <span class="built_in">string</span> str1 = strStream1.str();  </span><br><span class="line"></span><br><span class="line">        <span class="built_in">stringstream</span> strStream2; </span><br><span class="line">        strStream2 &lt;&lt; isface &lt;&lt; <span class="string">" , "</span> &lt;&lt; <span class="string">"pretotal_ary:"</span> &lt;&lt; pretotal_ary; </span><br><span class="line">        <span class="built_in">string</span> str2 = strStream2.str();  </span><br><span class="line"></span><br><span class="line">        cv::putText(cImageBGR, <span class="string">"RECOGNITION RESULT: "</span>, cv::Point(<span class="number">20</span>,<span class="number">20</span>), cv::FONT_HERSHEY_COMPLEX,<span class="number">0.4</span>,Scalar(<span class="number">255</span>, <span class="number">255</span>, <span class="number">255</span>),<span class="number">1</span>,<span class="number">8</span>,<span class="number">0</span>);</span><br><span class="line">        cv::putText(cImageBGR, str1, cv::Point(<span class="number">20</span>,<span class="number">40</span>), cv::FONT_HERSHEY_COMPLEX,<span class="number">0.5</span>,Scalar(<span class="number">0</span>, <span class="number">255</span>, <span class="number">0</span>),<span class="number">1</span>,<span class="number">8</span>,<span class="number">0</span>);</span><br><span class="line">        cv::putText(cImageBGR, <span class="string">"LIVENESS DETECTION RESULT: "</span>, cv::Point(<span class="number">20</span>,<span class="number">60</span>), cv::FONT_HERSHEY_COMPLEX,<span class="number">0.4</span>,Scalar(<span class="number">255</span>, <span class="number">255</span>, <span class="number">255</span>),<span class="number">1</span>,<span class="number">8</span>,<span class="number">0</span>);</span><br><span class="line">        cv::putText(cImageBGR, str2, cv::Point(<span class="number">20</span>,<span class="number">80</span>), cv::FONT_HERSHEY_COMPLEX,<span class="number">0.5</span>,Scalar(<span class="number">0</span>, <span class="number">255</span>, <span class="number">0</span>),<span class="number">1</span>,<span class="number">8</span>,<span class="number">0</span>);</span><br><span class="line">      &#125;</span><br><span class="line"></span><br><span class="line">      cv::imshow( <span class="string">"Color Image"</span>, cImageBGR);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 6a. check keyboard</span></span><br><span class="line">    <span class="keyword">if</span>( cv::waitKey( <span class="number">1</span> ) == <span class="string">'q'</span> )&#123;</span><br><span class="line">      <span class="keyword">break</span>;</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 9. stop</span></span><br><span class="line">  mDepthStream.destroy();</span><br><span class="line">  mColorStream.destroy();</span><br><span class="line">  mDevice.close();</span><br><span class="line">  OpenNI::shutdown();</span><br><span class="line"></span><br><span class="line">  <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>#this_is_who.cpp</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br><span class="line">180</span><br><span class="line">181</span><br><span class="line">182</span><br><span class="line">183</span><br><span class="line">184</span><br><span class="line">185</span><br><span class="line">186</span><br><span class="line">187</span><br><span class="line">188</span><br><span class="line">189</span><br><span class="line">190</span><br><span class="line">191</span><br><span class="line">192</span><br><span class="line">193</span><br><span class="line">194</span><br><span class="line">195</span><br><span class="line">196</span><br><span class="line">197</span><br><span class="line">198</span><br><span class="line">199</span><br><span class="line">200</span><br><span class="line">201</span><br><span class="line">202</span><br><span class="line">203</span><br><span class="line">204</span><br><span class="line">205</span><br><span class="line">206</span><br><span class="line">207</span><br><span class="line">208</span><br><span class="line">209</span><br><span class="line">210</span><br><span class="line">211</span><br><span class="line">212</span><br><span class="line">213</span><br><span class="line">214</span><br><span class="line">215</span><br><span class="line">216</span><br><span class="line">217</span><br><span class="line">218</span><br><span class="line">219</span><br><span class="line">220</span><br><span class="line">221</span><br><span class="line">222</span><br><span class="line">223</span><br><span class="line">224</span><br><span class="line">225</span><br><span class="line">226</span><br><span class="line">227</span><br><span class="line">228</span><br><span class="line">229</span><br><span class="line">230</span><br><span class="line">231</span><br><span class="line">232</span><br><span class="line">233</span><br><span class="line">234</span><br><span class="line">235</span><br><span class="line">236</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;dlib/dnn.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;dlib/image_processing/frontal_face_detector.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;dlib/image_processing.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;dlib/gui_widgets.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;dlib/image_io.h&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;iostream&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;time.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;dirent.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;string.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;math.h&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> dlib;</span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> <span class="built_in">std</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">/* 函数声明 */</span></span><br><span class="line"><span class="comment">/* 输出人脸位置 返回识别结果 */</span></span><br><span class="line"><span class="function"><span class="built_in">string</span> <span class="title">face_location</span><span class="params">(<span class="keyword">const</span> <span class="keyword">char</span> *imgFile,<span class="built_in">std</span>::<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt;&amp;locates, <span class="built_in">std</span>::<span class="built_in">vector</span>&lt;matrix&lt;<span class="keyword">float</span>,<span class="number">0</span>,<span class="number">1</span>&gt;&gt;&amp;candidates_descriptors,<span class="built_in">std</span>::<span class="built_in">vector</span>&lt;<span class="built_in">string</span>&gt;&amp;candidates)</span></span>;</span><br><span class="line"><span class="comment">/* 判断是否为活体 */</span></span><br><span class="line"><span class="function"><span class="keyword">bool</span> <span class="title">liveness_detection</span><span class="params">(<span class="keyword">const</span> <span class="keyword">char</span> *DeepFile,<span class="built_in">std</span>::<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt;&amp;locates)</span></span>;  </span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> <span class="keyword">int</span> IMG_HEIGHT =  <span class="number">720</span>;</span><br><span class="line"><span class="keyword">const</span> <span class="keyword">int</span> IMG_WIDTH =  <span class="number">1280</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">template</span> &lt;<span class="keyword">template</span> &lt;<span class="keyword">int</span>,<span class="keyword">template</span>&lt;<span class="keyword">typename</span>&gt;<span class="class"><span class="keyword">class</span>,<span class="title">int</span>,<span class="title">typename</span>&gt; <span class="title">class</span> <span class="title">block</span>, <span class="title">int</span> <span class="title">N</span>, <span class="title">template</span>&lt;typename&gt;<span class="title">class</span> <span class="title">BN</span>, <span class="title">typename</span> <span class="title">SUBNET</span>&gt;</span></span><br><span class="line"><span class="class"><span class="title">using</span> <span class="title">residual</span> = <span class="title">add_prev1</span>&lt;block&lt;N,BN,1,tag1&lt;SUBNET&gt;&gt;&gt;;</span></span><br><span class="line"><span class="keyword">template</span> &lt;<span class="keyword">template</span> &lt;<span class="keyword">int</span>,<span class="keyword">template</span>&lt;<span class="keyword">typename</span>&gt;<span class="class"><span class="keyword">class</span>,<span class="title">int</span>,<span class="title">typename</span>&gt; <span class="title">class</span> <span class="title">block</span>, <span class="title">int</span> <span class="title">N</span>, <span class="title">template</span>&lt;typename&gt;<span class="title">class</span> <span class="title">BN</span>, <span class="title">typename</span> <span class="title">SUBNET</span>&gt;</span></span><br><span class="line"><span class="class"><span class="title">using</span> <span class="title">residual_down</span> = <span class="title">add_prev2</span>&lt;avg_pool&lt;2,2,2,2,skip1&lt;tag2&lt;block&lt;N,BN,2,tag1&lt;SUBNET&gt;&gt;&gt;&gt;&gt;&gt;;</span></span><br><span class="line"><span class="keyword">template</span> &lt;<span class="keyword">int</span> N, <span class="keyword">template</span> &lt;<span class="keyword">typename</span>&gt; <span class="class"><span class="keyword">class</span> <span class="title">BN</span>, <span class="title">int</span> <span class="title">stride</span>, <span class="title">typename</span> <span class="title">SUBNET</span>&gt; </span></span><br><span class="line"><span class="class"><span class="title">using</span> <span class="title">block</span>  = <span class="title">BN</span>&lt;con&lt;N,3,3,1,1,relu&lt;BN&lt;con&lt;N,3,3,stride,stride,SUBNET&gt;&gt;&gt;&gt;&gt;;</span></span><br><span class="line"><span class="keyword">template</span> &lt;<span class="keyword">int</span> N, <span class="keyword">typename</span> SUBNET&gt; <span class="keyword">using</span> ares      = relu&lt;residual&lt;block,N,affine,SUBNET&gt;&gt;;</span><br><span class="line"><span class="keyword">template</span> &lt;<span class="keyword">int</span> N, <span class="keyword">typename</span> SUBNET&gt; <span class="keyword">using</span> ares_down = relu&lt;residual_down&lt;block,N,affine,SUBNET&gt;&gt;;</span><br><span class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> SUBNET&gt; <span class="keyword">using</span> alevel0 = ares_down&lt;<span class="number">256</span>,SUBNET&gt;;</span><br><span class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> SUBNET&gt; <span class="keyword">using</span> alevel1 = ares&lt;<span class="number">256</span>,ares&lt;<span class="number">256</span>,ares_down&lt;<span class="number">256</span>,SUBNET&gt;&gt;&gt;;</span><br><span class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> SUBNET&gt; <span class="keyword">using</span> alevel2 = ares&lt;<span class="number">128</span>,ares&lt;<span class="number">128</span>,ares_down&lt;<span class="number">128</span>,SUBNET&gt;&gt;&gt;;</span><br><span class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> SUBNET&gt; <span class="keyword">using</span> alevel3 = ares&lt;<span class="number">64</span>,ares&lt;<span class="number">64</span>,ares&lt;<span class="number">64</span>,ares_down&lt;<span class="number">64</span>,SUBNET&gt;&gt;&gt;&gt;;</span><br><span class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> SUBNET&gt; <span class="keyword">using</span> alevel4 = ares&lt;<span class="number">32</span>,ares&lt;<span class="number">32</span>,ares&lt;<span class="number">32</span>,SUBNET&gt;&gt;&gt;;</span><br><span class="line"><span class="keyword">using</span> anet_type = loss_metric&lt;fc_no_bias&lt;<span class="number">128</span>,avg_pool_everything&lt;</span><br><span class="line">    alevel0&lt;</span><br><span class="line">    alevel1&lt;</span><br><span class="line">    alevel2&lt;</span><br><span class="line">    alevel3&lt;</span><br><span class="line">    alevel4&lt;</span><br><span class="line">    max_pool&lt;<span class="number">3</span>,<span class="number">3</span>,<span class="number">2</span>,<span class="number">2</span>,relu&lt;affine&lt;con&lt;<span class="number">32</span>,<span class="number">7</span>,<span class="number">7</span>,<span class="number">2</span>,<span class="number">2</span>,</span><br><span class="line">    input_rgb_image_sized&lt;<span class="number">150</span>&gt;</span><br><span class="line">    &gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">(<span class="keyword">int</span> argc, <span class="keyword">char</span>** argv)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (argc == <span class="number">1</span>)</span><br><span class="line">        &#123;</span><br><span class="line">            <span class="built_in">cout</span> &lt;&lt; <span class="string">"\nCall this program like this:"</span> &lt;&lt; <span class="built_in">endl</span>;</span><br><span class="line">            <span class="built_in">cout</span> &lt;&lt; <span class="string">"./this_is_who ../data/allface/0004_IR_allleft.jpg ../data/allface/0004_raw_allleft.raw"</span> &lt;&lt; <span class="built_in">endl</span>;</span><br><span class="line">            <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="keyword">const</span> <span class="keyword">char</span> *imgFile = argv[<span class="number">1</span>];</span><br><span class="line">    <span class="keyword">const</span> <span class="keyword">char</span> *DeepFile = argv[<span class="number">2</span>];</span><br><span class="line"></span><br><span class="line">    </span><br><span class="line">    <span class="built_in">std</span>::<span class="built_in">vector</span>&lt;matrix&lt;<span class="keyword">float</span>,0,1&gt;&gt; candidates_descriptors;</span><br><span class="line">    deserialize(<span class="string">"../candidates_descriptors.dat"</span>) &gt;&gt; candidates_descriptors;</span><br><span class="line"></span><br><span class="line">    <span class="built_in">std</span>::<span class="built_in">vector</span>&lt;<span class="built_in">string</span>&gt; candidates;</span><br><span class="line">    deserialize(<span class="string">"../candidates.dat"</span>) &gt;&gt; candidates;</span><br><span class="line">   </span><br><span class="line">    <span class="built_in">std</span>::<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; locates;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/* 输出人脸位置 返回识别结果 */</span></span><br><span class="line">    <span class="built_in">string</span> who = face_location(imgFile, locates, candidates_descriptors,candidates); </span><br><span class="line">    <span class="built_in">cout</span> &lt;&lt; <span class="string">"\nRECOGNITION RESULT："</span> &lt;&lt; <span class="built_in">endl</span>;</span><br><span class="line">    <span class="built_in">cout</span> &lt;&lt; <span class="string">"This is "</span> &lt;&lt; who &lt;&lt; <span class="built_in">endl</span>;</span><br><span class="line"></span><br><span class="line">    <span class="comment">//深度图与红外图是水平翻转的</span></span><br><span class="line">    locates[<span class="number">0</span>] = IMG_WIDTH - locates[<span class="number">0</span>] -locates[<span class="number">2</span>];  </span><br><span class="line"></span><br><span class="line">    <span class="comment">/* 判断是否为活体 */</span></span><br><span class="line">    liveness_detection( DeepFile, locates);</span><br><span class="line"></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">/* 函数 输出人脸位置 返回识别结果 */</span></span><br><span class="line"><span class="function"><span class="built_in">string</span> <span class="title">face_location</span><span class="params">(<span class="keyword">const</span> <span class="keyword">char</span>* imgFile,<span class="built_in">std</span>::<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt;&amp;locates, <span class="built_in">std</span>::<span class="built_in">vector</span>&lt;matrix&lt;<span class="keyword">float</span>,<span class="number">0</span>,<span class="number">1</span>&gt;&gt;&amp;candidates_descriptors,<span class="built_in">std</span>::<span class="built_in">vector</span>&lt;<span class="built_in">string</span>&gt;&amp;candidates)</span></span></span><br><span class="line"><span class="function"></span>&#123;   </span><br><span class="line">    frontal_face_detector detector = get_frontal_face_detector(); <span class="comment">// 人脸正脸检测器</span></span><br><span class="line">    shape_predictor sp; <span class="comment">//人脸关键点检测器</span></span><br><span class="line">    anet_type net;  <span class="comment">// 人脸识别模型</span></span><br><span class="line"></span><br><span class="line">    deserialize(<span class="string">"../model/shape_predictor_68_face_landmarks.dat"</span>) &gt;&gt; sp;</span><br><span class="line">    deserialize(<span class="string">"../model/dlib_face_recognition_resnet_model_v1.dat"</span>) &gt;&gt; net;</span><br><span class="line">    </span><br><span class="line">    <span class="built_in">cout</span> &lt;&lt; <span class="string">"\nprocessing image "</span> &lt;&lt; imgFile &lt;&lt; <span class="built_in">endl</span>;</span><br><span class="line">    matrix&lt;rgb_pixel&gt; img;</span><br><span class="line">    load_image(img, imgFile);</span><br><span class="line">    <span class="built_in">std</span>::<span class="built_in">vector</span>&lt;rectangle&gt; dets = detector(img);</span><br><span class="line">    <span class="comment">// cout &lt;&lt; "Number of faces detected: " &lt;&lt; dets.size() &lt;&lt; endl;</span></span><br><span class="line">    locates.push_back(dets[<span class="number">0</span>].left());</span><br><span class="line">    locates.push_back(dets[<span class="number">0</span>].top());</span><br><span class="line">    locates.push_back(dets[<span class="number">0</span>].right() - dets[<span class="number">0</span>].left());</span><br><span class="line">    locates.push_back(dets[<span class="number">0</span>].bottom() - dets[<span class="number">0</span>].top());</span><br><span class="line">    full_object_detection shape = sp(img, dets[<span class="number">0</span>]);</span><br><span class="line">    <span class="built_in">std</span>::<span class="built_in">vector</span>&lt;matrix&lt;rgb_pixel&gt;&gt; faces;</span><br><span class="line">    matrix&lt;rgb_pixel&gt; face_chip;</span><br><span class="line">    extract_image_chip(img, get_face_chip_details(shape,<span class="number">150</span>,<span class="number">0.25</span>), face_chip);</span><br><span class="line">    faces.push_back(move(face_chip));</span><br><span class="line">    <span class="built_in">std</span>::<span class="built_in">vector</span>&lt;matrix&lt;<span class="keyword">float</span>,0,1&gt;&gt; face_descriptors = net(faces);</span><br><span class="line">    <span class="keyword">float</span> distance;</span><br><span class="line">    <span class="keyword">float</span> best_distance = length(face_descriptors[<span class="number">0</span>]-candidates_descriptors[<span class="number">0</span>]);</span><br><span class="line">    <span class="keyword">size_t</span> candidates_num = candidates_descriptors.size();</span><br><span class="line">    <span class="keyword">int</span> candidates_num_int = <span class="keyword">static_cast</span>&lt;<span class="keyword">int</span>&gt;(candidates_num);</span><br><span class="line">    <span class="keyword">int</span> best_k = <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> k = <span class="number">1</span>; k &lt; candidates_num_int; k++)</span><br><span class="line">    &#123;</span><br><span class="line">        distance = length(face_descriptors[<span class="number">0</span>]-candidates_descriptors[k]);</span><br><span class="line">        <span class="keyword">if</span> (distance &lt; best_distance) </span><br><span class="line">        &#123;</span><br><span class="line">            best_distance = distance;</span><br><span class="line">            best_k = k;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="built_in">string</span> who;</span><br><span class="line">    <span class="keyword">if</span> (best_distance &lt; <span class="number">0.6</span>) &#123;</span><br><span class="line">        who = candidates[best_k];</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">else</span>&#123;</span><br><span class="line">        who = <span class="string">"Unknow"</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> who;</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">/* 函数判断是否为活体 */</span></span><br><span class="line"><span class="function"><span class="keyword">bool</span> <span class="title">liveness_detection</span><span class="params">(<span class="keyword">const</span> <span class="keyword">char</span> *DeepFile,<span class="built_in">std</span>::<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt;&amp;locates)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="keyword">const</span> <span class="keyword">int</span> ITER = <span class="number">5000</span>; <span class="comment">// 随机取点次数</span></span><br><span class="line">    <span class="keyword">const</span> <span class="keyword">float</span> PLANE_OR_NOT = <span class="number">0.2</span>; <span class="comment">// 判断是否为平面的分界线</span></span><br><span class="line">    <span class="keyword">const</span> <span class="keyword">int</span> SIGMA = <span class="number">1</span>;</span><br><span class="line">    <span class="keyword">typedef</span> <span class="keyword">unsigned</span> <span class="keyword">short</span> UNIT16;</span><br><span class="line">    <span class="comment">// 从.raw读取二进制16位数据到MatDATA</span></span><br><span class="line">    UNIT16 MatDATA[IMG_HEIGHT*IMG_WIDTH];</span><br><span class="line">    FILE *fp = <span class="literal">NULL</span>;</span><br><span class="line">    fp = fopen( DeepFile, <span class="string">"rb"</span> );</span><br><span class="line">    <span class="keyword">size_t</span> sizeRead = fread(MatDATA,<span class="keyword">sizeof</span>(UNIT16),IMG_HEIGHT*IMG_WIDTH,fp);</span><br><span class="line">    <span class="keyword">if</span> (sizeRead != IMG_HEIGHT*IMG_WIDTH) &#123;</span><br><span class="line">        <span class="built_in">cout</span> &lt;&lt; <span class="string">"DeepFile open error!"</span> &lt;&lt; <span class="built_in">endl</span>;</span><br><span class="line">        <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">    &#125;    </span><br><span class="line">    fclose(fp);</span><br><span class="line">    <span class="keyword">int</span> n = <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">int</span> i,j;</span><br><span class="line">    <span class="keyword">int</span> COL = locates[<span class="number">0</span>],ROW = locates[<span class="number">1</span>],FACE_WIDTH = locates[<span class="number">2</span>],FACE_HEIGHT = locates[<span class="number">3</span>]; <span class="comment">//位置信息</span></span><br><span class="line">    <span class="comment">// txt :157 66 172 198 , 取行66：66+198,列取157：157+172</span></span><br><span class="line">    <span class="keyword">int</span> faceno0_num = FACE_HEIGHT*FACE_WIDTH <span class="number">-1</span>; </span><br><span class="line">    <span class="keyword">int</span> FaceDATA[<span class="number">3</span>][<span class="number">100000</span>];</span><br><span class="line">    n = <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">for</span>(i = <span class="number">1</span>;i&lt; FACE_HEIGHT+<span class="number">1</span>;i++)</span><br><span class="line">        &#123;</span><br><span class="line">            <span class="keyword">for</span>(j= <span class="number">1</span>;j&lt; FACE_WIDTH+<span class="number">1</span>;j++) </span><br><span class="line">            &#123; </span><br><span class="line">                <span class="keyword">if</span> (MatDATA[IMG_WIDTH*(ROW+i<span class="number">-2</span>)+COL+j<span class="number">-2</span>] == <span class="number">0</span>)</span><br><span class="line">                &#123;</span><br><span class="line">                    faceno0_num -= <span class="number">1</span>; <span class="comment">// 非零深度点个数为 faceno0_num+1</span></span><br><span class="line">                    <span class="keyword">continue</span>;</span><br><span class="line">                &#125;</span><br><span class="line">                FaceDATA[<span class="number">1</span>][n] = i;</span><br><span class="line">                FaceDATA[<span class="number">0</span>][n] = j; </span><br><span class="line">                FaceDATA[<span class="number">2</span>][n] = MatDATA[IMG_WIDTH*(ROW+i<span class="number">-2</span>)+COL+j<span class="number">-2</span>];</span><br><span class="line">                n += <span class="number">1</span>;</span><br><span class="line">            &#125; </span><br><span class="line">        &#125; </span><br><span class="line"></span><br><span class="line">    <span class="keyword">int</span> pretotal = <span class="number">0</span>;  <span class="comment">// 符合拟合模型的数据的个数</span></span><br><span class="line">    <span class="keyword">int</span> x[<span class="number">3</span>],y[<span class="number">3</span>],z[<span class="number">3</span>];  <span class="comment">// 随机取三个点 </span></span><br><span class="line">    srand((<span class="keyword">unsigned</span>)time(<span class="literal">NULL</span>));</span><br><span class="line">    <span class="keyword">float</span> a,b,c;  <span class="comment">// 拟合平面方程 z=ax+by+c</span></span><br><span class="line">    <span class="comment">// float besta,bestb,bestc;  // 最佳参数</span></span><br><span class="line">    <span class="keyword">int</span> rand_num[<span class="number">3</span>];</span><br><span class="line">    <span class="keyword">float</span> check,distance;</span><br><span class="line">    <span class="keyword">int</span> total = <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">for</span>(i = <span class="number">0</span>; i &lt; ITER; i++)</span><br><span class="line">    &#123;</span><br><span class="line">        <span class="keyword">do</span>&#123;</span><br><span class="line">            rand_num[<span class="number">0</span>] = <span class="built_in">std</span>::rand()%faceno0_num; </span><br><span class="line">            rand_num[<span class="number">1</span>] = <span class="built_in">std</span>::rand()%faceno0_num; </span><br><span class="line">            rand_num[<span class="number">2</span>] = <span class="built_in">std</span>::rand()%faceno0_num; </span><br><span class="line">        &#125;<span class="keyword">while</span>(rand_num[<span class="number">0</span>] == rand_num[<span class="number">1</span>] || rand_num[<span class="number">0</span>] == rand_num[<span class="number">2</span>] || rand_num[<span class="number">1</span>] == rand_num[<span class="number">2</span>]);</span><br><span class="line">        <span class="keyword">for</span>(n = <span class="number">0</span>; n &lt; <span class="number">3</span>; n++ )</span><br><span class="line">        &#123;</span><br><span class="line">            x[n] = FaceDATA[<span class="number">0</span>][rand_num[n]];</span><br><span class="line">            y[n] = FaceDATA[<span class="number">1</span>][rand_num[n]];</span><br><span class="line">            z[n] = FaceDATA[<span class="number">2</span>][rand_num[n]];</span><br><span class="line">        &#125;</span><br><span class="line">        check = (x[<span class="number">0</span>]-x[<span class="number">1</span>])*(y[<span class="number">0</span>]-y[<span class="number">2</span>]) - (x[<span class="number">0</span>]-x[<span class="number">2</span>])*(y[<span class="number">0</span>]-y[<span class="number">1</span>]);</span><br><span class="line">        <span class="keyword">if</span> ( check == <span class="number">0</span>)  <span class="comment">// 防止提示浮点数例外 (核心已转储)</span></span><br><span class="line">        &#123;</span><br><span class="line">            i -= <span class="number">1</span>;</span><br><span class="line">            <span class="keyword">continue</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        a = ( (z[<span class="number">0</span>]-z[<span class="number">1</span>])*(y[<span class="number">0</span>]-y[<span class="number">2</span>]) - (z[<span class="number">0</span>]-z[<span class="number">2</span>])*(y[<span class="number">0</span>]-y[<span class="number">1</span>]) )*<span class="number">1.0</span>/( (x[<span class="number">0</span>]-x[<span class="number">1</span>])*(y[<span class="number">0</span>]-y[<span class="number">2</span>]) - (x[<span class="number">0</span>]-x[<span class="number">2</span>])*(y[<span class="number">0</span>]-y[<span class="number">1</span>]) );</span><br><span class="line">        <span class="keyword">if</span> (y[<span class="number">0</span>] == y[<span class="number">2</span>])  <span class="comment">// 防止提示浮点数例外 (核心已转储)</span></span><br><span class="line">        &#123;</span><br><span class="line">            i -= <span class="number">1</span>;</span><br><span class="line">            <span class="keyword">continue</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        b = ((z[<span class="number">0</span>] - z[<span class="number">2</span>]) - a * (x[<span class="number">0</span>] - x[<span class="number">2</span>]))*<span class="number">1.0</span>/(y[<span class="number">0</span>]-y[<span class="number">2</span>]);</span><br><span class="line">        c = z[<span class="number">0</span>]- a * x[<span class="number">0</span>] - b * y[<span class="number">0</span>];</span><br><span class="line">        total = <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">for</span>(n = <span class="number">0</span>; n &lt; faceno0_num +<span class="number">1</span> ; n++ )</span><br><span class="line">        &#123;</span><br><span class="line">            distance = <span class="built_in">fabs</span>(a*FaceDATA[<span class="number">0</span>][n] + b*FaceDATA[<span class="number">1</span>][n] - <span class="number">1</span>*FaceDATA[<span class="number">2</span>][n] + c*<span class="number">1</span>);</span><br><span class="line">            <span class="keyword">if</span> (distance &lt; SIGMA)</span><br><span class="line">            &#123;</span><br><span class="line">                total +=<span class="number">1</span>;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span> (total &gt; pretotal)  <span class="comment">// 找到符合拟合平面数据最多的拟合平面</span></span><br><span class="line">        &#123;</span><br><span class="line">            pretotal=total;</span><br><span class="line">            <span class="comment">// besta = a;</span></span><br><span class="line">            <span class="comment">// bestb = b;</span></span><br><span class="line">            <span class="comment">// bestc = c;</span></span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">float</span> pretotal_ary = pretotal *<span class="number">1.0</span>/ faceno0_num ;</span><br><span class="line">    <span class="built_in">cout</span> &lt;&lt; <span class="string">"\nLIVENESS DETECTION RESULT："</span>  &lt;&lt; <span class="built_in">endl</span>;</span><br><span class="line">    <span class="keyword">bool</span> IS_FACE;</span><br><span class="line">    <span class="keyword">if</span> (pretotal_ary &lt; PLANE_OR_NOT)</span><br><span class="line">    &#123;</span><br><span class="line">        IS_FACE =  <span class="literal">true</span>;</span><br><span class="line">        <span class="built_in">cout</span> &lt;&lt; <span class="string">"pretotal_ary = "</span> &lt;&lt; pretotal_ary  &lt;&lt; <span class="string">" , Is FACE!"</span> &lt;&lt; <span class="built_in">endl</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">else</span></span><br><span class="line">    &#123;</span><br><span class="line">        IS_FACE = <span class="literal">false</span>;</span><br><span class="line">        <span class="built_in">cout</span> &lt;&lt; <span class="string">"pretotal_ary = "</span> &lt;&lt; pretotal_ary  &lt;&lt; <span class="string">" , Is not FACE!"</span> &lt;&lt; <span class="built_in">endl</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span>  IS_FACE;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>代码比较粗糙，应该以后也不会再改了……</p>]]></content>
    
    <summary type="html">
    
      &lt;h1 id=&quot;一、配置&quot;&gt;&lt;a href=&quot;#一、配置&quot; class=&quot;headerlink&quot; title=&quot;一、配置&quot;&gt;&lt;/a&gt;一、配置&lt;/h1&gt;&lt;h2 id=&quot;1、opencv&quot;&gt;&lt;a href=&quot;#1、opencv&quot; class=&quot;headerlink&quot; title=&quot;1、opencv&quot;&gt;&lt;/a&gt;1、opencv&lt;/h2&gt;&lt;p&gt;#安装依赖&lt;/p&gt;
&lt;figure class=&quot;highlight c&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;sudo apt-get install libvtk5-dev&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;sudo apt-get install libgtk2&lt;span class=&quot;number&quot;&gt;.0&lt;/span&gt;-dev&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
    
    </summary>
    
      <category term="深度相机" scheme="http://yoursite.com/categories/%E6%B7%B1%E5%BA%A6%E7%9B%B8%E6%9C%BA/"/>
    
      <category term="C++" scheme="http://yoursite.com/categories/C/"/>
    
    
      <category term="活体检测" scheme="http://yoursite.com/tags/%E6%B4%BB%E4%BD%93%E6%A3%80%E6%B5%8B/"/>
    
      <category term="Dlib" scheme="http://yoursite.com/tags/Dlib/"/>
    
      <category term="Opencv" scheme="http://yoursite.com/tags/Opencv/"/>
    
      <category term="Kinect" scheme="http://yoursite.com/tags/Kinect/"/>
    
      <category term="实时人脸识别" scheme="http://yoursite.com/tags/%E5%AE%9E%E6%97%B6%E4%BA%BA%E8%84%B8%E8%AF%86%E5%88%AB/"/>
    
  </entry>
  
  <entry>
    <title>ElasticFusion在ubuntu16.04+cuda8.0上的实现</title>
    <link href="http://yoursite.com/2019/04/12/15/"/>
    <id>http://yoursite.com/2019/04/12/15/</id>
    <published>2019-04-12T13:06:41.000Z</published>
    <updated>2019-12-18T04:14:43.160Z</updated>
    
    <content type="html"><![CDATA[<h1 id="一、驱动与cuda安装"><a href="#一、驱动与cuda安装" class="headerlink" title="一、驱动与cuda安装"></a>一、驱动与cuda安装</h1><p>#安装驱动与cuda8.0<br>参考这篇：<a href="https://blog.csdn.net/ffcjjhv/article/details/89151382" target="_blank" rel="noopener">https://blog.csdn.net/ffcjjhv/article/details/89151382</a></p><h1 id="二、配置"><a href="#二、配置" class="headerlink" title="二、配置"></a>二、配置</h1><h2 id="1、依赖包"><a href="#1、依赖包" class="headerlink" title="1、依赖包"></a>1、依赖包</h2><a id="more"></a><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">sudo apt-get install cmake cmake-qt-gui git build-essential libusb<span class="number">-1.0</span><span class="number">-0</span>-dev libudev-dev </span><br><span class="line">sudo apt-get install freeglut3-dev libglew-dev libsuitesparse-dev libeigen3-dev </span><br><span class="line">sudo apt-get install zlib1g-dev libjpeg-dev doxygen graphviz</span><br></pre></td></tr></table></figure><h2 id="2、openjdk-7-jdk"><a href="#2、openjdk-7-jdk" class="headerlink" title="2、openjdk-7-jdk"></a>2、openjdk-7-jdk</h2><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">sudo add-apt-repository ppa:openjdk-r/ppa</span><br><span class="line">sudo apt-get update</span><br><span class="line">sudo apt-get install openjdk<span class="number">-7</span>-jdk</span><br></pre></td></tr></table></figure><h2 id="3、OpenGL"><a href="#3、OpenGL" class="headerlink" title="3、OpenGL"></a>3、OpenGL</h2><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">sudo apt-get install build-essential libgl1-mesa-dev</span><br><span class="line">sudo apt-get install freeglut3-dev</span><br><span class="line">sudo apt-get install libglew-dev libsdl2-dev libsdl2-image-dev libglm-dev libfreetype6-dev</span><br></pre></td></tr></table></figure><h1 id="三、代码编译"><a href="#三、代码编译" class="headerlink" title="三、代码编译"></a>三、代码编译</h1><p>#download ElasticFusion<br>GitHub地址：<a href="https://github.com/mp3guy/ElasticFusion" target="_blank" rel="noopener">https://github.com/mp3guy/ElasticFusion</a> ，解压到<code>ElasticFusion/ElasticFusion-master</code></p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">cd ElasticFusion</span><br></pre></td></tr></table></figure><h2 id="1、安装-Pangolin"><a href="#1、安装-Pangolin" class="headerlink" title="1、安装 Pangolin"></a>1、安装 Pangolin</h2><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">git clone https:<span class="comment">//github.com/stevenlovegrove/Pangolin.git</span></span><br><span class="line">cd Pangolin</span><br><span class="line">mkdir build &amp;&amp; cd build</span><br><span class="line">cmake ../ -DAVFORMAT_INCLUDE_DIR=<span class="string">""</span> -DCPP11_NO_BOOST=ON</span><br><span class="line">make -j4</span><br><span class="line">cd ../..</span><br></pre></td></tr></table></figure><h2 id="2、安装-OpenNI2"><a href="#2、安装-OpenNI2" class="headerlink" title="2、安装 OpenNI2"></a>2、安装 OpenNI2</h2><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">git clone https:<span class="comment">//github.com/occipital/OpenNI2.git</span></span><br><span class="line">cd OpenNI2</span><br><span class="line">make -j4</span><br><span class="line">cd ..</span><br></pre></td></tr></table></figure><h2 id="3、配置-ElasticFusion"><a href="#3、配置-ElasticFusion" class="headerlink" title="3、配置 ElasticFusion"></a>3、配置 ElasticFusion</h2><h3 id="（1）build-Core"><a href="#（1）build-Core" class="headerlink" title="（1）build Core"></a>（1）build Core</h3><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">cd ElasticFusion-master/Core</span><br><span class="line">mkdir build &amp;&amp; cd build</span><br><span class="line">cmake ../src</span><br><span class="line">make -j4</span><br><span class="line">cd ../../</span><br></pre></td></tr></table></figure><h3 id="（2）build-GPUTest"><a href="#（2）build-GPUTest" class="headerlink" title="（2）build GPUTest"></a>（2）build GPUTest</h3><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">cd GPUTest</span><br><span class="line">mkdir build &amp;&amp; cd build</span><br><span class="line">cmake ../src</span><br><span class="line">make -j4</span><br><span class="line">cd ../../</span><br></pre></td></tr></table></figure><h3 id="（3）build-GUI"><a href="#（3）build-GUI" class="headerlink" title="（3）build GUI"></a>（3）build GUI</h3><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">cd GUI</span><br><span class="line">mkdir build &amp;&amp; cd build</span><br><span class="line">cmake ../src</span><br><span class="line">make -j4</span><br><span class="line">cd ../../</span><br></pre></td></tr></table></figure><h1 id="四、-运行"><a href="#四、-运行" class="headerlink" title="四、 运行"></a>四、 运行</h1><h2 id="1、数据集离线运行"><a href="#1、数据集离线运行" class="headerlink" title="1、数据集离线运行"></a>1、数据集离线运行</h2><p>下载数据集：  <a href="http://www.doc.ic.ac.uk/~sleutene/datasets/elasticfusion/dyson_lab.klg" target="_blank" rel="noopener">http://www.doc.ic.ac.uk/~sleutene/datasets/elasticfusion/dyson_lab.klg</a> ，放到<code>ElasticFusion/ElasticFusion-master/GUI/build</code>，并运行</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">./ElasticFusion -l dyson_lab.klg</span><br></pre></td></tr></table></figure><p>#运行结果<br><img src="https://img-blog.csdnimg.cn/20190412210419542.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZmY2pqaHY=,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"></p><h2 id="2、在Kinect-v1上实时运行"><a href="#2、在Kinect-v1上实时运行" class="headerlink" title="2、在Kinect v1上实时运行"></a>2、在Kinect v1上实时运行</h2><h3 id="（1）build-libFreenect"><a href="#（1）build-libFreenect" class="headerlink" title="（1）build libFreenect"></a>（1）build libFreenect</h3><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">cd ElasticFusion</span><br><span class="line">git clone https:<span class="comment">//github.com/OpenKinect/libfreenect</span></span><br><span class="line">cd libfreenect</span><br></pre></td></tr></table></figure><p>打开<code>libfreenect/CMakeLists.txt</code>，在33行<code>cmake_minimum_required(VERSION 2.8.12)</code>下一行添加</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">add_definitions(-<span class="built_in">std</span>=c++<span class="number">11</span>)</span><br></pre></td></tr></table></figure><p>保存后关闭，命令行继续执行</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">mkdir build &amp;&amp; cd build  </span><br><span class="line">cmake .. -DBUILD_OPENNI2_DRIVER=ON  </span><br><span class="line">make -j4</span><br><span class="line">cp -L lib/OpenNI2-FreenectDriver/libFreenectDriver.so $&#123;OPENNI2_DIR&#125;/Bin/x64-Release/OpenNI2/Drivers   #OPENNI2_DIR需要修改</span><br></pre></td></tr></table></figure><p>注：<code>${OPENNI2_DIR}</code>是OpenNI2的解压文件夹，比如我的在ElasticFusion文件夹，则<br><img src="https://img-blog.csdnimg.cn/2019041516412934.png" alt="在这里插入图片描述"></p><h3 id="（2）Kinect-v1接入"><a href="#（2）Kinect-v1接入" class="headerlink" title="（2）Kinect v1接入"></a>（2）Kinect v1接入</h3><p>打开<code>libfreenect</code>文件夹，运行</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo cp platform/linux/udev/<span class="number">51</span>-kinect.rules /etc/udev/rules.d</span><br></pre></td></tr></table></figure><p>重启后，插上kinect后，命令行运行<code>lsusb</code>，查看是否包含：Xbox camera，Xbox motor，Xbox audio<br><img src="https://img-blog.csdnimg.cn/20190415165040377.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZmY2pqaHY=,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"></p><h3 id="（3）修改GPUConfig-h"><a href="#（3）修改GPUConfig-h" class="headerlink" title="（3）修改GPUConfig.h"></a>（3）修改GPUConfig.h</h3><p>如果代码运行很慢且出现如下提示，需要修改修改<code>GPUConfig.h</code><br><img src="https://img-blog.csdnimg.cn/20190415170500705.png" alt="在这里插入图片描述"><br>在<code>ElasticFusion/ElasticFusion-master/GPUtest/build</code>文件夹运行</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">./GPUTest ../</span><br></pre></td></tr></table></figure><p><img src="https://img-blog.csdnimg.cn/20190415165848574.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZmY2pqaHY=,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"><br>将最后4行添加到<code>/ElasticFusion/ElasticFusion-master/Core/src/Utils/GPUConfig.h</code><br><img src="https://img-blog.csdnimg.cn/20190415170048968.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZmY2pqaHY=,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"></p><h3 id="（4）运行"><a href="#（4）运行" class="headerlink" title="（4）运行"></a>（4）运行</h3><p>打开<code>ElasticFusion/ElasticFusion-master/GUI/build</code>，运行</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">./ElasticFusion</span><br></pre></td></tr></table></figure><p>#运行结果<br><img src="https://img-blog.csdnimg.cn/20190415170315378.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZmY2pqaHY=,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"></p>]]></content>
    
    <summary type="html">
    
      &lt;h1 id=&quot;一、驱动与cuda安装&quot;&gt;&lt;a href=&quot;#一、驱动与cuda安装&quot; class=&quot;headerlink&quot; title=&quot;一、驱动与cuda安装&quot;&gt;&lt;/a&gt;一、驱动与cuda安装&lt;/h1&gt;&lt;p&gt;#安装驱动与cuda8.0&lt;br&gt;参考这篇：&lt;a href=&quot;https://blog.csdn.net/ffcjjhv/article/details/89151382&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://blog.csdn.net/ffcjjhv/article/details/89151382&lt;/a&gt;&lt;/p&gt;
&lt;h1 id=&quot;二、配置&quot;&gt;&lt;a href=&quot;#二、配置&quot; class=&quot;headerlink&quot; title=&quot;二、配置&quot;&gt;&lt;/a&gt;二、配置&lt;/h1&gt;&lt;h2 id=&quot;1、依赖包&quot;&gt;&lt;a href=&quot;#1、依赖包&quot; class=&quot;headerlink&quot; title=&quot;1、依赖包&quot;&gt;&lt;/a&gt;1、依赖包&lt;/h2&gt;
    
    </summary>
    
      <category term="深度相机" scheme="http://yoursite.com/categories/%E6%B7%B1%E5%BA%A6%E7%9B%B8%E6%9C%BA/"/>
    
      <category term="C++" scheme="http://yoursite.com/categories/C/"/>
    
    
      <category term="RGBD" scheme="http://yoursite.com/tags/RGBD/"/>
    
      <category term="ElasticFusion" scheme="http://yoursite.com/tags/ElasticFusion/"/>
    
      <category term="三维重建" scheme="http://yoursite.com/tags/%E4%B8%89%E7%BB%B4%E9%87%8D%E5%BB%BA/"/>
    
      <category term="Ubuntu" scheme="http://yoursite.com/tags/Ubuntu/"/>
    
  </entry>
  
  <entry>
    <title>BundleFusion在win10+vs2013+cuda8.0上的实现</title>
    <link href="http://yoursite.com/2019/04/12/21/"/>
    <id>http://yoursite.com/2019/04/12/21/</id>
    <published>2019-04-12T03:06:00.000Z</published>
    <updated>2019-12-18T04:17:16.164Z</updated>
    
    <content type="html"><![CDATA[<h2 id="介绍"><a href="#介绍" class="headerlink" title="介绍"></a>介绍</h2><p>在深度相机室内实时稠密三维重建领域，BundleFusion是目前效果最好的开源算法框架。论文地址：<a href="https://arxiv.org/pdf/1604.01093.pdf" target="_blank" rel="noopener">https://arxiv.org/pdf/1604.01093.pdf</a><br>演示视频截取片断：</p><a id="more"></a><p><img src="https://img-blog.csdnimg.cn/20190412112621627.gif" alt="在这里插入图片描述"><br>视频地址：<a href="https://www.youtube.com/watch?v=keIirXrRb1k" target="_blank" rel="noopener">https://www.youtube.com/watch?v=keIirXrRb1k</a><br>在演示视频中，structure sensor是卡在iPad上，将采集到的数据通过无线网络传给台式机（带GPU），匹配、优化和重建工作都是在台式机上运行，重建的结果再通过无线网络传到iPad上显示。<br>重建效果图：<br><img src="https://img-blog.csdnimg.cn/20190412112318524.JPG?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZmY2pqaHY=,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"></p><h1 id="一、配置"><a href="#一、配置" class="headerlink" title="一、配置"></a>一、配置</h1><h2 id="1、cuda8-0安装"><a href="#1、cuda8-0安装" class="headerlink" title="1、cuda8.0安装"></a>1、cuda8.0安装</h2><p>#建议安装：<code>cuda8.0</code>，<code>vs2013</code></p><p>#卸载cuda10.0<br>在控制面板/卸载程序，卸载掉所有带有NVIDIA的程序，卸载顺序不影响</p><p>#下载cuda8.0：<a href="https://developer.nvidia.com/cuda-80-ga2-download-archive" target="_blank" rel="noopener">https://developer.nvidia.com/cuda-80-ga2-download-archive</a> ，并运行安装。<br><img src="https://img-blog.csdnimg.cn/2019041122513930.JPG?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZmY2pqaHY=,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"></p><p>#验证安装成功，输入<code>nvcc --version</code><br><img src="https://img-blog.csdnimg.cn/20190412102533535.JPG" alt="在这里插入图片描述"></p><h2 id="2、DirectX-SDK安装"><a href="#2、DirectX-SDK安装" class="headerlink" title="2、DirectX SDK安装"></a>2、DirectX SDK安装</h2><p>下载地址：<a href="http://download.microsoft.com/download/A/E/7/AE743F1F-632B-4809-87A9-AA1BB3458E31/DXSDK_Jun10.exe" target="_blank" rel="noopener">http://download.microsoft.com/download/A/E/7/AE743F1F-632B-4809-87A9-AA1BB3458E31/DXSDK_Jun10.exe</a> ，运行安装。</p><p>#若运行安装出现 错误 <code>ErrorCode:s1023</code><br>解决办法1：<br><img src="https://img-blog.csdnimg.cn/20190411225804404.JPG" alt="在这里插入图片描述"><br>控制面板卸载以上两项，再重新安装DXSDK_Jun10.exe即可。</p><p>大部分通过这个方法可以解决，如果以上两项不存在或者卸载后仍不能解决问题（比如我），可能Microsoft Visual C++ 运行库安装有问题，得<code>删除并重新安装 Microsoft Visual C++ 运行库</code>，步骤如下：</p><p>1、控制面板卸载名称包含“Microsoft Visual C++”和“Redistributable”的所有程序<br>2、下载并安装以下所有软件：</p><p> <a href="http://www.microsoft.com/download/en/details.aspx?id=5638" target="_blank" rel="noopener">Microsoft Visual C++ 2005 SP1 Redistributable (x86)</a><br>  <a href="http://www.microsoft.com/download/en/details.aspx?id=18471" target="_blank" rel="noopener">Microsoft Visual C++ 2005 SP1 Redistributable (x64)</a><br> <a href="http://www.microsoft.com/download/en/details.aspx?id=5582" target="_blank" rel="noopener">Microsoft Visual C++ 2008 SP1 Redistributable (x86)</a><br> <a href="http://www.microsoft.com/download/en/details.aspx?id=2092" target="_blank" rel="noopener">Microsoft Visual C++ 2008 SP1 Redistributable (x64)</a><br><a href="http://www.microsoft.com/download/en/details.aspx?id=8328" target="_blank" rel="noopener">Microsoft Visual C++ 2010 SP1 Redistributable (x86)</a><br><a href="http://www.microsoft.com/download/en/details.aspx?id=13523" target="_blank" rel="noopener">Microsoft Visual C++ 2010 SP1 Redistributable (x64)</a><br><a href="https://www.microsoft.com/en-us/download/details.aspx?id=30679" target="_blank" rel="noopener">Microsoft Visual C++ 2012 Update 4 Redistributable(x86 和 x64)</a><br><a href="https://support.microsoft.com/en-us/help/3179560/update-for-visual-c-2013-and-visual-c-redistributable-package" target="_blank" rel="noopener">Microsoft Visual C++ 2013 Update 5 Redistributable Package(x86 和 x64)</a><br><a href="https://www.microsoft.com/en-us/download/details.aspx?id=52685" target="_blank" rel="noopener">Microsoft Visual C++ 2015 Update 3 Redistributable(x86 和 x64)</a></p><p>注意：</p><ul><li>每个下载的文件名均相同，因此在安装它之前，请确保不覆盖之前的文件。下载一个安装一个，然后再下载下一个并安装，依此类推。<ul><li>64 位系统上需要 x86 和 x64 版本。32 位系统只需要 x86 版本。</li></ul></li></ul><p>3、重启后，控制面板卸载2010两项，再重新安装DXSDK_Jun10.exe，即可解决。</p><h1 id="二、vs2013代码生成"><a href="#二、vs2013代码生成" class="headerlink" title="二、vs2013代码生成"></a>二、vs2013代码生成</h1><p>BundleFusion GitHub地址：<a href="https://github.com/niessner/BundleFusion" target="_blank" rel="noopener">https://github.com/niessner/BundleFusion</a><br>配置过程主要参考<a href="https://bericht.neopostmodern.com/posts/artist-guide-to-bundlefusion" target="_blank" rel="noopener">这里</a></p><p>从GitHub上下载该BundleFusion，并解压，得到工程 <code>BundleFusioin-master</code></p><h2 id="1、mLib与-mLib-external配置"><a href="#1、mLib与-mLib-external配置" class="headerlink" title="1、mLib与 mLib external配置"></a>1、mLib与 mLib external配置</h2><h3 id="mLib"><a href="#mLib" class="headerlink" title="mLib"></a>mLib</h3><p>下载地址：<a href="https://github.com/niessner/mLib" target="_blank" rel="noopener">https://github.com/niessner/mLib</a>  ，解压后，替换掉目录 <code>BundleFusion-master\external\mLib</code></p><h3 id="mLib-external"><a href="#mLib-external" class="headerlink" title="mLib external"></a>mLib external</h3><p>下载地址：<a href="https://www.dropbox.com/s/fve3uen5mzonidx/mLibExternal.zip?dl=0" target="_blank" rel="noopener">https://www.dropbox.com/s/fve3uen5mzonidx/mLibExternal.zip?dl=0</a> ，解压后，放到 <code>BundleFusioin-master 同级目录</code>,网址访问不了的话可以用我传到网盘的mLibExternal.zip：链接：<a href="https://pan.baidu.com/s/1CJysQCHl4t7RPfvqliwfew" target="_blank" rel="noopener">https://pan.baidu.com/s/1CJysQCHl4t7RPfvqliwfew</a> 提取码：0x4t </p><p>最终目录结构：</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line">bundlefusion</span><br><span class="line">BundleFusion-master/</span><br><span class="line">  external/</span><br><span class="line">    mLib/ <span class="meta"># this is the submodule you replaced</span></span><br><span class="line">      data/</span><br><span class="line">      src/</span><br><span class="line">      [...]</span><br><span class="line">  FriedLiver/</span><br><span class="line">    [...]</span><br><span class="line">    FriedLiver.sln</span><br><span class="line">    [...]</span><br><span class="line">mLibExternal/ <span class="meta"># you downloaded this from Dropbox</span></span><br><span class="line">  include</span><br><span class="line">  libsWindows</span><br><span class="line">  [...]</span><br></pre></td></tr></table></figure><h2 id="2、cuda设置"><a href="#2、cuda设置" class="headerlink" title="2、cuda设置"></a>2、cuda设置</h2><h3 id="修改cuda版本"><a href="#修改cuda版本" class="headerlink" title="修改cuda版本"></a>修改cuda版本</h3><p>用VS2013打开 <code>BundleFusion-master\FriedLiver\FriedLiver.sln</code> 工程，如果cuda版本不是原代码设置的cuda7.0，就会出现如下错误：<br><img src="https://img-blog.csdnimg.cn/20190412093658412.JPG" alt="在这里插入图片描述"><br>修改 <code>BundleFusion-master\FriedLiver\FriedLiver.vcxproj</code> 文件，用vs code打开该文件，并修改如下两行：<br><img src="https://img-blog.csdnimg.cn/20190412094229611.JPG" alt="在这里插入图片描述"><br><img src="https://img-blog.csdnimg.cn/20190412094237754.JPG" alt="在这里插入图片描述"><br>再次打开就不会报错了。</p><h3 id="显卡计算能力设置"><a href="#显卡计算能力设置" class="headerlink" title="显卡计算能力设置"></a>显卡计算能力设置</h3><p>选择适合你显卡的compute能力，显卡计算能力在<a href="https://developer.nvidia.com/cuda-gpus" target="_blank" rel="noopener">这里</a>查询<br>我的笔记本显卡NVIDIA GeForce MX150，计算能力与GeForce 940M等同，为5.0，在工程的配置选项中设置如下：<br><img src="https://img-blog.csdnimg.cn/20190412101315737.JPG?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZmY2pqaHY=,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"></p><h2 id="3、相机类型设置（以apt0-sens离线数据为例）"><a href="#3、相机类型设置（以apt0-sens离线数据为例）" class="headerlink" title="3、相机类型设置（以apt0.sens离线数据为例）"></a>3、相机类型设置（以apt0.sens离线数据为例）</h2><h3 id="输入类型"><a href="#输入类型" class="headerlink" title="输入类型"></a>输入类型</h3><p>输入数据可以为Kinect v1，Kinect v2，PrimeSenseSensor，IntelSensor，RealSense，StructureSensor以及SensorDataReader（离线数据）<br>具体可以查看<code>FriedLiver.cpp</code>中7-103行的内容</p><p>没有深度相机的，以离线数据<code>office3.sens</code>为例，下载地址：<a href="http://graphics.stanford.edu/projects/bundlefusion/" target="_blank" rel="noopener">http://graphics.stanford.edu/projects/bundlefusion/</a> </p><h3 id="修改GlobalAppState-h"><a href="#修改GlobalAppState-h" class="headerlink" title="修改GlobalAppState.h"></a>修改GlobalAppState.h</h3><p>因为使用的是离线数据，将<code>GlobalAppState.h</code>中深度相机全部注释掉。<br><img src="https://img-blog.csdnimg.cn/20190412102815288.JPG?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZmY2pqaHY=,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"><br>注：如果用深度相机（如：Kinect v1）实时运行，用哪个将哪个取消注释，并安装对应SDK。</p><h2 id="4、生成FriedLiver-exe"><a href="#4、生成FriedLiver-exe" class="headerlink" title="4、生成FriedLiver.exe"></a>4、生成FriedLiver.exe</h2><p>修改为 <code>Release</code> 版本，然后选择 <code>生成-&gt;生成解决方法</code><br>编译通过后，如下图：<br><img src="https://img-blog.csdnimg.cn/20190412104215614.JPG?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZmY2pqaHY=,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"><br>在<code>BundleFusion-master\FriedLiver\x64\Release</code>中生成可执行文件<code>FriedLiver.exe</code></p><h1 id="三、运行与结果"><a href="#三、运行与结果" class="headerlink" title="三、运行与结果"></a>三、运行与结果</h1><h2 id="1、配置文件修改"><a href="#1、配置文件修改" class="headerlink" title="1、配置文件修改"></a>1、配置文件修改</h2><p>将<code>BundleFusion-master\FriedLiver</code> 目录下的 <code>zParametersBundlingDefault.txt</code> 和 <code>zParametersDefault.txt</code> 拷贝到 <code>BundleFusion-master\FriedLiver\x64\Release</code> </p><h3 id="修改zParametersDefault-txt"><a href="#修改zParametersDefault-txt" class="headerlink" title="修改zParametersDefault.txt"></a>修改zParametersDefault.txt</h3><p>用vs code打开 <code>zParametersDefault.txt</code> 配置文件，选择输入类型，这里使用离线数据，修改第2行，设置<code>s_sensorIdx = 8</code> 。如果用深度相机（如：Kinect v1）实时运行，修改为对应的序列号。<br><img src="https://img-blog.csdnimg.cn/20190412105005826.JPG" alt="在这里插入图片描述"><br>修改第49行，设置<code>s_hashNumSDFBlocks = 100000</code><br><img src="https://img-blog.csdnimg.cn/20190412105613837.JPG" alt="在这里插入图片描述"><br>修改第58行，设置输入路径<code>s_binaryDumpSensorFile = &quot;../data/office3.sens&quot;</code><br><img src="https://img-blog.csdnimg.cn/20190412110258422.JPG" alt="在这里插入图片描述"><br>将下载的<code>office3.sens</code>放置到<code>BundleFusion-master\FriedLiver\x64\data</code></p><h3 id="修改zParametersBundlingDefault-txt"><a href="#修改zParametersBundlingDefault-txt" class="headerlink" title="修改zParametersBundlingDefault.txt"></a>修改zParametersBundlingDefault.txt</h3><p>双击运行后，若出现窗口崩溃或者没有响应直接跳出，如下图：<br><img src="https://img-blog.csdnimg.cn/20190412105858577.JPG?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZmY2pqaHY=,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"><br>用vs code打开 <code>zParametersBundlingDefault.txt</code> 配置文件，修改第30行，设置<code>s_maxNumImages = 400</code> </p><h2 id="2、运行结果"><a href="#2、运行结果" class="headerlink" title="2、运行结果"></a>2、运行结果</h2><p>配置修改后，双击运行FriedLiver.exe<br><img src="https://img-blog.csdnimg.cn/20190411222117900.gif" alt="在这里插入图片描述"><br>按下<code>tab键</code>，如下图所示，按照提示与软件进行交互，按下<code>ctrl+2</code>显示带颜色深度，按下<code>ctrl+3</code>显示彩色视频流，按下<code>ctrl+9</code>导出当前模型到<code>FriedLiver\x64\Release\scans\scan.ply</code> ，具体实现代码查看<code>FriedLiver\Source\DepthSensing\DepthSensing.cpp</code><br><img src="https://img-blog.csdnimg.cn/20190412113926745.JPG?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZmY2pqaHY=,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"></p><h2 id="3、模型生成"><a href="#3、模型生成" class="headerlink" title="3、模型生成"></a>3、模型生成</h2><p>运行结束后，<code>BundleFusion-master\FriedLiver\x64\data\office3.sens</code>同目录下生成office3.ply，用meshlab打开<br><img src="https://img-blog.csdnimg.cn/20190411224542285.gif" alt="在这里插入图片描述"></p><h2 id="4、在Kinect-v1上的实时运行"><a href="#4、在Kinect-v1上的实时运行" class="headerlink" title="4、在Kinect v1上的实时运行"></a>4、在Kinect v1上的实时运行</h2><h3 id="安装-Kinect-SDK-v1-8"><a href="#安装-Kinect-SDK-v1-8" class="headerlink" title="安装 Kinect  SDK v1.8"></a>安装 Kinect  SDK v1.8</h3><p> <a href="https://www.microsoft.com/en-us/download/details.aspx?id=40278" target="_blank" rel="noopener">Kinect for Windows SDK v1.8</a><br> <a href="https://www.microsoft.com/en-us/download/details.aspx?id=40276" target="_blank" rel="noopener">Kinect for Windows Developer Toolkit v1.8</a><br> 下载后默认安装</p><h3 id="设置Kinect-v1输入"><a href="#设置Kinect-v1输入" class="headerlink" title="设置Kinect v1输入"></a>设置Kinect v1输入</h3><p> 重新打开 <code>BundleFusion-master\FriedLiver\FriedLiver.sln</code> 工程，将<code>GlobalAppState.h</code>中第三行取消注释<br><img src="https://img-blog.csdnimg.cn/20190415110414701.JPG?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZmY2pqaHY=,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"><br> 选择 <code>生成-&gt;生成解决方法</code>，即可编译通过。</p><p> <code>zParametersDefault.txt</code> 配置文件，选择输入类型，这里使用Kinect v1，修改第2行，设置<code>s_sensorIdx = 0</code> </p><h3 id="实时运行"><a href="#实时运行" class="headerlink" title="实时运行"></a>实时运行</h3><p>插上Kinect v1，双击运行FriedLiver.exe<br><img src="https://img-blog.csdnimg.cn/20190415111035525.JPG?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZmY2pqaHY=,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"></p>]]></content>
    
    <summary type="html">
    
      &lt;h2 id=&quot;介绍&quot;&gt;&lt;a href=&quot;#介绍&quot; class=&quot;headerlink&quot; title=&quot;介绍&quot;&gt;&lt;/a&gt;介绍&lt;/h2&gt;&lt;p&gt;在深度相机室内实时稠密三维重建领域，BundleFusion是目前效果最好的开源算法框架。论文地址：&lt;a href=&quot;https://arxiv.org/pdf/1604.01093.pdf&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://arxiv.org/pdf/1604.01093.pdf&lt;/a&gt;&lt;br&gt;演示视频截取片断：&lt;/p&gt;
    
    </summary>
    
      <category term="深度相机" scheme="http://yoursite.com/categories/%E6%B7%B1%E5%BA%A6%E7%9B%B8%E6%9C%BA/"/>
    
      <category term="C++" scheme="http://yoursite.com/categories/C/"/>
    
    
      <category term="BundleFusion" scheme="http://yoursite.com/tags/BundleFusion/"/>
    
      <category term="Win10" scheme="http://yoursite.com/tags/Win10/"/>
    
      <category term="室内重建" scheme="http://yoursite.com/tags/%E5%AE%A4%E5%86%85%E9%87%8D%E5%BB%BA/"/>
    
  </entry>
  
  <entry>
    <title>DynamicFusion在ubuntu16.04+显卡GT740+cuda8.0上的实现</title>
    <link href="http://yoursite.com/2019/04/09/14/"/>
    <id>http://yoursite.com/2019/04/09/14/</id>
    <published>2019-04-09T10:10:06.000Z</published>
    <updated>2019-12-18T04:13:14.533Z</updated>
    
    <content type="html"><![CDATA[<h2 id="介绍"><a href="#介绍" class="headerlink" title="介绍"></a>介绍</h2><p><img src="https://img-blog.csdnimg.cn/20190409152447293.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZmY2pqaHY=,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"><br>DynamicFusion构建了一个可以实时重建 非刚性变形 动态场景 的系统，随着新的数据融合进模型当中，模型得到降噪、细节更加精细。</p><a id="more"></a><p>论文地址：<a href="http://grail.cs.washington.edu/projects/dynamicfusion/papers/DynamicFusion.pdf" target="_blank" rel="noopener">http://grail.cs.washington.edu/projects/dynamicfusion/papers/DynamicFusion.pdf</a><br>GitHub地址：<a href="https://github.com/mihaibujanca/dynamicfusion" target="_blank" rel="noopener">https://github.com/mihaibujanca/dynamicfusion</a><br>注意：这个项目是对论文的复现，但是目前<code>尚未准确复现论文内容</code>，运行速度仍然有待优化，10s/frame不满足实时运行，建议转换成离线数据，再进行运行。</p><p>这里记录DynamicFusion在ubuntu16.04+显卡GT740+cuda8.0上的实现。（虽然可以实现，但是GT740真的是太慢慢慢慢了…电脑是刚重装完系统的机子）</p><h1 id="1、驱动与cuda安装"><a href="#1、驱动与cuda安装" class="headerlink" title="1、驱动与cuda安装"></a>1、驱动与cuda安装</h1><h2 id="（1）驱动安装"><a href="#（1）驱动安装" class="headerlink" title="（1）驱动安装"></a>（1）驱动安装</h2><h3 id="a-驱动下载"><a href="#a-驱动下载" class="headerlink" title="a.驱动下载"></a>a.驱动下载</h3><p>#查看显卡型号</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">lspci | grep -i nvidia</span><br></pre></td></tr></table></figure><p>nvidia官网 <a href="https://www.geforce.cn/drivers" target="_blank" rel="noopener">https://www.geforce.cn/drivers</a> 搜索显卡型号对应的驱动，下载（别用最新的）后放到home文件夹<br><img src="https://img-blog.csdnimg.cn/20190409155616337.JPG?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZmY2pqaHY=,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"></p><h3 id="b-禁用nouveau驱动"><a href="#b-禁用nouveau驱动" class="headerlink" title="b.禁用nouveau驱动"></a>b.禁用nouveau驱动</h3><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo gedit /etc/modprobe.d/blacklist.conf</span><br></pre></td></tr></table></figure><p>在文本最后添加：</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">blacklist nouveau</span><br><span class="line">options nouveau modeset=<span class="number">0</span></span><br></pre></td></tr></table></figure><p>然后执行：</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo update-initramfs -u</span><br></pre></td></tr></table></figure><p>重启后，屏幕分辨率可能不对不用管，命令行执行：<code>lsmod | grep nouveau</code> ，如果没有屏幕输出，说明禁用nouveau成功。</p><h3 id="c-禁用X-Window服务"><a href="#c-禁用X-Window服务" class="headerlink" title="c.禁用X-Window服务"></a>c.禁用X-Window服务</h3><p><code>#注意：这会关闭图形界面，提前用手机或者笔记本看下面的步骤</code></p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo service lightdm stop</span><br></pre></td></tr></table></figure><p>按<code>Ctrl-Alt+F1</code>进入命令行界面，输入用户名和密码登录。</p><h3 id="d-命令行安装驱动"><a href="#d-命令行安装驱动" class="headerlink" title="d.命令行安装驱动"></a>d.命令行安装驱动</h3><p>#给驱动run文件赋予执行权限：</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo chmod +x NVIDIA-Linux-x86_64<span class="number">-384.59</span>.run</span><br></pre></td></tr></table></figure><p>#后面的参数不可省略：</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo ./NVIDIA-Linux-x86_64<span class="number">-384.59</span>.run –no-opengl-files</span><br></pre></td></tr></table></figure><p>按照提示安装，回车确定，成功安装后在命令行输入：<code>sudo service lightdm start</code>，恢复到图形界面，此时屏幕分辨率恢复正常，重启。</p><h3 id="e-驱动测试"><a href="#e-驱动测试" class="headerlink" title="e.驱动测试"></a>e.驱动测试</h3><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo nvidia-smi</span><br></pre></td></tr></table></figure><p>若列出GPU的信息列表，表示驱动安装成功。<br><img src="https://img-blog.csdnimg.cn/20190409161619534.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZmY2pqaHY=,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"></p><h2 id="（2）cuda7-5安装"><a href="#（2）cuda7-5安装" class="headerlink" title="（2）cuda7.5安装"></a>（2）cuda7.5安装</h2><p>cuda7.5可以使用命令行安装，到了cuda8.0以及往上就不行了</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">sudo apt-get update</span><br><span class="line">sudo apt-get install nvidia-cuda-dev nvidia-cuda-toolkit nvidia-nsight nvidia-prime</span><br></pre></td></tr></table></figure><p>等待安装完成后，输入<code>nvcc -V</code>，检查是否安装成功。<br><img src="https://img-blog.csdnimg.cn/20190409162225446.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZmY2pqaHY=,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"></p><h1 id="2、环境配置"><a href="#2、环境配置" class="headerlink" title="2、环境配置"></a>2、环境配置</h1><p>下载DynamicFusion代码：<a href="https://github.com/mihaibujanca/dynamicfusion" target="_blank" rel="noopener">https://github.com/mihaibujanca/dynamicfusion</a><br>整个配置过程参考dynamicfusion-master/build.sh 文件（不要直接运行build.sh会有各种报错）</p><h2 id="（1）apt-get-install-依赖安装"><a href="#（1）apt-get-install-依赖安装" class="headerlink" title="（1）apt-get install 依赖安装"></a>（1）apt-get install 依赖安装</h2><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">sudo apt-get install cmake libvtk5-dev libsuitesparse-dev liblapack-dev --fix-missing</span><br><span class="line">sudo apt-get install libblas-dev libgtk2<span class="number">.0</span>-dev pkg-config libopenni-dev --fix-missing</span><br><span class="line">sudo apt-get install libusb<span class="number">-1.0</span><span class="number">-0</span>-dev wget zip clang --fix-missing</span><br></pre></td></tr></table></figure><h2 id="（2）安装gflags、glog、Eigen、Ceres"><a href="#（2）安装gflags、glog、Eigen、Ceres" class="headerlink" title="（2）安装gflags、glog、Eigen、Ceres"></a>（2）安装gflags、glog、Eigen、Ceres</h2><p>进入<code>dynamicfusion-master</code>文件夹的<code>上一目录</code></p><h3 id="安装gflags、glog、Eigen"><a href="#安装gflags、glog、Eigen" class="headerlink" title="安装gflags、glog、Eigen"></a>安装gflags、glog、Eigen</h3><p>#安装 gflags</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">git clone https:<span class="comment">//github.com/gflags/gflags.git</span></span><br><span class="line">cd gflags</span><br><span class="line">mkdir -p build/ &amp;&amp; cd build</span><br><span class="line">cmake .. &amp;&amp; make </span><br><span class="line">cd ../../</span><br></pre></td></tr></table></figure><p>#安装 glog</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">git clone https:<span class="comment">//github.com/google/glog.git</span></span><br><span class="line">cd glog</span><br><span class="line">mkdir -p build/ &amp;&amp; cd build/</span><br><span class="line">cmake .. &amp;&amp; make</span><br><span class="line">cd ../../</span><br></pre></td></tr></table></figure><p>#安装 Eigen 3.3.4</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">wget http:<span class="comment">//bitbucket.org/eigen/eigen/get/3.3.4.tar.gz</span></span><br><span class="line">tar -xf <span class="number">3.3</span><span class="number">.4</span>.tar.gz</span><br><span class="line">cd eigen-eigen<span class="number">-5</span>a0156e40feb</span><br><span class="line">mkdir -p build &amp;&amp; cd build</span><br><span class="line">cmake ..</span><br><span class="line">sudo make install</span><br><span class="line">cd ../../</span><br></pre></td></tr></table></figure><h3 id="配置ceres-solver"><a href="#配置ceres-solver" class="headerlink" title="配置ceres-solver"></a>配置ceres-solver</h3><p>#下载ceres-solver：<a href="https://github.com/ceres-solver/ceres-solver" target="_blank" rel="noopener">https://github.com/ceres-solver/ceres-solver</a> 并解压到<code>dynamicfusion-master文件夹的上一目录</code> ，将ceres-solver-master重命名为<code>ceres-solver</code></p><p>#配置 Ceres</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">cd ceres-solver</span><br><span class="line">mkdir -p build/ &amp;&amp; cd build/</span><br><span class="line">cmake ..</span><br><span class="line">make -j4</span><br><span class="line">sudo make install</span><br><span class="line">cd ../../</span><br></pre></td></tr></table></figure><h2 id="（3）安装OpenCV-2-4-13"><a href="#（3）安装OpenCV-2-4-13" class="headerlink" title="（3）安装OpenCV 2.4.13"></a>（3）安装OpenCV 2.4.13</h2><p>注：opencv的下载过程非常非常慢，建议前天晚上下载，第二天再接着配置</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">git clone https:<span class="comment">//github.com/opencv/opencv</span></span><br><span class="line">cd opencv/</span><br><span class="line">git checkout <span class="number">2.4</span><span class="number">.13</span><span class="number">.3</span></span><br><span class="line">mkdir -p build &amp;&amp; cd build</span><br><span class="line">cmake -DWITH_VTK=ON -DBUILD_opencv_calib3d=ON -DBUILD_opencv_imgproc=ON -DWITH_CUDA=OFF ..</span><br><span class="line">make -j4</span><br><span class="line">sudo make install</span><br><span class="line">cd ../../</span><br></pre></td></tr></table></figure><h2 id="（4）安装Boost"><a href="#（4）安装Boost" class="headerlink" title="（4）安装Boost"></a>（4）安装Boost</h2><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">wget https:<span class="comment">//dl.bintray.com/boostorg/release/1.64.0/source/boost_1_64_0.tar.gz</span></span><br><span class="line">tar -xf boost_1_64_0.tar.gz</span><br><span class="line">cd boost_1_64_0</span><br><span class="line">sudo ./bootstrap.sh</span><br><span class="line">./b2</span><br><span class="line">sudo ./b2 install</span><br><span class="line">cd ..</span><br></pre></td></tr></table></figure><p>删除掉无用的压缩包，最终目录如图<br><img src="https://img-blog.csdnimg.cn/20190409171511176.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZmY2pqaHY=,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"></p><h1 id="3、代码修改与dataset获取"><a href="#3、代码修改与dataset获取" class="headerlink" title="3、代码修改与dataset获取"></a>3、代码修改与dataset获取</h1><h2 id="（1）配置deps-terra"><a href="#（1）配置deps-terra" class="headerlink" title="（1）配置deps/terra"></a>（1）配置deps/terra</h2><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">cd dynamicfusion-master/deps</span><br><span class="line">wget https:<span class="comment">//github.com/zdevito/terra/releases/download/release-2016-03-25/terra-Linux-x86_64-332a506.zip</span></span><br><span class="line">unzip terra-Linux-x86_64<span class="number">-332</span>a506.zip</span><br><span class="line">rm terra-Linux-x86_64<span class="number">-332</span>a506.zip</span><br><span class="line">mv terra-Linux-x86_64<span class="number">-332</span>a506 terra</span><br></pre></td></tr></table></figure><h2 id="（2）配置deps-Opt"><a href="#（2）配置deps-Opt" class="headerlink" title="（2）配置deps/Opt"></a>（2）配置deps/Opt</h2><p>#下载Opt：<a href="https://github.com/niessner/Opt/tree/c6012e7e4c67fa3bea96161ba24fe88a2b79deed" target="_blank" rel="noopener">https://github.com/niessner/Opt/tree/c6012e7e4c67fa3bea96161ba24fe88a2b79deed</a> ，并解压到deps，重命名为Opt</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">cd Opt/API/</span><br><span class="line">make -j4</span><br></pre></td></tr></table></figure><h2 id="（3）修改kfusion-src-warp-field-cpp"><a href="#（3）修改kfusion-src-warp-field-cpp" class="headerlink" title="（3）修改kfusion/src/warp_field.cpp"></a>（3）修改kfusion/src/warp_field.cpp</h2><p>为了解决之后运行代码会出现的报错</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">.../dynamicfusion/kfusion/src/warp_field.cpp:<span class="number">158</span>:<span class="number">10</span>: error: ‘<span class="class"><span class="keyword">struct</span> <span class="title">ceres</span>:</span>:Solver::Options’ has no member named ‘num_threads_used’</span><br><span class="line">options.num_threads_used = <span class="number">8</span>;</span><br></pre></td></tr></table></figure><p>将第157行<code>options.num_linear_solver_threads = 8;</code>注释掉</p><h2 id="（4）dataset下载"><a href="#（4）dataset下载" class="headerlink" title="（4）dataset下载"></a>（4）dataset下载</h2><p>下载地址 <a href="https://www.dropbox.com/sh/qgy2n9bmioofqnj/AABUnT7pi2ECpxSi80EmXOXna?dl=0" target="_blank" rel="noopener">https://www.dropbox.com/sh/qgy2n9bmioofqnj/AABUnT7pi2ECpxSi80EmXOXna?dl=0</a> （给的数据挺多的，如果网站上不去可以下载我传到百度云的数据，只传了作为demo的umbrella_data.zip）</p><p>umbrella_data.zip下载链接：<a href="https://pan.baidu.com/s/1PRf7-xl5vgj2SUQVNiuk-g" target="_blank" rel="noopener">https://pan.baidu.com/s/1PRf7-xl5vgj2SUQVNiuk-g</a>  ，提取码：25s1<br>下载后放置到dynamicfusion-master文件夹中，运行</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">mkdir -p data/umbrella/depth</span><br><span class="line">mkdir -p data/umbrella/color</span><br><span class="line"></span><br><span class="line">mv umbrella_data.zip data/umbrella</span><br><span class="line">cd data/umbrella</span><br><span class="line">unzip umbrella_data.zip</span><br><span class="line">rm *.txt</span><br><span class="line">mv *color*.png color/</span><br><span class="line">mv *depth*.png depth/</span><br><span class="line">rm umbrella_data.zip</span><br></pre></td></tr></table></figure><h1 id="4、运行"><a href="#4、运行" class="headerlink" title="4、运行"></a>4、运行</h1><h2 id="（1）编译"><a href="#（1）编译" class="headerlink" title="（1）编译"></a>（1）编译</h2><p>进入dynamicfusion-master文件夹，运行</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">mkdir -p build &amp;&amp; cd build</span><br><span class="line">cmake -DOpenCV_DIR=~/opencv/build -DBOOST_ROOT=~/boost_1_64_0/ -DOPENNI_INCLUDE_DIR=/usr/include/ni -DOpenCV_FOUND=TRUE ..</span><br><span class="line">make -j4</span><br></pre></td></tr></table></figure><h2 id="（2）运行与报错"><a href="#（2）运行与报错" class="headerlink" title="（2）运行与报错"></a>（2）运行与报错</h2><p>进入dynamicfusion-master文件夹，运行</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">./build/bin/dynamicfusion data/umbrella</span><br></pre></td></tr></table></figure><p>运行后报错 <code>llvm: No such file or directory</code> ,查看这里：<a href="https://github.com/mihaibujanca/dynamicfusion/issues/54" target="_blank" rel="noopener">https://github.com/mihaibujanca/dynamicfusion/issues/54</a><br>升级cuda7.5到8.0能够解决</p><h2 id="（3）升级cuda7-5到8-0"><a href="#（3）升级cuda7-5到8-0" class="headerlink" title="（3）升级cuda7.5到8.0"></a>（3）升级cuda7.5到8.0</h2><h3 id="卸载cuda7-5"><a href="#卸载cuda7-5" class="headerlink" title="卸载cuda7.5"></a>卸载cuda7.5</h3><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo apt-get autoremove nvidia-cuda-toolkit</span><br></pre></td></tr></table></figure><p><img src="https://img-blog.csdnimg.cn/20190409174954238.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZmY2pqaHY=,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"></p><h3 id="安装cuda8-0"><a href="#安装cuda8-0" class="headerlink" title="安装cuda8.0"></a>安装cuda8.0</h3><p>#下载cuda8.0：<a href="https://developer.nvidia.com/cuda-80-ga2-download-archive" target="_blank" rel="noopener">https://developer.nvidia.com/cuda-80-ga2-download-archive</a><br><img src="https://img-blog.csdnimg.cn/20190409175454360.JPG?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZmY2pqaHY=,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"></p><p>#安装依赖</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo apt-get install freeglut3-dev build-essential libx11-dev libxmu-dev libxi-dev libgl1-mesa-glx libglu1-mesa libglu1-mesa-dev</span><br></pre></td></tr></table></figure><p>#安装cuda8.0</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">sudo chmod <span class="number">777</span> cuda_8<span class="number">.0</span><span class="number">.61</span>_375<span class="number">.26</span>_linux.run </span><br><span class="line">sudo ./cuda_8<span class="number">.0</span><span class="number">.61</span>_375<span class="number">.26</span>_linux.run</span><br></pre></td></tr></table></figure><p>执行后会先出现一个声明，需要阅读到100%才会开始安装，直接ctr+c跳过<br>按照提示输入回答就行，位置全部选择默认，注：<code>第二个选择是否安装nvidia驱动时，一定要选择否</code><br>安装完依赖后，如果仍然提示</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">Installing the CUDA Toolkit in /usr/local/cuda<span class="number">-8.0</span> … </span><br><span class="line">Missing recommended library: libXmu.so</span><br></pre></td></tr></table></figure><p>不用管</p><p>#添加环境变量</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo gedit ~/.bashrc</span><br></pre></td></tr></table></figure><p>将以下内容写入到~/.bashrc尾部：</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">export</span> PATH=/usr/local/cuda<span class="number">-8.0</span>/bin$&#123;PATH:+:$&#123;PATH&#125;&#125;</span><br><span class="line"><span class="keyword">export</span> LD_LIBRARY_PATH=/usr/local/cuda<span class="number">-8.0</span>/lib64$&#123;LD_LIBRARY_PATH:+:$&#123;LD_LIBRARY_PATH&#125;&#125;</span><br></pre></td></tr></table></figure><p>重启后，输入<code>nvcc --version</code> 测试是否安装成功<br><img src="https://img-blog.csdnimg.cn/20190409180512255.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZmY2pqaHY=,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"></p><h2 id="（4）运行与结果"><a href="#（4）运行与结果" class="headerlink" title="（4）运行与结果"></a>（4）运行与结果</h2><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo apt-get install nvidia-cuda-dev nvidia-cuda-toolkit nvidia-nsight nvidia-prime</span><br></pre></td></tr></table></figure><p>#编译<br>进入dynamicfusion-master文件夹，运行</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">mkdir -p build &amp;&amp; cd build</span><br><span class="line">cmake -DOpenCV_DIR=~/opencv/build -DBOOST_ROOT=~/boost_1_64_0/ -DOPENNI_INCLUDE_DIR=/usr/include/ni -DOpenCV_FOUND=TRUE ..</span><br><span class="line">make -j4</span><br></pre></td></tr></table></figure><p>#运行<br>进入dynamicfusion-master文件夹，运行</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">./build/bin/dynamicfusion data/umbrella</span><br></pre></td></tr></table></figure><p>#结果<br><img src="https://img-blog.csdnimg.cn/20190409180742100.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZmY2pqaHY=,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"><br>DynamicFusion效果（项目视频）：<br><img src="https://img-blog.csdnimg.cn/20190409181625827.gif" alt="在这里插入图片描述"><br>视频地址：<a href="https://www.youtube.com/watch?v=i1eZekcc_lM" target="_blank" rel="noopener">https://www.youtube.com/watch?v=i1eZekcc_lM</a></p>]]></content>
    
    <summary type="html">
    
      &lt;h2 id=&quot;介绍&quot;&gt;&lt;a href=&quot;#介绍&quot; class=&quot;headerlink&quot; title=&quot;介绍&quot;&gt;&lt;/a&gt;介绍&lt;/h2&gt;&lt;p&gt;&lt;img src=&quot;https://img-blog.csdnimg.cn/20190409152447293.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZmY2pqaHY=,size_16,color_FFFFFF,t_70&quot; alt=&quot;在这里插入图片描述&quot;&gt;&lt;br&gt;DynamicFusion构建了一个可以实时重建 非刚性变形 动态场景 的系统，随着新的数据融合进模型当中，模型得到降噪、细节更加精细。&lt;/p&gt;
    
    </summary>
    
      <category term="深度相机" scheme="http://yoursite.com/categories/%E6%B7%B1%E5%BA%A6%E7%9B%B8%E6%9C%BA/"/>
    
      <category term="C++" scheme="http://yoursite.com/categories/C/"/>
    
    
      <category term="三维重建" scheme="http://yoursite.com/tags/%E4%B8%89%E7%BB%B4%E9%87%8D%E5%BB%BA/"/>
    
      <category term="DynamicFusion" scheme="http://yoursite.com/tags/DynamicFusion/"/>
    
  </entry>
  
  <entry>
    <title>刷题汇总（一）leetcode 精选50题 JavaScript答案总结</title>
    <link href="http://yoursite.com/2019/03/11/13/"/>
    <id>http://yoursite.com/2019/03/11/13/</id>
    <published>2019-03-11T12:58:24.000Z</published>
    <updated>2019-12-18T04:11:05.244Z</updated>
    
    <content type="html"><![CDATA[<h3 id="题目来源"><a href="#题目来源" class="headerlink" title="题目来源"></a>题目来源</h3><p> <a href="https://leetcode-cn.com/problemset/50/" target="_blank" rel="noopener">腾讯精选练习（50 题）</a></p><p>GitHub地址：<a href="https://github.com/zj19941113/LeetCode-50-JavaScript-Answers" target="_blank" rel="noopener">https://github.com/zj19941113/LeetCode-50-JavaScript-Answers</a></p><p>相关：<br><a href="https://blog.csdn.net/ffcjjhv/article/details/96879804" target="_blank" rel="noopener">刷题汇总（二）剑指Offer 66题 C++答案总结</a><br><a href="https://blog.csdn.net/ffcjjhv/article/details/100104411" target="_blank" rel="noopener">刷题汇总（三）leetcode 精选50题 C++答案总结</a><br><a href="https://blog.csdn.net/ffcjjhv/article/details/103195691" target="_blank" rel="noopener">刷题汇总（四）技术类编程题汇总 C++</a><br><a href="https://blog.csdn.net/ffcjjhv/article/details/103381516" target="_blank" rel="noopener">刷题汇总（五）leetcode 热题 HOT 100 C++ 答案总结</a><br><a href="https://blog.csdn.net/ffcjjhv/article/details/103503745" target="_blank" rel="noopener">刷题汇总（六）leetcode 多线程 / Shell</a></p><h5 id="2两数相加-33-0-中等"><a href="#2两数相加-33-0-中等" class="headerlink" title="2两数相加-33.0%-中等"></a>2两数相加-33.0%-中等</h5><a id="more"></a><p><a href="https://leetcode-cn.com/problems/add-two-numbers/" target="_blank" rel="noopener">https://leetcode-cn.com/problems/add-two-numbers/</a></p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Definition for singly-linked list.</span></span><br><span class="line"><span class="comment"> * function ListNode(val) &#123;</span></span><br><span class="line"><span class="comment"> *     this.val = val;</span></span><br><span class="line"><span class="comment"> *     this.next = null;</span></span><br><span class="line"><span class="comment"> * &#125;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * @param &#123;ListNode&#125; l1</span></span><br><span class="line"><span class="comment"> * @param &#123;ListNode&#125; l2</span></span><br><span class="line"><span class="comment"> * @return &#123;ListNode&#125;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">var</span> addTwoNumbers = <span class="function"><span class="keyword">function</span>(<span class="params">l1, l2</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">var</span> re = <span class="keyword">new</span> ListNode(<span class="number">0</span>); <span class="comment">//0随便取，不会用到，只为了初始化</span></span><br><span class="line">    <span class="keyword">var</span> r=re;  <span class="comment">//浅拷贝</span></span><br><span class="line">    <span class="keyword">var</span> carry=<span class="number">0</span>;</span><br><span class="line">    <span class="keyword">while</span>(l1!=<span class="literal">null</span> || l2!=<span class="literal">null</span>)&#123;</span><br><span class="line">        <span class="keyword">var</span> x = l1==<span class="literal">null</span>? <span class="number">0</span>:l1.val;</span><br><span class="line">        <span class="keyword">var</span> y = l2==<span class="literal">null</span>? <span class="number">0</span>:l2.val;</span><br><span class="line">        r.next=<span class="keyword">new</span> ListNode((carry+x+y)%<span class="number">10</span>);</span><br><span class="line">        r=r.next;</span><br><span class="line">        <span class="keyword">if</span>(carry+x+y&gt;<span class="number">9</span>)&#123;</span><br><span class="line">            carry=<span class="number">1</span>;</span><br><span class="line">        &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">            carry=<span class="number">0</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span>(l1!=<span class="literal">null</span>)&#123;</span><br><span class="line">            l1=l1.next;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span>(l2!=<span class="literal">null</span>)&#123;</span><br><span class="line">            l2=l2.next;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span>(carry&gt;<span class="number">0</span>)&#123;</span><br><span class="line">        r.next=<span class="keyword">new</span> ListNode(<span class="number">1</span>); <span class="comment">//最高位进1</span></span><br><span class="line">    &#125; </span><br><span class="line">    <span class="keyword">return</span> re.next;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h5 id="4寻找两个有序数组的中位数-33-8-困难"><a href="#4寻找两个有序数组的中位数-33-8-困难" class="headerlink" title="4寻找两个有序数组的中位数-33.8%-困难"></a>4寻找两个有序数组的中位数-33.8%-困难</h5><p><a href="https://leetcode-cn.com/problems/median-of-two-sorted-arrays/" target="_blank" rel="noopener">https://leetcode-cn.com/problems/median-of-two-sorted-arrays/</a></p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * @param &#123;number[]&#125; nums1</span></span><br><span class="line"><span class="comment"> * @param &#123;number[]&#125; nums2</span></span><br><span class="line"><span class="comment"> * @return &#123;number&#125;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">var</span> findMedianSortedArrays = <span class="function"><span class="keyword">function</span>(<span class="params">a, b</span>) </span>&#123;</span><br><span class="line">    <span class="comment">// 谁小谁移，移动k次，k中间</span></span><br><span class="line">    <span class="keyword">var</span> n = a.length;</span><br><span class="line">    <span class="keyword">var</span> m = b.length;</span><br><span class="line">    <span class="keyword">var</span> nm = n + m;</span><br><span class="line">    <span class="keyword">var</span> ni = <span class="number">0</span>,mi = <span class="number">0</span>,x,y; </span><br><span class="line"></span><br><span class="line">    <span class="keyword">while</span>(ni + mi &lt; nm )&#123;  </span><br><span class="line">        <span class="keyword">if</span>(ni &lt; n )&#123;</span><br><span class="line">            <span class="keyword">while</span>(mi == m || a[ni] &lt;= b[mi])&#123;</span><br><span class="line">                ni=ni+<span class="number">1</span>;</span><br><span class="line">                <span class="keyword">if</span>(ni+mi == (nm+<span class="number">1</span>)/<span class="number">2</span>)&#123; <span class="comment">//总长奇</span></span><br><span class="line">                    <span class="keyword">return</span> a[ni<span class="number">-1</span>];</span><br><span class="line">                &#125;</span><br><span class="line">                <span class="keyword">if</span>(ni+mi == nm/<span class="number">2</span>)&#123;<span class="comment">//总长偶</span></span><br><span class="line">                    x = a[ni<span class="number">-1</span>];</span><br><span class="line">                    <span class="keyword">break</span>;</span><br><span class="line">                &#125;</span><br><span class="line">                <span class="keyword">if</span>(ni+mi == (nm/<span class="number">2</span> + <span class="number">1</span>))&#123; </span><br><span class="line">                    y = a[ni<span class="number">-1</span>];</span><br><span class="line">                    <span class="keyword">return</span> (x+y)/<span class="number">2</span></span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span>(mi &lt; m)&#123;</span><br><span class="line">            <span class="keyword">while</span>(ni == n || b[mi] &lt;= a[ni])&#123;</span><br><span class="line">                mi = mi + <span class="number">1</span>;</span><br><span class="line">                <span class="keyword">if</span>(ni+mi == (nm+<span class="number">1</span>)/<span class="number">2</span>)&#123;</span><br><span class="line">                    <span class="keyword">return</span> b[mi<span class="number">-1</span>];</span><br><span class="line">                &#125;</span><br><span class="line">                <span class="keyword">if</span>(ni+mi == nm/<span class="number">2</span>)&#123;</span><br><span class="line">                    x = b[mi<span class="number">-1</span>];</span><br><span class="line">                &#125;</span><br><span class="line">                <span class="keyword">if</span>(ni+mi == (nm/<span class="number">2</span> + <span class="number">1</span>))&#123; </span><br><span class="line">                    y = b[mi<span class="number">-1</span>];</span><br><span class="line">                    <span class="keyword">return</span> (x+y)/<span class="number">2</span></span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="number">-1</span>;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h5 id="5最长回文子串-24-7-中等"><a href="#5最长回文子串-24-7-中等" class="headerlink" title="5最长回文子串-24.7%-中等"></a>5最长回文子串-24.7%-中等</h5><p><a href="https://leetcode-cn.com/problems/longest-palindromic-substring/submissions/" target="_blank" rel="noopener">https://leetcode-cn.com/problems/longest-palindromic-substring/submissions/</a></p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * @param &#123;string&#125; s</span></span><br><span class="line"><span class="comment"> * @return &#123;string&#125;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">var</span> longestPalindrome = <span class="function"><span class="keyword">function</span>(<span class="params">s</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (s==<span class="literal">null</span>&amp;&amp;s.length&lt;<span class="number">1</span>)&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="string">""</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">var</span> fir = <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">var</span> las = <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">var</span> i=<span class="number">0</span>;i&lt;s.length;i++)&#123;</span><br><span class="line">        <span class="keyword">var</span> lenl = getsub(s,i,i);</span><br><span class="line">        <span class="keyword">var</span> lenr = getsub(s,i,i+<span class="number">1</span>);</span><br><span class="line">        <span class="keyword">var</span> len = <span class="built_in">Math</span>.max(lenl,lenr);</span><br><span class="line">        <span class="keyword">if</span>(len&gt;las-fir)&#123;</span><br><span class="line">            fir = i - <span class="built_in">Math</span>.floor((len<span class="number">-1</span>)/<span class="number">2</span>);</span><br><span class="line">            las = i + <span class="built_in">Math</span>.floor(len/<span class="number">2</span>);</span><br><span class="line">        &#125;     </span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> s.slice(fir,las+<span class="number">1</span>);</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">getsub</span>(<span class="params">s,l,r</span>)</span>&#123;</span><br><span class="line">    <span class="keyword">while</span>(l&gt;=<span class="number">0</span>&amp;&amp;r&lt;=s.length<span class="number">-1</span>&amp;&amp;s.charAt(l)==s.charAt(r))&#123;</span><br><span class="line">        l--;</span><br><span class="line">        r++;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> r-l<span class="number">-1</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h5 id="7整数反转-31-8-简单"><a href="#7整数反转-31-8-简单" class="headerlink" title="7整数反转-31.8%-简单"></a>7整数反转-31.8%-简单</h5><p><a href="https://leetcode-cn.com/problems/reverse-integer/" target="_blank" rel="noopener">https://leetcode-cn.com/problems/reverse-integer/</a></p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * @param &#123;number&#125; x</span></span><br><span class="line"><span class="comment"> * @return &#123;number&#125;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">var</span> reverse = <span class="function"><span class="keyword">function</span>(<span class="params">x</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">var</span> result = <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">var</span> strx;</span><br><span class="line">    <span class="keyword">var</span> mayAns;</span><br><span class="line">    <span class="keyword">if</span>(x&gt;<span class="number">0</span>)&#123;</span><br><span class="line">        strx = <span class="built_in">String</span>(x);</span><br><span class="line">        mayAns = <span class="built_in">Number</span>(strx.split(<span class="string">""</span>).reverse().join(<span class="string">""</span>));</span><br><span class="line">        <span class="keyword">return</span> mayAns&lt;=<span class="built_in">Math</span>.pow(<span class="number">2</span>,<span class="number">31</span>)<span class="number">-1</span>?mayAns:<span class="number">0</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">else</span>&#123;</span><br><span class="line">        strx = <span class="built_in">String</span>(-x);</span><br><span class="line">        mayAns = -<span class="built_in">Number</span>(strx.split(<span class="string">""</span>).reverse().join(<span class="string">""</span>));</span><br><span class="line">        <span class="keyword">return</span> mayAns&gt;=-<span class="built_in">Math</span>.pow(<span class="number">2</span>,<span class="number">31</span>) ?mayAns:<span class="number">0</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> result;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h5 id="8字符串转换整数-atoi-16-6-中等"><a href="#8字符串转换整数-atoi-16-6-中等" class="headerlink" title="8字符串转换整数 (atoi)-16.6%-中等"></a>8字符串转换整数 (atoi)-16.6%-中等</h5><p><a href="https://leetcode-cn.com/problems/median-of-two-sorted-arrays" target="_blank" rel="noopener">https://leetcode-cn.com/problems/median-of-two-sorted-arrays</a></p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * @param &#123;string&#125; str</span></span><br><span class="line"><span class="comment"> * @return &#123;number&#125;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">var</span> myAtoi = <span class="function"><span class="keyword">function</span>(<span class="params">str</span>) </span>&#123;</span><br><span class="line">    str = str.trim();</span><br><span class="line">    <span class="keyword">var</span> word = str.split(<span class="string">" "</span>)[<span class="number">0</span>];</span><br><span class="line">    <span class="keyword">if</span>(<span class="built_in">parseInt</span>(word))&#123;</span><br><span class="line">        <span class="keyword">if</span>(<span class="built_in">parseInt</span>(word)&gt;<span class="built_in">Math</span>.pow(<span class="number">2</span>,<span class="number">31</span>)<span class="number">-1</span>)&#123;</span><br><span class="line">            <span class="keyword">return</span> <span class="built_in">Math</span>.pow(<span class="number">2</span>,<span class="number">31</span>)<span class="number">-1</span>;</span><br><span class="line">        &#125;;</span><br><span class="line">        <span class="keyword">if</span>(<span class="built_in">parseInt</span>(word)&lt;-<span class="built_in">Math</span>.pow(<span class="number">2</span>,<span class="number">31</span>))&#123;</span><br><span class="line">            <span class="keyword">return</span> -<span class="built_in">Math</span>.pow(<span class="number">2</span>,<span class="number">31</span>);</span><br><span class="line">        &#125;;</span><br><span class="line">        <span class="keyword">return</span> <span class="built_in">parseInt</span>(word);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h5 id="9回文数-56-0-简单"><a href="#9回文数-56-0-简单" class="headerlink" title="9回文数-56.0%-简单"></a>9回文数-56.0%-简单</h5><p><a href="https://leetcode-cn.com/problems/palindrome-number/" target="_blank" rel="noopener">https://leetcode-cn.com/problems/palindrome-number/</a></p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * @param &#123;number&#125; x</span></span><br><span class="line"><span class="comment"> * @return &#123;boolean&#125;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">var</span> isPalindrome = <span class="function"><span class="keyword">function</span>(<span class="params">x</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">if</span>(x &gt;= <span class="number">0</span>)&#123;</span><br><span class="line">       <span class="keyword">var</span> strx = <span class="built_in">String</span>(x); </span><br><span class="line">       <span class="keyword">return</span> strx == strx.split(<span class="string">""</span>).reverse().join(<span class="string">""</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h5 id="11盛最多水的容器-53-5-中等"><a href="#11盛最多水的容器-53-5-中等" class="headerlink" title="11盛最多水的容器-53.5%-中等"></a>11盛最多水的容器-53.5%-中等</h5><p><a href="https://leetcode-cn.com/problems/container-with-most-water/" target="_blank" rel="noopener">https://leetcode-cn.com/problems/container-with-most-water/</a></p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * @param &#123;number[]&#125; height</span></span><br><span class="line"><span class="comment"> * @return &#123;number&#125;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">var</span> maxArea = <span class="function"><span class="keyword">function</span>(<span class="params">height</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">var</span> maxs = <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">var</span> i=<span class="number">0</span>;i&lt;height.length;i++)&#123;</span><br><span class="line">        <span class="keyword">for</span> (<span class="keyword">var</span> j=i+<span class="number">1</span>;j&lt;height.length;j++)&#123;</span><br><span class="line">            <span class="keyword">var</span> tmp = <span class="built_in">Math</span>.min(height[i],height[j])*(j-i);</span><br><span class="line">            <span class="keyword">if</span>(tmp&gt;maxs)&#123;</span><br><span class="line">                maxs = tmp;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> maxs;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h5 id="14最长公共前缀-32-2-简单"><a href="#14最长公共前缀-32-2-简单" class="headerlink" title="14最长公共前缀-32.2%-简单"></a>14最长公共前缀-32.2%-简单</h5><p><a href="https://leetcode-cn.com/problems/longest-common-prefix/" target="_blank" rel="noopener">https://leetcode-cn.com/problems/longest-common-prefix/</a></p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * @param &#123;string[]&#125; strs</span></span><br><span class="line"><span class="comment"> * @return &#123;string&#125;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">var</span> longestCommonPrefix = <span class="function"><span class="keyword">function</span>(<span class="params">strs</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">if</span>(strs.length == <span class="number">0</span>)&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="string">""</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">var</span> mini = <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">var</span> i=<span class="number">1</span>;i&lt;strs.length;i++)&#123;</span><br><span class="line">        <span class="keyword">if</span> (strs[i].length&lt;strs[mini].length)&#123;</span><br><span class="line">            mini = i;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">var</span> result = <span class="string">""</span>;</span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">let</span> j=<span class="number">0</span>;j&lt;strs[mini].length;j++)&#123;</span><br><span class="line">        <span class="keyword">for</span>( i=<span class="number">0</span>;i&lt;strs.length;i++)&#123;</span><br><span class="line">            <span class="keyword">if</span>(strs[mini].slice(<span class="number">0</span>,j+<span class="number">1</span>) != strs[i].slice(<span class="number">0</span>,j+<span class="number">1</span>))&#123;</span><br><span class="line">                <span class="keyword">return</span> result;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        result =  strs[mini].slice(<span class="number">0</span>,j+<span class="number">1</span>); </span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> result;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h5 id="15三数之和-21-2-中等"><a href="#15三数之和-21-2-中等" class="headerlink" title="15三数之和-21.2%-中等"></a>15三数之和-21.2%-中等</h5><p><a href="https://leetcode-cn.com/problems/3sum" target="_blank" rel="noopener">https://leetcode-cn.com/problems/3sum</a></p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * @param &#123;number[]&#125; nums</span></span><br><span class="line"><span class="comment"> * @return &#123;number[][]&#125;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">var</span> threeSum = <span class="function"><span class="keyword">function</span>(<span class="params">nums</span>) </span>&#123;</span><br><span class="line">    nums.sort(<span class="function"><span class="keyword">function</span>(<span class="params">a,b</span>)</span>&#123;<span class="keyword">return</span> a-b&#125;);</span><br><span class="line">    <span class="keyword">var</span> ls = [];</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">var</span> i=<span class="number">0</span>;i&lt;nums.length<span class="number">-2</span>;i++) &#123;</span><br><span class="line">        <span class="keyword">if</span>(nums[i]==nums[i<span class="number">-1</span>])&#123; <span class="comment">//i和前面一样，跳过</span></span><br><span class="line">            <span class="keyword">continue</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">for</span> (<span class="keyword">var</span> j=i+<span class="number">1</span>;j&lt;nums.length<span class="number">-1</span>;j++) &#123;</span><br><span class="line">            <span class="keyword">if</span>(nums[j]==nums[j<span class="number">-1</span>]&amp;&amp;j!=i+<span class="number">1</span>)&#123; <span class="comment">//j和前面一样，且前面不是i，跳过</span></span><br><span class="line">                <span class="keyword">continue</span>;</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">for</span> (<span class="keyword">var</span> k=j+<span class="number">1</span>;k&lt;nums.length;k++) &#123;</span><br><span class="line">                <span class="keyword">if</span>(nums[k]+nums[j]+nums[i] == <span class="number">0</span>)&#123;</span><br><span class="line">                    ls.push([nums[i],nums[j],nums[k]]); <span class="comment">//找到k跳出，不再往后</span></span><br><span class="line">                    <span class="keyword">break</span>;</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> ls;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h5 id="16最接近的三数之和-39-0-中等"><a href="#16最接近的三数之和-39-0-中等" class="headerlink" title="16最接近的三数之和-39.0%-中等"></a>16最接近的三数之和-39.0%-中等</h5><p><a href="https://leetcode-cn.com/problems/3sum-closest/" target="_blank" rel="noopener">https://leetcode-cn.com/problems/3sum-closest/</a></p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * @param &#123;number[]&#125; nums</span></span><br><span class="line"><span class="comment"> * @param &#123;number&#125; target</span></span><br><span class="line"><span class="comment"> * @return &#123;number&#125;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">var</span> threeSumClosest = <span class="function"><span class="keyword">function</span>(<span class="params">nums, target</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">var</span> len = nums.length;</span><br><span class="line">    <span class="keyword">var</span> minl = nums[<span class="number">0</span>]+nums[<span class="number">1</span>]+nums[<span class="number">2</span>];</span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">var</span> i=<span class="number">0</span>;i&lt;len<span class="number">-2</span>;i++)&#123;</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">var</span> j=i+<span class="number">1</span>;j&lt;len<span class="number">-1</span>;j++)&#123;</span><br><span class="line">            <span class="keyword">for</span>(<span class="keyword">var</span> k=j+<span class="number">1</span>;k&lt;len;k++)&#123;</span><br><span class="line">                <span class="keyword">var</span> tmp = nums[i]+nums[j]+nums[k];</span><br><span class="line">                <span class="keyword">if</span>(<span class="built_in">Math</span>.abs(tmp-target)&lt;<span class="built_in">Math</span>.abs(minl-target))&#123;</span><br><span class="line">                    minl = tmp;</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> minl;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h5 id="20有效的括号-36-7-简单"><a href="#20有效的括号-36-7-简单" class="headerlink" title="20有效的括号-36.7%-简单"></a>20有效的括号-36.7%-简单</h5><p><a href="https://leetcode-cn.com/problems/valid-parentheses/" target="_blank" rel="noopener">https://leetcode-cn.com/problems/valid-parentheses/</a></p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * @param &#123;string&#125; s</span></span><br><span class="line"><span class="comment"> * @return &#123;boolean&#125;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">var</span> isValid = <span class="function"><span class="keyword">function</span>(<span class="params">s</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">if</span>(s == <span class="literal">null</span>||s.length &lt;<span class="number">1</span>)&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">var</span> stack = [];</span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">var</span> i=<span class="number">0</span>;i&lt;s.length;i++)&#123;</span><br><span class="line">        <span class="keyword">if</span>(s[i] == <span class="string">""</span>)&#123;</span><br><span class="line">            <span class="keyword">continue</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span>(stack.leng&lt;<span class="number">1</span>)&#123;</span><br><span class="line">            stack.push(s[i]);</span><br><span class="line">        &#125;<span class="keyword">else</span> <span class="keyword">if</span>(stack[stack.length<span class="number">-1</span>]==<span class="string">"("</span>&amp;&amp;s[i]==<span class="string">")"</span> ||stack[stack.length<span class="number">-1</span>]==<span class="string">"&#123;"</span>&amp;&amp;s[i]==<span class="string">"&#125;"</span> ||stack[stack.length<span class="number">-1</span>]==<span class="string">"["</span>&amp;&amp;s[i]==<span class="string">"]"</span>)&#123;</span><br><span class="line">            stack.pop();</span><br><span class="line">        &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">            stack.push(s[i]);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> stack.length&lt;<span class="number">1</span>;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h5 id="21合并两个有序链表-52-9-简单"><a href="#21合并两个有序链表-52-9-简单" class="headerlink" title="21合并两个有序链表-52.9%-简单"></a>21合并两个有序链表-52.9%-简单</h5><p><a href="https://leetcode-cn.com/problems/merge-two-sorted-lists/" target="_blank" rel="noopener">https://leetcode-cn.com/problems/merge-two-sorted-lists/</a></p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Definition for singly-linked list.</span></span><br><span class="line"><span class="comment"> * function ListNode(val) &#123;</span></span><br><span class="line"><span class="comment"> *     this.val = val;</span></span><br><span class="line"><span class="comment"> *     this.next = null;</span></span><br><span class="line"><span class="comment"> * &#125;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * @param &#123;ListNode&#125; l1</span></span><br><span class="line"><span class="comment"> * @param &#123;ListNode&#125; l2</span></span><br><span class="line"><span class="comment"> * @return &#123;ListNode&#125;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">var</span> mergeTwoLists = <span class="function"><span class="keyword">function</span>(<span class="params">l1, l2</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">var</span> l3 = <span class="keyword">new</span> ListNode(<span class="number">0</span>);</span><br><span class="line">    <span class="keyword">var</span> l4 = l3;</span><br><span class="line">    <span class="keyword">while</span>(l1!=<span class="literal">null</span> &amp;&amp; l2!=<span class="literal">null</span>)&#123;</span><br><span class="line">        <span class="keyword">if</span>(l1.val&lt;l2.val)&#123;</span><br><span class="line">            l4.next = l1;</span><br><span class="line">            l1 = l1.next;</span><br><span class="line">        &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">            l4.next = l2;</span><br><span class="line">            l2 = l2.next;</span><br><span class="line">        &#125;</span><br><span class="line">        l4 = l4.next;</span><br><span class="line">    &#125;</span><br><span class="line">    l4.next = l1==<span class="literal">null</span>?l2:l1;</span><br><span class="line">    <span class="keyword">return</span> l3.next;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h5 id="23合并K个排序链表-43-8-困难"><a href="#23合并K个排序链表-43-8-困难" class="headerlink" title="23合并K个排序链表-43.8%-困难"></a>23合并K个排序链表-43.8%-困难</h5><p><a href="https://leetcode-cn.com/problems/merge-k-sorted-lists/" target="_blank" rel="noopener">https://leetcode-cn.com/problems/merge-k-sorted-lists/</a></p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Definition for singly-linked list.</span></span><br><span class="line"><span class="comment"> * function ListNode(val) &#123;</span></span><br><span class="line"><span class="comment"> *     this.val = val;</span></span><br><span class="line"><span class="comment"> *     this.next = null;</span></span><br><span class="line"><span class="comment"> * &#125;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * @param &#123;ListNode[]&#125; lists</span></span><br><span class="line"><span class="comment"> * @return &#123;ListNode&#125;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">var</span> mergeKLists = <span class="function"><span class="keyword">function</span>(<span class="params">lists</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">var</span> rl = <span class="literal">null</span>;</span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">var</span> i=<span class="number">0</span>;i&lt;lists.length;i++)&#123;</span><br><span class="line">        rl = mergeTwoLists(lists[i],rl);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> rl;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> mergeTwoLists = <span class="function"><span class="keyword">function</span>(<span class="params">l1, l2</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">var</span> l3 = <span class="keyword">new</span> ListNode(<span class="number">0</span>);</span><br><span class="line">    <span class="keyword">var</span> l4 = l3;</span><br><span class="line">    <span class="keyword">while</span>(l1!=<span class="literal">null</span> &amp;&amp; l2!=<span class="literal">null</span>)&#123;</span><br><span class="line">        <span class="keyword">if</span>(l1.val&lt;l2.val)&#123;</span><br><span class="line">            l4.next = l1;</span><br><span class="line">            l1 = l1.next;</span><br><span class="line">        &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">            l4.next = l2;</span><br><span class="line">            l2 = l2.next;</span><br><span class="line">        &#125;</span><br><span class="line">        l4 = l4.next;</span><br><span class="line">    &#125;</span><br><span class="line">    l4.next = l1==<span class="literal">null</span>?l2:l1;</span><br><span class="line">    <span class="keyword">return</span> l3.next;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h5 id="26删除排序数组中的重复项-42-9-简单"><a href="#26删除排序数组中的重复项-42-9-简单" class="headerlink" title="26删除排序数组中的重复项-42.9%-简单"></a>26删除排序数组中的重复项-42.9%-简单</h5><p><a href="https://leetcode-cn.com/problems/remove-duplicates-from-sorted-array/" target="_blank" rel="noopener">https://leetcode-cn.com/problems/remove-duplicates-from-sorted-array/</a></p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * @param &#123;number[]&#125; nums</span></span><br><span class="line"><span class="comment"> * @return &#123;number&#125;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">var</span> removeDuplicates = <span class="function"><span class="keyword">function</span>(<span class="params">nums</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">var</span> i=<span class="number">0</span>;i&lt;nums.length;i++)&#123;</span><br><span class="line">        <span class="keyword">var</span> j=<span class="number">1</span>;</span><br><span class="line">        <span class="keyword">while</span>(nums[i] == nums[i+j])&#123;</span><br><span class="line">            ++j;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span>(j!=<span class="number">1</span>)&#123;</span><br><span class="line">            nums.splice(i,j<span class="number">-1</span>);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> nums.length;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h5 id="33搜索旋转排序数组-35-8-中等"><a href="#33搜索旋转排序数组-35-8-中等" class="headerlink" title="33搜索旋转排序数组-35.8%-中等"></a>33搜索旋转排序数组-35.8%-中等</h5><p><a href="https://leetcode-cn.com/problems/search-in-rotated-sorted-array/" target="_blank" rel="noopener">https://leetcode-cn.com/problems/search-in-rotated-sorted-array/</a></p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * @param &#123;number[]&#125; nums</span></span><br><span class="line"><span class="comment"> * @param &#123;number&#125; target</span></span><br><span class="line"><span class="comment"> * @return &#123;number&#125;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">var</span> search = <span class="function"><span class="keyword">function</span>(<span class="params">nums, target</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">return</span> searchs(nums, <span class="number">0</span>, nums.length<span class="number">-1</span>, target);</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">searchs</span>(<span class="params">nums,l,h,target</span>)</span>&#123;</span><br><span class="line">    <span class="comment">//搜不到返回-1，搜到了返回target</span></span><br><span class="line">    <span class="keyword">if</span> (l &gt; h)&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="number">-1</span>;</span><br><span class="line">    &#125; </span><br><span class="line">    <span class="keyword">var</span> mid = <span class="built_in">Math</span>.floor((l + h)/<span class="number">2</span>);<span class="comment">//[0,1,2,4,5,6,7]</span></span><br><span class="line">    <span class="keyword">if</span>(nums[mid] == target)&#123;</span><br><span class="line">        <span class="keyword">return</span> mid;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span>(nums[mid] &lt; nums[h])&#123; <span class="comment">//旋转在左 [6,7,0,1,2,4,5]</span></span><br><span class="line">        <span class="keyword">if</span>(nums[mid]&lt;target&amp;&amp;target&lt;=nums[h])&#123; </span><br><span class="line">            <span class="keyword">return</span> searchs(nums,mid+<span class="number">1</span>,h,target);<span class="comment">//在右，右顺序</span></span><br><span class="line">        &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">            <span class="keyword">return</span> searchs(nums,l,mid<span class="number">-1</span>,target);<span class="comment">//不在右</span></span><br><span class="line">        &#125;</span><br><span class="line">    &#125;<span class="keyword">else</span>&#123; <span class="comment">//旋转在右 [2,4,5,6,7,0,1]</span></span><br><span class="line">        <span class="keyword">if</span>(nums[l]&lt;=target&amp;&amp;target&lt;nums[mid])&#123; </span><br><span class="line">            <span class="keyword">return</span> searchs(nums,l,mid<span class="number">-1</span>,target);<span class="comment">//在左，左顺序</span></span><br><span class="line">        &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">            <span class="keyword">return</span> searchs(nums,mid+<span class="number">1</span>,h,target);<span class="comment">//不在右</span></span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h5 id="43字符串相乘-37-9-中等"><a href="#43字符串相乘-37-9-中等" class="headerlink" title="43字符串相乘-37.9%-中等"></a>43字符串相乘-37.9%-中等</h5><p><a href="https://leetcode-cn.com/problems/multiply-strings/" target="_blank" rel="noopener">https://leetcode-cn.com/problems/multiply-strings/</a></p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * @param &#123;string&#125; num1</span></span><br><span class="line"><span class="comment"> * @param &#123;string&#125; num2</span></span><br><span class="line"><span class="comment"> * @return &#123;string&#125;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">var</span> multiply = <span class="function"><span class="keyword">function</span>(<span class="params">num1, num2</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">var</span> res = <span class="string">""</span>;</span><br><span class="line">    <span class="keyword">var</span> len1 = num1.length;</span><br><span class="line">    <span class="keyword">var</span> len2 = num2.length;</span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">var</span> i=<span class="number">0</span>;i&lt;len1;i++)&#123;</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">var</span> j=<span class="number">0</span>;j&lt;len2;j++)&#123;</span><br><span class="line">            <span class="keyword">var</span> base = <span class="built_in">Array</span>(i+j+<span class="number">1</span>).join(<span class="number">0</span>);<span class="comment">//i+j个0  eg:"00"  //逐位相乘</span></span><br><span class="line">            <span class="keyword">var</span> tmp = <span class="built_in">String</span>(<span class="built_in">Number</span>(num1[len1<span class="number">-1</span>-i])*<span class="built_in">Number</span>(num2[len2<span class="number">-1</span>-j])) + base;</span><br><span class="line">            res = addstr(res,tmp);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">while</span>(res[<span class="number">0</span>] == <span class="number">0</span> &amp;&amp; res.length &gt; <span class="number">1</span>)&#123;<span class="comment">//"002" -&gt; "2"</span></span><br><span class="line">        res = res.slice(<span class="number">1</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">addstr</span>(<span class="params">s1, s2</span>) </span>&#123; <span class="comment">//字符串相加</span></span><br><span class="line">    <span class="keyword">var</span> re = <span class="string">""</span>;</span><br><span class="line">    <span class="keyword">if</span>(s1.length&gt;=s2.length)&#123;</span><br><span class="line">        s2 =  <span class="built_in">Array</span>(s1.length-s2.length+<span class="number">1</span>).join(<span class="number">0</span>) + s2;</span><br><span class="line">    &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">        s1 = <span class="built_in">Array</span>(s2.length-s1.length+<span class="number">1</span>).join(<span class="number">0</span>) + s1;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">var</span> flag = <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">let</span> i=<span class="number">0</span>;i&lt;s1.length;i++)&#123;</span><br><span class="line">        <span class="keyword">var</span> t = <span class="built_in">Number</span>(s1[s1.length - <span class="number">1</span> - i]) + <span class="built_in">Number</span>(s2[s1.length - <span class="number">1</span> - i]) + flag;</span><br><span class="line">        <span class="keyword">if</span>(t &lt; <span class="number">10</span>)&#123;</span><br><span class="line">            re = <span class="built_in">String</span>(t).concat(re);</span><br><span class="line">            flag = <span class="number">0</span>;</span><br><span class="line">        &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">            re = <span class="built_in">String</span>(t<span class="number">-10</span>).concat(re);</span><br><span class="line">            flag = <span class="number">1</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> flag == <span class="number">0</span>? re:<span class="string">"1"</span>+re;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h5 id="46全排列-66-7-中等"><a href="#46全排列-66-7-中等" class="headerlink" title="46全排列-66.7%-中等"></a>46全排列-66.7%-中等</h5><p><a href="https://leetcode-cn.com/problems/permutations/" target="_blank" rel="noopener">https://leetcode-cn.com/problems/permutations/</a></p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * @param &#123;number[]&#125; nums</span></span><br><span class="line"><span class="comment"> * @return &#123;number[][]&#125;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">var</span> permute = <span class="function"><span class="keyword">function</span>(<span class="params">nums</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">if</span>(nums.length == <span class="number">0</span>)&#123;</span><br><span class="line">        <span class="keyword">return</span> [[]];</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span>(nums.length == <span class="number">1</span>)&#123;</span><br><span class="line">        <span class="keyword">var</span> re = [];</span><br><span class="line">        re.push(nums);</span><br><span class="line">        <span class="keyword">return</span> re;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">var</span> nums1 = permute(nums.slice(<span class="number">1</span>));</span><br><span class="line">    <span class="keyword">var</span> num0 = nums[<span class="number">0</span>];</span><br><span class="line">    <span class="keyword">var</span> result = [];</span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">var</span> i=<span class="number">0</span>;i&lt;nums1.length;i++)&#123;</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">var</span> j=<span class="number">0</span>;j&lt;nums1[i].length+<span class="number">1</span>;j++)&#123;</span><br><span class="line">            <span class="keyword">var</span> tmp = nums1[i].concat();</span><br><span class="line">            tmp.splice(j,<span class="number">0</span>,num0);</span><br><span class="line">            result.push(tmp);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> result;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h5 id="53最大子序和-42-9-简单"><a href="#53最大子序和-42-9-简单" class="headerlink" title="53最大子序和-42.9%-简单"></a>53最大子序和-42.9%-简单</h5><p><a href="https://leetcode-cn.com/problems/maximum-subarray/" target="_blank" rel="noopener">https://leetcode-cn.com/problems/maximum-subarray/</a></p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * @param &#123;number[]&#125; nums</span></span><br><span class="line"><span class="comment"> * @return &#123;number&#125;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">var</span> maxSubArray = <span class="function"><span class="keyword">function</span>(<span class="params">nums</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">var</span> sum = <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">var</span> maxsum = nums[<span class="number">0</span>];</span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">var</span> i=<span class="number">0</span>;i&lt;nums.length;i++)&#123;</span><br><span class="line">        sum +=nums[i];</span><br><span class="line">        <span class="keyword">if</span>(sum &gt; maxsum)&#123;</span><br><span class="line">            maxsum = sum;</span><br><span class="line">        &#125; </span><br><span class="line">        <span class="keyword">if</span>(sum &lt; <span class="number">0</span>)&#123;</span><br><span class="line">            sum = <span class="number">0</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> maxsum;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h5 id="54螺旋矩阵-34-0-中等"><a href="#54螺旋矩阵-34-0-中等" class="headerlink" title="54螺旋矩阵-34.0%-中等"></a>54螺旋矩阵-34.0%-中等</h5><p><a href="https://leetcode-cn.com/problems/spiral-matrix/" target="_blank" rel="noopener">https://leetcode-cn.com/problems/spiral-matrix/</a></p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * @param &#123;number[][]&#125; matrix</span></span><br><span class="line"><span class="comment"> * @return &#123;number[]&#125;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">var</span> spiralOrder = <span class="function"><span class="keyword">function</span>(<span class="params">matrix</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">var</span> arr = [];</span><br><span class="line">    <span class="keyword">while</span>(!(matrix.length == <span class="number">0</span>||matrix[<span class="number">0</span>].length == <span class="number">0</span>))&#123;</span><br><span class="line">        <span class="keyword">var</span> tmp = matrix.shift(); <span class="comment">//剪第一行</span></span><br><span class="line">        arr = arr.concat(tmp);</span><br><span class="line">        <span class="keyword">if</span>(matrix.length == <span class="number">0</span>||matrix[<span class="number">0</span>].length == <span class="number">0</span>)&#123; <span class="comment">//[]   [[],[]]</span></span><br><span class="line">            <span class="keyword">return</span> arr;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">var</span> i=<span class="number">0</span>;i&lt;matrix.length;i++)&#123;<span class="comment">//剪最后一列</span></span><br><span class="line">            <span class="keyword">var</span> tmp = matrix[i].pop();</span><br><span class="line">            arr.push(tmp);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span>(matrix.length == <span class="number">0</span>||matrix[<span class="number">0</span>].length == <span class="number">0</span>)&#123;</span><br><span class="line">            <span class="keyword">return</span> arr;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">var</span> tmp = matrix.pop().reverse();<span class="comment">//剪最后一行</span></span><br><span class="line">        arr = arr.concat(tmp);</span><br><span class="line">        <span class="keyword">if</span>(matrix.length == <span class="number">0</span>||matrix[<span class="number">0</span>].length == <span class="number">0</span>)&#123;</span><br><span class="line">            <span class="keyword">return</span> arr;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">var</span> i=<span class="number">0</span>;i&lt;matrix.length;i++)&#123;<span class="comment">//剪第一列</span></span><br><span class="line">            <span class="keyword">var</span> tmp = matrix[matrix.length<span class="number">-1</span>-i].shift();</span><br><span class="line">            arr.push(tmp);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> arr;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h5 id="59螺旋矩阵II-71-1-中等"><a href="#59螺旋矩阵II-71-1-中等" class="headerlink" title="59螺旋矩阵II-71.1%-中等"></a>59螺旋矩阵II-71.1%-中等</h5><p><a href="https://leetcode-cn.com/problems/spiral-matrix-ii/" target="_blank" rel="noopener">https://leetcode-cn.com/problems/spiral-matrix-ii/</a></p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * @param &#123;number&#125; n</span></span><br><span class="line"><span class="comment"> * @return &#123;number[][]&#125;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">var</span> generateMatrix = <span class="function"><span class="keyword">function</span>(<span class="params">n</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">var</span> arr = [];</span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">var</span> i = <span class="number">0</span>; i &lt; n; i++) &#123;</span><br><span class="line">        arr.push(<span class="keyword">new</span> <span class="built_in">Array</span>(n).fill(<span class="number">0</span>));<span class="comment">//创建n*n零矩阵</span></span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">var</span> c = <span class="number">1</span>;</span><br><span class="line">    <span class="keyword">var</span> i = <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">while</span>(c &lt;= n*n)&#123;</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">var</span> j=i;j&lt;n-i;j++)&#123;<span class="comment">//第一行</span></span><br><span class="line">            arr[i][j] = c++;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">var</span> j=i+<span class="number">1</span>;j&lt;n-i;j++)&#123;<span class="comment">//最后一列</span></span><br><span class="line">            arr[j][n-i<span class="number">-1</span>] = c++;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">var</span> j=i+<span class="number">1</span>;j&lt;n-i;j++)&#123;<span class="comment">//最后一行</span></span><br><span class="line">            arr[n-i<span class="number">-1</span>][n-j<span class="number">-1</span>] = c++;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">var</span> j=i+<span class="number">1</span>;j&lt;n-i<span class="number">-1</span>;j++)&#123;<span class="comment">//第一列</span></span><br><span class="line">            arr[n-j<span class="number">-1</span>][i] = c++;</span><br><span class="line">        &#125;</span><br><span class="line">        i++;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> arr;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h5 id="61旋转链表-37-5-中等"><a href="#61旋转链表-37-5-中等" class="headerlink" title="61旋转链表-37.5%-中等"></a>61旋转链表-37.5%-中等</h5><p><a href="https://leetcode-cn.com/problems/rotate-list/" target="_blank" rel="noopener">https://leetcode-cn.com/problems/rotate-list/</a></p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Definition for singly-linked list.</span></span><br><span class="line"><span class="comment"> * function ListNode(val) &#123;</span></span><br><span class="line"><span class="comment"> *     this.val = val;</span></span><br><span class="line"><span class="comment"> *     this.next = null;</span></span><br><span class="line"><span class="comment"> * &#125;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * @param &#123;ListNode&#125; head</span></span><br><span class="line"><span class="comment"> * @param &#123;number&#125; k</span></span><br><span class="line"><span class="comment"> * @return &#123;ListNode&#125;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">var</span> rotateRight = <span class="function"><span class="keyword">function</span>(<span class="params">head, k</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">if</span>(head == <span class="literal">null</span>||k==<span class="number">0</span>)&#123;</span><br><span class="line">        <span class="keyword">return</span> head;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">var</span> h = head;</span><br><span class="line">    <span class="keyword">var</span> len = <span class="number">1</span>;<span class="comment">//总长</span></span><br><span class="line">    <span class="keyword">while</span>(h.next !=<span class="literal">null</span> )&#123;</span><br><span class="line">        ++len;</span><br><span class="line">        h = h.next;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span>(k % len == <span class="number">0</span>)&#123;<span class="comment">//不用旋转 head本身</span></span><br><span class="line">        <span class="keyword">return</span> head;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span>(k &gt; len)&#123;<span class="comment">//需旋转</span></span><br><span class="line">        k = k % len;</span><br><span class="line">    &#125;</span><br><span class="line">    len = len - k;</span><br><span class="line">    <span class="keyword">var</span> ln = <span class="keyword">new</span> ListNode(<span class="number">0</span>);<span class="comment">//0-&gt;1-&gt;2-&gt;3-&gt;NULL</span></span><br><span class="line">    <span class="keyword">var</span> n = ln; </span><br><span class="line">    <span class="keyword">while</span>(len != <span class="number">0</span>)&#123;</span><br><span class="line">        n.next = head;</span><br><span class="line">        n = n.next;</span><br><span class="line">        head = head.next;</span><br><span class="line">        --len;</span><br><span class="line">    &#125;</span><br><span class="line">    n.next = <span class="literal">null</span>;</span><br><span class="line">    <span class="keyword">var</span> r = head;</span><br><span class="line">    <span class="keyword">var</span> lr = r;</span><br><span class="line">    <span class="keyword">while</span>(head.next != <span class="literal">null</span>)&#123;</span><br><span class="line">        lr = head;</span><br><span class="line">        head = head.next;</span><br><span class="line">        lr = lr.next;</span><br><span class="line">    &#125;</span><br><span class="line">    lr.next = ln.next</span><br><span class="line">    <span class="keyword">return</span> r;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h5 id="62不同路径-52-6-中等"><a href="#62不同路径-52-6-中等" class="headerlink" title="62不同路径-52.6%-中等"></a>62不同路径-52.6%-中等</h5><p><a href="https://leetcode-cn.com/problems/unique-paths/" target="_blank" rel="noopener">https://leetcode-cn.com/problems/unique-paths/</a></p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * @param &#123;number&#125; m</span></span><br><span class="line"><span class="comment"> * @param &#123;number&#125; n</span></span><br><span class="line"><span class="comment"> * @return &#123;number&#125;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">var</span> uniquePaths = <span class="function"><span class="keyword">function</span>(<span class="params">m, n</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">var</span> dp = [];</span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">var</span> i=<span class="number">0</span>;i&lt;m;i++)&#123; <span class="comment">//创建m*n零矩阵</span></span><br><span class="line">        dp.push(<span class="keyword">new</span> <span class="built_in">Array</span>(n).fill(<span class="number">0</span>));</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">var</span> i=<span class="number">0</span>;i&lt;m;i++)&#123;</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">var</span> j=<span class="number">0</span>;j&lt;n;j++)&#123;</span><br><span class="line">            <span class="keyword">if</span>(i==<span class="number">0</span>||j==<span class="number">0</span>)&#123;</span><br><span class="line">                dp[i][j] = <span class="number">1</span>;</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">else</span>&#123;</span><br><span class="line">                dp[i][j] = dp[i<span class="number">-1</span>][j]+dp[i][j<span class="number">-1</span>]</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> dp[m<span class="number">-1</span>][n<span class="number">-1</span>];</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h5 id="70爬楼梯-44-5-简单"><a href="#70爬楼梯-44-5-简单" class="headerlink" title="70爬楼梯-44.5%-简单"></a>70爬楼梯-44.5%-简单</h5><p><a href="https://leetcode-cn.com/problems/climbing-stairs/" target="_blank" rel="noopener">https://leetcode-cn.com/problems/climbing-stairs/</a></p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * @param &#123;number&#125; n</span></span><br><span class="line"><span class="comment"> * @return &#123;number&#125;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">var</span> climbStairs = <span class="function"><span class="keyword">function</span>(<span class="params">n</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">if</span>(n==<span class="number">1</span>)&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="number">1</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span>(n==<span class="number">2</span>)&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="number">2</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">var</span> i = <span class="number">1</span>;</span><br><span class="line">    <span class="keyword">var</span> j = <span class="number">2</span>;</span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">var</span> k=<span class="number">0</span>;k&lt;n<span class="number">-2</span>;k++)&#123;</span><br><span class="line">        <span class="keyword">var</span> tmp = i + j;</span><br><span class="line">        i = j;</span><br><span class="line">        j = tmp;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> j;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h5 id="78子集-71-6-中等"><a href="#78子集-71-6-中等" class="headerlink" title="78子集-71.6%-中等"></a>78子集-71.6%-中等</h5><p><a href="https://leetcode-cn.com/problems/subsets/" target="_blank" rel="noopener">https://leetcode-cn.com/problems/subsets/</a></p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * @param &#123;number[]&#125; nums</span></span><br><span class="line"><span class="comment"> * @return &#123;number[][]&#125;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">var</span> subsets = <span class="function"><span class="keyword">function</span>(<span class="params">nums</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">var</span> arr = [];</span><br><span class="line">    arr.push([]);</span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">var</span> i=<span class="number">0</span>;i&lt;nums.length;i++)&#123;</span><br><span class="line">        <span class="keyword">var</span> tmp = []; <span class="comment">//tmp深拷贝arr</span></span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">var</span> k=<span class="number">0</span>;k&lt;arr.length;k++)&#123;</span><br><span class="line">            tmp[k] = arr[k].slice(<span class="number">0</span>);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">var</span> j=<span class="number">0</span>;j&lt;tmp.length;j++)&#123;</span><br><span class="line">            tmp[j].push(nums[i]);</span><br><span class="line">            arr.push(tmp[j]);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> arr;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h5 id="88合并两个有序数组-43-0-简单"><a href="#88合并两个有序数组-43-0-简单" class="headerlink" title="88合并两个有序数组-43.0%-简单"></a>88合并两个有序数组-43.0%-简单</h5><p><a href="https://leetcode-cn.com/problems/merge-two-sorted-lists/" target="_blank" rel="noopener">https://leetcode-cn.com/problems/merge-two-sorted-lists/</a></p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Definition for singly-linked list.</span></span><br><span class="line"><span class="comment"> * function ListNode(val) &#123;</span></span><br><span class="line"><span class="comment"> *     this.val = val;</span></span><br><span class="line"><span class="comment"> *     this.next = null;</span></span><br><span class="line"><span class="comment"> * &#125;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * @param &#123;ListNode&#125; l1</span></span><br><span class="line"><span class="comment"> * @param &#123;ListNode&#125; l2</span></span><br><span class="line"><span class="comment"> * @return &#123;ListNode&#125;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">var</span> mergeTwoLists = <span class="function"><span class="keyword">function</span>(<span class="params">l1, l2</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">var</span> l3 = <span class="keyword">new</span> ListNode(<span class="number">0</span>);</span><br><span class="line">    <span class="keyword">var</span> l4 = l3;</span><br><span class="line">    <span class="keyword">while</span>(l1!=<span class="literal">null</span> &amp;&amp; l2!=<span class="literal">null</span>)&#123;</span><br><span class="line">        <span class="keyword">if</span>(l1.val&lt;l2.val)&#123;</span><br><span class="line">            l4.next = l1;</span><br><span class="line">            l1 = l1.next;</span><br><span class="line">        &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">            l4.next = l2;</span><br><span class="line">            l2 = l2.next;</span><br><span class="line">        &#125;</span><br><span class="line">        l4 = l4.next;</span><br><span class="line">    &#125;</span><br><span class="line">    l4.next = l1==<span class="literal">null</span>?l2:l1;</span><br><span class="line">    <span class="keyword">return</span> l3.next;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h5 id="89格雷编码-62-7-中等"><a href="#89格雷编码-62-7-中等" class="headerlink" title="89格雷编码-62.7%-中等"></a>89格雷编码-62.7%-中等</h5><p><a href="https://leetcode-cn.com/problems/gray-code/" target="_blank" rel="noopener">https://leetcode-cn.com/problems/gray-code/</a></p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * @param &#123;number&#125; n</span></span><br><span class="line"><span class="comment"> * @return &#123;number[]&#125;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="comment">// 000 001 011 010  ——</span></span><br><span class="line"><span class="comment">//                    |</span></span><br><span class="line"><span class="comment">// 100 101 111 110 &lt;——</span></span><br><span class="line"><span class="keyword">var</span> grayCode = <span class="function"><span class="keyword">function</span>(<span class="params">n</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">if</span>(n == <span class="number">0</span>)&#123;</span><br><span class="line">        <span class="keyword">return</span> [<span class="number">0</span>];</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">var</span> tmp = grayCode(n<span class="number">-1</span>).concat();<span class="comment">//深拷贝</span></span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">var</span> i=<span class="number">0</span>;i&lt;tmp.length;i++)&#123;</span><br><span class="line">        tmp[i] += <span class="built_in">Math</span>.pow(<span class="number">2</span>,n<span class="number">-1</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    tmp.reverse();</span><br><span class="line">    <span class="keyword">return</span> grayCode(n<span class="number">-1</span>).concat(tmp);</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h5 id="104二叉树的最大深度-67-4-简单"><a href="#104二叉树的最大深度-67-4-简单" class="headerlink" title="104二叉树的最大深度-67.4%-简单"></a>104二叉树的最大深度-67.4%-简单</h5><p><a href="https://leetcode-cn.com/problems/maximum-depth-of-binary-tree/" target="_blank" rel="noopener">https://leetcode-cn.com/problems/maximum-depth-of-binary-tree/</a></p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Definition for a binary tree node.</span></span><br><span class="line"><span class="comment"> * function TreeNode(val) &#123;</span></span><br><span class="line"><span class="comment"> *     this.val = val;</span></span><br><span class="line"><span class="comment"> *     this.left = this.right = null;</span></span><br><span class="line"><span class="comment"> * &#125;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * @param &#123;TreeNode&#125; root</span></span><br><span class="line"><span class="comment"> * @return &#123;number&#125;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> maxDepth = <span class="function"><span class="keyword">function</span>(<span class="params">root</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">if</span>(root == <span class="literal">null</span>)&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">var</span> l_height = maxDepth(root.left);</span><br><span class="line">    <span class="keyword">var</span> r_height = maxDepth(root.right);</span><br><span class="line">    <span class="keyword">return</span> <span class="built_in">Math</span>.max(l_height,r_height) + <span class="number">1</span>;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h5 id="121买卖股票的最佳时机-48-5-简单"><a href="#121买卖股票的最佳时机-48-5-简单" class="headerlink" title="121买卖股票的最佳时机-48.5%-简单"></a>121买卖股票的最佳时机-48.5%-简单</h5><p><a href="https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock/" target="_blank" rel="noopener">https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock/</a></p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * @param &#123;number[]&#125; prices</span></span><br><span class="line"><span class="comment"> * @return &#123;number&#125;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">var</span> maxProfit = <span class="function"><span class="keyword">function</span>(<span class="params">prices</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">var</span> maxtmp = <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">var</span> i=<span class="number">0</span>;i&lt;prices.length;i++)&#123;  </span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">var</span> j=i+<span class="number">1</span>;j&lt;prices.length;j++)&#123; </span><br><span class="line">            <span class="keyword">if</span>(prices[j]-prices[i]&gt;maxtmp)&#123;</span><br><span class="line">                maxtmp = prices[j]-prices[i];</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;   </span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> maxtmp;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h5 id="122买卖股票的最佳时机II-51-6-简单"><a href="#122买卖股票的最佳时机II-51-6-简单" class="headerlink" title="122买卖股票的最佳时机II-51.6%-简单"></a>122买卖股票的最佳时机II-51.6%-简单</h5><p><a href="https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-ii/" target="_blank" rel="noopener">https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-ii/</a></p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * @param &#123;number[]&#125; prices</span></span><br><span class="line"><span class="comment"> * @return &#123;number&#125;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">var</span> maxProfit = <span class="function"><span class="keyword">function</span>(<span class="params">prices</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">var</span> maxtmp = <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">var</span> i=<span class="number">0</span>;i&lt;prices.length<span class="number">-1</span>;i++)&#123;  </span><br><span class="line">        <span class="keyword">if</span> (prices[i]&lt;prices[i+<span class="number">1</span>])&#123;</span><br><span class="line">            maxtmp += prices[i+<span class="number">1</span>]-prices[i];</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> maxtmp;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h5 id="124二叉树中的最大路径和-33-8-困难"><a href="#124二叉树中的最大路径和-33-8-困难" class="headerlink" title="124二叉树中的最大路径和-33.8%-困难"></a>124二叉树中的最大路径和-33.8%-困难</h5><p><a href="https://leetcode-cn.com/problems/binary-tree-maximum-path-sum/" target="_blank" rel="noopener">https://leetcode-cn.com/problems/binary-tree-maximum-path-sum/</a></p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Definition for a binary tree node.</span></span><br><span class="line"><span class="comment"> * function TreeNode(val) &#123;</span></span><br><span class="line"><span class="comment"> *     this.val = val;</span></span><br><span class="line"><span class="comment"> *     this.left = this.right = null;</span></span><br><span class="line"><span class="comment"> * &#125;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * @param &#123;TreeNode&#125; root</span></span><br><span class="line"><span class="comment"> * @return &#123;number&#125;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">var</span> maxPathSum = <span class="function"><span class="keyword">function</span>(<span class="params">root</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">var</span> len = -<span class="built_in">Number</span>.MAX_VALUE;</span><br><span class="line">    submax(root);</span><br><span class="line">    <span class="function"><span class="keyword">function</span> <span class="title">submax</span>(<span class="params">t</span>)</span>&#123;</span><br><span class="line">        <span class="keyword">if</span>(t == <span class="literal">null</span>)&#123;</span><br><span class="line">            <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">var</span> l = <span class="built_in">Math</span>.max(submax(t.left),<span class="number">0</span>);</span><br><span class="line">        <span class="keyword">var</span> r = <span class="built_in">Math</span>.max(submax(t.right),<span class="number">0</span>);</span><br><span class="line">        <span class="keyword">if</span>(t.val + l + r &gt; len)&#123;</span><br><span class="line">            len = t.val + l + r;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> <span class="built_in">Math</span>.max(l,r) + t.val;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> len;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h5 id="136只出现一次的数字-59-1-简单"><a href="#136只出现一次的数字-59-1-简单" class="headerlink" title="136只出现一次的数字-59.1%-简单"></a>136只出现一次的数字-59.1%-简单</h5><p><a href="https://leetcode-cn.com/problems/single-number/" target="_blank" rel="noopener">https://leetcode-cn.com/problems/single-number/</a></p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * @param &#123;number[]&#125; nums</span></span><br><span class="line"><span class="comment"> * @return &#123;number&#125;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">var</span> singleNumber = <span class="function"><span class="keyword">function</span>(<span class="params">nums</span>) </span>&#123;</span><br><span class="line">    <span class="comment">// 交换律：a ^ b ^ c  &lt;=&gt; a ^ c ^ b,俩两相同的移到一起</span></span><br><span class="line">    <span class="comment">// 相同的数异或为0: n ^ n =&gt; 0,只剩下单个的了</span></span><br><span class="line">    <span class="comment">// 任何数于0异或为任何数 0 ^ n =&gt; n</span></span><br><span class="line">    <span class="keyword">var</span> s = <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">var</span> i=<span class="number">0</span>;i&lt;nums.length;i++)&#123;</span><br><span class="line">        s = s^nums[i];</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> s;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h5 id="141环形链表-35-5-简单"><a href="#141环形链表-35-5-简单" class="headerlink" title="141环形链表-35.5%-简单"></a>141环形链表-35.5%-简单</h5><p><a href="https://leetcode-cn.com/problems/linked-list-cycle" target="_blank" rel="noopener">https://leetcode-cn.com/problems/linked-list-cycle</a></p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Definition for singly-linked list.</span></span><br><span class="line"><span class="comment"> * function ListNode(val) &#123;</span></span><br><span class="line"><span class="comment"> *     this.val = val;</span></span><br><span class="line"><span class="comment"> *     this.next = null;</span></span><br><span class="line"><span class="comment"> * &#125;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"> </span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * @param &#123;ListNode&#125; head</span></span><br><span class="line"><span class="comment"> * @return &#123;boolean&#125;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">var</span> hasCycle = <span class="function"><span class="keyword">function</span>(<span class="params">head</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">var</span> slow = head, fast = head;</span><br><span class="line">    <span class="keyword">while</span>(fast &amp;&amp; fast.next)&#123;</span><br><span class="line">        slow = slow.next;</span><br><span class="line">        fast = fast.next.next;</span><br><span class="line">        <span class="keyword">if</span>(slow == fast)&#123;</span><br><span class="line">            <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h5 id="142环形链表II-34-8-中等"><a href="#142环形链表II-34-8-中等" class="headerlink" title="142环形链表II-34.8%-中等"></a>142环形链表II-34.8%-中等</h5><p><a href="https://leetcode-cn.com/problems/linked-list-cycle-ii/" target="_blank" rel="noopener">https://leetcode-cn.com/problems/linked-list-cycle-ii/</a></p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Definition for singly-linked list.</span></span><br><span class="line"><span class="comment"> * function ListNode(val) &#123;</span></span><br><span class="line"><span class="comment"> *     this.val = val;</span></span><br><span class="line"><span class="comment"> *     this.next = null;</span></span><br><span class="line"><span class="comment"> * &#125;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * @param &#123;ListNode&#125; head</span></span><br><span class="line"><span class="comment"> * @return &#123;ListNode&#125;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">var</span> detectCycle = <span class="function"><span class="keyword">function</span>(<span class="params">head</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">var</span> slow = head,fast = head;</span><br><span class="line">    <span class="keyword">var</span> isloop = <span class="literal">false</span>;</span><br><span class="line">    <span class="keyword">while</span>(fast &amp;&amp; fast.next)&#123;</span><br><span class="line">        slow  = slow.next;</span><br><span class="line">        fast = fast.next.next;</span><br><span class="line">        <span class="keyword">if</span>(slow == fast)&#123;<span class="comment">//相遇</span></span><br><span class="line">            isloop = <span class="literal">true</span>;</span><br><span class="line">            <span class="keyword">break</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span>(isloop)&#123;</span><br><span class="line">        <span class="keyword">var</span> l  = head;</span><br><span class="line">        <span class="keyword">while</span>(l != slow)&#123;</span><br><span class="line">            l = l.next;</span><br><span class="line">            slow = slow.next;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> slow;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="literal">null</span>;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h5 id="146LRU缓存机制-39-0-困难"><a href="#146LRU缓存机制-39-0-困难" class="headerlink" title="146LRU缓存机制-39.0%-困难"></a>146LRU缓存机制-39.0%-困难</h5><p><a href="https://leetcode-cn.com/problems/lru-cache/" target="_blank" rel="noopener">https://leetcode-cn.com/problems/lru-cache/</a></p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * @param &#123;number&#125; capacity</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment">1.新加入的数据</span></span><br><span class="line"><span class="comment">            ————&gt; ___ 头 &lt;—————</span></span><br><span class="line"><span class="comment">                  ___          |</span></span><br><span class="line"><span class="comment">                  ___          |2.被访问的数据</span></span><br><span class="line"><span class="comment">                  ___     —————</span></span><br><span class="line"><span class="comment">                  ___</span></span><br><span class="line"><span class="comment">                  ___</span></span><br><span class="line"><span class="comment">            &lt;———— ___ 尾</span></span><br><span class="line"><span class="comment">3.淘汰的数据</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> LRUCache = <span class="function"><span class="keyword">function</span>(<span class="params">capacity</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">this</span>.size = capacity;</span><br><span class="line">    <span class="keyword">this</span>.map = &#123;&#125;;</span><br><span class="line">    <span class="keyword">this</span>.list = []; </span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">/** </span></span><br><span class="line"><span class="comment"> * @param &#123;number&#125; key</span></span><br><span class="line"><span class="comment"> * @return &#123;number&#125;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line">LRUCache.prototype.get = <span class="function"><span class="keyword">function</span>(<span class="params">key</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">if</span>(<span class="keyword">this</span>.map[key] != <span class="literal">null</span>)&#123;</span><br><span class="line">        <span class="keyword">this</span>.list.splice(<span class="keyword">this</span>.list.indexOf(key),<span class="number">1</span>);<span class="comment">//更新list</span></span><br><span class="line">        <span class="keyword">this</span>.list.unshift(key);</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">this</span>.map[key];</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="number">-1</span>;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">/** </span></span><br><span class="line"><span class="comment"> * @param &#123;number&#125; key </span></span><br><span class="line"><span class="comment"> * @param &#123;number&#125; value</span></span><br><span class="line"><span class="comment"> * @return &#123;void&#125;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line">LRUCache.prototype.put = <span class="function"><span class="keyword">function</span>(<span class="params">key, value</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">var</span> tmp = <span class="keyword">this</span>.list.indexOf(key);</span><br><span class="line">    <span class="keyword">if</span>(tmp != <span class="number">-1</span>)&#123; <span class="comment">//key已存在，更新list</span></span><br><span class="line">        <span class="keyword">this</span>.list.splice(tmp,<span class="number">1</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">else</span>&#123; <span class="comment">//key不存在</span></span><br><span class="line">        <span class="keyword">if</span>(<span class="keyword">this</span>.list.length == <span class="keyword">this</span>.size)&#123; <span class="comment">//栈满</span></span><br><span class="line">            <span class="keyword">var</span> d = <span class="keyword">this</span>.list.pop();</span><br><span class="line">            <span class="keyword">this</span>.map[d] = <span class="literal">null</span>;</span><br><span class="line">        &#125;   </span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">this</span>.list.unshift(key);</span><br><span class="line">    <span class="keyword">this</span>.map[key] = value;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">/** </span></span><br><span class="line"><span class="comment"> * Your LRUCache object will be instantiated and called as such:</span></span><br><span class="line"><span class="comment"> * var obj = Object.create(LRUCache).createNew(capacity)</span></span><br><span class="line"><span class="comment"> * var param_1 = obj.get(key)</span></span><br><span class="line"><span class="comment"> * obj.put(key,value)</span></span><br><span class="line"><span class="comment"> */</span></span><br></pre></td></tr></table></figure><h5 id="148排序链表-58-6-中等"><a href="#148排序链表-58-6-中等" class="headerlink" title="148排序链表-58.6%-中等"></a>148排序链表-58.6%-中等</h5><p><a href="https://leetcode-cn.com/problems/sort-list/" target="_blank" rel="noopener">https://leetcode-cn.com/problems/sort-list/</a></p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Definition for singly-linked list.</span></span><br><span class="line"><span class="comment"> * function ListNode(val) &#123;</span></span><br><span class="line"><span class="comment"> *     this.val = val;</span></span><br><span class="line"><span class="comment"> *     this.next = null;</span></span><br><span class="line"><span class="comment"> * &#125;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * @param &#123;ListNode&#125; head</span></span><br><span class="line"><span class="comment"> * @return &#123;ListNode&#125;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">var</span> sortList = <span class="function"><span class="keyword">function</span>(<span class="params">head</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (!head || !head.next)&#123;</span><br><span class="line">        <span class="keyword">return</span> head;</span><br><span class="line">    &#125; </span><br><span class="line">    <span class="keyword">var</span> slow = head,bk = head,fast = head;</span><br><span class="line">    <span class="keyword">while</span>(fast &amp;&amp; fast.next )&#123;</span><br><span class="line">        bk = slow;</span><br><span class="line">        slow = slow.next;</span><br><span class="line">        fast = fast.next.next;</span><br><span class="line">    &#125;</span><br><span class="line">    bk.next = <span class="literal">null</span>;</span><br><span class="line">    <span class="keyword">var</span> l1 = sortList(head);<span class="comment">//中分，归并</span></span><br><span class="line">    <span class="keyword">var</span> l2 = sortList(slow);</span><br><span class="line">    <span class="keyword">return</span> merge(l1,l2);</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">merge</span>(<span class="params">l1,l2</span>)</span>&#123;<span class="comment">//合并有序链表</span></span><br><span class="line">    <span class="keyword">var</span> l = <span class="keyword">new</span> ListNode(<span class="number">0</span>);</span><br><span class="line">    <span class="keyword">var</span> rl = l;</span><br><span class="line">    <span class="keyword">while</span>(l1 &amp;&amp; l2)&#123;</span><br><span class="line">        <span class="keyword">if</span>(l1.val &lt; l2.val)&#123;</span><br><span class="line">            rl.next = l1;</span><br><span class="line">            l1 = l1.next;</span><br><span class="line">        &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">            rl.next = l2;</span><br><span class="line">            l2 = l2.next;</span><br><span class="line">        &#125;</span><br><span class="line">        rl = rl.next;</span><br><span class="line">    &#125;</span><br><span class="line">    rl.next = l1==<span class="literal">null</span>?l2:l1;</span><br><span class="line">    <span class="keyword">return</span> l.next;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h5 id="155最小栈-47-7-简单"><a href="#155最小栈-47-7-简单" class="headerlink" title="155最小栈-47.7%-简单"></a>155最小栈-47.7%-简单</h5><p><a href="https://leetcode-cn.com/problems/min-stack/" target="_blank" rel="noopener">https://leetcode-cn.com/problems/min-stack/</a></p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * initialize your data structure here.</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">var</span> MinStack = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="keyword">this</span>.arr = [];</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">/** </span></span><br><span class="line"><span class="comment"> * @param &#123;number&#125; x</span></span><br><span class="line"><span class="comment"> * @return &#123;void&#125;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line">MinStack.prototype.push = <span class="function"><span class="keyword">function</span>(<span class="params">x</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">this</span>.arr.push(x);</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * @return &#123;void&#125;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line">MinStack.prototype.pop = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="keyword">this</span>.arr.pop();</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * @return &#123;number&#125;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line">MinStack.prototype.top = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">this</span>.arr[<span class="keyword">this</span>.arr.length<span class="number">-1</span>];</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * @return &#123;number&#125;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line">MinStack.prototype.getMin = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="built_in">Math</span>.min.apply( &#123;&#125;, <span class="keyword">this</span>.arr );</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">/** </span></span><br><span class="line"><span class="comment"> * Your MinStack object will be instantiated and called as such:</span></span><br><span class="line"><span class="comment"> * var obj = Object.create(MinStack).createNew()</span></span><br><span class="line"><span class="comment"> * obj.push(x)</span></span><br><span class="line"><span class="comment"> * obj.pop()</span></span><br><span class="line"><span class="comment"> * var param_3 = obj.top()</span></span><br><span class="line"><span class="comment"> * var param_4 = obj.getMin()</span></span><br><span class="line"><span class="comment"> */</span></span><br></pre></td></tr></table></figure><h5 id="160相交链表-37-2-简单"><a href="#160相交链表-37-2-简单" class="headerlink" title="160相交链表-37.2%-简单"></a>160相交链表-37.2%-简单</h5><p><a href="https://leetcode-cn.com/problems/intersection-of-two-linked-lists/" target="_blank" rel="noopener">https://leetcode-cn.com/problems/intersection-of-two-linked-lists/</a></p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Definition for singly-linked list.</span></span><br><span class="line"><span class="comment"> * function ListNode(val) &#123;</span></span><br><span class="line"><span class="comment"> *     this.val = val;</span></span><br><span class="line"><span class="comment"> *     this.next = null;</span></span><br><span class="line"><span class="comment"> * &#125;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * @param &#123;ListNode&#125; headA</span></span><br><span class="line"><span class="comment"> * @param &#123;ListNode&#125; headB</span></span><br><span class="line"><span class="comment"> * @return &#123;ListNode&#125;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">var</span> getIntersectionNode = <span class="function"><span class="keyword">function</span>(<span class="params">headA, headB</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">if</span>(headA == <span class="literal">null</span> || headB == <span class="literal">null</span>)&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="literal">null</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">var</span> pA = headA;</span><br><span class="line">    <span class="keyword">var</span> pB = headB;</span><br><span class="line">    <span class="keyword">while</span>(pA != pB) &#123;</span><br><span class="line">        pA = pA == <span class="literal">null</span> ? headB : pA.next;</span><br><span class="line">        pB = pB == <span class="literal">null</span> ? headA : pB.next;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> pA;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h5 id="169求众数-58-0-简单"><a href="#169求众数-58-0-简单" class="headerlink" title="169求众数-58.0%-简单"></a>169求众数-58.0%-简单</h5><p><a href="https://leetcode-cn.com/problems/majority-element/" target="_blank" rel="noopener">https://leetcode-cn.com/problems/majority-element/</a></p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * @param &#123;number[]&#125; nums</span></span><br><span class="line"><span class="comment"> * @return &#123;number&#125;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">var</span> majorityElement = <span class="function"><span class="keyword">function</span>(<span class="params">nums</span>) </span>&#123;</span><br><span class="line">    nums.sort();</span><br><span class="line">    <span class="keyword">return</span> nums[<span class="built_in">Math</span>.floor(nums.length/<span class="number">2</span>)];</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h5 id="206反转链表-58-6-简单"><a href="#206反转链表-58-6-简单" class="headerlink" title="206反转链表-58.6%-简单"></a>206反转链表-58.6%-简单</h5><p><a href="https://leetcode-cn.com/problems/reverse-linked-list/" target="_blank" rel="noopener">https://leetcode-cn.com/problems/reverse-linked-list/</a></p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Definition for singly-linked list.</span></span><br><span class="line"><span class="comment"> * function ListNode(val) &#123;</span></span><br><span class="line"><span class="comment"> *     this.val = val;</span></span><br><span class="line"><span class="comment"> *     this.next = null;</span></span><br><span class="line"><span class="comment"> * &#125;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * @param &#123;ListNode&#125; head</span></span><br><span class="line"><span class="comment"> * @return &#123;ListNode&#125;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">var</span> reverseList = <span class="function"><span class="keyword">function</span>(<span class="params">head</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">var</span> l  = <span class="literal">null</span>;</span><br><span class="line">    <span class="keyword">while</span>(head != <span class="literal">null</span>)&#123;</span><br><span class="line">        <span class="keyword">var</span> newl = <span class="keyword">new</span> ListNode(head.val);</span><br><span class="line">        <span class="keyword">var</span> tmp = l;</span><br><span class="line">        l = newl;</span><br><span class="line">        l.next = tmp;</span><br><span class="line">        head = head.next;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> l;   </span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h5 id="215数组中的第K个最大元素-56-6-中等"><a href="#215数组中的第K个最大元素-56-6-中等" class="headerlink" title="215数组中的第K个最大元素-56.6%-中等"></a>215数组中的第K个最大元素-56.6%-中等</h5><p><a href="https://leetcode-cn.com/problems/kth-largest-element-in-an-array/" target="_blank" rel="noopener">https://leetcode-cn.com/problems/kth-largest-element-in-an-array/</a></p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * @param &#123;number[]&#125; nums</span></span><br><span class="line"><span class="comment"> * @param &#123;number&#125; k</span></span><br><span class="line"><span class="comment"> * @return &#123;number&#125;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">var</span> findKthLargest = <span class="function"><span class="keyword">function</span>(<span class="params">nums, k</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">return</span> fastkmax(nums,<span class="number">0</span>,nums.length<span class="number">-1</span>,k);</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">fastkmax</span>(<span class="params">n,l,r,k</span>)</span>&#123;</span><br><span class="line">    <span class="keyword">var</span> mid = partiton(n,l,r);<span class="comment">//排序 左边都是比mid小的，右边都是比mid大的</span></span><br><span class="line">    <span class="keyword">var</span> rk = r - mid + <span class="number">1</span>;</span><br><span class="line">    <span class="keyword">if</span>(rk == k)&#123;</span><br><span class="line">        <span class="keyword">return</span> n[mid];</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span>(rk &gt; k)&#123;</span><br><span class="line">        <span class="keyword">return</span> fastkmax(n,mid + <span class="number">1</span>,r,k);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> fastkmax(n,l,mid - <span class="number">1</span>,k -rk );</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">partiton</span>(<span class="params">n,l,r</span>)</span>&#123;<span class="comment">//一次快排</span></span><br><span class="line">    <span class="keyword">var</span> base = n[l];</span><br><span class="line">    <span class="keyword">var</span> i = l,j = r,tmp;</span><br><span class="line">    <span class="keyword">while</span>(i &lt; j)&#123;</span><br><span class="line">        <span class="keyword">while</span>(n[j] &gt;= base &amp;&amp; i &lt; j)&#123;</span><br><span class="line">            j--;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">while</span>(n[i] &lt;= base &amp;&amp; i &lt; j)&#123;</span><br><span class="line">            i++;</span><br><span class="line">        &#125;</span><br><span class="line">            tmp = n[i];</span><br><span class="line">            n[i] = n[j];</span><br><span class="line">            n[j] = tmp;</span><br><span class="line">    &#125;</span><br><span class="line">    n[l] = n[i];</span><br><span class="line">    n[i] = base;</span><br><span class="line">    <span class="keyword">return</span> i;</span><br><span class="line"> &#125;</span><br></pre></td></tr></table></figure><h5 id="217存在重复元素-47-0-简单"><a href="#217存在重复元素-47-0-简单" class="headerlink" title="217存在重复元素-47.0%-简单"></a>217存在重复元素-47.0%-简单</h5><p><a href="https://leetcode-cn.com/problems/contains-duplicate/" target="_blank" rel="noopener">https://leetcode-cn.com/problems/contains-duplicate/</a></p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * @param &#123;number[]&#125; nums</span></span><br><span class="line"><span class="comment"> * @return &#123;boolean&#125;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">var</span> containsDuplicate = <span class="function"><span class="keyword">function</span>(<span class="params">nums</span>) </span>&#123;</span><br><span class="line">    nums.sort();</span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">var</span> i=<span class="number">0</span>;i&lt;nums.length<span class="number">-1</span>;i++)&#123;</span><br><span class="line">        <span class="keyword">if</span>(nums[i]==nums[i+<span class="number">1</span>])&#123;</span><br><span class="line">            <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h5 id="230二叉搜索树中第K小的元素-62-0-中等"><a href="#230二叉搜索树中第K小的元素-62-0-中等" class="headerlink" title="230二叉搜索树中第K小的元素-62.0%-中等"></a>230二叉搜索树中第K小的元素-62.0%-中等</h5><p><a href="https://leetcode-cn.com/problems/kth-smallest-element-in-a-bst/" target="_blank" rel="noopener">https://leetcode-cn.com/problems/kth-smallest-element-in-a-bst/</a></p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Definition for a binary tree node.</span></span><br><span class="line"><span class="comment"> * function TreeNode(val) &#123;</span></span><br><span class="line"><span class="comment"> *     this.val = val;</span></span><br><span class="line"><span class="comment"> *     this.left = this.right = null;</span></span><br><span class="line"><span class="comment"> * &#125;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * @param &#123;TreeNode&#125; root</span></span><br><span class="line"><span class="comment"> * @param &#123;number&#125; k</span></span><br><span class="line"><span class="comment"> * @return &#123;number&#125;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">var</span> kthSmallest = <span class="function"><span class="keyword">function</span>(<span class="params">root, k</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">var</span> list = [];</span><br><span class="line">    order(root,list);</span><br><span class="line">    <span class="keyword">return</span> list[k<span class="number">-1</span>];</span><br><span class="line">&#125;;</span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">order</span>(<span class="params">root,list</span>)</span>&#123;<span class="comment">//中序遍历</span></span><br><span class="line">    <span class="keyword">if</span>(!root)&#123;</span><br><span class="line">        <span class="keyword">return</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    order(root.left,list);</span><br><span class="line">    list.push(root.val);</span><br><span class="line">    order(root.right,list);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h5 id="231-2的幂-44-3-简单"><a href="#231-2的幂-44-3-简单" class="headerlink" title="231 2的幂-44.3%-简单"></a>231 2的幂-44.3%-简单</h5><p><a href="https://leetcode-cn.com/problems/power-of-two/" target="_blank" rel="noopener">https://leetcode-cn.com/problems/power-of-two/</a></p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * @param &#123;number&#125; n</span></span><br><span class="line"><span class="comment"> * @return &#123;boolean&#125;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">var</span> isPowerOfTwo = <span class="function"><span class="keyword">function</span>(<span class="params">n</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">if</span>(n == <span class="number">0</span>)&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span>(n == <span class="number">1</span>)&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> n%<span class="number">2</span>==<span class="number">0</span>?isPowerOfTwo(n/<span class="number">2</span>):<span class="literal">false</span>;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h5 id="235二叉搜索树的最近公共祖先-56-9-简单"><a href="#235二叉搜索树的最近公共祖先-56-9-简单" class="headerlink" title="235二叉搜索树的最近公共祖先-56.9%-简单"></a>235二叉搜索树的最近公共祖先-56.9%-简单</h5><p><a href="https://leetcode-cn.com/problems/lowest-common-ancestor-of-a-binary-search-tree/" target="_blank" rel="noopener">https://leetcode-cn.com/problems/lowest-common-ancestor-of-a-binary-search-tree/</a></p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Definition for a binary tree node.</span></span><br><span class="line"><span class="comment"> * function TreeNode(val) &#123;</span></span><br><span class="line"><span class="comment"> *     this.val = val;</span></span><br><span class="line"><span class="comment"> *     this.left = this.right = null;</span></span><br><span class="line"><span class="comment"> * &#125;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * @param &#123;TreeNode&#125; root</span></span><br><span class="line"><span class="comment"> * @param &#123;TreeNode&#125; p</span></span><br><span class="line"><span class="comment"> * @param &#123;TreeNode&#125; q</span></span><br><span class="line"><span class="comment"> * @return &#123;TreeNode&#125;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">var</span> lowestCommonAncestor = <span class="function"><span class="keyword">function</span>(<span class="params">root, p, q</span>) </span>&#123;</span><br><span class="line">    <span class="comment">// 二叉搜索树(二叉排序树):若它的左子树不空，则左子树上所有结点的值均小于它的根结点的值;</span></span><br><span class="line">    <span class="keyword">var</span> res = <span class="literal">null</span>;</span><br><span class="line">    lca(root, p , q);</span><br><span class="line">    <span class="function"><span class="keyword">function</span> <span class="title">lca</span>(<span class="params">root, p, q</span>)</span>&#123;</span><br><span class="line">        <span class="keyword">if</span>((root.val - p.val)*(root.val - q.val) &lt;= <span class="number">0</span>)&#123; <span class="comment">//root为p、q根节点</span></span><br><span class="line">            res = root;</span><br><span class="line">        &#125;<span class="keyword">else</span> <span class="keyword">if</span>(root.val &lt; p.val &amp;&amp; root.val &lt; q.val)&#123; <span class="comment">//都在右子树</span></span><br><span class="line">            lca(root.right, p , q);</span><br><span class="line">        &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">            lca(root.left, p , q);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h5 id="236二叉树的最近公共祖先-50-4-中等"><a href="#236二叉树的最近公共祖先-50-4-中等" class="headerlink" title="236二叉树的最近公共祖先-50.4%-中等"></a>236二叉树的最近公共祖先-50.4%-中等</h5><p><a href="https://leetcode-cn.com/problems/lowest-common-ancestor-of-a-binary-tree/" target="_blank" rel="noopener">https://leetcode-cn.com/problems/lowest-common-ancestor-of-a-binary-tree/</a></p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Definition for a binary tree node.</span></span><br><span class="line"><span class="comment"> * function TreeNode(val) &#123;</span></span><br><span class="line"><span class="comment"> *     this.val = val;</span></span><br><span class="line"><span class="comment"> *     this.left = this.right = null;</span></span><br><span class="line"><span class="comment"> * &#125;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * @param &#123;TreeNode&#125; root</span></span><br><span class="line"><span class="comment"> * @param &#123;TreeNode&#125; p</span></span><br><span class="line"><span class="comment"> * @param &#123;TreeNode&#125; q</span></span><br><span class="line"><span class="comment"> * @return &#123;TreeNode&#125;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">var</span> lowestCommonAncestor = <span class="function"><span class="keyword">function</span>(<span class="params">root, p, q</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">if</span>(!root)&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="literal">null</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span>(root == p || root == q)&#123;</span><br><span class="line">        <span class="keyword">return</span> root;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">var</span> l = lowestCommonAncestor(root.left,p,q)<span class="comment">//左支存在一个的位置</span></span><br><span class="line">    <span class="keyword">var</span> r = lowestCommonAncestor(root.right,p,q)</span><br><span class="line">    <span class="keyword">if</span>(l &amp;&amp; r)&#123;<span class="comment">//左支有一个，右支有一个</span></span><br><span class="line">        <span class="keyword">return</span> root;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span>(l)&#123;<span class="comment">//右没有，都在左，先找到的即为根节点</span></span><br><span class="line">        <span class="keyword">return</span> l;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span>(r)&#123;</span><br><span class="line">        <span class="keyword">return</span> r;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="literal">null</span>;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h5 id="237删除链表中的节点-69-4-简单"><a href="#237删除链表中的节点-69-4-简单" class="headerlink" title="237删除链表中的节点-69.4%-简单"></a>237删除链表中的节点-69.4%-简单</h5><p><a href="https://leetcode-cn.com/problems/delete-node-in-a-linked-list/" target="_blank" rel="noopener">https://leetcode-cn.com/problems/delete-node-in-a-linked-list/</a></p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Definition for singly-linked list.</span></span><br><span class="line"><span class="comment"> * function ListNode(val) &#123;</span></span><br><span class="line"><span class="comment"> *     this.val = val;</span></span><br><span class="line"><span class="comment"> *     this.next = null;</span></span><br><span class="line"><span class="comment"> * &#125;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * @param &#123;ListNode&#125; node</span></span><br><span class="line"><span class="comment"> * @return &#123;void&#125; Do not return anything, modify node in-place instead.</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">var</span> deleteNode = <span class="function"><span class="keyword">function</span>(<span class="params">node</span>) </span>&#123;</span><br><span class="line">    node.val = node.next.val;</span><br><span class="line">    node.next = node.next.next;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h5 id="238除自身以外数组的乘积-58-8-中等"><a href="#238除自身以外数组的乘积-58-8-中等" class="headerlink" title="238除自身以外数组的乘积-58.8%-中等"></a>238除自身以外数组的乘积-58.8%-中等</h5><p><a href="https://leetcode-cn.com/problems/product-of-array-except-self/" target="_blank" rel="noopener">https://leetcode-cn.com/problems/product-of-array-except-self/</a></p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * @param &#123;number[]&#125; nums</span></span><br><span class="line"><span class="comment"> * @return &#123;number[]&#125;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">var</span> productExceptSelf = <span class="function"><span class="keyword">function</span>(<span class="params">nums</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">var</span> arr = [];</span><br><span class="line">    <span class="keyword">var</span> l = <span class="number">1</span>, r = <span class="number">1</span>;</span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">var</span> i=<span class="number">0</span>;i&lt;nums.length;i++)&#123;<span class="comment">//arr[i] i左边数乘积</span></span><br><span class="line">        arr[i] = l;</span><br><span class="line">        l *= nums[i];</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">var</span> j=nums.length<span class="number">-1</span>;j&gt;=<span class="number">0</span>;j--)&#123;</span><br><span class="line">        arr[j] *= r;</span><br><span class="line">        r *= nums[j];</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> arr;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h5 id="292Nim游戏-66-4-简单"><a href="#292Nim游戏-66-4-简单" class="headerlink" title="292Nim游戏-66.4%-简单"></a>292Nim游戏-66.4%-简单</h5><p><a href="https://leetcode-cn.com/problems/nim-game/" target="_blank" rel="noopener">https://leetcode-cn.com/problems/nim-game/</a></p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * @param &#123;number&#125; n</span></span><br><span class="line"><span class="comment"> * @return &#123;boolean&#125;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">var</span> canWinNim = <span class="function"><span class="keyword">function</span>(<span class="params">n</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">return</span> n%<span class="number">4</span> == <span class="number">0</span>?<span class="literal">false</span>:<span class="literal">true</span>;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h5 id="344反转字符串-65-1-简单"><a href="#344反转字符串-65-1-简单" class="headerlink" title="344反转字符串-65.1%-简单"></a>344反转字符串-65.1%-简单</h5><p><a href="https://leetcode-cn.com/problems/reverse-string/" target="_blank" rel="noopener">https://leetcode-cn.com/problems/reverse-string/</a></p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * @param &#123;character[]&#125; s</span></span><br><span class="line"><span class="comment"> * @return &#123;void&#125; Do not return anything, modify s in-place instead.</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">var</span> reverseString = <span class="function"><span class="keyword">function</span>(<span class="params">s</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">var</span> i=<span class="number">1</span>;i&lt;s.length;i++)&#123;</span><br><span class="line">        <span class="keyword">var</span> tmp = s.splice(i,<span class="number">1</span>)[<span class="number">0</span>];</span><br><span class="line">        s.unshift(tmp);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h5 id="557反转字符串中的单词III-63-5-简单"><a href="#557反转字符串中的单词III-63-5-简单" class="headerlink" title="557反转字符串中的单词III-63.5%-简单"></a>557反转字符串中的单词III-63.5%-简单</h5><p><a href="https://leetcode-cn.com/problems/reverse-words-in-a-string-iii/" target="_blank" rel="noopener">https://leetcode-cn.com/problems/reverse-words-in-a-string-iii/</a></p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * @param &#123;string&#125; s</span></span><br><span class="line"><span class="comment"> * @return &#123;string&#125;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">var</span> reverseWords = <span class="function"><span class="keyword">function</span>(<span class="params">s</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">var</span> arr = s.split(<span class="string">" "</span>);</span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">var</span> i=<span class="number">0</span>;i&lt;arr.length;i++)&#123;</span><br><span class="line">        arr[i] = arr[i].split(<span class="string">""</span>).reverse().join(<span class="string">""</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> arr.join(<span class="string">" "</span>);</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure>]]></content>
    
    <summary type="html">
    
      &lt;h3 id=&quot;题目来源&quot;&gt;&lt;a href=&quot;#题目来源&quot; class=&quot;headerlink&quot; title=&quot;题目来源&quot;&gt;&lt;/a&gt;题目来源&lt;/h3&gt;&lt;p&gt; &lt;a href=&quot;https://leetcode-cn.com/problemset/50/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;腾讯精选练习（50 题）&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;GitHub地址：&lt;a href=&quot;https://github.com/zj19941113/LeetCode-50-JavaScript-Answers&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://github.com/zj19941113/LeetCode-50-JavaScript-Answers&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;相关：&lt;br&gt;&lt;a href=&quot;https://blog.csdn.net/ffcjjhv/article/details/96879804&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;刷题汇总（二）剑指Offer 66题 C++答案总结&lt;/a&gt;&lt;br&gt;&lt;a href=&quot;https://blog.csdn.net/ffcjjhv/article/details/100104411&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;刷题汇总（三）leetcode 精选50题 C++答案总结&lt;/a&gt;&lt;br&gt;&lt;a href=&quot;https://blog.csdn.net/ffcjjhv/article/details/103195691&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;刷题汇总（四）技术类编程题汇总 C++&lt;/a&gt;&lt;br&gt;&lt;a href=&quot;https://blog.csdn.net/ffcjjhv/article/details/103381516&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;刷题汇总（五）leetcode 热题 HOT 100 C++ 答案总结&lt;/a&gt;&lt;br&gt;&lt;a href=&quot;https://blog.csdn.net/ffcjjhv/article/details/103503745&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;刷题汇总（六）leetcode 多线程 / Shell&lt;/a&gt;&lt;/p&gt;
&lt;h5 id=&quot;2两数相加-33-0-中等&quot;&gt;&lt;a href=&quot;#2两数相加-33-0-中等&quot; class=&quot;headerlink&quot; title=&quot;2两数相加-33.0%-中等&quot;&gt;&lt;/a&gt;2两数相加-33.0%-中等&lt;/h5&gt;
    
    </summary>
    
      <category term="前端" scheme="http://yoursite.com/categories/%E5%89%8D%E7%AB%AF/"/>
    
      <category term="CodeCode" scheme="http://yoursite.com/categories/CodeCode/"/>
    
    
      <category term="JavaScript" scheme="http://yoursite.com/tags/JavaScript/"/>
    
      <category term="Leetcode" scheme="http://yoursite.com/tags/Leetcode/"/>
    
  </entry>
  
  <entry>
    <title>setTimeout、Promise、Async/Await 异步机制 事件循环</title>
    <link href="http://yoursite.com/2019/02/22/12/"/>
    <id>http://yoursite.com/2019/02/22/12/</id>
    <published>2019-02-22T12:48:32.000Z</published>
    <updated>2019-12-18T04:09:25.822Z</updated>
    
    <content type="html"><![CDATA[<p><strong>javascript是一门单线程语言</strong> </p><p>将任务分为两类：</p><ul><li>同步任务</li><li>异步任务</li></ul><p>打开网站时，网页的渲染过程就是一大堆同步任务，比如页面骨架和页面元素的渲染。而像加载图片音乐之类占用资源大耗时久的任务，就是异步任务。</p><a id="more"></a><p>同步的进入<strong>主线程</strong>，异步的进入<strong>Event Table并注册函数</strong>。当指定的事情完成时，Event Table会将这个函数移入Event Queue。主线程内的任务执行完毕为空，会去Event Queue读取对应的函数，进入主线程执行。上述过程会不断重复，也就是常说的Event Loop(事件循环)。<br><img src="https://img-blog.csdnimg.cn/20190222200045901.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZmY2pqaHY=,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"><br>js引擎存在monitoring process进程，会持续不断的检查主线程执行栈是否为空，一旦为空，就会去Event Queue那里检查是否有等待被调用的函数。</p><p>举些例子：</p><h5 id="1、setTimeout"><a href="#1、setTimeout" class="headerlink" title="1、setTimeout"></a>1、setTimeout</h5><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">console</span>.log(<span class="string">'script start'</span>)<span class="comment">//1. 打印 script start</span></span><br><span class="line">setTimeout(<span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">'settimeout'</span>)<span class="comment">// 3. 打印 settimeout</span></span><br><span class="line">&#125;)</span><br><span class="line"><span class="built_in">console</span>.log(<span class="string">'script end'</span>)<span class="comment">//2. 打印 script start</span></span><br></pre></td></tr></table></figure><p> 输出顺序：script start-&gt;script end-&gt;settimeout</p><h5 id="2、Promise"><a href="#2、Promise" class="headerlink" title="2、Promise"></a>2、Promise</h5><p>Promise本身是同步的立即执行函数， 当在executor中执行resolve或者reject的时候, 此时是异步操作， 会先执行then/catch等，当主栈完成后，才会去调用resolve/reject中存放的方法执行，打印p的时候，是打印的返回结果，一个Promise实例。</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">console</span>.log(<span class="string">'script start'</span>)  <span class="comment">//1. 打印 script start</span></span><br><span class="line"><span class="keyword">let</span> promise1 = <span class="keyword">new</span> <span class="built_in">Promise</span>(<span class="function"><span class="keyword">function</span> (<span class="params">resolve</span>) </span>&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">'promise1'</span>)  <span class="comment">//2. 打印 promise1</span></span><br><span class="line">    resolve()</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">'promise1 end'</span>)  <span class="comment">//3. 打印 promise1 end</span></span><br><span class="line">&#125;).then(<span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">'promise2'</span>)  <span class="comment">//5. 打印 promise2</span></span><br><span class="line">&#125;)</span><br><span class="line"><span class="built_in">console</span>.log(<span class="string">'script end'</span>)  <span class="comment">//4. 打印 script end</span></span><br></pre></td></tr></table></figure><p>// 输出顺序: script start-&gt;promise1-&gt;promise1 end-&gt;script end-&gt;promise2-&gt;settimeout</p><h5 id="3、async-await"><a href="#3、async-await" class="headerlink" title="3、async await"></a>3、async await</h5><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">async</span> <span class="function"><span class="keyword">function</span> <span class="title">async1</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">   <span class="built_in">console</span>.log(<span class="string">'async1 start'</span>);  <span class="comment">//2. 打印 async1 start</span></span><br><span class="line">   <span class="keyword">await</span> async2();</span><br><span class="line">   <span class="built_in">console</span>.log(<span class="string">'async1 end'</span>)  <span class="comment">//5. 打印 async1 end</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">async</span> <span class="function"><span class="keyword">function</span> <span class="title">async2</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">   <span class="built_in">console</span>.log(<span class="string">'async2'</span>)  <span class="comment">//3. 打印 async2</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="built_in">console</span>.log(<span class="string">'script start'</span>);  <span class="comment">//1. 打印 script start</span></span><br><span class="line">async1();</span><br><span class="line"><span class="built_in">console</span>.log(<span class="string">'script end'</span>)  <span class="comment">//4. 打印 script end</span></span><br></pre></td></tr></table></figure><p>// 输出顺序：script start-&gt;async1 start-&gt;async2-&gt;script end-&gt;async1 end</p><h2 id="同时有setTimeout、Promise、Async-Await-，执行顺序又是什么？引入"><a href="#同时有setTimeout、Promise、Async-Await-，执行顺序又是什么？引入" class="headerlink" title="同时有setTimeout、Promise、Async/Await ，执行顺序又是什么？引入"></a>同时有setTimeout、Promise、Async/Await ，执行顺序又是什么？引入</h2><ul><li>macro-task(宏任务)：包括整体代码script，setTimeout，setInterval</li><li>micro-task(微任务)：Promise，process.nextTick</li></ul><p>进入整体代码(宏任务)后，开始第一次循环。接着执行所有的微任务。然后再次从宏任务开始，找到其中一个任务队列执行完毕，再执行所有的微任务。<br><img src="https://img-blog.csdnimg.cn/20190222202120577.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZmY2pqaHY=,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"></p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">setTimeout(<span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">'setTimeout'</span>);  <span class="comment">//4. 打印 setTimeout</span></span><br><span class="line">&#125;)</span><br><span class="line"><span class="keyword">new</span> <span class="built_in">Promise</span>(<span class="function"><span class="keyword">function</span>(<span class="params">resolve</span>) </span>&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">'promise'</span>);  <span class="comment">//1. 打印 promise</span></span><br><span class="line">&#125;).then(<span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">'then'</span>);  <span class="comment">//3. 打印 then</span></span><br><span class="line">&#125;)</span><br><span class="line"><span class="built_in">console</span>.log(<span class="string">'console'</span>);  <span class="comment">//2. 打印 console</span></span><br></pre></td></tr></table></figure><p>// 输出顺序：promise-&gt;console-&gt;then-&gt;setTimeout</p><ul><li>先遇到setTimeout，那么将其回调函数注册后分发到宏任务Event Queue。</li><li>接下来遇到了Promise，new Promise立即执行，then函数分发到微任务Event Queue。</li><li>遇到console.log()，立即执行。</li><li>整体代码script作为第一个宏任务执行结束，发现了then在微任务Event Queue里面，执行。</li><li>第一轮事件循环结束了，从宏任务Event Queue开始第二轮循环。发现了宏任务EventQueue中setTimeout对应的回调函数，立即执行。</li><li>结束。</li></ul><p>再来分析两个案例：</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">console</span>.log(<span class="string">'1'</span>);  <span class="comment">//1. 打印 1</span></span><br><span class="line"> </span><br><span class="line">setTimeout(<span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">'2'</span>);  <span class="comment">//5. 打印 2</span></span><br><span class="line">    process.nextTick(<span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">        <span class="built_in">console</span>.log(<span class="string">'3'</span>);  <span class="comment">//7. 打印 3</span></span><br><span class="line">    &#125;)</span><br><span class="line">    <span class="keyword">new</span> <span class="built_in">Promise</span>(<span class="function"><span class="keyword">function</span>(<span class="params">resolve</span>) </span>&#123;</span><br><span class="line">        <span class="built_in">console</span>.log(<span class="string">'4'</span>);  <span class="comment">//6. 打印 4</span></span><br><span class="line">        resolve();</span><br><span class="line">    &#125;).then(<span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">        <span class="built_in">console</span>.log(<span class="string">'5'</span>)  <span class="comment">//8. 打印 5</span></span><br><span class="line">    &#125;)</span><br><span class="line">&#125;)</span><br><span class="line"></span><br><span class="line">process.nextTick(<span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">'6'</span>);  <span class="comment">//3. 打印 6</span></span><br><span class="line">&#125;)</span><br><span class="line"></span><br><span class="line"><span class="keyword">new</span> <span class="built_in">Promise</span>(<span class="function"><span class="keyword">function</span>(<span class="params">resolve</span>) </span>&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">'7'</span>);  <span class="comment">//2. 打印 7</span></span><br><span class="line">    resolve();</span><br><span class="line">&#125;).then(<span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">'8'</span>)  <span class="comment">//4. 打印 8</span></span><br><span class="line">&#125;)</span><br><span class="line"> </span><br><span class="line">setTimeout(<span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">'9'</span>);  <span class="comment">//9. 打印 9</span></span><br><span class="line">    process.nextTick(<span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">        <span class="built_in">console</span>.log(<span class="string">'10'</span>);  <span class="comment">//11. 打印 10</span></span><br><span class="line">    &#125;)</span><br><span class="line">    </span><br><span class="line">    <span class="keyword">new</span> <span class="built_in">Promise</span>(<span class="function"><span class="keyword">function</span>(<span class="params">resolve</span>) </span>&#123;</span><br><span class="line">        <span class="built_in">console</span>.log(<span class="string">'11'</span>);  <span class="comment">//10. 打印 11</span></span><br><span class="line">        resolve(); </span><br><span class="line">    &#125;).then(<span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">        <span class="built_in">console</span>.log(<span class="string">'12'</span>)  <span class="comment">//12. 打印 12</span></span><br><span class="line">    &#125;)</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure><p>// 输出顺序：1，7，6，8，2，4，3，5，9，11，10，12</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">async</span> <span class="function"><span class="keyword">function</span> <span class="title">async1</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">'async1 start'</span>)  <span class="comment">//2. 打印 async1 start</span></span><br><span class="line">    <span class="keyword">await</span> async2()</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">'async1 end'</span>)  <span class="comment">//7. 打印 async1 end</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">async</span> <span class="function"><span class="keyword">function</span> <span class="title">async2</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">'async2'</span>)  <span class="comment">//3. 打印 async2</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="built_in">console</span>.log(<span class="string">'script start'</span>)  <span class="comment">//1. 打印 script start</span></span><br><span class="line">setTimeout(<span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">'settimeout'</span>)  <span class="comment">//8. 打印 settimeout</span></span><br><span class="line">&#125;)</span><br><span class="line">async1()</span><br><span class="line"><span class="keyword">new</span> <span class="built_in">Promise</span>(<span class="function"><span class="keyword">function</span> (<span class="params">resolve</span>) </span>&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">'promise1'</span>)  <span class="comment">//4. 打印 promise1</span></span><br><span class="line">    resolve()</span><br><span class="line">&#125;).then(<span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">'promise2'</span>)  <span class="comment">//6. 打印 promise2</span></span><br><span class="line">&#125;)</span><br><span class="line"><span class="built_in">console</span>.log(<span class="string">'script end'</span>)  <span class="comment">//5. 打印 script end</span></span><br></pre></td></tr></table></figure><p>// 输出顺序：script start-&gt;async1 start-&gt;async2-&gt;promise1-&gt;script end-&gt;promise2-&gt;async1 end-&gt;settimeout</p>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;&lt;strong&gt;javascript是一门单线程语言&lt;/strong&gt; &lt;/p&gt;
&lt;p&gt;将任务分为两类：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;同步任务&lt;/li&gt;
&lt;li&gt;异步任务&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;打开网站时，网页的渲染过程就是一大堆同步任务，比如页面骨架和页面元素的渲染。而像加载图片音乐之类占用资源大耗时久的任务，就是异步任务。&lt;/p&gt;
    
    </summary>
    
      <category term="前端" scheme="http://yoursite.com/categories/%E5%89%8D%E7%AB%AF/"/>
    
    
      <category term="Promise" scheme="http://yoursite.com/tags/Promise/"/>
    
      <category term="JavaScript" scheme="http://yoursite.com/tags/JavaScript/"/>
    
  </entry>
  
</feed>
