<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>张天宇的博客</title>
  <icon>https://tyzhang.top/img/logo.png</icon>
  <subtitle>欲买桂花同载酒，终不似，少年游</subtitle>
  <link href="https://tyzhang.top/feed.xml" rel="self"/>
  <link href="https://tyzhang.top/" rel="hub"/>
  <link href="https://tyzhang.top/"/>
  <updated>2024-05-22T13:23:22.366Z</updated>
  <id>https://tyzhang.top/</id>
  
  <author>
    <name>张天宇</name>
    <email>zhangty1996@163.com</email>
  </author>
  
  <generator uri="https://hexo.io/">Hexo</generator>
  
  <entry>
    <title>卡路里回收中心</title>
    <link href="https://tyzhang.top/article/sport-record/"/>
    <id>https://tyzhang.top/article/sport-record/</id>
    <published>2024-05-18T16:00:00.000Z</published>
    <updated>2024-05-22T13:23:22.366Z</updated>
    
    <content type="html"><![CDATA[<p>最近半年在尝试养成运动的习惯，有氧&amp;无氧，悄悄瘦了一点点🤏。分享一下自己的运动种类和跟做视频，方便寻找，不用去收藏夹里扒了。</p><h3><span id="热身">热身</span></h3><iframe src="//player.bilibili.com/player.html?isOutside=true&aid=888187208&bvid=BV1WK4y1G7Xk&cid=342349592&p=1&autoplay=0" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true" style="width:100%;aspect-ratio:16/9;"></iframe><h3><span id="运动">运动</span></h3><blockquote><p>选两组半小时左右，约三百千卡。</p></blockquote><h4><span id="哑铃全身">哑铃全身</span></h4><iframe src="//player.bilibili.com/player.html?isOutside=true&aid=974672335&bvid=BV1a44y1C7En&cid=384347623&p=1&autoplay=0" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true" style="width:100%;aspect-ratio:16/9;"></iframe><h4><span id="哑铃练胸">哑铃练胸</span></h4><iframe src="//player.bilibili.com/player.html?isOutside=true&aid=252517852&bvid=BV1rY411H7V2&cid=468121421&p=1&autoplay=0" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true" style="width:100%;aspect-ratio:16/9;"></iframe><h4><span id="哑铃手臂">哑铃手臂</span></h4><iframe src="//player.bilibili.com/player.html?isOutside=true&aid=806290385&bvid=BV1c34y1U7Kv&cid=433879058&p=1&autoplay=0" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true" style="width:100%;aspect-ratio:16/9;"></iframe><h4><span id="有氧">有氧</span></h4><blockquote><p>选两组半小时左右，约三百千卡。</p></blockquote><iframe src="//player.bilibili.com/player.html?isOutside=true&aid=828294453&bvid=BV1Bg4y1w7kY&cid=1193698186&p=1&autoplay=0" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true" style="width:100%;aspect-ratio:16/9;"></iframe><h4><span id="跳绳">跳绳</span></h4><p>一般会在 3000-5000 左右，有意控制心率在 135-155 之间，使用 <code>YaoYao</code> 记录，单次四十分钟左右，450千卡左右。</p><h4><span id="有氧拳击">有氧拳击</span></h4><p>Switch 有氧拳击运动游戏，魔鬼模式 x 2，单次运动半小时左右。</p><h3><span id="拉伸">拉伸</span></h3><blockquote><p>很不错的一组拉伸，有时候没有时间运动了，也会单独做一组拉伸。</p></blockquote><iframe src="//player.bilibili.com/player.html?isOutside=true&aid=289240976&bvid=BV1Yf4y1z76H&cid=299172474&p=1&autoplay=0" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true" style="width:100%;aspect-ratio:16/9;"></iframe>]]></content>
    
    
      
      
    <summary type="html">&lt;p&gt;最近半年在尝试养成运动的习惯，有氧&amp;amp;无氧，悄悄瘦了一点点🤏。分享一下自己的运动种类和跟做视频，方便寻找，不用去收藏夹里扒了。&lt;/p&gt;
&lt;h3&gt;&lt;span id=&quot;热身&quot;&gt;热身&lt;/span&gt;&lt;/h3&gt;
&lt;iframe src=&quot;//player.bilibili.c</summary>
      
    
    
    
    
    <category term="运动" scheme="https://tyzhang.top/tags/%E8%BF%90%E5%8A%A8/"/>
    
  </entry>
  
  <entry>
    <title>书和远方 : 2023</title>
    <link href="https://tyzhang.top/article/booklist/"/>
    <id>https://tyzhang.top/article/booklist/</id>
    <published>2023-11-08T16:00:00.000Z</published>
    <updated>2023-11-11T12:44:06.313Z</updated>
    
    <content type="html"><![CDATA[<h3><span id="远方">远方</span></h3><h4><span id="扬州">扬州</span></h4><p>2023-08-22<br>扬州很不错，好玩、好吃。</p><table><thead><tr><th><img src="https://pic.tyzhang.top/images/2023/11/11/AF5BC32B-3BE1-48ED-B568-104084DC75DA_1_105_c.md.jpg" alt="jpg" style="zoom:40%;"></th><th><img src="https://pic.tyzhang.top/images/2023/11/11/FE6A2854-974D-4A0E-816B-FFC2DB841CBE_1_105_c.jpg" alt="jpg" style="zoom:40%;"></th><th><img src="https://pic.tyzhang.top/images/2023/11/11/F480DE5F-7F3D-401E-AD55-2249E6BBCD2F_1_105_c.md.jpg" alt="jpg" style="zoom:85%;"></th></tr></thead></table><h4><span id="苏州">苏州</span></h4><p>2023-06-03<br>和小付盘算了好久的苏州，终于去咯，开心的四天。<br>游玩体验非常不错，期待下次再来苏州，期待下次出去玩，只是不要再这么热了。</p><table><thead><tr><th><img src="https://pic.tyzhang.top/images/2023/11/11/2EBCE966-8FF8-474A-91FD-3CC3A0D5A6F0_1_105_c.md.jpg" style="zoom:50%;" alt="jpg"></th><th><img src="https://pic.tyzhang.top/images/2023/11/11/F0AE49E8-F208-424A-97DF-71363E3F0CA0_1_105_c.md.jpg" style="zoom:89%;" alt="jpg"></th></tr></thead></table><h3><span id="书">书</span></h3><blockquote><p>截止 11/09 完成阅读 7本半。以下部分内容摘自微博记录。</p></blockquote><h4><span id="一个人的村庄">一个人的村庄</span></h4><p>2023/11/09<br>最近在读《一个人的村庄》。</p><h4><span id="告别的年代">告别的年代</span></h4><p>2023/7/30<br>《告别的年代》写得像俄罗斯套娃一样，复杂，真是复杂，脑子有点不够用了。</p><h4><span id="献给阿尔吉侬的花束">献给阿尔吉侬的花束</span></h4><p>2023/6/12<br>前几天发了一条微博，说《献给阿尔吉侬的花束》似乎不太像科幻小说，像是心理小说。今天把它看完了。<br>高登通过手术从弱智到天才最后又回到了弱智，像极了人的一生缩影。他从开始的什么也不知道，随随便便就相信别人；到满腹经纶，开始自负又有些愤世嫉俗；最后又开始慢慢失去一切，失去情感与智慧，眼睁睁的看着自己曾经拥有的慢慢消失。它是科幻的，它构建了一种现实中尚未可能的治疗方式，它在高登一人身上演绎了人的一生，并放大了每个阶段的差距。它也是心理小说，短短的实验过程，囊括了儿时、青年和老年的所思所想。<br>当高登的日记开始重新出现错别字，当他开始让位查理，很难不让人跟着思考，什么样的自己才是人想要的？我们所记住的东西都会忘记，所认识的人也会慢慢远离直至消失。如果非要选择，是当查理还是高登呢。如果它注定要消失，还要不要选择拥有呢。<br>“人们总是在自己的生活中寻找幸福，但真正的幸福却往往隐藏在平凡的生活中。”“智慧离间了我和所有我爱的人。”“如果没有人性情感的调和，智慧与教育根本毫无价值。”“只是在追寻知识的过程中，对爱的追寻往往就被搁在一旁。只知专注在心智本身，以致排除人际关系并因此形成封闭的自我中心，只会导致暴力与痛苦。”<br>人生永远是道难题，我不建议把它再归为科幻小说了。<br><a href="https://pic.tyzhang.top/image/UfCc"><img src="https://pic.tyzhang.top/images/2023/06/12/9E721DCA-0725-4DEB-AD30-B49F17871E27.md.jpg" alt="9E721DCA-0725-4DEB-AD30-B49F17871E27.md.jpg" style="zoom:67%;"></a></p><h4><span id="挪威的森林">挪威的森林</span></h4><p>2023/5/18<br>读起来稍微有一点压抑，渡边孤独倒也幸运，绿子就是渡边森林中的一抹彩色，是“春天的熊”。<br><img src="https://pic.tyzhang.top/images/2023/06/06/3162C701-4F07-4081-B23C-146B60BCB8B0.md.jpg" alt="3162C701-4F07-4081-B23C-146B60BCB8B0.md.jpg" style="zoom:75%;"></p><h4><span id="白鹿原">白鹿原</span></h4><p>2023/4/22<br>后劲太大<br><img src="https://pic.tyzhang.top/images/2023/06/06/91AD6099-7273-415D-A6DB-92A3BC1F5D2A.md.jpg" alt="91AD6099-7273-415D-A6DB-92A3BC1F5D2A.md.jpg" style="zoom:75%;"></p><h4><span id="长安的荔枝">长安的荔枝</span></h4><p>2023/3/18<br>没什么事情，下午睡到五点多，还以为会错过很多消息，事实是一条没有。醒来把《长安的荔枝》剩下的看完了，具象地理解了前段时间朋友说的“和光同尘”。人人都是李善德，人人都有自己的长安和荔枝。忙忙碌碌的生活，需要“打铁还要自身硬”，也需要“我嫁的是他，又不是长安”。李善德很幸运，有共患难的朋友，也有懂他体谅他的妻子。影视化可以让苏无名来演。这周不做饭了，点个外卖吧。最后附上一段文化人的车。<br><img src="https://pic.tyzhang.top/images/2023/06/06/A7E6160F-FE9F-4C14-9561-3D90395C78AF.md.jpg" alt="A7E6160F-FE9F-4C14-9561-3D90395C78AF.md.jpg" style="zoom:75%;"></p><h4><span id="活着">活着</span></h4><p>2023/3/11<br>觉得有庆的死惨，家珍的死可怜，凤霞的死可惜，苦根的死荒诞，读完之后想起这一切都给了福贵，福贵还活着。仔细想想，这几年，其实每一年都可以写进《活着》，“月光照在路上，像是洒满了盐。”。没事别碰余华。</p><img src="https://pic.tyzhang.top/images/2023/06/06/D7DD7B38-15A9-44D4-B8A9-DDD68C505714.md.jpg" alt="D7DD7B38-15A9-44D4-B8A9-DDD68C505714.md.jpg" style="zoom:75%;"><h4><span id="望春风">望春风</span></h4><p>2023/2/26<br>读完了望春风，比预想的要早一些。<br>儒里赵村是幸运的，格非用一本书记录了它的盛衰与消亡。合上书，每个人物都历历在目，就像回乡时候听到老人们提起谁家的谁谁，脑海里开始翻腾出的那片片画面。<br>乡村是留不住的。更多的村庄，在历史的车轮中悄无声息地湮灭，无人问津，更不要奢望在最后还会有人为他们献上一本挽歌。我们都是这消亡里的奥比克，四下望去，只有春风，陪我们长大的村子去了再也不会回来了，人面也早已不知何处去。<br>春琴在结尾说的那时候，还会有吗？也许吧。<br><img src="https://pic.tyzhang.top/images/2023/06/06/0BBC9CA7-323D-45BE-A35B-EA7D65B9B0FA.md.jpg" alt="0BBC9CA7-323D-45BE-A35B-EA7D65B9B0FA.md.jpg" style="zoom:75%;"></p><img src="https://pic.tyzhang.top/images/2023/06/06/AC5D8EDF-83E3-482A-B191-E885E0F85AA3.md.jpg" alt="AC5D8EDF-83E3-482A-B191-E885E0F85AA3.md.jpg" style="zoom:75%;"><h4><span id="红星照耀中国">红星照耀中国</span></h4><p>2023/2/4<br>在电子工业出版社的一堆砖头的时间缝隙里，断断续续读完了。很意外，书中没有太多对各种主义的探讨，偏纪实，偏群像，没有那些谁对谁错。一共的巅峰开局，红小鬼的幽默，还有人生五十始的老徐。读这本书的时候，我经常想起之前看的王阁老的美国反对美国。上世纪八十年代的美国那些深层次的矛盾，还在今天的美国，也在当下的中国。只可惜很多道理，一旦自身身处之中，就不灵光了。能不能跳出历史周期律，仍然是个问题。<br>开始下一本，望春风，看乡土中国。<br><img src="https://pic.tyzhang.top/images/2023/06/06/7B09EBF8-8F5A-414C-B89D-299901A87E88.md.jpg" alt="7B09EBF8-8F5A-414C-B89D-299901A87E88.md.jpg" style="zoom:75%;"></p>]]></content>
    
    
      
      
    <summary type="html">&lt;h3&gt;&lt;span id=&quot;远方&quot;&gt;远方&lt;/span&gt;&lt;/h3&gt;
&lt;h4&gt;&lt;span id=&quot;扬州&quot;&gt;扬州&lt;/span&gt;&lt;/h4&gt;
&lt;p&gt;2023-08-22&lt;br&gt;
扬州很不错，好玩、好吃。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;img src=&quot;http</summary>
      
    
    
    
    
    <category term="读书" scheme="https://tyzhang.top/tags/%E8%AF%BB%E4%B9%A6/"/>
    
  </entry>
  
  <entry>
    <title>十四</title>
    <link href="https://tyzhang.top/article/new-year/"/>
    <id>https://tyzhang.top/article/new-year/</id>
    <published>2022-12-30T16:00:00.000Z</published>
    <updated>2023-11-08T16:30:05.088Z</updated>
    
    <content type="html"><![CDATA[<blockquote><p>电影《甲方乙方》有一句经典的台词，1999 年过去了，我很怀念它。今天，2022 年就要过去了，但我并不想再怀念它。</p></blockquote><p>按惯例，每年的这个时候是要有一篇年终随笔，给自己，给家人，给所有关心我的朋友们。</p><p>昨晚躺在床上，翻来覆去，好像在这场宏大的叙事中，个人的一切文字都显得苍白无力。翻了翻相册，今年也拍了很多照片，不如就用一个个瞬间回顾今年吧。照片不像文字，它没那么会说谎。</p><h4><span id="2022-年-1-月-30-号在大润发办年货贴对联掌勺年夜饭">2022 年 1 月 30 号，在大润发，办年货贴对联，掌勺年夜饭。</span></h4><p><a href="https://pic.tyzhang.top/image/OYj8"><img src="https://pic.tyzhang.top/images/2022/12/31/2022-01-30.jpg" alt="2022-01-30.jpg"></a></p><h4><span id="2022-年-2-月-29-号上海下班后两个朋友在车库打闹">2022 年 2 月 29 号，上海，下班后，两个朋友在车库打闹。</span></h4><p><a href="https://pic.tyzhang.top/image/O1i0"><img src="https://pic.tyzhang.top/images/2022/12/31/2022-02-29.jpg" alt="2022-02-29.jpg"></a></p><h4><span id="2022-年-3-月-26-号通知开始为期四天的封控没想那么多那一天我把冰箱里的肉都拿出来做了">2022 年 3 月 26 号，通知开始为期四天的封控，没想那么多，那一天，我把冰箱里的肉都拿出来做了。</span></h4><p><a href="https://pic.tyzhang.top/image/OFFs"><img src="https://pic.tyzhang.top/images/2022/12/31/2022-03-26.jpg" alt="2022-03-26.jpg"></a></p><h4><span id="2022-年-4-月-2-号四天结束没有等来解封等来了封城的消息和发放的物资">2022 年 4 月 2 号，四天结束，没有等来解封，等来了封城的消息和发放的物资。</span></h4><p><a href="https://pic.tyzhang.top/image/OLKL"><img src="https://pic.tyzhang.top/images/2022/12/31/2022-04-02.jpg" alt="2022-04-02.jpg"></a></p><h4><span id="2022-年-4-月-17-号搞到了一些可乐生活已经很苦了为什么不喝点甜的呢">2022 年 4 月 17 号，搞到了一些可乐，生活已经很苦了，为什么不喝点甜的呢。</span></h4><p><a href="https://pic.tyzhang.top/image/OAR5"><img src="https://pic.tyzhang.top/images/2022/12/31/2022-04-17.jpg" alt="2022-04-17.jpg"></a></p><h4><span id="2022-年-4-月-21-号第一次当上管长">2022 年 4 月 21 号，第一次当上“管长”。</span></h4><p><a href="https://pic.tyzhang.top/image/OQqK"><img src="https://pic.tyzhang.top/images/2022/12/31/2022-04-21.jpg" alt="2022-04-21.jpg"></a></p><h4><span id="2022-年-4-月-28-号小葱成为紧俏货小区群里开始交流水培葱经验楼下的樱花已经悄悄开过又谢">2022 年 4 月 28 号，小葱成为紧俏货，小区群里开始交流水培葱经验，楼下的樱花已经悄悄开过又谢。</span></h4><h4><span id></span></h4><h4><span id="2022-年-4-月-29-号发了很多抗原-连花清瘟但是不让随便吃-弹尽粮绝大家开始琢磨当时正如火如荼的团购">2022 年 4 月 29 号，发了很多抗原、连花清瘟，但是不让随便吃。弹尽粮绝，大家开始琢磨当时正如火如荼的“团购”。</span></h4><p><a href="https://pic.tyzhang.top/image/OiZo"><img src="https://pic.tyzhang.top/images/2022/12/31/2022-04-29.jpg" alt="2022-04-29.jpg"></a></p><h4><span id="2022-年-5-月-1-号放了假不能出门刷着疫情新闻看着天">2022 年 5 月 1 号，放了假，不能出门，刷着疫情新闻看着天。</span></h4><p><a href="https://pic.tyzhang.top/image/OJNJ"><img src="https://pic.tyzhang.top/images/2022/12/31/2022-05-01.jpg" alt="2022-05-01.jpg"></a></p><h4><span id="2022-年-5-月-7-号收到公司发放的物资和补贴意外发现小区里还有不少同事因为还有好几个同款泡沫箱">2022 年 5 月 7 号，收到公司发放的物资和补贴，意外发现小区里还有不少同事，因为还有好几个同款泡沫箱。</span></h4><p><a href="https://pic.tyzhang.top/image/OOcT"><img src="https://pic.tyzhang.top/images/2022/12/31/2022-05-07.jpg" alt="2022-05-07.jpg"></a></p><h4><span id="2022-年-5-月-31-号小区降为防范区解封三个月来第一次出门是在小区门口做核酸">2022 年 5 月 31 号，小区降为防范区，解封，三个月来第一次出门，是在小区门口做核酸。</span></h4><p><a href="https://pic.tyzhang.top/image/O0h1"><img src="https://pic.tyzhang.top/images/2022/12/31/2022-05-31.jpg" alt="2022-05-31.jpg"></a></p><h4><span id="2022-年-6-月-5-号江南阴雨天雨后彩虹现">2022 年 6 月 5 号，“江南阴雨天，雨后彩虹现”。</span></h4><p><a href="https://pic.tyzhang.top/image/O57A"><img src="https://pic.tyzhang.top/images/2022/12/31/2022-06-05.jpg" alt="2022-06-05.jpg"></a></p><h4><span id="2022-年-7-月-1-号结束居家办公去工区那一天天气不错">2022 年 7 月 1 号，结束居家办公，去工区，那一天天气不错。</span></h4><p><a href="https://pic.tyzhang.top/image/OVJn"><img src="https://pic.tyzhang.top/images/2022/12/31/2022-07-01.jpg" alt="2022-07-01.jpg"></a></p><h4><span id="2022-年-7-月-17-号和同事周末一起参加净滩公益行动成为河流守望者">2022 年 7 月 17 号，和同事周末一起参加“净滩公益行动”，成为河流守望者。</span></h4><p><a href="https://pic.tyzhang.top/image/OwK9"><img src="https://pic.tyzhang.top/images/2022/12/31/2022-07-171.jpg" alt="2022-07-171.jpg"></a></p><h4><span id="2022-年-8-月-12-号丰富下业余生活在内部商城花-9-块-9-买了十颗多肉">2022 年 8 月 12 号，丰富下业余生活，在内部商城花 9 块 9 买了十颗多肉。</span></h4><p><a href="https://pic.tyzhang.top/image/O6Mp"><img src="https://pic.tyzhang.top/images/2022/12/31/2022-08-12.jpg" alt="2022-08-12.jpg"></a></p><h4><span id="2022-年-9-月-17-号在共青国家森林公园坐在江边看了半个小时来来往往的货船">2022 年 9 月 17 号，在共青国家森林公园，坐在江边看了半个小时来来往往的货船。</span></h4><p><a href="https://pic.tyzhang.top/image/OHqH"><img src="https://pic.tyzhang.top/images/2022/12/31/2022-09-17.jpg" alt="2022-09-17.jpg"></a></p><h4><span id="2022-年-10-月-13-号每周二四七做核酸路上发现大堂这个角度还挺好看">2022 年 10 月 13 号，每周二四七做核酸，路上发现大堂这个角度还挺好看。</span></h4><p><a href="https://pic.tyzhang.top/image/OXpN"><img src="https://pic.tyzhang.top/images/2022/12/31/2022-10-13.jpg" alt="2022-10-13.jpg"></a></p><h4><span id="2022-年-11-月-25-号和朋友们一起在北外滩闲逛在前几天我刚重温完蜗居">2022 年 11 月 25 号，和朋友们一起在北外滩闲逛，在前几天，我刚重温完《蜗居》。</span></h4><p><a href="https://pic.tyzhang.top/image/OqNt"><img src="https://pic.tyzhang.top/images/2022/12/31/2022-11-25.jpg" alt="2022-11-25.jpg"></a></p><h4><span id="2022-年-12-月-24-号平安夜和师兄闲聊发现家里还有一颗苹果许愿家人-朋友健健康康-用一个汉字回顾今年师兄选了难我选了艹">2022 年 12 月 24 号，平安夜，和师兄闲聊，发现家里还有一颗苹果，许愿家人、朋友健健康康。用一个汉字回顾今年，师兄选了“<strong>难</strong>”，我选了“艹”。</span></h4><p><a href="https://pic.tyzhang.top/image/OSwZ"><img src="https://pic.tyzhang.top/images/2022/12/31/2022-12-24.jpg" alt="2022-12-24.jpg"></a></p><h4><span id="2022-年-12-月-31-号四个菜炒完菜坐下来发现仪式感这东西人越多越像样">2022 年 12 月 31 号，四个菜，炒完菜坐下来，发现仪式感这东西，人越多越像样。</span></h4><p><a href="https://pic.tyzhang.top/image/Otjg"><img src="https://pic.tyzhang.top/images/2022/12/31/2022-12-31.md.jpg" alt="2022-12-31.md.jpg"></a></p><h4><span id="新年快乐再见2022再也不见">新年快乐，再见，2022，再也不见。</span></h4>]]></content>
    
    
      
      
    <summary type="html">&lt;blockquote&gt;
&lt;p&gt;电影《甲方乙方》有一句经典的台词，1999 年过去了，我很怀念它。今天，2022 年就要过去了，但我并不想再怀念它。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;按惯例，每年的这个时候是要有一篇年终随笔，给自己，给家人，给所有关心我的朋友们。&lt;/p&gt;</summary>
      
    
    
    
    
    <category term="少年游" scheme="https://tyzhang.top/tags/%E5%B0%91%E5%B9%B4%E6%B8%B8/"/>
    
  </entry>
  
  <entry>
    <title>十三</title>
    <link href="https://tyzhang.top/article/byegewen/"/>
    <id>https://tyzhang.top/article/byegewen/</id>
    <published>2022-07-09T16:00:00.000Z</published>
    <updated>2022-07-10T11:13:28.000Z</updated>
    
    <content type="html"><![CDATA[<blockquote><p>最近在玩一个很有意思的游戏，灵魂旅者。</p></blockquote><p>​    忘记和葛文相识的时候是什么场景了，在盛夏的下午，在小岛上再遇到了它。</p><p>​    那时候的我刚接过了夏隆灵魂摆渡人的衣钵，一艘小船，陪着我的还有一只猫。我的任务是帮一个个灵魂实现愿望，送走他们。</p><p><img src="https://pic.tyzhang.top/images/2022/07/10/2022062921475200_s.jpg" alt="2022062921475200_s.jpg"></p><p>​    起初，它住在船上的客房中。我们一起在船上建造并改进了一间属于它自己的房间，还一起去过几次浣熊商店，买亚麻线。它常常会问我，亚麻线买多了，是直接给我，还是织好了再给我。尽管经常选择了织好再给我，它仍然教会了我用织布机。</p><p>​    葛文喜欢喝黑咖啡，喜欢吃没吃过的食物，不喜欢吃水果。我买来咖啡种子，收获咖啡豆之后在厨房做上一杯黑咖啡会摇晃铃铛叫醒大家吃早饭。它会告诉我，在早上摇铃没完没了是不礼貌的。</p><p>​    在这船上的日日夜夜，我的灵魂小船，也渐渐升级到了灵魂渡轮。我们一起走过了很多岛屿，认识了很多朋友，接上了阿图尔、爱丽丝。葛文还向我分享了很多关于以前的秘密。我们一起参观了它儿时的家，在父母的庄园，它讲着和父母的心结和矛盾。</p><p><img src="https://pic.tyzhang.top/images/2022/07/10/5006c68868b0704c30e2df898cbd164a.jpg" alt="5006c68868b0704c30e2df898cbd164a.jpg"></p><p>​    有一天我看到了“我得走了”的提示，想到可能是葛文。但我转遍了每个房间，也没有找到它。当我终于在别墅找到了它，此刻的它放下了矛盾和心结，准备好离开。后来我在永恒之桥周边徘徊了很久，依旧每天早上会为它做一杯黑咖啡，在厨房准备着它没有吃过的食材。总归还是要分别，我也要前往下一个目的地，船上的小伙伴一起送别了葛文。</p><p><img src="https://pic.tyzhang.top/images/2022/07/10/7623233d264f925bd8673afd23a41d6a.jpg" alt="7623233d264f925bd8673afd23a41d6a.jpg"></p><p>​    “别忘了我曾深深爱过你，再见了，我的朋友”，我们用拥抱迎接别离，就像以前它不开心时那样，最终变成了天空中的星座。</p><p><img src="https://pic.tyzhang.top/images/2022/07/10/2022071016410300_s.jpg" alt="2022071016410300_s.jpg"></p><p><img src="https://pic.tyzhang.top/images/2022/07/10/2022071016411100_s.jpg" alt="2022071016411100_s.jpg"></p><p>​    我们最先认识的人，往往要最先离开。《寻梦环游记》中，艾米托说，真正的死亡是遗忘，是世间再无有关你的记忆。死也并非作为生的对立面，而是作为生的一部分永远存在。</p><p>​    我将继续驾驶渡轮游历冥河诸岛。</p><p><img src="https://pic.tyzhang.top/images/2022/07/10/Snipaste_2022-07-10_18-52-34.png" alt="Snipaste_2022-07-10_18-52-34.png"></p>]]></content>
    
    
      
      
    <summary type="html">&lt;blockquote&gt;
&lt;p&gt;最近在玩一个很有意思的游戏，灵魂旅者。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;​    忘记和葛文相识的时候是什么场景了，在盛夏的下午，在小岛上再遇到了它。&lt;/p&gt;
&lt;p&gt;​    那时候的我刚接过了夏隆灵魂摆渡人的衣钵，一艘小船，陪着我的还有</summary>
      
    
    
    
    
    <category term="少年游" scheme="https://tyzhang.top/tags/%E5%B0%91%E5%B9%B4%E6%B8%B8/"/>
    
  </entry>
  
  <entry>
    <title>十二</title>
    <link href="https://tyzhang.top/article/road/"/>
    <id>https://tyzhang.top/article/road/</id>
    <published>2022-06-08T16:00:00.000Z</published>
    <updated>2022-06-09T09:45:34.000Z</updated>
    
    <content type="html"><![CDATA[<blockquote><p>距离上次更新博客好像快一年了，攒了一些话题，却又不知道该从何写起。</p></blockquote><p><img src="https://pic.tyzhang.top/images/2022/06/09/_20220609173117.jpg" alt="村西头也有这么一条路"></p><p>​    村子的西头也有这么一条路，路的两边是高大的行道树。</p><p>​    这条路没有硬化过的路面，在雨后会被车轮碾压的泥泞不堪。村口还有一座桥，是在一年路面抬高的时候一起修的。桥是水泥桥，桥下面的水沟不深，南北通连着农田，平日里坡上长着绿草，沟沿上放着，放羊的人会坐在桥墩上，看着羊慢吞吞的啃着青草。</p><p>​    道路两旁的农田里应季种着玉米、花生或者小麦。浇地可以从周围的自用井里挑水，赶到旱时要从池塘里抽水。池塘主人会把大泵打开，让水流入农田两侧的灌溉渠里。放水浇地一家接着一家，拿着铁锨在地头看着，轮到自己了，就先把下游堵住，把水渠预留的口打开，让水流到自家田地里。灌溉完后，渠里的水就会渐渐退去，留下一些坑坑洼洼的积水，长上了草丛，慢慢就驻扎了蛤蟆、蚊子。</p><p><img src="https://pic.tyzhang.top/images/2022/06/09/1284.jpg" alt="农村的灌溉渠"></p><p>​    路往西继续走，往北穿过黄埠西，就是汶泗公路，从这条路可以去镇上。我家住在村西头，爸爸从这条路带回来过新华字典、钢笔、卷笔刀和羊肉汤。还有在镇上上幼儿园的我。字典和新华书店的卷笔刀，是在镇上的新华书店买的，在中心街十字路口的拐角，里面是一排玻璃柜台。</p><p>​    我小时候的活动半径也就这么远，那时候感觉房子大、路远。站在村头的这条路上，向西看去，一望无际的农田，和视野尽处的一排排树林，还有那挂在树杈上的咸蛋黄样的太阳。</p><p><img src="https://pic.tyzhang.top/images/2022/06/09/727928_175118042922_2.jpg" alt="印象里村子的夕阳"></p><p>​    刚才翻看卫星地图，新屋林立的村子里，老屋更难找了。这条满满林荫的路还在，只是是否已经变了模样我已经无从知晓了。</p><p>​    最后一次走过这条路，是十几年前搬家到临沂，在一个早晨，在一辆塞满了家当、装满了回忆的面包车上。</p>]]></content>
    
    
      
      
    <summary type="html">&lt;blockquote&gt;
&lt;p&gt;距离上次更新博客好像快一年了，攒了一些话题，却又不知道该从何写起。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src=&quot;https://pic.tyzhang.top/images/2022/06/09/_20220609173117.j</summary>
      
    
    
    
    
    <category term="少年游" scheme="https://tyzhang.top/tags/%E5%B0%91%E5%B9%B4%E6%B8%B8/"/>
    
  </entry>
  
  <entry>
    <title>十一</title>
    <link href="https://tyzhang.top/article/stuend/"/>
    <id>https://tyzhang.top/article/stuend/</id>
    <published>2021-05-30T16:00:00.000Z</published>
    <updated>2022-06-09T09:46:40.000Z</updated>
    
    <content type="html"><![CDATA[<blockquote><p>遥知天下路，不负远行人。节选自硕士毕业论文致谢。</p></blockquote><p>​    时光如水，总是无言，入学已悄然三载。在论文完成之际，想对长期以来对我的学术、科研与生活一直关心的老师、家人、同学和朋友们表示最为衷心的感谢。</p><p>​    首先，谨向导师张建辉教授致以由衷的感谢。您在科研工作指导上的不厌其烦的帮助，让我克服了重重困难，最终得以顺利地完成科研工作。感谢您在科研和人生道路上的谆谆教导。</p><p>​    感谢父母的养育之恩，还有长久以来的付出，你们的支持和理解是我最大的动力。我的父母都是辛苦了半辈子的庄稼人。在同村的孩子早早辍学结婚生子时，坚信读书是我唯一出路，带我进城，省吃俭用供我求学至今。走上计算机的道路多是源于我自己的兴趣，父母虽然不懂这些，但也没有就此阻拦。不仅如此，父母对我人生中的每一次选择都十分支持，是我强大的后盾，他们常说我是他们最大的骄傲。感谢父母长期以来的厚爱与支持。</p><p>​    还要感谢生命中的那些朋友们。感谢挚友包浩伊、王记龙和吕冠晓，虽与你们远隔千山万水，无需多言，却心意相通。</p><p>​    感谢同门邓育健、管思琪以及师弟宋正兵、郑航、刘黎明、王嘉诚和王瀚翔在科研工作以及生活上的帮助。</p><p>​    感谢师兄师姐姜飞龙、甘家羽、卢鹏钎、郑思文和张天豪在学习、科研以及生活上的帮助。特别感谢姜飞龙、郑思文和张天豪，与你们一起学习、一起快乐的日子将铭记于心。</p><p>​    感谢舍友施康康和同届刁文杰读研期间的陪伴和支持。</p><p>​    最后，感谢自己迷茫时的坚持，感谢自己低落时的自我调节。感谢自己走过的路，感谢自己遇到的人。</p><p>​    遥知天下路，不负远行人。</p><p>——2021年5月 于浙江杭州</p>]]></content>
    
    
      
      
    <summary type="html">&lt;blockquote&gt;
&lt;p&gt;遥知天下路，不负远行人。节选自硕士毕业论文致谢。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;​    时光如水，总是无言，入学已悄然三载。在论文完成之际，想对长期以来对我的学术、科研与生活一直关心的老师、家人、同学和朋友们表示最为衷心的感谢。&lt;/p</summary>
      
    
    
    
    
    <category term="少年游" scheme="https://tyzhang.top/tags/%E5%B0%91%E5%B9%B4%E6%B8%B8/"/>
    
  </entry>
  
  <entry>
    <title>LeetCode 解题报告</title>
    <link href="https://tyzhang.top/article/leetcodesolu/"/>
    <id>https://tyzhang.top/article/leetcodesolu/</id>
    <published>2021-04-06T16:00:00.000Z</published>
    <updated>2021-04-09T07:13:58.000Z</updated>
    
    <content type="html"><![CDATA[<blockquote><p>LeetCode 解题报告与每日打卡记录，顺便记录不太顺利或者有其他巧妙思路的题目。题目较多，渲染可能比较缓慢。<font id="qusnum"></font></p></blockquote><script src="/js/jquery.min.js"></script><script language="javascript" type="text/javascript">$(document).ready(function(){    var i=$('h3').size();    var years = {};var myDate = new Date(); var year = myDate.getFullYear();var month = myDate.getMonth()+1;var day = myDate.getDate();var newDay = year + "年" + month + "月" + day + "日";    var str = '截至' + newDay +  '，已收录' + i + '道题目。';    document.getElementById('qusnum').innerHTML = str;});</script><!-- <font id="qusnum" style="font-size:20px; font-weight: bold;"></font> --><h3><span id="2-add-two-numbers">2 Add Two Numbers</span></h3><h4><span id="题目大意">题目大意</span></h4><p>多位整数每位按照倒序排列放入链表，使用链表求和并返回。</p><h4><span id="解题思路">解题思路</span></h4><p>设立一个表示进位的变量temp，建立一个新链表，把输入的两个链表从头往后同时处理，每两个相加，将结果加上temp%10后的进位作为一个新节点到新链表后面。</p><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> ListNode <span class="title function_">addTwoNumbers</span><span class="params">(ListNode l1, ListNode l2)</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> (l1 == <span class="literal">null</span>)</span><br><span class="line">            <span class="keyword">return</span> l1;</span><br><span class="line">        <span class="keyword">if</span> (l2 == <span class="literal">null</span>)</span><br><span class="line">            <span class="keyword">return</span> l2;</span><br><span class="line">        <span class="type">ListNode</span> <span class="variable">resu</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">ListNode</span>(<span class="number">0</span>);</span><br><span class="line">        <span class="type">ListNode</span> <span class="variable">node</span> <span class="operator">=</span> resu;</span><br><span class="line">        <span class="type">int</span> <span class="variable">temp</span> <span class="operator">=</span> <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> || temp != <span class="number">0</span>) &#123;</span><br><span class="line">            <span class="keyword">if</span> (l1 != <span class="literal">null</span>) &#123;</span><br><span class="line">                temp += l1.val;</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">                temp += l2.val;</span><br><span class="line">                l2 = l2.next;</span><br><span class="line">            &#125;</span><br><span class="line">            node.next = <span class="keyword">new</span> <span class="title class_">ListNode</span>(temp % <span class="number">10</span>);</span><br><span class="line">            node = node.next;</span><br><span class="line">            temp /= <span class="number">10</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> resu.next;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3><span id="3-longest-substring-without-repeating-characters">3  Longest Substring Without Repeating Characters</span></h3><h4><span id="题目大意">题目大意</span></h4><p>寻找最长的无重复的子串。</p><h4><span id="解题思路">解题思路</span></h4><p>寻找当前字符串出现的上一次位置，长度就是中间的长度，因为中间的字符串也是这么判断过来的。</p><p>这里的 start 和 map 数组设计的很巧妙。</p><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">lengthOfLongestSubstring</span><span class="params">(String s)</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> (s == <span class="literal">null</span> || s.length() == <span class="number">0</span>) <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">        <span class="type">int</span>[] count = <span class="keyword">new</span> <span class="title class_">int</span>[<span class="number">256</span>];</span><br><span class="line">        <span class="comment">// 因为0也是位置，所以全部-1防止误判断</span></span><br><span class="line">        Arrays.fill(count, -<span class="number">1</span>);</span><br><span class="line">        <span class="type">int</span> <span class="variable">start</span> <span class="operator">=</span> -<span class="number">1</span>, result = <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; s.length(); i++)&#123;</span><br><span class="line">            <span class="comment">// 更新重复的字符最后一次出现的位置</span></span><br><span class="line">            start = Math.max(count[s.charAt(i)], start);</span><br><span class="line">            <span class="comment">// 修改当前字符出现的位置</span></span><br><span class="line">            count[s.charAt(i)] = i;</span><br><span class="line">            <span class="comment">// 取最大值</span></span><br><span class="line">            result = Math.max(result, i - start);</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><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3><span id="5-longest-palindromic-substring">5 Longest Palindromic Substring</span></h3><h4><span id="题目大意">题目大意</span></h4><p>寻找字符串中最长的回文子串。</p><h4><span id="解题思路">解题思路</span></h4><p>动态规划，设置dp[i][j]为字符串上i到j的字符串是否为子串。它将由它的内部决定，即如果它的两头相等的话且去掉两头后仍为回文字符串。即：<br>$$<br>dp[i][j] = dp[i+1][j-1], if(s[i]==s[j])<br>$$<br>发现回文字符串后，更新最大值。同时，显然有些必要条件要考虑，如i一定是&lt;=j的。</p><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> String <span class="title function_">longestPalindrome</span><span class="params">(String s)</span> &#123;</span><br><span class="line">        <span class="type">boolean</span>[][] dp = <span class="keyword">new</span> <span class="title class_">boolean</span>[<span class="number">1005</span>][<span class="number">1005</span>];</span><br><span class="line">        <span class="type">int</span> <span class="variable">left</span> <span class="operator">=</span> <span class="number">0</span>;</span><br><span class="line">        <span class="type">int</span> <span class="variable">right</span> <span class="operator">=</span> <span class="number">0</span>;</span><br><span class="line">        <span class="type">int</span> <span class="variable">maxl</span> <span class="operator">=</span> <span class="number">1</span>;</span><br><span class="line">        <span class="type">int</span> <span class="variable">n</span> <span class="operator">=</span> s.length();</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">j</span> <span class="operator">=</span> <span class="number">0</span>; j &lt; n; j++) &#123;</span><br><span class="line">            <span class="comment">// 单个字符肯定是回文字符串</span></span><br><span class="line">            dp[j][j] = <span class="literal">true</span>;</span><br><span class="line">            <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; j; i++) &#123;</span><br><span class="line">                <span class="keyword">if</span> (s.charAt(i) == s.charAt(j) &amp;&amp; (j - i &lt; <span class="number">2</span> || dp[i + <span class="number">1</span>][j - <span class="number">1</span>])) &#123;</span><br><span class="line">                    dp[i][j] = <span class="literal">true</span>;</span><br><span class="line">                &#125;</span><br><span class="line">                <span class="keyword">if</span> (dp[i][j] &amp;&amp; maxl &lt; j - i + <span class="number">1</span>) &#123;</span><br><span class="line">                    maxl = j - i + <span class="number">1</span>;</span><br><span class="line">                    left = i;</span><br><span class="line">                    right = 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> (s == <span class="literal">null</span> || s.length() &lt;= <span class="number">1</span>) ? s : s.substring(left, 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><h3><span id="6-zigzag-conversion">6 ZigZag Conversion</span></h3><h4><span id="题目大意">题目大意</span></h4><p>将字符串改为N字后逐行输出，例如 “PAYPALISHIRING” 输出为 “PAHNAPLSIIGYIR” 。</p><h4><span id="解题思路">解题思路</span></h4><p>使用StringBuffer作为储存每一行的工具，然后分别处理上下两种状态。</p><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> String <span class="title function_">convert</span><span class="params">(String s, <span class="type">int</span> nRows)</span> &#123;</span><br><span class="line">        <span class="type">char</span>[] c = s.toCharArray();</span><br><span class="line">        <span class="type">int</span> <span class="variable">len</span> <span class="operator">=</span> c.length;</span><br><span class="line">        StringBuffer[] sb = <span class="keyword">new</span> <span class="title class_">StringBuffer</span>[nRows];</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; sb.length; i++)</span><br><span class="line">            sb[i] = <span class="keyword">new</span> <span class="title class_">StringBuffer</span>();</span><br><span class="line">        <span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">while</span> (i &lt; len) &#123;</span><br><span class="line">            <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">idx</span> <span class="operator">=</span> <span class="number">0</span>; idx &lt; nRows &amp;&amp; i &lt; len; idx++) <span class="comment">// 竖着的</span></span><br><span class="line">                sb[idx].append(c[i++]);</span><br><span class="line">            <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">idx</span> <span class="operator">=</span> nRows - <span class="number">2</span>; idx &gt;= <span class="number">1</span> &amp;&amp; i &lt; len; idx--) <span class="comment">// 斜向上的</span></span><br><span class="line">                sb[idx].append(c[i++]);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">idx</span> <span class="operator">=</span> <span class="number">1</span>; idx &lt; sb.length; idx++)</span><br><span class="line">            sb[<span class="number">0</span>].append(sb[idx]);</span><br><span class="line">        <span class="keyword">return</span> sb[<span class="number">0</span>].toString();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3><span id="8-string-to-integer-atoi">8 String to Integer (atoi)</span></h3><h4><span id="题目大意">题目大意</span></h4><p>将输入的字符串转化为整数。有以下几点要求：</p><ol><li>第一个非空字符必须是可选的±或者数字，然后是一些数字。</li><li>字符串后面可以包含额外字符，将被忽略。</li><li>如果非法，将不发生转换。</li><li>没有发生转换返回0，如果超出了正值就返回整数最大值，或者最小值。</li></ol><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><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">Input: &quot;   -42&quot;</span><br><span class="line">Output: -42</span><br><span class="line">Explanation: The first non-whitespace character is &#x27;-&#x27;, which is the minus sign.</span><br><span class="line">             Then take as many numerical digits as possible, which gets 42.</span><br><span class="line">Input: &quot;4193 with words&quot;</span><br><span class="line">Output: 4193</span><br><span class="line">Explanation: Conversion stops at digit &#x27;3&#x27; as the next character is not a numerical digit.</span><br><span class="line">Input: &quot;words and 987&quot;</span><br><span class="line">Output: 0</span><br><span class="line">Explanation: The first non-whitespace character is &#x27;w&#x27;, which is not a numerical </span><br><span class="line">             digit or a +/- sign. Therefore no valid conversion could be performed.</span><br></pre></td></tr></table></figure><h4><span id="解题思路">解题思路</span></h4><p>按照题目要求处理即可，注意最大值最小值的判断。</p><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">myAtoi</span><span class="params">(String str)</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> (str == <span class="literal">null</span> || str.length() == <span class="number">0</span>)</span><br><span class="line">            <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">        str = str.trim();</span><br><span class="line">        <span class="keyword">if</span> (str.length() == <span class="number">0</span>)</span><br><span class="line">            <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">        <span class="type">int</span> <span class="variable">start</span> <span class="operator">=</span> <span class="number">0</span>, sign = <span class="number">1</span>, base = <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">if</span> (str.charAt(start) == <span class="string">&#x27;-&#x27;</span> || str.charAt(start) == <span class="string">&#x27;+&#x27;</span>) &#123;</span><br><span class="line">            sign = (str.charAt(start) == <span class="string">&#x27;-&#x27;</span> ? -<span class="number">1</span> : <span class="number">1</span>);</span><br><span class="line">            start++;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">while</span> (start &lt; str.length() &amp;&amp; str.charAt(start) &gt;= <span class="string">&#x27;0&#x27;</span> &amp;&amp; str.charAt(start) &lt;= <span class="string">&#x27;9&#x27;</span>) &#123;</span><br><span class="line">            <span class="keyword">if</span> (base &gt; Integer.MAX_VALUE / <span class="number">10</span></span><br><span class="line">                    || (base == Integer.MAX_VALUE / <span class="number">10</span> &amp;&amp; (str.charAt(start) - <span class="string">&#x27;0&#x27;</span> &gt; Integer.MAX_VALUE % <span class="number">10</span>))) &#123;</span><br><span class="line">                <span class="keyword">return</span> sign &gt; <span class="number">0</span> ? Integer.MAX_VALUE : Integer.MIN_VALUE;</span><br><span class="line">            &#125;</span><br><span class="line">            base = base * <span class="number">10</span> + (str.charAt(start++) - <span class="string">&#x27;0&#x27;</span>);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> base * sign;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3><span id="9-palindrome-number">9 Palindrome Number</span></h3><h4><span id="题目大意">题目大意</span></h4><p>判断一个整数是不是回文数。</p><h4><span id="解题思路">解题思路</span></h4><ol><li>利用字符串的反转，回文串反转和原串相同。</li><li>判断每个位数。</li></ol><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><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="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="type">boolean</span> <span class="title function_">isPalindrome</span><span class="params">(<span class="type">int</span> x)</span> &#123;</span><br><span class="line">        <span class="type">String</span> <span class="variable">str</span> <span class="operator">=</span> String.valueOf(x);</span><br><span class="line">        <span class="type">StringBuilder</span> <span class="variable">sb</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">StringBuilder</span>(str);</span><br><span class="line">        <span class="keyword">return</span> sb.reverse().toString().equals(str);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="type">boolean</span> <span class="title function_">isPalindrome</span><span class="params">(<span class="type">int</span> x)</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="type">int</span>[] a = <span class="keyword">new</span> <span class="title class_">int</span>[<span class="number">33</span>];</span><br><span class="line">        <span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <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">            a[i++] = x % <span class="number">10</span>;</span><br><span class="line">            x /= <span class="number">10</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">j</span> <span class="operator">=</span> <span class="number">0</span>; j &lt; i; j++) &#123;</span><br><span class="line">            <span class="keyword">if</span> (a[j] != a[i - j - <span class="number">1</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">        &#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="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line">        System.out.println(isPalindrome(<span class="number">1234564321</span>));</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3><span id="10-regular-expression-matching">10 Regular Expression Matching</span></h3><h4><span id="题目大意">题目大意</span></h4><p>字符串的匹配，<code>.</code>表示任意字符，<code>*</code>表示一个字符重复n次或者0次。</p><h4><span id="解题思路与代码">解题思路与代码</span></h4><p>这道题开始理解为了*为代表任意个数的任意字符，提交怎么也不对，后来看了别人的解析恍然大悟，题目会错意了，已经不是第一次了。下面是总结了一下简书上一个很棒的解析。</p><h5><span id="一-递归">一、递归</span></h5><ol><li><p>先假设没有通配符<code>*</code>，只需要一个字符一个字符的匹配即可。</p><p>设函数为isMatch(String text, String pattern)，text和pattern匹配，等价于text和pattern的第一个字符匹配并且剩下的也匹配。去判断剩下的是否匹配时候，就可以继续调用isMatch函数。</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">boolean</span> <span class="variable">first_match</span> <span class="operator">=</span> (pattern.charAt(<span class="number">0</span>) == text.charAt(<span class="number">0</span>) || pattern.charAt(<span class="number">0</span>) == <span class="string">&#x27;.&#x27;</span>)&amp;&amp;isMatch(text.substring(<span class="number">1</span>), pattern.substring(<span class="number">1</span>));</span><br></pre></td></tr></table></figure><p>递归出口：随着规模的减小，当pattern为空的时候，如果text也为空，就返回true，否则就返回false。</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">if</span> (pattern.isEmpty()) <span class="keyword">return</span> text.isEmpty();</span><br></pre></td></tr></table></figure><p>综上所述，针对1的代码如下，</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><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">public</span> <span class="type">boolean</span> <span class="title function_">isMatch</span><span class="params">(String text, String pattern)</span> &#123;</span><br><span class="line"><span class="keyword">if</span> (pattern.isEmpty()) <span class="keyword">return</span> text.isEmpty();</span><br><span class="line"><span class="comment">//判断 text 是否为空，防止越界，如果 text 为空， 表达式直接判为 false, text.charAt(0)就不会执行了</span></span><br><span class="line"><span class="type">boolean</span> <span class="variable">first_match</span> <span class="operator">=</span> (!text.isEmpty() &amp;&amp; (pattern.charAt(<span class="number">0</span>) == text.charAt(<span class="number">0</span>) || pattern.charAt(<span class="number">0</span>) == <span class="string">&#x27;.&#x27;</span>));</span><br><span class="line"><span class="keyword">return</span> first_match &amp;&amp; isMatch(text.substring(<span class="number">1</span>), pattern.substring(<span class="number">1</span>));</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></li><li><p>当考虑了通配符，代码如下</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><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="keyword">public</span> <span class="type">boolean</span> <span class="title function_">isMatch</span><span class="params">(String text, String pattern)</span> &#123;</span><br><span class="line"><span class="keyword">if</span> (pattern.isEmpty()) <span class="keyword">return</span> text.isEmpty();</span><br><span class="line"><span class="type">boolean</span> <span class="variable">first_match</span> <span class="operator">=</span> (!text.isEmpty() &amp;&amp; (pattern.charAt(<span class="number">0</span>) == text.charAt(<span class="number">0</span>) || pattern.charAt(<span class="number">0</span>) == <span class="string">&#x27;.&#x27;</span>));</span><br><span class="line"><span class="comment">//只有长度大于 2 的时候，才考虑 *</span></span><br><span class="line"><span class="keyword">if</span> (pattern.length() &gt;= <span class="number">2</span> &amp;&amp; pattern.charAt(<span class="number">1</span>) == <span class="string">&#x27;*&#x27;</span>)&#123;</span><br><span class="line">        <span class="comment">//两种情况</span></span><br><span class="line">        <span class="comment">//pattern 直接跳过两个字符。表示 * 前边的字符出现 0 次</span></span><br><span class="line">        <span class="comment">//pattern 不变，例如 text = aa ，pattern = a*，第一个 a 匹配，然后 text 的第二个 a 接着和 pattern 的第一个 a 进行匹配。表示 * 用前一个字符替代。</span></span><br><span class="line">        <span class="keyword">return</span> (isMatch(text, pattern.substring(<span class="number">2</span>)) || (first_match &amp;&amp; isMatch(text.substring(<span class="number">1</span>), pattern)));</span><br><span class="line">&#125; <span class="keyword">else</span> &#123;</span><br><span class="line"><span class="keyword">return</span> first_match &amp;&amp; isMatch(text.substring(<span class="number">1</span>), pattern.substring(<span class="number">1</span>));</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></li></ol><h5><span id="二-动态规划">二、动态规划</span></h5><p>设定二维数组 dp[i][j] 表示 s[0…i-1] 可以和 p[0…j-1] 完全匹配，那么会存在以下几种情况：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><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">1. if s[i-1] == p[j-1] || p[j-1] == &#x27;.&#x27; : dp[i][j] = dp[i-1][j-1] // i-1和j-1相同，或者可以跳过</span><br><span class="line">2. if p[j-1] == &#x27;*&#x27;:</span><br><span class="line">// j-1是*了，看j-2，如果j-2不是*而且不等于i-1，就不要这个字符了</span><br><span class="line">if p[j-2] != &#x27;*&#x27; &amp;&amp; p[j-2] != s[i-1]: dp[i][j] = dp[i][j-2] // 0a</span><br><span class="line">// 不然的话，分情况讨论</span><br><span class="line">else:</span><br><span class="line">dp[i][j] = dp[i][j-2] // 0a</span><br><span class="line">dp[i][j] = dp[i-1][j-2] // 1a</span><br><span class="line">dp[i][j] = dp[i-1][j] // 1+a</span><br></pre></td></tr></table></figure><p>对于初始化，dp[0][0] 为 true，<code>dp[i][0]</code> 为 false，而 <code>dp[0][j]</code> 的取值当 p 为<code>#*#*#*</code> 或者 <code>(#*)*</code> 时为 true。</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="type">boolean</span> <span class="title function_">isMatch</span><span class="params">(String s, String p)</span> &#123;</span><br><span class="line">        <span class="type">int</span> <span class="variable">l1</span> <span class="operator">=</span> s.length(), l2 = p.length();</span><br><span class="line">        <span class="type">boolean</span>[][] dp = <span class="keyword">new</span> <span class="title class_">boolean</span>[l1 + <span class="number">1</span>][l2 + <span class="number">1</span>];</span><br><span class="line">        dp[<span class="number">0</span>][<span class="number">0</span>] = <span class="literal">true</span>;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">2</span>; i &lt; l2 + <span class="number">1</span>; i += <span class="number">2</span>) &#123;</span><br><span class="line">            <span class="keyword">if</span> (p.charAt(i - <span class="number">1</span>) == <span class="string">&#x27;*&#x27;</span> &amp;&amp; dp[<span class="number">0</span>][i - <span class="number">2</span>]) &#123;</span><br><span class="line">                dp[<span class="number">0</span>][i] = <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">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">1</span>; i &lt; l1 + <span class="number">1</span>; i++) &#123;</span><br><span class="line">            <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">j</span> <span class="operator">=</span> <span class="number">1</span>; j &lt; l2 + <span class="number">1</span>; j++) &#123;</span><br><span class="line">                <span class="keyword">if</span> (s.charAt(i - <span class="number">1</span>) == p.charAt(j - <span class="number">1</span>) || p.charAt(j - <span class="number">1</span>) == <span class="string">&#x27;.&#x27;</span>) &#123;</span><br><span class="line">                    dp[i][j] = dp[i - <span class="number">1</span>][j - <span class="number">1</span>];</span><br><span class="line">                &#125; <span class="keyword">else</span> <span class="keyword">if</span> (p.charAt(j - <span class="number">1</span>) == <span class="string">&#x27;*&#x27;</span>) &#123;</span><br><span class="line">                    <span class="keyword">if</span> (p.charAt(j - <span class="number">2</span>) != s.charAt(i - <span class="number">1</span>) &amp;&amp; p.charAt(j - <span class="number">2</span>) != <span class="string">&#x27;.&#x27;</span>) &#123;</span><br><span class="line">                        dp[i][j] = dp[i][j - <span class="number">2</span>];</span><br><span class="line">                    &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                        dp[i][j] = dp[i - <span class="number">1</span>][j] || dp[i - <span class="number">1</span>][j - <span class="number">2</span>] || dp[i][j - <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> dp[l1][l2];</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3><span id="15-3sum">15 3Sum</span></h3><h4><span id="题目大意">题目大意</span></h4><p>在数组中寻找三个和为0的数的组合。</p><h4><span id="解题思路">解题思路</span></h4><p>排序后，固定一个值，另外两个夹逼寻找。如果和大于零，说明正数太大，右边的需要缩小往左移。如果和小于零，说明负数太小，需要左边的需要往右移。</p><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> List&lt;List&lt;Integer&gt;&gt; <span class="title function_">threeSum</span><span class="params">(<span class="type">int</span>[] nums)</span> &#123;</span><br><span class="line">        List&lt;List&lt;Integer&gt;&gt; result = <span class="keyword">new</span> <span class="title class_">ArrayList</span>&lt;&gt;();</span><br><span class="line">        <span class="keyword">if</span> (nums == <span class="literal">null</span> || nums.length == <span class="number">0</span>) <span class="keyword">return</span> result;</span><br><span class="line">        Arrays.sort(nums);</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; nums.length; i++)&#123;</span><br><span class="line">            <span class="keyword">if</span> (nums[i] &gt; <span class="number">0</span>)&#123;</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> (i &gt; <span class="number">0</span> &amp;&amp; nums[i] == nums[i - <span class="number">1</span>])</span><br><span class="line">                <span class="keyword">continue</span>;</span><br><span class="line">            <span class="type">int</span> <span class="variable">left</span> <span class="operator">=</span> i + <span class="number">1</span>, right = nums.length - <span class="number">1</span>;</span><br><span class="line">            <span class="keyword">while</span> (left &lt; right)&#123;</span><br><span class="line">                <span class="type">int</span> <span class="variable">l</span> <span class="operator">=</span> nums[left];</span><br><span class="line">                <span class="type">int</span> <span class="variable">r</span> <span class="operator">=</span> nums[right];</span><br><span class="line">                <span class="type">int</span> <span class="variable">m</span> <span class="operator">=</span> nums[i];</span><br><span class="line">                <span class="keyword">if</span> (l + r + m == <span class="number">0</span>)&#123;</span><br><span class="line">                    result.add(Arrays.asList(m, l, r));</span><br><span class="line">                    <span class="keyword">while</span> (left &lt; right &amp;&amp; nums[left] == l) left ++;</span><br><span class="line">                    <span class="keyword">while</span> (left &lt; right &amp;&amp; nums[right] == r) right --;</span><br><span class="line">                &#125; <span class="keyword">else</span> <span class="keyword">if</span> (l + r + m &lt; <span class="number">0</span>)&#123;</span><br><span class="line">                    left ++;</span><br><span class="line">                &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                    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="keyword">return</span> result;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> List&lt;List&lt;Integer&gt;&gt; <span class="title function_">threeSum</span><span class="params">(<span class="type">int</span>[] nums)</span> &#123;</span><br><span class="line">        List&lt;List&lt;Integer&gt;&gt; result = <span class="keyword">new</span> <span class="title class_">ArrayList</span>&lt;&gt;();</span><br><span class="line">        <span class="keyword">if</span> (nums.length == <span class="number">0</span>)</span><br><span class="line">            <span class="keyword">return</span> result;</span><br><span class="line">        Arrays.sort(nums);</span><br><span class="line">        <span class="type">int</span> left, right, temp;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; nums.length; i++) &#123;</span><br><span class="line">            <span class="keyword">if</span> (nums[i] &gt; <span class="number">0</span>)</span><br><span class="line">                <span class="keyword">break</span>;</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><br><span class="line">                <span class="keyword">continue</span>;</span><br><span class="line">            left = i + <span class="number">1</span>;</span><br><span class="line">            right = nums.length - <span class="number">1</span>;</span><br><span class="line">            <span class="keyword">while</span> (left &lt; right) &#123;</span><br><span class="line">                temp = nums[left] + nums[right] + nums[i];</span><br><span class="line">                <span class="keyword">if</span> (temp == <span class="number">0</span>) &#123;</span><br><span class="line">                    List&lt;Integer&gt; resu = <span class="keyword">new</span> <span class="title class_">ArrayList</span>&lt;&gt;();</span><br><span class="line">                    <span class="type">int</span> <span class="variable">lll</span> <span class="operator">=</span> nums[left];</span><br><span class="line">                    <span class="type">int</span> <span class="variable">rrr</span> <span class="operator">=</span> nums[right];</span><br><span class="line">                    resu.add(nums[i]);</span><br><span class="line">                    resu.add(nums[left]);</span><br><span class="line">                    resu.add(nums[right]);</span><br><span class="line">                    result.add(resu);</span><br><span class="line">                    <span class="keyword">while</span> (left &lt; right &amp;&amp; nums[left] == lll)</span><br><span class="line">                        left++;</span><br><span class="line">                    <span class="keyword">while</span> (left &lt; right &amp;&amp; nums[right] == rrr)</span><br><span class="line">                        right--;</span><br><span class="line">                &#125; <span class="keyword">else</span> <span class="keyword">if</span> (temp &gt; <span class="number">0</span>)</span><br><span class="line">                    right--;</span><br><span class="line">                <span class="keyword">else</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> result;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3><span id="16-3sum-closest">16 3Sum Closest</span></h3><h4><span id="题目大意">题目大意</span></h4><p>找到乱序数列中和最接近目标值的三个数。</p><h4><span id="解题思路">解题思路</span></h4><p>和三数之和类似，双指针法，遇到绝对值更小的更新。</p><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">threeSumClosest</span><span class="params">(<span class="type">int</span>[] nums, <span class="type">int</span> target)</span> &#123;</span><br><span class="line">        Arrays.sort(nums);</span><br><span class="line">        <span class="type">int</span> <span class="variable">resu</span> <span class="operator">=</span> <span class="number">0</span>;</span><br><span class="line">        <span class="type">int</span> <span class="variable">sub</span> <span class="operator">=</span> Integer.MAX_VALUE; <span class="comment">// 这里要注意一下。</span></span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; nums.length - <span class="number">1</span>; i++) &#123;</span><br><span class="line">            <span class="type">int</span> <span class="variable">mid</span> <span class="operator">=</span> i + <span class="number">1</span>;</span><br><span class="line">            <span class="type">int</span> <span class="variable">right</span> <span class="operator">=</span> nums.length - <span class="number">1</span>;</span><br><span class="line">            <span class="keyword">while</span> (mid &lt; right) &#123;</span><br><span class="line">                <span class="type">int</span> <span class="variable">sum</span> <span class="operator">=</span> nums[i] + nums[right] + nums[mid];</span><br><span class="line">                <span class="keyword">if</span> (Math.abs(sum - target) &lt; sub) &#123;</span><br><span class="line">                    sub = Math.abs(sum - target);</span><br><span class="line">                    resu = sum;</span><br><span class="line">                &#125;</span><br><span class="line">                <span class="keyword">if</span> (sum &lt; target) &#123;</span><br><span class="line">                    mid++;</span><br><span class="line">                &#125; <span class="keyword">else</span> <span class="keyword">if</span> (sum &gt; target) &#123;</span><br><span class="line">                    right--;</span><br><span class="line">                &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                    <span class="keyword">return</span> target;</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> resu;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3><span id="17-letter-combinations-of-a-phone-number">17  Letter Combinations of a Phone Number</span></h3><h4><span id="题目大意">题目大意</span></h4><p>输出电话号码代表的字母全排列。</p><figure class="highlight plaintext"><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">Input: &quot;23&quot;</span><br><span class="line">Output: [&quot;ad&quot;, &quot;ae&quot;, &quot;af&quot;, &quot;bd&quot;, &quot;be&quot;, &quot;bf&quot;, &quot;cd&quot;, &quot;ce&quot;, &quot;cf&quot;].</span><br></pre></td></tr></table></figure><h4><span id="解题思路">解题思路</span></h4><p>将电话号码对应的字母存储到Map中，定义一个空vector，每处理一个字符串中的字符就将vector中的所有元素拿出来追加这个电话号码的全排列。</p><h4><span id="代码">代码</span></h4><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">   <span class="keyword">public</span>:</span><br><span class="line">    <span class="function">vector&lt;string&gt; <span class="title">letterCombinations</span><span class="params">(string digits)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">if</span> (digits == <span class="string">&quot;&quot;</span>) <span class="keyword">return</span> <span class="built_in">vector</span>&lt;string&gt;();</span><br><span class="line">        <span class="function">vector&lt;string&gt; <span class="title">resu</span><span class="params">(<span class="number">1</span>, <span class="string">&quot;&quot;</span>)</span></span>;</span><br><span class="line">        map&lt;<span class="type">int</span>, vector&lt;string&gt;&gt; key;</span><br><span class="line">        <span class="comment">//存储键值对</span></span><br><span class="line">        vector&lt;string&gt; t = &#123;<span class="string">&quot;a&quot;</span>, <span class="string">&quot;b&quot;</span>, <span class="string">&quot;c&quot;</span>&#125;;</span><br><span class="line">        key.<span class="built_in">insert</span>(<span class="built_in">make_pair</span>(<span class="number">2</span>, t));</span><br><span class="line">        t = &#123;<span class="string">&quot;d&quot;</span>, <span class="string">&quot;e&quot;</span>, <span class="string">&quot;f&quot;</span>&#125;;</span><br><span class="line">        key.<span class="built_in">insert</span>(<span class="built_in">make_pair</span>(<span class="number">3</span>, t));</span><br><span class="line">        t = &#123;<span class="string">&quot;g&quot;</span>, <span class="string">&quot;h&quot;</span>, <span class="string">&quot;i&quot;</span>&#125;;</span><br><span class="line">        key.<span class="built_in">insert</span>(<span class="built_in">make_pair</span>(<span class="number">4</span>, t));</span><br><span class="line">        t = &#123;<span class="string">&quot;j&quot;</span>, <span class="string">&quot;k&quot;</span>, <span class="string">&quot;l&quot;</span>&#125;;</span><br><span class="line">        key.<span class="built_in">insert</span>(<span class="built_in">make_pair</span>(<span class="number">5</span>, t));</span><br><span class="line">        t = &#123;<span class="string">&quot;m&quot;</span>, <span class="string">&quot;n&quot;</span>, <span class="string">&quot;o&quot;</span>&#125;;</span><br><span class="line">        key.<span class="built_in">insert</span>(<span class="built_in">make_pair</span>(<span class="number">6</span>, t));</span><br><span class="line">        t = &#123;<span class="string">&quot;p&quot;</span>, <span class="string">&quot;q&quot;</span>, <span class="string">&quot;r&quot;</span>, <span class="string">&quot;s&quot;</span>&#125;;</span><br><span class="line">        key.<span class="built_in">insert</span>(<span class="built_in">make_pair</span>(<span class="number">7</span>, t));</span><br><span class="line">        t = &#123;<span class="string">&quot;t&quot;</span>, <span class="string">&quot;u&quot;</span>, <span class="string">&quot;v&quot;</span>&#125;;</span><br><span class="line">        key.<span class="built_in">insert</span>(<span class="built_in">make_pair</span>(<span class="number">8</span>, t));</span><br><span class="line">        t = &#123;<span class="string">&quot;w&quot;</span>, <span class="string">&quot;x&quot;</span>, <span class="string">&quot;y&quot;</span>, <span class="string">&quot;z&quot;</span>&#125;;</span><br><span class="line">        key.<span class="built_in">insert</span>(<span class="built_in">make_pair</span>(<span class="number">9</span>, t));</span><br><span class="line">        <span class="comment">//对每个电话号码处理</span></span><br><span class="line">        <span class="keyword">for</span> (<span class="keyword">auto</span> d : digits) &#123;</span><br><span class="line">            vector&lt;string&gt; temp;</span><br><span class="line">            <span class="comment">//将上个电话号码处理后的结果拿出来</span></span><br><span class="line">            <span class="keyword">for</span> (<span class="keyword">auto</span> r : resu) &#123;</span><br><span class="line">                <span class="comment">//追加当前号码代表的字母</span></span><br><span class="line">                <span class="keyword">for</span> (<span class="keyword">auto</span> k : key[d - <span class="string">&#x27;0&#x27;</span>]) &#123;</span><br><span class="line">                    temp.<span class="built_in">push_back</span>(r + k);</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">            resu = temp;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> resu;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h3><span id="20-valid-parentheses">20 Valid Parentheses</span></h3><h4><span id="题目大意">题目大意</span></h4><p>判断括号是不是符合开闭规则。</p><h4><span id="解题思路">解题思路</span></h4><p>主要是特殊情况的考虑。</p><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="type">boolean</span> <span class="title function_">isValid</span><span class="params">(String s)</span> &#123;</span><br><span class="line">        HashMap&lt;Character, Character&gt; map = <span class="keyword">new</span> <span class="title class_">HashMap</span>&lt;&gt;();</span><br><span class="line">        map.put(<span class="string">&#x27;&#123;&#x27;</span>,<span class="string">&#x27;&#125;&#x27;</span>);</span><br><span class="line">        map.put(<span class="string">&#x27;(&#x27;</span>,<span class="string">&#x27;)&#x27;</span>);</span><br><span class="line">        map.put(<span class="string">&#x27;[&#x27;</span>,<span class="string">&#x27;]&#x27;</span>);</span><br><span class="line">        Stack&lt;Character&gt; stack = <span class="keyword">new</span> <span class="title class_">Stack</span>&lt;&gt;();</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i&lt; s.length(); i++)&#123;</span><br><span class="line">            <span class="type">char</span> <span class="variable">sa</span> <span class="operator">=</span> s.charAt(i);</span><br><span class="line">            <span class="comment">// 判断是不是左括号，左括号压入</span></span><br><span class="line">            <span class="keyword">if</span> (map.containsKey(sa))&#123;</span><br><span class="line">                stack.push(sa);</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> (map.containsValue(sa))&#123;</span><br><span class="line">                <span class="keyword">if</span> (stack.isEmpty()) <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">                <span class="type">char</span> <span class="variable">tmp</span> <span class="operator">=</span> stack.peek();</span><br><span class="line">                <span class="keyword">if</span> (map.get(tmp) == sa)&#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">                    <span class="keyword">return</span> <span class="literal">false</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> stack.isEmpty();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3><span id="22-generate-parentheses">22 Generate Parentheses</span></h3><h4><span id="题目大意">题目大意</span></h4><p>生成n对括号的合法全排列。</p><h4><span id="解题思路">解题思路</span></h4><ol><li>常规，每次都往上一次的结果的缝隙中插入成对的括号。</li><li>回溯，考虑左括号和右括号的情况，如果发现左小于n，就填左；如果右小于左，就填右。</li></ol><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> List&lt;String&gt; <span class="title function_">generateParenthesis</span><span class="params">(<span class="type">int</span> n)</span> &#123;</span><br><span class="line">        Set&lt;String&gt; set = <span class="keyword">new</span> <span class="title class_">HashSet</span>&lt;&gt;();</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="keyword">new</span> <span class="title class_">ArrayList</span>&lt;&gt;(set);</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">            set.add(<span class="string">&quot;()&quot;</span>);</span><br><span class="line">            <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">ArrayList</span>&lt;&gt;(set);</span><br><span class="line">        &#125;</span><br><span class="line">        List&lt;String&gt; tmp = generateParenthesis(n - <span class="number">1</span>);</span><br><span class="line">        <span class="keyword">for</span> (String s : tmp) &#123;</span><br><span class="line">            <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; s.length(); i++) &#123;</span><br><span class="line">                set.add(s.substring(<span class="number">0</span>, i) + <span class="string">&quot;()&quot;</span> + s.substring(i +));</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">ArrayList</span>&lt;&gt;(set);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> List&lt;String&gt; <span class="title function_">generateParenthesis</span><span class="params">(<span class="type">int</span> n)</span> &#123;</span><br><span class="line">        List&lt;String&gt; list = <span class="keyword">new</span> <span class="title class_">ArrayList</span>&lt;&gt;();</span><br><span class="line">        help(list, n, <span class="number">0</span>, <span class="number">0</span>, <span class="string">&quot;&quot;</span>);</span><br><span class="line">        <span class="keyword">return</span> list;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">help</span><span class="params">(List&lt;String&gt; list, <span class="type">int</span> n, <span class="type">int</span> l, <span class="type">int</span> r, String s)</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> (s.length() == <span class="number">2</span> * n) &#123;</span><br><span class="line">            list.add(s);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span> (l &lt; n) &#123;</span><br><span class="line">            help(list, n, l + <span class="number">1</span>, r, s + <span class="string">&#x27;(&#x27;</span>);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span> (r &lt; l) &#123;</span><br><span class="line">            help(list, n, l, r + <span class="number">1</span>, s + <span class="string">&#x27;)&#x27;</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><h3><span id="23-merge-k-sorted-lists">23 Merge k Sorted Lists</span></h3><h4><span id="题目大意">题目大意</span></h4><p>合并 k 个有序链表。</p><h4><span id="解题思路">解题思路</span></h4><p>将所有节点存放进 PriorityQueue，重写排序方法。这里先将每个节点放入队列中，因为分列表已经有序，取出来的时候，将下一个节点扔进去，自动排序后，再取头。</p><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> ListNode <span class="title function_">mergeKLists</span><span class="params">(ListNode[] lists)</span> &#123;</span><br><span class="line">        PriorityQueue&lt;ListNode&gt; queue = <span class="keyword">new</span> <span class="title class_">PriorityQueue</span>&lt;&gt;(<span class="keyword">new</span> <span class="title class_">Comparator</span>&lt;ListNode&gt;() &#123;</span><br><span class="line">            <span class="meta">@Override</span></span><br><span class="line">            <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">compare</span><span class="params">(ListNode o1, ListNode o2)</span> &#123;</span><br><span class="line">                <span class="keyword">return</span> o1.val - o2.val;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;);</span><br><span class="line">        <span class="type">ListNode</span> <span class="variable">result</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">ListNode</span>(<span class="number">0</span>);</span><br><span class="line">        <span class="type">ListNode</span> <span class="variable">tmp</span> <span class="operator">=</span> result;</span><br><span class="line">        <span class="keyword">for</span> (ListNode l : lists) &#123;</span><br><span class="line">            tmp = l;</span><br><span class="line">            <span class="keyword">if</span> (tmp != <span class="literal">null</span>) &#123;</span><br><span class="line">                queue.add(tmp);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="type">ListNode</span> <span class="variable">iter</span> <span class="operator">=</span> result;</span><br><span class="line">        <span class="keyword">while</span> (!queue.isEmpty()) &#123;</span><br><span class="line">            tmp = queue.poll();</span><br><span class="line">            iter.next = tmp;</span><br><span class="line">            iter = iter.next;</span><br><span class="line">            <span class="keyword">if</span> (iter.next != <span class="literal">null</span>) &#123;</span><br><span class="line">                queue.add(iter.next);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> result.next;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3><span id="24-swap-nodes-in-pairs">24 Swap Nodes in Pairs</span></h3><h4><span id="题目大意">题目大意</span></h4><p>给定一个链表，交换临近的两个链表结点。</p><h4><span id="解题思路">解题思路</span></h4><ol><li>递归：判断是否符合条件，不符合停止。如果符合条件，交换前两个，并接上去掉前两个的调换结果。</li><li>建立头节点的前节点，按照步骤理清。<a href="https://leetcode.wang/leetCode-24-Swap-Nodes-in-Pairs.html">解析</a></li></ol><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> ListNode <span class="title function_">swapPairs</span><span class="params">(ListNode head)</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> (head == <span class="literal">null</span> || head.next == <span class="literal">null</span>)</span><br><span class="line">            <span class="keyword">return</span> head;</span><br><span class="line">        <span class="type">ListNode</span> <span class="variable">origin</span> <span class="operator">=</span> head.next;</span><br><span class="line">        head.next = swapPairs(head.next.next);</span><br><span class="line">        origin.next = head;</span><br><span class="line">        <span class="keyword">return</span> origin;</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">public</span> ListNode <span class="title function_">swapPairs</span><span class="params">(ListNode head)</span> &#123;</span><br><span class="line">    <span class="type">ListNode</span> <span class="variable">dummy</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">ListNode</span>(<span class="number">0</span>);</span><br><span class="line">    dummy.next = head;</span><br><span class="line">    <span class="type">ListNode</span> <span class="variable">point</span> <span class="operator">=</span> dummy;</span><br><span class="line">    <span class="keyword">while</span> (point.next != <span class="literal">null</span> &amp;&amp; point.next.next != <span class="literal">null</span>) &#123; </span><br><span class="line">        <span class="type">ListNode</span> <span class="variable">swap1</span> <span class="operator">=</span> point.next;</span><br><span class="line">        <span class="type">ListNode</span> <span class="variable">swap2</span> <span class="operator">=</span> point.next.next;</span><br><span class="line">        point.next = swap2;</span><br><span class="line">        swap1.next = swap2.next;</span><br><span class="line">        swap2.next = swap1;</span><br><span class="line">        point = swap1;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> dummy.next;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3><span id="25-reverse-nodes-in-k-group">25 Reverse Nodes in k-Group</span></h3><h4><span id="题目大意">题目大意</span></h4><p>给你一个链表，每 <em>k</em> 个节点一组进行翻转，请你返回翻转后的链表。</p><p><em>k</em> 是一个正整数，它的值小于或等于链表的长度。</p><p>如果节点总数不是 <em>k</em> 的整数倍，那么请将最后剩余的节点保持原有顺序。</p><p>给定这个链表：1-&gt;2-&gt;3-&gt;4-&gt;5</p><p>当 k = 2 时，应当返回: 2-&gt;1-&gt;4-&gt;3-&gt;5</p><p>当 k = 3 时，应当返回: 3-&gt;2-&gt;1-&gt;4-&gt;5</p><p>你的算法只能使用常数的额外空间。<br>你不能只是单纯的改变节点内部的值，而是需要实际的进行节点交换。</p><h4><span id="解题思路">解题思路</span></h4><p>你可以想象把一个很长的链表分成很多个小链表，每一份的长度都是 k (最后一份的长度如果小于 k 则不需要反转)，然后对每个小链表进行反转，最后将所有反转后的小链表按之前的顺序拼接在一起。</p><ul><li>第一，在反转子链表的时候，上一个子链表的尾必须知道</li><li>第二，下一个子链表的头也必须知道</li><li>第三，当前反转的链表的头尾都必须知道</li></ul><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> ListNode <span class="title function_">reverseKGroup</span><span class="params">(ListNode head, <span class="type">int</span> k)</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> (head == <span class="literal">null</span> || head.next == <span class="literal">null</span> || k &lt;= <span class="number">1</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="type">ListNode</span> <span class="variable">dummy</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">ListNode</span>(<span class="number">0</span>);</span><br><span class="line">        dummy.next = head;</span><br><span class="line">        <span class="type">ListNode</span> <span class="variable">pointer</span> <span class="operator">=</span> dummy;</span><br><span class="line">        <span class="keyword">while</span> (pointer != <span class="literal">null</span>) &#123;</span><br><span class="line">            <span class="comment">// 记录上一个子链表的尾</span></span><br><span class="line">            <span class="type">ListNode</span> <span class="variable">lastGroup</span> <span class="operator">=</span> pointer;</span><br><span class="line">            <span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>;</span><br><span class="line">            <span class="keyword">for</span> (; i &lt; k; ++i) &#123;</span><br><span class="line">                pointer = pointer.next;</span><br><span class="line">                <span class="keyword">if</span> (pointer == <span class="literal">null</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 class="comment">// 如果当前子链表的节点数满足 k, 就进行反转</span></span><br><span class="line">            <span class="comment">// 反之，说明程序到尾了，节点数不够，不用反转</span></span><br><span class="line">            <span class="keyword">if</span> (i == k) &#123;</span><br><span class="line">                <span class="comment">// 记录下一个子链表的头</span></span><br><span class="line">                <span class="type">ListNode</span> <span class="variable">nextGroup</span> <span class="operator">=</span> pointer.next;</span><br><span class="line">                <span class="comment">// 反转当前子链表，reverse 函数返回反转后子链表的头</span></span><br><span class="line">                <span class="type">ListNode</span> <span class="variable">reversedList</span> <span class="operator">=</span> reverse(lastGroup.next, nextGroup);</span><br><span class="line">                <span class="comment">// lastGroup 是上一个子链表的尾，其 next 指向当前反转子链表的头</span></span><br><span class="line">                <span class="comment">// 但是因为当前链表已经被反转，所以它指向的是反转后的链表的尾</span></span><br><span class="line">                pointer = lastGroup.next;</span><br><span class="line">                <span class="comment">// 将上一个链表的尾连向反转后链表的头</span></span><br><span class="line">                lastGroup.next = reversedList;</span><br><span class="line">                <span class="comment">// 当前反转后的链表的尾连向下一个子链表的头</span></span><br><span class="line">                pointer.next = nextGroup;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> dummy.next;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">private</span> ListNode <span class="title function_">reverse</span><span class="params">(ListNode head, ListNode tail)</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> (head == <span class="literal">null</span> || head.next == <span class="literal">null</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="type">ListNode</span> <span class="variable">prev</span> <span class="operator">=</span> <span class="literal">null</span>, temp = <span class="literal">null</span>;</span><br><span class="line">        <span class="keyword">while</span> ((head != <span class="literal">null</span>) &amp;&amp; (head != tail)) &#123;</span><br><span class="line">            temp = head.next;</span><br><span class="line">            head.next = prev;</span><br><span class="line">            prev = head;</span><br><span class="line">            head = temp;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> prev;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3><span id="26-remove-duplicates-from-sorted-array">26  Remove Duplicates from Sorted Array</span></h3><h4><span id="题目大意">题目大意</span></h4><p>数组去重并返回去重后的长度。</p><h4><span id="解题思路">解题思路</span></h4><p>本题主要记录Vector函数的使用。</p><h4><span id="代码">代码</span></h4><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><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="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function"><span class="type">int</span> <span class="title">removeDuplicates</span><span class="params">(vector&lt;<span class="type">int</span>&gt;&amp; nums)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">auto</span> it =<span class="built_in">unique</span>(nums.<span class="built_in">begin</span>(),nums.<span class="built_in">end</span>());</span><br><span class="line">        nums.<span class="built_in">resize</span>(<span class="built_in">distance</span>(nums.<span class="built_in">begin</span>(),it));</span><br><span class="line">        <span class="keyword">return</span> nums.<span class="built_in">size</span>();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h3><span id="28-implement-strstr">28 Implement strStr()</span></h3><h4><span id="题目大意">题目大意</span></h4><p>找子串出现的第一次位置，如果没出现，就返回-1。</p><h4><span id="解题思路">解题思路</span></h4><p>纯暴力。KMP 实在太久远了，没去看。此外这道题在 LeetCode 是 Easy。</p><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">strStr</span><span class="params">(String haystack, String needle)</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> (needle.equals(<span class="string">&quot;&quot;</span>)) <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">if</span> (haystack.equals(<span class="string">&quot;&quot;</span>) || haystack.length() &lt; needle.length()) <span class="keyword">return</span> -<span class="number">1</span>;</span><br><span class="line">        <span class="type">int</span> <span class="variable">index</span> <span class="operator">=</span> <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; haystack.length(); i++) &#123;</span><br><span class="line">            <span class="type">int</span> <span class="variable">ni</span> <span class="operator">=</span> <span class="number">0</span>;</span><br><span class="line">            <span class="type">int</span> <span class="variable">hi</span> <span class="operator">=</span> i;</span><br><span class="line">            <span class="keyword">while</span> (ni &lt; needle.length()&amp;&amp;hi &lt; haystack.length()) &#123;</span><br><span class="line">                <span class="keyword">if</span> (haystack.charAt(hi) == needle.charAt(ni)) &#123;</span><br><span class="line">                    <span class="keyword">if</span> (ni == needle.length() - <span class="number">1</span>) &#123;</span><br><span class="line">                        <span class="keyword">return</span> i;</span><br><span class="line">                    &#125;</span><br><span class="line">                    ni++;</span><br><span class="line">                    hi++;</span><br><span class="line">                &#125; <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">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><h3><span id="30-substring-with-concatenation-of-all-words">30 Substring with Concatenation of All Words</span></h3><h4><span id="题目大意">题目大意</span></h4><p>找出串联所有单词的字串，且每个单词只能出现一次(样例2因为good出现了不止一次)。单词的长度一致。返回索引。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><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">Input:</span><br><span class="line">  s = &quot;barfoothefoobarman&quot;,</span><br><span class="line">  words = [&quot;foo&quot;,&quot;bar&quot;]</span><br><span class="line">Output: [0,9]</span><br><span class="line">Explanation: Substrings starting at index 0 and 9 are &quot;barfoo&quot; and &quot;foobar&quot; respectively.</span><br><span class="line">The output order does not matter, returning [9,0] is fine too.</span><br><span class="line">Input:</span><br><span class="line">  s = &quot;wordgoodgoodgoodbestword&quot;,</span><br><span class="line">  words = [&quot;word&quot;,&quot;good&quot;,&quot;best&quot;,&quot;word&quot;]</span><br><span class="line">Output: []</span><br></pre></td></tr></table></figure><h4><span id="解题思路">解题思路</span></h4><p>本题引入了HashMap，使得我们不需要纠结单词的排列顺序。这里引用一下别人的解答：</p><ol><li><p>常规解法：先建立word中单词到次数的映射，因为某些单词可能不止出现一次。再使用新的HashMap建立一个映射用来记录当前的寻找过程中每个单词出现的次数。如果次数超过了words中的次数，直接退出，下一次寻找；如果单词不对，也退出。</p></li><li><p>解法一中，每次移动一个字符然后判断指定单词的数量是否合法。现在每次移动一个单词。</p><p>以从0开始移动为例，看一下优化情况：</p><p>① 当子串完全匹配，移动到下一个子串的时候：</p><p><img src="https://windliang.oss-cn-beijing.aliyuncs.com/30_9.jpg" alt="完全匹配"></p><p>在1中，对于i = 3的子串，我们肯定是从第一个foo开始判断。但其实前两个foo都不用判断了 ，因为在判断上一个i=0的子串的时候我们已经判断过了。所以解法一中的HashMap2每次并不需要清空从0开始，而是可以只移除之前i=0子串的第一个单词bar即可，然后直接从箭头所指的foo开始就可以了。 、</p><p>②  当判断过程中，出现不符合的单词：</p><p><img src="https://windliang.oss-cn-beijing.aliyuncs.com/30_10.jpg" alt="不符合"></p><p>在判断i=0的时候出现了the，所以i=36都不用判断了，直接判断i=9。</p><p>③  判断过程中，出现的是符合的单词，但是次数超了：</p><p><img src="https://windliang.oss-cn-beijing.aliyuncs.com/30_11.jpg" alt></p><p>对于i=0，虽然bar符合要求，但是bar出现了两次。往后移动窗口虽然删除了foo但是bar仍然两个，因此需要继续移动。直到bar被删除一个，i=6时候，就可以判断了。</p></li></ol><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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></pre></td><td class="code"><pre><span class="line"><span class="comment">//1</span></span><br><span class="line"><span class="keyword">public</span> List&lt;Integer&gt; <span class="title function_">findSubstring</span><span class="params">(String s, String[] words)</span> &#123;</span><br><span class="line">    List&lt;Integer&gt; res = <span class="keyword">new</span> <span class="title class_">ArrayList</span>&lt;Integer&gt;();</span><br><span class="line">    <span class="type">int</span> <span class="variable">wordNum</span> <span class="operator">=</span> words.length;</span><br><span class="line">    <span class="keyword">if</span> (wordNum == <span class="number">0</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="type">int</span> <span class="variable">wordLen</span> <span class="operator">=</span> words[<span class="number">0</span>].length();</span><br><span class="line">    <span class="comment">//HashMap1 存所有单词</span></span><br><span class="line">    HashMap&lt;String, Integer&gt; allWords = <span class="keyword">new</span> <span class="title class_">HashMap</span>&lt;String, Integer&gt;();</span><br><span class="line">    <span class="keyword">for</span> (String w : words) &#123;</span><br><span class="line">        <span class="type">int</span> <span class="variable">value</span> <span class="operator">=</span> allWords.getOrDefault(w, <span class="number">0</span>);</span><br><span class="line">        allWords.put(w, value + <span class="number">1</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">//遍历所有子串</span></span><br><span class="line">    <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; s.length() - wordNum * wordLen + <span class="number">1</span>; i++) &#123;</span><br><span class="line">        <span class="comment">//HashMap2 存当前扫描的字符串含有的单词</span></span><br><span class="line">        HashMap&lt;String, Integer&gt; hasWords = <span class="keyword">new</span> <span class="title class_">HashMap</span>&lt;String, Integer&gt;();</span><br><span class="line">        <span class="type">int</span> <span class="variable">num</span> <span class="operator">=</span> <span class="number">0</span>;</span><br><span class="line">        <span class="comment">//判断该子串是否符合</span></span><br><span class="line">        <span class="keyword">while</span> (num &lt; wordNum) &#123;</span><br><span class="line">            <span class="type">String</span> <span class="variable">word</span> <span class="operator">=</span> s.substring(i + num * wordLen, i + (num + <span class="number">1</span>) * wordLen);</span><br><span class="line">            <span class="comment">//判断该单词在 HashMap1 中</span></span><br><span class="line">            <span class="keyword">if</span> (allWords.containsKey(word)) &#123;</span><br><span class="line">                <span class="type">int</span> <span class="variable">value</span> <span class="operator">=</span> hasWords.getOrDefault(word, <span class="number">0</span>);</span><br><span class="line">                hasWords.put(word, value + <span class="number">1</span>);</span><br><span class="line">                <span class="comment">//判断当前单词的 value 和 HashMap1 中该单词的 value</span></span><br><span class="line">                <span class="keyword">if</span> (hasWords.get(word) &gt; allWords.get(word)) &#123;</span><br><span class="line">                    <span class="keyword">break</span>;</span><br><span class="line">                &#125;</span><br><span class="line">            &#125; <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">            num++;</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> (num == wordNum) &#123;</span><br><span class="line">            res.add(i);</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="comment">//2</span></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> List&lt;Integer&gt; <span class="title function_">findSubstring</span><span class="params">(String s, String[] words)</span> &#123;</span><br><span class="line">        List&lt;Integer&gt; res = <span class="keyword">new</span> <span class="title class_">ArrayList</span>&lt;Integer&gt;();</span><br><span class="line">        <span class="type">int</span> <span class="variable">wordNum</span> <span class="operator">=</span> words.length;</span><br><span class="line">        <span class="keyword">if</span> (wordNum == <span class="number">0</span>) &#123;</span><br><span class="line">            <span class="keyword">return</span> res;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="type">int</span> <span class="variable">wordLen</span> <span class="operator">=</span> words[<span class="number">0</span>].length();</span><br><span class="line">        HashMap&lt;String, Integer&gt; allWords = <span class="keyword">new</span> <span class="title class_">HashMap</span>&lt;String, Integer&gt;();</span><br><span class="line">        <span class="keyword">for</span> (String w : words) &#123;</span><br><span class="line">            <span class="type">int</span> <span class="variable">value</span> <span class="operator">=</span> allWords.getOrDefault(w, <span class="number">0</span>);</span><br><span class="line">            allWords.put(w, value + <span class="number">1</span>);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="comment">// 将所有移动分成 wordLen 类情况</span></span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">j</span> <span class="operator">=</span> <span class="number">0</span>; j &lt; wordLen; j++) &#123;</span><br><span class="line">            HashMap&lt;String, Integer&gt; hasWords = <span class="keyword">new</span> <span class="title class_">HashMap</span>&lt;String, Integer&gt;();</span><br><span class="line">            <span class="type">int</span> <span class="variable">num</span> <span class="operator">=</span> <span class="number">0</span>; <span class="comment">// 记录当前 HashMap2（这里的 hasWords 变量）中有多少个单词</span></span><br><span class="line">            <span class="comment">// 每次移动一个单词长度</span></span><br><span class="line">            <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> j; i &lt; s.length() - wordNum * wordLen + <span class="number">1</span>; i = i + wordLen) &#123;</span><br><span class="line">                <span class="type">boolean</span> <span class="variable">hasRemoved</span> <span class="operator">=</span> <span class="literal">false</span>; <span class="comment">// 防止情况三移除后，情况一继续移除</span></span><br><span class="line">                <span class="keyword">while</span> (num &lt; wordNum) &#123;</span><br><span class="line">                    <span class="type">String</span> <span class="variable">word</span> <span class="operator">=</span> s.substring(i + num * wordLen, i + (num + <span class="number">1</span>) * wordLen);</span><br><span class="line">                    <span class="keyword">if</span> (allWords.containsKey(word)) &#123;</span><br><span class="line">                        <span class="type">int</span> <span class="variable">value</span> <span class="operator">=</span> hasWords.getOrDefault(word, <span class="number">0</span>);</span><br><span class="line">                        hasWords.put(word, value + <span class="number">1</span>);</span><br><span class="line">                        <span class="comment">// 出现情况三，遇到了符合的单词，但是次数超了</span></span><br><span class="line">                        <span class="keyword">if</span> (hasWords.get(word) &gt; allWords.get(word)) &#123;</span><br><span class="line">                            <span class="comment">// hasWords.put(word, value);</span></span><br><span class="line">                            hasRemoved = <span class="literal">true</span>;</span><br><span class="line">                            <span class="type">int</span> <span class="variable">removeNum</span> <span class="operator">=</span> <span class="number">0</span>;</span><br><span class="line">                            <span class="comment">// 一直移除单词，直到次数符合了</span></span><br><span class="line">                            <span class="keyword">while</span> (hasWords.get(word) &gt; allWords.get(word)) &#123;</span><br><span class="line">                                <span class="type">String</span> <span class="variable">firstWord</span> <span class="operator">=</span> s.substring(i + removeNum * wordLen, i + (removeNum + <span class="number">1</span>) * wordLen);</span><br><span class="line">                                <span class="type">int</span> <span class="variable">v</span> <span class="operator">=</span> hasWords.get(firstWord);</span><br><span class="line">                                hasWords.put(firstWord, v - <span class="number">1</span>);</span><br><span class="line">                                removeNum++;</span><br><span class="line">                            &#125;</span><br><span class="line">                            num = num - removeNum + <span class="number">1</span>; <span class="comment">// 加 1 是因为我们把当前单词加入到了 HashMap 2 中</span></span><br><span class="line">                            i = i + (removeNum - <span class="number">1</span>) * wordLen; <span class="comment">// 这里依旧是考虑到了最外层的 for 循环，看情况二的解释</span></span><br><span class="line">                            <span class="keyword">break</span>;</span><br><span class="line">                        &#125;</span><br><span class="line">                        <span class="comment">// 出现情况二，遇到了不匹配的单词，直接将 i 移动到该单词的后边（但其实这里</span></span><br><span class="line">                        <span class="comment">// 只是移动到了出现问题单词的地方，因为最外层有 for 循环， i 还会移动一个单词</span></span><br><span class="line">                        <span class="comment">// 然后刚好就移动到了单词后边）</span></span><br><span class="line">                    &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                        hasWords.clear();</span><br><span class="line">                        i = i + num * wordLen;</span><br><span class="line">                        num = <span class="number">0</span>;</span><br><span class="line">                        <span class="keyword">break</span>;</span><br><span class="line">                    &#125;</span><br><span class="line">                    num++;</span><br><span class="line">                &#125;</span><br><span class="line">                <span class="keyword">if</span> (num == wordNum) &#123;</span><br><span class="line">                    res.add(i);</span><br><span class="line"></span><br><span class="line">                &#125;</span><br><span class="line">                <span class="comment">// 出现情况一，子串完全匹配，我们将上一个子串的第一个单词从 HashMap2 中移除</span></span><br><span class="line">                <span class="keyword">if</span> (num &gt; <span class="number">0</span> &amp;&amp; !hasRemoved) &#123;</span><br><span class="line">                    <span class="type">String</span> <span class="variable">firstWord</span> <span class="operator">=</span> s.substring(i, i + wordLen);</span><br><span class="line">                    <span class="type">int</span> <span class="variable">v</span> <span class="operator">=</span> hasWords.get(firstWord);</span><br><span class="line">                    hasWords.put(firstWord, v - <span class="number">1</span>);</span><br><span class="line">                    num = num - <span class="number">1</span>;</span><br><span class="line">                &#125;</span><br><span class="line"></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">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3><span id="31-next-permutation">31 Next Permutation</span></h3><h4><span id="题目大意">题目大意</span></h4><p>对于一个数组进行全排列后按照字典序排列，求某一种排列后的下一个排列顺序。例如，127341的下一个排列为131247。他是127341的下一个最小的排列。</p><h4><span id="解题思路">解题思路</span></h4><p>这道题主要是全排列规律的应用，对于一个全排列，他的字典序下一个排列有这么一个规律。</p><p>通过观察原数组可以发现，如果从末尾往前看，数字逐渐变大，到了2时才减小的，然后再从后往前找第一个比2大的数字，是3，那么我们交换2和3，再把此时3后面的所有数字转置一下即可，步骤如下：</p><p>1　　2　　7　　4　　3　　1</p><p>1　　2　　7　　4　　3　　1</p><p>1　　3　　7　　4　　2　　1</p><p>1　　3　　1　　2　　4　　7</p><h4><span id="代码">代码</span></h4><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function"><span class="type">void</span> <span class="title">nextPermutation</span><span class="params">(vector&lt;<span class="type">int</span>&gt;&amp; nums)</span> </span>&#123;</span><br><span class="line">        <span class="built_in">next_permutation</span>(nums.<span class="built_in">begin</span>(), nums.<span class="built_in">end</span>());</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><p>按照上面解题思路的代码：</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">nextPermutation</span><span class="params">(<span class="type">int</span>[] nums)</span> &#123;</span><br><span class="line">        <span class="comment">// 先从后往前找到第一次出现升序的两个数，i指向前一个数</span></span><br><span class="line">        <span class="type">int</span> <span class="variable">n</span> <span class="operator">=</span> nums.length;</span><br><span class="line">        <span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> n - <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>])</span><br><span class="line">            i--;</span><br><span class="line">        <span class="comment">// 然后从后向前找到第一个大于nums[i]的数</span></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="type">int</span> <span class="variable">j</span> <span class="operator">=</span> nums.length - <span class="number">1</span>;</span><br><span class="line">            <span class="keyword">while</span> (nums[j] &lt;= nums[i])</span><br><span class="line">                j--;</span><br><span class="line">            <span class="comment">// 交换2个下标对应的元素</span></span><br><span class="line">            swap(nums, i, j);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="comment">// 逆置i之后的所有元素</span></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="keyword">public</span> <span class="keyword">void</span> <span class="title function_">swap</span><span class="params">(<span class="type">int</span>[] nums, <span class="type">int</span> i, <span class="type">int</span> j)</span> &#123;</span><br><span class="line">        <span class="type">int</span> <span class="variable">temp</span> <span class="operator">=</span> nums[i];</span><br><span class="line">        nums[i] = nums[j];</span><br><span class="line">        nums[j] = temp;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">reverse</span><span class="params">(<span class="type">int</span>[] nums, <span class="type">int</span> start)</span> &#123;</span><br><span class="line">        <span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> start;</span><br><span class="line">        <span class="type">int</span> <span class="variable">j</span> <span class="operator">=</span> nums.length - <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(nums, i, j);</span><br><span class="line">            i++;</span><br><span class="line">            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><h3><span id="32-longest-valid-parentheses">32 Longest Valid Parentheses</span></h3><h4><span id="题目描述">题目描述</span></h4><p>给定一个只包含左括号和右括号的字符串，找出最长的包含有效括号的子串的长度。</p><h4><span id="解题思路">解题思路</span></h4><p>例如，“(()”，先遍历一遍字符串 S，判断遍历到的字符 ch 是不是左括号，如果是的话，将此时 ch 的位置加入到栈中。</p><p>继续判断，发现又碰到了左括号，同样的，将它的位置添加到栈中。</p><p>如果遇到的元素是右括号，且栈不为空栈顶元素是左括号，就出栈。</p><p>如果当前栈为空，不管遇到什么元素，都入栈。</p><p>这样扫描完一轮，栈里存放的就是没有匹配到的位置。</p><p>最后考虑栈空的情况，当前的最长匹配就是当前指针位置+1，如果不为空，那么最长匹配就是当前指针位置减去栈顶元素位置。</p><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="keyword">import</span> java.util.Stack;</span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="type">int</span> <span class="title function_">longestValidParentheses</span><span class="params">(String s)</span> &#123;</span><br><span class="line">        <span class="type">int</span> <span class="variable">res</span> <span class="operator">=</span> <span class="number">0</span>;</span><br><span class="line">        Stack&lt;Integer&gt; stack = <span class="keyword">new</span> <span class="title class_">Stack</span>&lt;&gt;();</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; s.length(); i++) &#123;</span><br><span class="line">            <span class="keyword">if</span> (!stack.isEmpty()) &#123;</span><br><span class="line">                <span class="keyword">if</span> (s.charAt(stack.peek()) == <span class="string">&#x27;(&#x27;</span> &amp;&amp; s.charAt(i) == <span class="string">&#x27;)&#x27;</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(i);</span><br><span class="line">                &#125;</span><br><span class="line">            &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                stack.push(i);</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">if</span> (!stack.isEmpty()) &#123;</span><br><span class="line">                res = Math.max(res, i - stack.peek());</span><br><span class="line">            &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                res = Math.max(res, 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">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3><span id="33-search-in-rotated-sorted-array">33 Search in Rotated Sorted Array</span></h3><h4><span id="题目描述">题目描述</span></h4><p>在旋转数组中查找目标，不存在返回-1。</p><figure class="highlight plaintext"><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">Input: nums = [4,5,6,7,0,1,2], target = 0</span><br><span class="line">Output: 4</span><br></pre></td></tr></table></figure><h4><span id="解题思路">解题思路</span></h4><p>基本有序，使用二分法查找，判断下一次要搜索左半段还是右半段，根据中间值和左右的关系，判断哪边有序哪边无序，在不同区域使用不同的判断方法。</p><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">search</span><span class="params">(<span class="type">int</span>[] nums, <span class="type">int</span> target)</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> (nums == <span class="literal">null</span> || nums.length == <span class="number">0</span>) <span class="keyword">return</span> -<span class="number">1</span>;</span><br><span class="line">        <span class="type">int</span> <span class="variable">left</span> <span class="operator">=</span> <span class="number">0</span>, right = nums.length - <span class="number">1</span>;</span><br><span class="line">        <span class="keyword">while</span> (left &lt;= right)&#123;</span><br><span class="line">            <span class="type">int</span> <span class="variable">mid</span> <span class="operator">=</span> left + (right - left) / <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[right])&#123;</span><br><span class="line">                <span class="keyword">if</span> (nums[mid] &lt; target &amp;&amp; nums[right] &gt;= target) left = mid + <span class="number">1</span>;</span><br><span class="line">                <span class="keyword">else</span> right = mid - <span class="number">1</span>;</span><br><span class="line">            &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                <span class="keyword">if</span> (nums[left] &lt;= target &amp;&amp; nums[mid] &gt;= target) right = mid;</span><br><span class="line">                <span class="keyword">else</span> left = mid + <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> -<span class="number">1</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3><span id="37-sudoku-solver">37 Sudoku Solver</span></h3><h4><span id="题目描述">题目描述</span></h4><p>给定一个指定格式的数独棋盘，输出他的一个解。</p><h4><span id="解题思路">解题思路</span></h4><p>采用回溯法，对于没有填写的空，填写一个合法数字，如果无法填写合法数字，退回到上一层，填写合法数字。</p><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">solveSudoku</span><span class="params">(<span class="type">char</span>[][] board)</span> &#123;</span><br><span class="line">        solver(board);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> <span class="type">boolean</span> <span class="title function_">solver</span><span class="params">(<span class="type">char</span>[][] board)</span> &#123;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; <span class="number">9</span>; i++)</span><br><span class="line">            <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">j</span> <span class="operator">=</span> <span class="number">0</span>; j &lt; <span class="number">9</span>; j++)</span><br><span class="line">                <span class="keyword">if</span> (board[i][j] == <span class="string">&#x27;.&#x27;</span>) &#123;</span><br><span class="line">                    <span class="type">char</span> <span class="variable">count</span> <span class="operator">=</span> <span class="string">&#x27;1&#x27;</span>;</span><br><span class="line">                    <span class="keyword">while</span> (count &lt;= <span class="string">&#x27;9&#x27;</span>) &#123;</span><br><span class="line">                        <span class="keyword">if</span> (isValid(i, j, board, count)) &#123;</span><br><span class="line">                            board[i][j] = count;</span><br><span class="line">                            <span class="keyword">if</span> (solver(board))</span><br><span class="line">                                <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line">                            <span class="keyword">else</span></span><br><span class="line">                                board[i][j] = <span class="string">&#x27;.&#x27;</span>;</span><br><span class="line">                        &#125;</span><br><span class="line">                        count++;</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="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="keyword">private</span> <span class="type">boolean</span> <span class="title function_">isValid</span><span class="params">(<span class="type">int</span> row, <span class="type">int</span> col, <span class="type">char</span>[][] board, <span class="type">char</span> c)</span> &#123;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; <span class="number">9</span>; i++)</span><br><span class="line">            <span class="keyword">if</span> (board[row][i] == c)</span><br><span class="line">                <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; <span class="number">9</span>; i++)</span><br><span class="line">            <span class="keyword">if</span> (board[i][col] == c)</span><br><span class="line">                <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">        <span class="type">int</span> <span class="variable">start_row</span> <span class="operator">=</span> row / <span class="number">3</span> * <span class="number">3</span>;</span><br><span class="line">        <span class="type">int</span> <span class="variable">start_col</span> <span class="operator">=</span> col / <span class="number">3</span> * <span class="number">3</span>;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; <span class="number">3</span>; i++)</span><br><span class="line">            <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">j</span> <span class="operator">=</span> <span class="number">0</span>; j &lt; <span class="number">3</span>; j++)</span><br><span class="line">                <span class="keyword">if</span> (board[start_row + i][start_col + j] == c)</span><br><span class="line">                    <span class="keyword">return</span> <span class="literal">false</span>;</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><h3><span id="38-count-and-say">38 Count and Say</span></h3><h4><span id="题目大意">题目大意</span></h4><p>按照题述规律打印指定项。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><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">1.     1</span><br><span class="line">2.     11</span><br><span class="line">3.     21</span><br><span class="line">4.     1211</span><br><span class="line">5.     111221</span><br><span class="line">1 is read off as &quot;one 1&quot; or 11.</span><br><span class="line">11 is read off as &quot;two 1s&quot; or 21.</span><br><span class="line">21 is read off as &quot;one 2, then one 1&quot; or 1211.</span><br></pre></td></tr></table></figure><h4><span id="解题思路">解题思路</span></h4><p>显然每一项都是上一项“数”出来的，因此写出相邻两项的转换规则之后递归解决就可以了。相邻两项就是数数。</p><h4><span id="代码">代码</span></h4><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">   <span class="keyword">public</span>:</span><br><span class="line">    <span class="function">string <span class="title">count</span><span class="params">(string input)</span> </span>&#123;</span><br><span class="line">        <span class="type">int</span> i, j;</span><br><span class="line">        string resu = <span class="string">&quot;&quot;</span>;</span><br><span class="line">        <span class="keyword">for</span> (i = <span class="number">0</span>; i &lt; input.<span class="built_in">size</span>(); i++) &#123;</span><br><span class="line">            <span class="keyword">for</span> (j = i; j &lt; input.<span class="built_in">size</span>(); j++) &#123;</span><br><span class="line">                <span class="keyword">if</span> (input[j] != input[i]) <span class="keyword">break</span>;</span><br><span class="line">            &#125;</span><br><span class="line">            resu += j - i + <span class="string">&#x27;0&#x27;</span>;</span><br><span class="line">            resu += input[i];</span><br><span class="line">            i = j - <span class="number">1</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> resu;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="function">string <span class="title">countAndSay</span><span class="params">(<span class="type">int</span> n)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">if</span> (n == <span class="number">1</span>) <span class="keyword">return</span> <span class="string">&quot;1&quot;</span>;</span><br><span class="line">        string str = <span class="string">&quot;1&quot;</span>;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">1</span>; i &lt; n; i++) &#123;</span><br><span class="line">            str = <span class="built_in">count</span>(str);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> str;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h3><span id="39-conbination-sum">39 Conbination Sum</span></h3><h4><span id="题目大意">题目大意</span></h4><p>给定数字集合，一个目标值，输出所有和等于目标值的组合。</p><h4><span id="解题思路">解题思路</span></h4><p>依旧是回溯法，找到一个解或者找不到可行解时候就回溯。</p><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> List&lt;List&lt;Integer&gt;&gt; <span class="title function_">combinationSum</span><span class="params">(<span class="type">int</span>[] candidates, <span class="type">int</span> target)</span> &#123;</span><br><span class="line">        List&lt;List&lt;Integer&gt;&gt; list = <span class="keyword">new</span> <span class="title class_">ArrayList</span>&lt;&gt;();</span><br><span class="line">        backtrack(list, <span class="keyword">new</span> <span class="title class_">ArrayList</span>&lt;&gt;(), candidates, target, <span class="number">0</span>);</span><br><span class="line">        <span class="keyword">return</span> list;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">void</span> <span class="title function_">backtrack</span><span class="params">(List&lt;List&lt;Integer&gt;&gt; list, List&lt;Integer&gt; tempList, <span class="type">int</span>[] nums, <span class="type">int</span> remain, <span class="type">int</span> start)</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> (remain &lt; <span class="number">0</span>)</span><br><span class="line">            <span class="keyword">return</span>;</span><br><span class="line">        <span class="keyword">else</span> <span class="keyword">if</span> (remain == <span class="number">0</span>)</span><br><span class="line">            list.add(<span class="keyword">new</span> <span class="title class_">ArrayList</span>&lt;&gt;(tempList));</span><br><span class="line">        <span class="keyword">else</span> &#123;</span><br><span class="line">            <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> start; i &lt; nums.length; i++) &#123;</span><br><span class="line">                tempList.add(nums[i]);</span><br><span class="line">                backtrack(list, tempList, nums, remain - nums[i], i);</span><br><span class="line">                tempList.remove(tempList.size() - <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">&#125;</span><br></pre></td></tr></table></figure><h3><span id="40-combination-sum-ii">40 Combination Sum Ⅱ</span></h3><h4><span id="题目大意">题目大意</span></h4><p>给定数字集合，一个目标值，输出所有和等于目标值的组合。数组中有重复数字，每个数字只能用一次。</p><h4><span id="解题思路">解题思路</span></h4><p>和上题类似，依旧回溯，这里为了避免元组会重复出现，先排序。</p><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> List&lt;List&lt;Integer&gt;&gt; <span class="title function_">combinationSum2</span><span class="params">(<span class="type">int</span>[] candidates, <span class="type">int</span> target)</span> &#123;</span><br><span class="line">        List&lt;List&lt;Integer&gt;&gt; list = <span class="keyword">new</span> <span class="title class_">ArrayList</span>&lt;&gt;();</span><br><span class="line">        Arrays.sort(candidates);</span><br><span class="line">        backtrack(list, <span class="keyword">new</span> <span class="title class_">ArrayList</span>&lt;&gt;(), candidates, target, <span class="number">0</span>);</span><br><span class="line">        <span class="keyword">return</span> list;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">void</span> <span class="title function_">backtrack</span><span class="params">(List&lt;List&lt;Integer&gt;&gt; list, List&lt;Integer&gt; tempList, <span class="type">int</span>[] nums, <span class="type">int</span> remain, <span class="type">int</span> start)</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> (remain &lt; <span class="number">0</span>)</span><br><span class="line">            <span class="keyword">return</span>;</span><br><span class="line">        <span class="keyword">else</span> <span class="keyword">if</span> (remain == <span class="number">0</span>) &#123;</span><br><span class="line">            list.add(<span class="keyword">new</span> <span class="title class_">ArrayList</span>&lt;&gt;(tempList));</span><br><span class="line">        &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">            <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> start; i &lt; nums.length; i++) &#123;</span><br><span class="line">                <span class="comment">// 避免多余计算，剪枝</span></span><br><span class="line">                <span class="keyword">if</span> (i &gt; start &amp;&amp; nums[i] == nums[i - <span class="number">1</span>])</span><br><span class="line">                    <span class="keyword">continue</span>;</span><br><span class="line">                tempList.add(nums[i]);</span><br><span class="line">                <span class="comment">// 每个数只能用一次，从自己的下一个计算</span></span><br><span class="line">                backtrack(list, tempList, nums, remain - nums[i], i + <span class="number">1</span>);</span><br><span class="line">                tempList.remove(tempList.size() - <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">&#125;</span><br></pre></td></tr></table></figure><h3><span id="41-first-missing-positive">41 FIrst Missing Positive</span></h3><h4><span id="题目大意">题目大意</span></h4><p>给定一个无序的整数数组，找到最小的缺失的正整数。要求 O(n) 级别的时间复杂度和常数级别的空间复杂度。</p><h4><span id="思路">思路</span></h4><p>这个题一开始没理解透，以为是找数列中缺少的那个数。实际上是指从1到 n 缺的最小的那个。</p><p>如果 nums 不缺任何数字的话，那么 nums 排序后，数字应该和索引是对应的。例如，[3, 4, -1, 1] 首先遇到 3，便将 3 放到 nums[2] 即第三个位置上，交换两个位置上的数。重复此操作，直到全部换完。即，[1, -1, 3, 4]。显然 -1 上的位置不对，返回 index+1。如果都在位置上，谁也不缺，返回下一个元素。</p><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">firstMissingPositive</span><span class="params">(<span class="type">int</span>[] nums)</span> &#123;</span><br><span class="line">        <span class="type">int</span> <span class="variable">len</span> <span class="operator">=</span> nums.length;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; len; i++) &#123;</span><br><span class="line">            <span class="keyword">while</span> (nums[i] &gt; <span class="number">0</span> &amp;&amp; nums[i] &lt;= len &amp;&amp; nums[nums[i] - <span class="number">1</span>] != nums[i]) &#123;</span><br><span class="line">                swap(nums, i, nums[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="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; len; i++) &#123;</span><br><span class="line">            <span class="keyword">if</span> (nums[i] != i + <span class="number">1</span>) &#123;</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><span class="line">        <span class="keyword">return</span> len + <span class="number">1</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">swap</span><span class="params">(<span class="type">int</span>[] nums, <span class="type">int</span> left, <span class="type">int</span> right)</span> &#123;</span><br><span class="line">        <span class="type">int</span> <span class="variable">tmp</span> <span class="operator">=</span> nums[left];</span><br><span class="line">        nums[left] = nums[right];</span><br><span class="line">        nums[right] = tmp;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3><span id="42-trapping-rain-water">42 Trapping Rain Water</span></h3><h4><span id="题目大意">题目大意</span></h4><p>求蓝色区域面积</p><figure class="highlight plaintext"><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">Input: [0,1,0,2,1,0,1,3,2,1,2,1]</span><br><span class="line">Output: 6</span><br></pre></td></tr></table></figure><p><img src="https://pic.tyzhang.top/images/2020/07/27/rainwatertrap.png" alt="填雨水"></p><h4><span id="解题思路">解题思路</span></h4><p>木桶理论中，桶能装的水高度取决于最短一块木板的高度。</p><p>在这题，当前槽能装多少水，取决于它左右最高的那块挡板的高度。因此先为每个槽寻找左右挡板最高高度，这个槽的储水量就是两个挡板最低的那个减掉槽高度。</p><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">trap</span><span class="params">(<span class="type">int</span>[] height)</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> (height == <span class="literal">null</span> || height.length &lt;= <span class="number">2</span>) <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">        <span class="type">int</span> <span class="variable">len</span> <span class="operator">=</span> height.length, temp = <span class="number">0</span>, res = <span class="number">0</span>;</span><br><span class="line">        <span class="type">int</span>[] left = <span class="keyword">new</span> <span class="title class_">int</span>[len];</span><br><span class="line">        <span class="type">int</span>[] right = <span class="keyword">new</span> <span class="title class_">int</span>[len];</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; len; i++) &#123;</span><br><span class="line">            temp = Math.max(temp, height[i]);</span><br><span class="line">            left[i] = temp;</span><br><span class="line">        &#125;</span><br><span class="line">        temp = <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> len - <span class="number">1</span>; i &gt;= <span class="number">0</span>; i--) &#123;</span><br><span class="line">            temp = Math.max(temp, height[i]);</span><br><span class="line">            right[i] = temp;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; len; i++) &#123;</span><br><span class="line">            res += Math.min(left[i], right[i]) - height[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><h3><span id="43-multiply-strings">43 Multiply Strings</span></h3><h4><span id="题目大意">题目大意</span></h4><p>大数乘法，不能用大数类。</p><h4><span id="解题思路">解题思路</span></h4><p>这应该算是第一次规规矩矩写了大数乘法，都是因为师兄一句面试时候让我撕了。</p><p>写了两个函数，两个字符串相加，还有字符串乘字符。因为123*456就是123*6+123*5*10。所以最后拼接时候追加0。</p><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> String <span class="title function_">multiply</span><span class="params">(String num1, String num2)</span> &#123;</span><br><span class="line">        <span class="comment">// 特殊情况的处理</span></span><br><span class="line">        <span class="keyword">if</span> (num1.equals(<span class="string">&quot;0&quot;</span>) || num2.equals(<span class="string">&quot;0&quot;</span>)) <span class="keyword">return</span> <span class="string">&quot;0&quot;</span>;</span><br><span class="line">        <span class="keyword">if</span> (num1.equals(<span class="string">&quot;1&quot;</span>) || num2.equals(<span class="string">&quot;1&quot;</span>)) <span class="keyword">return</span> num1.equals(<span class="string">&quot;1&quot;</span>) ? num2 : num1;</span><br><span class="line">        <span class="comment">// 逐个和字符相乘 然后后面追加0相加</span></span><br><span class="line">        <span class="type">String</span> <span class="variable">resu</span> <span class="operator">=</span> <span class="string">&quot;0&quot;</span>;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> num2.length() - <span class="number">1</span>; i &gt;= <span class="number">0</span>; i--) &#123;</span><br><span class="line">            <span class="type">String</span> <span class="variable">ts</span> <span class="operator">=</span> mul(num1, num2.charAt(i));</span><br><span class="line">            <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">j</span> <span class="operator">=</span> num2.length() - <span class="number">1</span>; j &gt; i; j--) &#123;</span><br><span class="line">                ts += <span class="string">&quot;0&quot;</span>;</span><br><span class="line">            &#125;</span><br><span class="line">            System.out.println(ts);</span><br><span class="line">            resu = add(ts, resu);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> resu;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">// 两个数相乘得到得字符串</span></span><br><span class="line">    <span class="keyword">public</span> String <span class="title function_">mul</span><span class="params">(String num1, <span class="type">char</span> c)</span> &#123;</span><br><span class="line">        <span class="comment">// 从0开始算，算出来的数</span></span><br><span class="line">        <span class="type">String</span> <span class="variable">resu</span> <span class="operator">=</span> <span class="string">&quot;&quot;</span>;</span><br><span class="line">        <span class="type">int</span> <span class="variable">flag</span> <span class="operator">=</span> <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> num1.length() - <span class="number">1</span>; i &gt;= <span class="number">0</span>; i--) &#123;</span><br><span class="line">            <span class="type">int</span> <span class="variable">tmp</span> <span class="operator">=</span> (num1.charAt(i) - <span class="string">&#x27;0&#x27;</span>) * (c - <span class="string">&#x27;0&#x27;</span>) + flag;</span><br><span class="line">            flag = tmp / <span class="number">10</span>;</span><br><span class="line">            tmp %= <span class="number">10</span>;</span><br><span class="line">            resu = tmp + resu;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span> (flag != <span class="number">0</span>) resu = flag + resu;</span><br><span class="line">        <span class="keyword">return</span> resu;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">// 两个字符串相加</span></span><br><span class="line">    <span class="keyword">public</span> String <span class="title function_">add</span><span class="params">(String num1, String num2)</span> &#123;</span><br><span class="line">        <span class="type">String</span> <span class="variable">resu</span> <span class="operator">=</span> <span class="string">&quot;&quot;</span>;</span><br><span class="line">        <span class="type">int</span> <span class="variable">flag</span> <span class="operator">=</span> <span class="number">0</span>;</span><br><span class="line">        <span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> num1.length() - <span class="number">1</span>;</span><br><span class="line">        <span class="type">int</span> <span class="variable">j</span> <span class="operator">=</span> num2.length() - <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="type">int</span> <span class="variable">tmp</span> <span class="operator">=</span> num1.charAt(i) - <span class="string">&#x27;0&#x27;</span> + num2.charAt(j) - <span class="string">&#x27;0&#x27;</span> + flag;</span><br><span class="line">            flag = tmp / <span class="number">10</span>;</span><br><span class="line">            tmp %= <span class="number">10</span>;</span><br><span class="line">            resu = tmp + resu;</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">while</span> (i &gt;= <span class="number">0</span>) &#123;</span><br><span class="line">            <span class="type">int</span> <span class="variable">tmp</span> <span class="operator">=</span> num1.charAt(i) - <span class="string">&#x27;0&#x27;</span> + flag;</span><br><span class="line">            flag = tmp / <span class="number">10</span>;</span><br><span class="line">            tmp %= <span class="number">10</span>;</span><br><span class="line">            resu = tmp + resu;</span><br><span class="line">            i--;</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">            <span class="type">int</span> <span class="variable">tmp</span> <span class="operator">=</span> num2.charAt(j) - <span class="string">&#x27;0&#x27;</span> + flag;</span><br><span class="line">            flag = tmp / <span class="number">10</span>;</span><br><span class="line">            tmp %= <span class="number">10</span>;</span><br><span class="line">            resu = tmp + resu;</span><br><span class="line">            j--;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span> (flag == <span class="number">1</span>) resu = <span class="string">&#x27;1&#x27;</span> + resu;</span><br><span class="line">        <span class="keyword">return</span> resu;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3><span id="44-wildcard-matching">44 Wildcard Matching</span></h3><h4><span id="题目大意">题目大意</span></h4><p>给定一个字符串 s 和 p，支持 “?” 和 “*” 的通配符匹配。</p><figure class="highlight plaintext"><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">&#x27;?&#x27; 可以匹配任何单个字符</span><br><span class="line">&#x27;*&#x27; 可以匹配任意字符串</span><br></pre></td></tr></table></figure><ul><li><code>s</code> 可能为空，且只包含从 <code>a-z</code> 的小写字母。</li><li><code>p</code> 可能为空，且只包含从 <code>a-z</code> 的小写字母，以及字符 <code>?</code> 和 <code>*。</code></li></ul><h4><span id="解题思路">解题思路</span></h4><p>建立数组用来记录，dp[i][j] 记录 s 的前 i 个字符是否可以编辑成 p 的前 j 个字符。</p><p>当遇见问号直接跳过了。要不然就三种情况。</p><figure class="highlight plaintext"><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">dp[i-1][j-1]=true，且s.charAt(i-1)==p.charAt(j-1);</span><br><span class="line">dp[i][j-1]=true，且p.charAt(j-1)==&#x27;*&#x27;，这时表示‘*’匹配了0 个字符；</span><br><span class="line">dp[i-1][j]=true，且p.charAt(j-1)==&#x27;*&#x27;，这时表示‘*’匹配了s的第i个字符；</span><br></pre></td></tr></table></figure><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="type">boolean</span> <span class="title function_">isMatch</span><span class="params">(String s, String p)</span> &#123;</span><br><span class="line">        <span class="type">int</span> <span class="variable">m</span> <span class="operator">=</span> s.length();</span><br><span class="line">        <span class="type">int</span> <span class="variable">n</span> <span class="operator">=</span> p.length();</span><br><span class="line">        <span class="type">boolean</span>[][] dp = <span class="keyword">new</span> <span class="title class_">boolean</span>[m + <span class="number">1</span>][n + <span class="number">1</span>];</span><br><span class="line">        dp[<span class="number">0</span>][<span class="number">0</span>] = <span class="literal">true</span>;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">j</span> <span class="operator">=</span> <span class="number">1</span>; j &lt;= n; j++) &#123;</span><br><span class="line">            dp[<span class="number">0</span>][j] = dp[<span class="number">0</span>][j - <span class="number">1</span>] &amp;&amp; p.charAt(j - <span class="number">1</span>) == <span class="string">&#x27;*&#x27;</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">1</span>; i &lt;= m; i++) &#123;</span><br><span class="line">            <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">j</span> <span class="operator">=</span> <span class="number">1</span>; j &lt;= n; j++) &#123;</span><br><span class="line">                <span class="keyword">if</span> (p.charAt(j - <span class="number">1</span>) == <span class="string">&#x27;?&#x27;</span>) &#123;</span><br><span class="line">                    dp[i][j] = dp[i - <span class="number">1</span>][j - <span class="number">1</span>];</span><br><span class="line">                &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                    dp[i][j] = (dp[i - <span class="number">1</span>][j - <span class="number">1</span>] &amp;&amp; s.charAt(i - <span class="number">1</span>) == p.charAt(j - <span class="number">1</span>)) <span class="comment">// 完全匹配了</span></span><br><span class="line">                            || (dp[i - <span class="number">1</span>][j] &amp;&amp; p.charAt(j - <span class="number">1</span>) == <span class="string">&#x27;*&#x27;</span>) <span class="comment">// * 匹配了0个字符</span></span><br><span class="line">                            || (dp[i][j - <span class="number">1</span>] &amp;&amp; p.charAt(j - <span class="number">1</span>) == <span class="string">&#x27;*&#x27;</span>);<span class="comment">// * 匹配了s的第i个字符</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][n];</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3><span id="46-permutations">46 Permutations</span></h3><h4><span id="题目大意">题目大意</span></h4><p>给定一个集合，生成全排列。</p><h4><span id="解题思路">解题思路</span></h4><p>每次都将当前位置和后面位置交换，换到不能换了添加到结果中去。</p><p><img src="https://pic.tyzhang.top/images/2020/08/05/image.md.png" alt="深度搜索"></p><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="keyword">import</span> java.util.ArrayList;</span><br><span class="line"><span class="keyword">import</span> java.util.Arrays;</span><br><span class="line"><span class="keyword">import</span> java.util.List;</span><br><span class="line"><span class="keyword">import</span> java.util.stream.Collectors;</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> List&lt;List&lt;Integer&gt;&gt; <span class="title function_">permute</span><span class="params">(<span class="type">int</span>[] nums)</span> &#123;</span><br><span class="line">        List&lt;List&lt;Integer&gt;&gt; resu = <span class="keyword">new</span> <span class="title class_">ArrayList</span>&lt;&gt;();</span><br><span class="line">        backtrack(nums, <span class="number">0</span>, resu);</span><br><span class="line">        <span class="keyword">return</span> resu;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">backtrack</span><span class="params">(<span class="type">int</span>[] nums, <span class="type">int</span> start, List&lt;List&lt;Integer&gt;&gt; resu)</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> (start &gt;= nums.length) &#123;</span><br><span class="line">            <span class="comment">// 因为asList只能接受包装类型，因此需要自动装箱至 Integer</span></span><br><span class="line">            List&lt;Integer&gt; list = Arrays.stream(nums).boxed().collect(Collectors.toList());</span><br><span class="line">            resu.add(list);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="comment">// 把当前元素和后面每个元素交换，并在此基础上继续交换</span></span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> start; i &lt; nums.length; i++) &#123;</span><br><span class="line">            swap(nums, start, i);</span><br><span class="line">            backtrack(nums, start + <span class="number">1</span>, resu);</span><br><span class="line">            swap(nums, start, i);</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">public</span> <span class="keyword">void</span> <span class="title function_">swap</span><span class="params">(<span class="type">int</span>[] nums, <span class="type">int</span> left, <span class="type">int</span> right)</span> &#123;</span><br><span class="line">        <span class="type">int</span> <span class="variable">tmp</span> <span class="operator">=</span> nums[left];</span><br><span class="line">        nums[left] = nums[right];</span><br><span class="line">        nums[right] = tmp;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3><span id="47-permutations-ii">47 Permutations Ⅱ</span></h3><h4><span id="题目大意">题目大意</span></h4><p>给定集合，生成全排列。与46不同，这些数字可能会重复。</p><h4><span id="解题思路">解题思路</span></h4><p>在 46 的基础上换用 set，遇到重复的不再添加。</p><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="keyword">import</span> java.util.*;</span><br><span class="line"><span class="keyword">import</span> java.util.stream.Collectors;</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> List&lt;List&lt;Integer&gt;&gt; <span class="title function_">permuteUnique</span><span class="params">(<span class="type">int</span>[] nums)</span> &#123;</span><br><span class="line">        Set&lt;List&lt;Integer&gt;&gt; resu = <span class="keyword">new</span> <span class="title class_">HashSet</span>&lt;&gt;();</span><br><span class="line">        backtrack(nums, <span class="number">0</span>, resu);</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">ArrayList</span>&lt;&gt;(resu);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">backtrack</span><span class="params">(<span class="type">int</span>[] nums, <span class="type">int</span> start, Set&lt;List&lt;Integer&gt;&gt; resu)</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> (start &gt;= nums.length) &#123;</span><br><span class="line">            List&lt;Integer&gt; list = Arrays.stream(nums).boxed().collect(Collectors.toList());</span><br><span class="line">            resu.add(list);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> start; i &lt; nums.length; i++) &#123;</span><br><span class="line">            <span class="keyword">if</span> (i != start &amp;&amp; nums[i] == nums[start]) <span class="keyword">continue</span>;</span><br><span class="line">            swap(nums, start, i);</span><br><span class="line">            backtrack(nums, start + <span class="number">1</span>, resu);</span><br><span class="line">            swap(nums, start, i);</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">public</span> <span class="keyword">void</span> <span class="title function_">swap</span><span class="params">(<span class="type">int</span>[] nums, <span class="type">int</span> left, <span class="type">int</span> right)</span> &#123;</span><br><span class="line">        <span class="type">int</span> <span class="variable">tmp</span> <span class="operator">=</span> nums[left];</span><br><span class="line">        nums[left] = nums[right];</span><br><span class="line">        nums[right] = tmp;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3><span id="48-rotate-image">48  Rotate Image</span></h3><h4><span id="题目大意">题目大意</span></h4><p>将矩阵顺时针旋转90°。</p><h4><span id="解题思路">解题思路</span></h4><p>将矩阵对角线对称，然后左右对称，即可。</p><h4><span id="代码">代码</span></h4><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="keyword">class</span> <span class="title class_">Solution</span> &#123;</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="function"><span class="type">void</span> <span class="title">rotate</span><span class="params">(vector&lt;vector&lt;<span class="type">int</span>&gt;&gt;&amp; matrix)</span> </span>&#123;</span><br><span class="line">        <span class="type">int</span> l = matrix.<span class="built_in">size</span>();</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">0</span>; i &lt; l; i++) &#123;</span><br><span class="line">            <span class="keyword">for</span> (<span class="type">int</span> j = i+<span class="number">1</span>; j &lt; l; j++) &#123;</span><br><span class="line">                <span class="built_in">swap</span>(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="type">int</span> i = <span class="number">0</span>; i &lt; l; i++) &#123;</span><br><span class="line">            <span class="keyword">for</span> (<span class="type">int</span> j = <span class="number">0</span>; j &lt; l / <span class="number">2</span> ; j++) &#123;</span><br><span class="line">                <span class="built_in">swap</span>(matrix[i][j], matrix[i][l - 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">&#125;;</span><br></pre></td></tr></table></figure><h3><span id="49-group-anagrams">49  Group Anagrams</span></h3><h4><span id="题目大意">题目大意</span></h4><p>将属于一个全排列的字符串粗放到一起。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><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">Input: [&quot;eat&quot;, &quot;tea&quot;, &quot;tan&quot;, &quot;ate&quot;, &quot;nat&quot;, &quot;bat&quot;],</span><br><span class="line">Output:</span><br><span class="line">[</span><br><span class="line">  [&quot;ate&quot;,&quot;eat&quot;,&quot;tea&quot;],</span><br><span class="line">  [&quot;nat&quot;,&quot;tan&quot;],</span><br><span class="line">  [&quot;bat&quot;]</span><br><span class="line">]</span><br></pre></td></tr></table></figure><h4><span id="解题思路">解题思路</span></h4><p>事实上，对全排列的字符串排序的结果应该相同，以结果作为索引储存到 HashMap 中。</p><p>比如，“ate” “aet” “tae”排序后都是“aet”。</p><h4><span id="代码">代码</span></h4><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> List&lt;List&lt;String&gt;&gt; <span class="built_in">groupAnagrams</span>(String[] strs) &#123;</span><br><span class="line">        HashMap&lt;String, List&lt;String&gt;&gt; map = <span class="keyword">new</span> HashMap&lt;&gt;();</span><br><span class="line">        <span class="keyword">for</span> (String str : strs) &#123;</span><br><span class="line">            <span class="type">char</span>[] astr = str.<span class="built_in">toCharArray</span>();</span><br><span class="line">            Arrays.<span class="built_in">sort</span>(astr);</span><br><span class="line">            <span class="comment">// 这里一定要用String的方法转，直接toString是把对象转了</span></span><br><span class="line">            String key = String.<span class="built_in">valueOf</span>(astr);</span><br><span class="line">            <span class="keyword">if</span> (!map.<span class="built_in">containsKey</span>(key)) &#123;</span><br><span class="line">                map.<span class="built_in">put</span>(key, <span class="keyword">new</span> ArrayList&lt;&gt;());</span><br><span class="line">            &#125;</span><br><span class="line">            map.<span class="built_in">get</span>(key).<span class="built_in">add</span>(str);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">new</span> ArrayList&lt;List&lt;String&gt;&gt;(map.<span class="built_in">values</span>());</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3><span id="53-maximum-subarray">53 Maximum Subarray</span></h3><h4><span id="题目大意">题目大意</span></h4><p>子数组最大和</p><h4><span id="解题思路">解题思路</span></h4><p>贪心，累加和，如果算到当前数字总和小于0了，说明这一步加的是非常小的一个复数，直接恢复0，因为负数会对后面的数产生影响。</p><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><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">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">maxSubArray</span><span class="params">(<span class="type">int</span>[] nums)</span> &#123;</span><br><span class="line">        <span class="type">int</span> <span class="variable">max</span> <span class="operator">=</span> nums[<span class="number">0</span>];</span><br><span class="line">        <span class="type">int</span> <span class="variable">sum</span> <span class="operator">=</span> <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> num: nums)&#123;</span><br><span class="line">            sum += num;</span><br><span class="line">            max = Math.max(max, sum);</span><br><span class="line">            sum = sum &lt;= <span class="number">0</span>? <span class="number">0</span>: sum;</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><h3><span id="54-spiral-matrix">54  Spiral Matrix</span></h3><h4><span id="题目大意">题目大意</span></h4><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">Input:</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><br><span class="line"> [ <span class="number">4</span>, <span class="number">5</span>, <span class="number">6</span> ],</span><br><span class="line"> [ <span class="number">7</span>, <span class="number">8</span>, <span class="number">9</span> ]</span><br><span class="line">]</span><br><span class="line">Output: [<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">6</span>,<span class="number">9</span>,<span class="number">8</span>,<span class="number">7</span>,<span class="number">4</span>,<span class="number">5</span>]</span><br></pre></td></tr></table></figure><h4><span id="解题思路">解题思路</span></h4><p>用变量left, right, top, bottom记录左，右，顶，底。然后按照左到右，顶到底，右到左，底到顶的顺序循环，把遍历的元素加入到结果。</p><h4><span id="代码">代码</span></h4><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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">//1</span></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">   <span class="keyword">public</span>:</span><br><span class="line">    <span class="function">vector&lt;<span class="type">int</span>&gt; <span class="title">spiralOrder</span><span class="params">(vector&lt;vector&lt;<span class="type">int</span>&gt;&gt; &amp;matrix)</span> </span>&#123;</span><br><span class="line">        vector&lt;<span class="type">int</span>&gt; res;</span><br><span class="line">        <span class="keyword">if</span> (matrix.<span class="built_in">empty</span>() || matrix[<span class="number">0</span>].<span class="built_in">empty</span>()) <span class="keyword">return</span> res;</span><br><span class="line">        <span class="type">int</span> m = matrix.<span class="built_in">size</span>(), n = matrix[<span class="number">0</span>].<span class="built_in">size</span>();</span><br><span class="line">        <span class="type">int</span> c = m &gt; n ? (n + <span class="number">1</span>) / <span class="number">2</span> : (m + <span class="number">1</span>) / <span class="number">2</span>;</span><br><span class="line">        <span class="type">int</span> p = m, q = n;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">0</span>; i &lt; c; ++i, p -= <span class="number">2</span>, q -= <span class="number">2</span>) &#123;</span><br><span class="line">            <span class="keyword">for</span> (<span class="type">int</span> col = i; col &lt; i + q; ++col) res.<span class="built_in">push_back</span>(matrix[i][col]);</span><br><span class="line">            <span class="keyword">for</span> (<span class="type">int</span> row = i + <span class="number">1</span>; row &lt; i + p; ++row)</span><br><span class="line">                res.<span class="built_in">push_back</span>(matrix[row][i + q - <span class="number">1</span>]);</span><br><span class="line">            <span class="keyword">if</span> (p == <span class="number">1</span> || q == <span class="number">1</span>) <span class="keyword">break</span>;</span><br><span class="line">            <span class="keyword">for</span> (<span class="type">int</span> col = i + q - <span class="number">2</span>; col &gt;= i; --col)</span><br><span class="line">                res.<span class="built_in">push_back</span>(matrix[i + p - <span class="number">1</span>][col]);</span><br><span class="line">            <span class="keyword">for</span> (<span class="type">int</span> row = i + p - <span class="number">2</span>; row &gt; i; --row)</span><br><span class="line">                res.<span class="built_in">push_back</span>(matrix[row][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><span class="line"><span class="comment">//2</span></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function">vector&lt;<span class="type">int</span>&gt; <span class="title">spiralOrder</span><span class="params">(vector&lt;vector&lt;<span class="type">int</span>&gt;&gt;&amp; matrix)</span> </span>&#123;</span><br><span class="line">        vector&lt;<span class="type">int</span>&gt; ans;</span><br><span class="line">        <span class="keyword">if</span> (matrix.<span class="built_in">size</span>() == <span class="number">0</span>) &#123;</span><br><span class="line">            <span class="keyword">return</span> ans;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="comment">//上下左右四个边界</span></span><br><span class="line">        <span class="type">int</span> up = <span class="number">0</span>, down = matrix.<span class="built_in">size</span>() - <span class="number">1</span>, left = <span class="number">0</span>, right = matrix[<span class="number">0</span>].<span class="built_in">size</span>() - <span class="number">1</span>;</span><br><span class="line">        <span class="keyword">while</span> (up &lt;= down &amp;&amp; left &lt;= right) &#123;</span><br><span class="line">            <span class="comment">//从左到右</span></span><br><span class="line">            <span class="keyword">if</span> (up &lt; matrix.<span class="built_in">size</span>()) &#123;</span><br><span class="line">                <span class="keyword">for</span> (<span class="type">int</span> i = left; i &lt;= right; ++i) &#123;</span><br><span class="line">                    ans.<span class="built_in">push_back</span>(matrix[up][i]);</span><br><span class="line">                &#125;</span><br><span class="line">                up++;</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> (right &gt;= <span class="number">0</span>) &#123;</span><br><span class="line">                <span class="keyword">for</span> (<span class="type">int</span> i = up; i &lt;= down; ++i) &#123;</span><br><span class="line">                    ans.<span class="built_in">push_back</span>(matrix[i][right]);</span><br><span class="line">                &#125;</span><br><span class="line">                right--;</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> (down &gt;= up) &#123;</span><br><span class="line">                <span class="keyword">for</span> (<span class="type">int</span> i = right; i &gt;= left; --i) &#123;</span><br><span class="line">                    ans.<span class="built_in">push_back</span>(matrix[down][i]);</span><br><span class="line">                &#125;</span><br><span class="line">                down--;</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> (left &lt;= right) &#123;</span><br><span class="line">                <span class="keyword">for</span> (<span class="type">int</span> i = down; i &gt;= up; --i) &#123;</span><br><span class="line">                    ans.<span class="built_in">push_back</span>(matrix[i][left]);</span><br><span class="line">                &#125;</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> ans;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h3><span id="56-merge-intervals">56 Merge Intervals</span></h3><h4><span id="题目大意">题目大意</span></h4><p>合并区间，输出最后的区间结果。</p><h4><span id="解题思路">解题思路</span></h4><p>贪心，将元素按照两个位排序之后，贪心建立区间，具体原理可以看代码中的注释。</p><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="keyword">import</span> java.util.Arrays;</span><br><span class="line"><span class="keyword">import</span> java.util.Comparator;</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="type">int</span>[][] merge(<span class="type">int</span>[][] intervals) &#123;</span><br><span class="line">        <span class="comment">// 对二维数组首元素按照升序排列</span></span><br><span class="line">        Comparator&lt;<span class="type">int</span>[]&gt; comparator = <span class="keyword">new</span> <span class="title class_">Comparator</span>&lt;<span class="type">int</span>[]&gt;() &#123;</span><br><span class="line">            <span class="meta">@Override</span></span><br><span class="line">            <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">compare</span><span class="params">(<span class="type">int</span>[] o1, <span class="type">int</span>[] o2)</span> &#123;</span><br><span class="line">                <span class="keyword">if</span> (o1[<span class="number">0</span>] == o2[<span class="number">0</span>]) &#123;</span><br><span class="line">                    <span class="keyword">return</span> o1[<span class="number">1</span>] - o2[<span class="number">1</span>];</span><br><span class="line">                &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                    <span class="keyword">return</span> o1[<span class="number">0</span>] - o2[<span class="number">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">        Arrays.sort(intervals, comparator);</span><br><span class="line">        <span class="comment">// 创建结果数组</span></span><br><span class="line">        <span class="type">int</span>[][] resu = <span class="keyword">new</span> <span class="title class_">int</span>[intervals.length][<span class="number">2</span>];</span><br><span class="line">        <span class="comment">// 结果集的索引</span></span><br><span class="line">        <span class="type">int</span> <span class="variable">idx</span> <span class="operator">=</span> -<span class="number">1</span>;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span>[] interval : intervals) &#123;</span><br><span class="line">            <span class="comment">// 如果结果集为空，新键一个区间，或者当前区间的元素比结果集中最后一个区间的末尾大，说明非重叠区间</span></span><br><span class="line">            <span class="keyword">if</span> (idx == -<span class="number">1</span> || interval[<span class="number">0</span>] &gt; resu[idx][<span class="number">1</span>]) &#123;</span><br><span class="line">                resu[++idx] = interval;</span><br><span class="line">            &#125; <span class="keyword">else</span> <span class="keyword">if</span> (interval[<span class="number">0</span>] &lt;= resu[idx][<span class="number">1</span>]) &#123;</span><br><span class="line">                <span class="comment">// 重叠了，选择最大的元素作为区间末尾</span></span><br><span class="line">                resu[idx][<span class="number">1</span>] = Math.max(resu[idx][<span class="number">1</span>], interval[<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> Arrays.copyOf(resu, idx + <span class="number">1</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3><span id="62-unique-paths">62 Unique Paths</span></h3><h4><span id="题目大意">题目大意</span></h4><p>机器人从右上角走向右下角，每次只能往下或者往右走，问有多少种走法。</p><h4><span id="解题思路">解题思路</span></h4><p>动态规划，如果机器人在终点所在的行列出发，毫无疑问，只有一种方法可达。如果从别的地方出发，它的方案个数等于下方的个数+右边的个数。即每个结果都依赖于右下角的数。将矩阵旋转180就可以转换为从依赖于左上角，方便计算。</p><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><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="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">uniquePaths</span><span class="params">(<span class="type">int</span> m, <span class="type">int</span> n)</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> (m == <span class="number">1</span> || n==<span class="number">1</span>) <span class="keyword">return</span> <span class="number">1</span>;</span><br><span class="line">        <span class="type">int</span>[][] dp = <span class="keyword">new</span> <span class="title class_">int</span>[n+<span class="number">1</span>][m+<span class="number">1</span>];</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">1</span>; i &lt;= n; i++)&#123;</span><br><span class="line">            <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">j</span> <span class="operator">=</span> <span class="number">1</span>; j &lt;= m; 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> &#123;</span><br><span class="line">                    dp[i][j] = dp[i][j-<span class="number">1</span>] + dp[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> dp[n][m];</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3><span id="63-unique-paths-ii">63 Unique Paths Ⅱ</span></h3><h4><span id="题目大意">题目大意</span></h4><p>机器人从右上角走向右下角，每次只能往下或者往右走，矩阵位置为1的地方不能走，问有多少种走法。</p><h4><span id="解题思路">解题思路</span></h4><p>和62差不多的思路，但是这道题加了限制路径不走过值为1的地方，因此如果某个位置为1那么经过他的路径为0。这样的话，边界条件也要改了，虽然机器人和终点在同一行或列但是中间有1也是白给。因此边界条件要单独拿出来判断。</p><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">uniquePathsWithObstacles</span><span class="params">(<span class="type">int</span>[][] o)</span> &#123;</span><br><span class="line">        <span class="type">int</span> <span class="variable">m</span> <span class="operator">=</span> o.length, n = o[<span class="number">0</span>].length;</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="type">int</span>[][] dp = <span class="keyword">new</span> <span class="title class_">int</span>[m+<span class="number">1</span>][n+<span class="number">1</span>];</span><br><span class="line">        dp[<span class="number">0</span>][<span class="number">1</span>] = dp[<span class="number">1</span>][<span class="number">0</span>] = <span class="number">1</span>;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">1</span>; i &lt;= m; i++)&#123;</span><br><span class="line">            <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">j</span> <span class="operator">=</span> <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>)&#123;</span><br><span class="line">                    dp[i][j] = o[i-<span class="number">1</span>][j-<span class="number">1</span>] == <span class="number">0</span> ? dp[i][j-<span class="number">1</span>]: <span class="number">0</span>;</span><br><span class="line">                &#125; <span class="keyword">else</span> <span class="keyword">if</span> (j == <span class="number">1</span>)&#123;</span><br><span class="line">                    dp[i][j] = o[i-<span class="number">1</span>][j-<span class="number">1</span>] == <span class="number">0</span> ? dp[i-<span class="number">1</span>][j]: <span class="number">0</span>;</span><br><span class="line">                &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                    dp[i][j] = o[i-<span class="number">1</span>][j-<span class="number">1</span>] == <span class="number">1</span> ? <span class="number">0</span>: (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][n];</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3><span id="64-最小路径和">64 最小路径和</span></h3><h4><span id="题目大意">题目大意</span></h4><p>给出一个二维矩阵，找出一条从左上角到右下角的路径， 使得路径上的数字总和最小。</p><h4><span id="解题思路">解题思路</span></h4><p>左上角到右下角的路径最小，就是从右下角往左上角寻找短路径和，非常简单的动态规划。</p><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">minPathSum</span><span class="params">(<span class="type">int</span>[][] grid)</span> &#123;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> grid.length - <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="type">int</span> <span class="variable">j</span> <span class="operator">=</span> grid[i].length - <span class="number">1</span>; j &gt;= <span class="number">0</span>; j--) &#123;</span><br><span class="line">                <span class="keyword">if</span> (i == grid.length - <span class="number">1</span> &amp;&amp; j == grid[i].length - <span class="number">1</span>) &#123;</span><br><span class="line"><span class="comment">// 啥也不做</span></span><br><span class="line">                &#125; <span class="keyword">else</span> <span class="keyword">if</span> (i == grid.length - <span class="number">1</span>) &#123;</span><br><span class="line">                    grid[i][j] +=grid[i][j + <span class="number">1</span>];</span><br><span class="line">                &#125; <span class="keyword">else</span> <span class="keyword">if</span> (j == grid[i].length - <span class="number">1</span>) &#123;</span><br><span class="line">                    grid[i][j] += grid[i + <span class="number">1</span>][j];</span><br><span class="line">                &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                    grid[i][j] += Math.min(grid[i + <span class="number">1</span>][j], grid[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> grid[<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><h3><span id="69-sqrtx">69 Sqrt(x)</span></h3><h4><span id="题目大意">题目大意</span></h4><p>一个数 x 的开方 sqrt 一定在 0 ~ x 之间，并且满足 sqrt == x / sqrt。可以利用二分查找在 0 ~ x 之间查找 sqrt。</p><h4><span id="解题思路">解题思路</span></h4><p>对于 x = 8，它的开方是 2.82842…，最后应该返回 2 而不是 3。在循环条件为 l &lt;= h 并且循环退出时，h 总是比 l 小 1，也就是说 h = 2，l = 3，因此最后的返回值应该为 h 而不是 l。</p><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">mySqrt</span><span class="params">(<span class="type">int</span> x)</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> (x &lt;= <span class="number">1</span>) <span class="keyword">return</span> x;</span><br><span class="line">        <span class="type">int</span> <span class="variable">left</span> <span class="operator">=</span> <span class="number">1</span>, right = x, sqrt = <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">while</span> (left &lt;= right) &#123;</span><br><span class="line">            <span class="type">int</span> <span class="variable">mid</span> <span class="operator">=</span> left + (right - left) / <span class="number">2</span>;</span><br><span class="line">            sqrt = x / mid;</span><br><span class="line">            <span class="keyword">if</span> (sqrt == mid)&#123;</span><br><span class="line">                <span class="keyword">return</span> mid;</span><br><span class="line">            &#125; <span class="keyword">else</span> <span class="keyword">if</span> (sqrt &lt; mid) &#123;</span><br><span class="line">                right = mid - <span class="number">1</span>;</span><br><span class="line">            &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                left = mid + <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> right;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3><span id="70-climbing-stairs">70 Climbing Stairs</span></h3><h4><span id="题目大意">题目大意</span></h4><p>数字拆解，1和2的组合。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><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">Input: 2</span><br><span class="line">Output: 2</span><br><span class="line">Explanation: There are two ways to climb to the top.</span><br><span class="line">1. 1 step + 1 step</span><br><span class="line">2. 2 steps</span><br><span class="line"></span><br><span class="line">Input: 3</span><br><span class="line">Output: 3</span><br><span class="line">Explanation: There are three ways to climb to the top.</span><br><span class="line">1. 1 step + 1 step + 1 step</span><br><span class="line">2. 1 step + 2 steps</span><br><span class="line">3. 2 steps + 1 step</span><br></pre></td></tr></table></figure><h4><span id="解题思路">解题思路</span></h4><p>dp[i] = dp[i-1] + dp[i-2] ，因为每次走一步或者两步， 所以dp[i]的方法就是它一步前和两步前方法加和 。</p><h4><span id="代码">代码</span></h4><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function"><span class="type">int</span> <span class="title">climbStairs</span><span class="params">(<span class="type">int</span> n)</span> </span>&#123;</span><br><span class="line">        <span class="comment">// cout &lt;&lt; n &lt;&lt; endl;</span></span><br><span class="line">        <span class="keyword">if</span> (n &lt;= <span class="number">1</span>) <span class="keyword">return</span> <span class="number">1</span>;</span><br><span class="line">        <span class="keyword">return</span> (<span class="built_in">climbStairs</span>(n - <span class="number">1</span>)) + (<span class="built_in">climbStairs</span>(n - <span class="number">2</span>));</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br><span class="line"><span class="comment">//DP解法</span></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function"><span class="type">int</span> <span class="title">climbStairs</span><span class="params">(<span class="type">int</span> n)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">if</span> (n &lt;= <span class="number">1</span>) <span class="keyword">return</span> <span class="number">1</span>;</span><br><span class="line">        <span class="function">vector&lt;<span class="type">int</span>&gt; <span class="title">dp</span><span class="params">(n)</span></span>;</span><br><span class="line">        dp[<span class="number">0</span>] = <span class="number">1</span>; dp[<span class="number">1</span>] = <span class="number">2</span>;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">2</span>; i &lt; n; ++i) &#123;</span><br><span class="line">            dp[i] = dp[i - <span class="number">1</span>] + dp[i - <span class="number">2</span>];</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> dp.<span class="built_in">back</span>();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h3><span id="71-simplify-path">71 Simplify Path</span></h3><h4><span id="题目大意">题目大意</span></h4><p>简化文件路径，比如&quot;…“代表返回上一级，”.&quot;表示当前目录，目的是为了将给定的目录翻译为简单目录。</p><figure class="highlight plaintext"><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">Input: &quot;/a/./b/../../c/&quot;</span><br><span class="line">Output: &quot;/c&quot;</span><br></pre></td></tr></table></figure><h4><span id="解题思路">解题思路</span></h4><p>将字符串切割后，按照不同规则压入栈，特别注意，根目录下遇到返回上一级就不再做处理了。同样的，如果解析到最后，栈里啥都没有，要返回根目录。</p><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> String <span class="title function_">simplifyPath</span><span class="params">(String path)</span> &#123;</span><br><span class="line">        <span class="comment">// 先针对//进行分割，然后根据每个的状态进行出栈和入栈操作</span></span><br><span class="line">        String[] paths = path.split(<span class="string">&quot;/&quot;</span>);</span><br><span class="line">        Stack&lt;String&gt; strings = <span class="keyword">new</span> <span class="title class_">Stack</span>&lt;&gt;();</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; paths.length; i++) &#123;</span><br><span class="line">            <span class="keyword">switch</span> (paths[i]) &#123;</span><br><span class="line">                <span class="keyword">case</span> <span class="string">&quot;..&quot;</span>:</span><br><span class="line">                    <span class="keyword">if</span> (!strings.isEmpty()) &#123;</span><br><span class="line">                        strings.pop();</span><br><span class="line">                    &#125;</span><br><span class="line">                    <span class="keyword">break</span>;</span><br><span class="line">                <span class="keyword">case</span> <span class="string">&quot;.&quot;</span>:</span><br><span class="line">                    <span class="keyword">break</span>;</span><br><span class="line">                <span class="keyword">case</span> <span class="string">&quot;&quot;</span>:</span><br><span class="line">                    <span class="keyword">break</span>;</span><br><span class="line">                <span class="keyword">default</span>:</span><br><span class="line">                    strings.push(paths[i]);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        List&lt;String&gt; list = <span class="keyword">new</span> <span class="title class_">ArrayList</span>&lt;&gt;();</span><br><span class="line">        <span class="keyword">while</span> (!strings.isEmpty()) &#123;</span><br><span class="line">            list.add(strings.pop());</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="type">StringBuilder</span> <span class="variable">stringBuilder</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">StringBuilder</span>();</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> list.size() - <span class="number">1</span>; i &gt;= <span class="number">0</span>; i--) &#123;</span><br><span class="line">            stringBuilder.append(<span class="string">&quot;/&quot;</span> + list.get(i));</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span> (list.size() == <span class="number">0</span>) <span class="keyword">return</span> <span class="string">&quot;/&quot;</span>;</span><br><span class="line">        <span class="keyword">return</span> stringBuilder.toString();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3><span id="72-edit-distance">72 Edit Distance</span></h3><h4><span id="题目大意">题目大意</span></h4><p>给定两个单词，计算将单词1转换为单词2所使用的最少操作数。</p><p>可以对一个单词进行如下操作，插入一个字符，删除一个字符，替换一个字符。</p><h4><span id="解题思路">解题思路</span></h4><p>通过动态规划解决问题，通过两个指针 ij 分别指向 word1 和 word2。定义一个数组 dp[i][j] 表示 word1[:i] 转换到 word2[:j] 需要的最少步骤。</p><p>需要先比较 word1[i-1] 和 word2[j-1] 是不是相同，如果相同的话，不用做任何操作，所以此时 dp[i][j] = dp[i-1][j-1]，即看前面的串了。</p><p>对于不相同的时候，情况比较复杂，有三种处理手段，分别是插入、替换和删除。先看插入操作，插入之后，也就是 word1 中的元素不变，j的位置往前挪一个，相当于匹配了这个，dp[i][j] = dp[i][j-1]+1。</p><p>考虑替换操作，相当于都忽略掉了当前位置的元素，因为会替换成需要的，dp[i][j] = dp[i][j-1]+1。</p><p>最后考虑删除操作，在单词1中删除即可，dp[i][j] = dp[i-1][j]+1。</p><p>最后取最小值即可。</p><p>初始条件即有一个单词为空的情况下，要不然插入到相同，要不然删除到相同。</p><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">minDistance</span><span class="params">(String word1, String word2)</span> &#123;</span><br><span class="line">        <span class="type">int</span> <span class="variable">len1</span> <span class="operator">=</span> word1.length();</span><br><span class="line">        <span class="type">int</span> <span class="variable">len2</span> <span class="operator">=</span> word2.length();</span><br><span class="line">        <span class="type">int</span>[][] dp = <span class="keyword">new</span> <span class="title class_">int</span>[len1 + <span class="number">1</span>][len2 + <span class="number">1</span>];</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; len1 + <span class="number">1</span>; i++) &#123;</span><br><span class="line">            dp[i][<span class="number">0</span>] = i;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; len2 + <span class="number">1</span>; i++) &#123;</span><br><span class="line">            dp[<span class="number">0</span>][i] = i;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">1</span>; i &lt; len1 + <span class="number">1</span>; i++) &#123;</span><br><span class="line">            <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">j</span> <span class="operator">=</span> <span class="number">1</span>; j &lt; len2 + <span class="number">1</span>; j++) &#123;</span><br><span class="line">                <span class="keyword">if</span> (word1.charAt(i - <span class="number">1</span>) == word2.charAt(j - <span class="number">1</span>)) &#123;</span><br><span class="line">                    dp[i][j] = dp[i - <span class="number">1</span>][j - <span class="number">1</span>];</span><br><span class="line">                &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                    dp[i][j] = Math.min(dp[i - <span class="number">1</span>][j], Math.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">        &#125;</span><br><span class="line">        <span class="keyword">return</span> dp[len1][len2];</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3><span id="75-sort-colors">75 Sort Colors</span></h3><h4><span id="题目大意">题目大意</span></h4><p>一串0 1 2构成的数字，排序，要求尽可能只遍历一次。</p><figure class="highlight plaintext"><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">Input: [2,0,2,1,1,0]</span><br><span class="line">Output: [0,0,1,1,2,2]</span><br></pre></td></tr></table></figure><h4><span id="解题思路">解题思路</span></h4><ol><li>统计个数，然后安排。</li><li>根据题目要求，我们只能遍历array一次，可以用到two pointers来实现。设一个指针red 在开头，blue 在最后。想法就是，遇到红色0，就交换，把0放到最左边去；遇到蓝色2就交换，把2都放到最右边去，这样1就会被保留在最中间。需要注意的是，当把蓝色2交换完毕之后，需要i–， 停留 i 在原地一次，因为还需要继续检查 被2交换回来的数字。那当遇到红色0，交换完毕不需要停留i 的原因是， 交换回来的只可能是1，对于1，我们不需要做任何处理，直接过就可以。</li></ol><h4><span id="代码">代码</span></h4><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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">//思路1</span></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span>:</span><br><span class="line">    <span class="function"><span class="type">void</span> <span class="title">sortColors</span><span class="params">(vector&lt;<span class="type">int</span>&gt;&amp; nums)</span> </span>&#123;</span><br><span class="line">        <span class="type">int</span> a[<span class="number">3</span>] = &#123;<span class="number">0</span>&#125;;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">0</span>; i &lt; nums.<span class="built_in">size</span>(); i++) a[nums[i]]++;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">0</span>; i &lt; nums.<span class="built_in">size</span>(); i++) &#123;</span><br><span class="line">            <span class="keyword">if</span> (a[<span class="number">0</span>] &gt; <span class="number">0</span>) &#123;</span><br><span class="line">                nums[i] = <span class="number">0</span>;</span><br><span class="line">                a[<span class="number">0</span>]--;</span><br><span class="line">            &#125; <span class="keyword">else</span> <span class="keyword">if</span> (a[<span class="number">1</span>] &gt; <span class="number">0</span>) &#123;</span><br><span class="line">                nums[i] = <span class="number">1</span>;</span><br><span class="line">                a[<span class="number">1</span>]--;</span><br><span class="line">            &#125; <span class="keyword">else</span> <span class="keyword">if</span> (a[<span class="number">2</span>] &gt; <span class="number">0</span>) &#123;</span><br><span class="line">                nums[i] = <span class="number">2</span>;</span><br><span class="line">                a[<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="comment">//思路2</span></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span>:</span><br><span class="line">    <span class="function"><span class="type">void</span> <span class="title">sortColors</span><span class="params">(vector&lt;<span class="type">int</span>&gt; nums)</span> </span>&#123;</span><br><span class="line">        <span class="type">int</span> red = <span class="number">0</span>;</span><br><span class="line">        <span class="type">int</span> blue = nums.<span class="built_in">size</span>() - <span class="number">1</span>;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">0</span>; i &lt;= blue; i++) &#123;</span><br><span class="line">            <span class="keyword">if</span> (nums[i] == <span class="number">0</span>)  <span class="comment">// if find 0, swap with red pointer</span></span><br><span class="line">            &#123;</span><br><span class="line">                <span class="type">int</span> temp = nums[i];</span><br><span class="line">                nums[i] = nums[red];</span><br><span class="line">                nums[red] = temp;</span><br><span class="line">                red++;</span><br><span class="line">            &#125; <span class="keyword">else</span> <span class="keyword">if</span> (nums[i] == <span class="number">2</span>)  <span class="comment">// if find 2, swap with blue pointer</span></span><br><span class="line">            &#123;</span><br><span class="line">                <span class="type">int</span> temp = nums[i];</span><br><span class="line">                nums[i] = nums[blue];</span><br><span class="line">                nums[blue] = temp;</span><br><span class="line">                i--;</span><br><span class="line">                blue--;</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><h3><span id="78-子集">78 子集</span></h3><h4><span id="题目大意">题目大意</span></h4><p>给你一个整数数组 <code>nums</code> ，数组中的元素 <strong>互不相同</strong> 。返回该数组所有可能的子集（幂集）。</p><p>解集 <strong>不能</strong> 包含重复的子集。你可以按 <strong>任意顺序</strong> 返回解集。</p><h4><span id="解题思路">解题思路</span></h4><p>每个元素都有取或者不取两种选择，从空集开始逐个增加。也可以参考重复元素的子集Ⅱ题目代码。</p><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> List&lt;List&lt;Integer&gt;&gt; <span class="title function_">subsets</span><span class="params">(<span class="type">int</span>[] array)</span> &#123;</span><br><span class="line">        List&lt;List&lt;Integer&gt;&gt; resu = <span class="keyword">new</span> <span class="title class_">ArrayList</span>&lt;&gt;();</span><br><span class="line">        resu.add(<span class="keyword">new</span> <span class="title class_">ArrayList</span>&lt;&gt;());</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; array.length; i++) &#123;</span><br><span class="line">            <span class="type">int</span> <span class="variable">size</span> <span class="operator">=</span> resu.size();</span><br><span class="line">            <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">j</span> <span class="operator">=</span> <span class="number">0</span>; j &lt; size; j++) &#123;</span><br><span class="line">                <span class="comment">// 注意 Java 传值问题</span></span><br><span class="line">                List&lt;Integer&gt; tmp = <span class="keyword">new</span> <span class="title class_">ArrayList</span>&lt;&gt;(resu.get(j));</span><br><span class="line">                tmp.add(array[i]);</span><br><span class="line">                resu.add(<span class="keyword">new</span> <span class="title class_">ArrayList</span>&lt;&gt;(tmp));</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> resu;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3><span id="80-删除有序数组中的重复项-ii">80 删除有序数组中的重复项 Ⅱ</span></h3><h4><span id="题目大意">题目大意</span></h4><p>给定有序数组，原地删除重复出现元素，使得每个元素最多出现两次，返回删除后数组的长度。需要原地修改数组并使用O(1)额外空间的条件下完成。</p><h4><span id="解题思路">解题思路</span></h4><p>快慢指针，快指针表示遍历到的元素，慢指针表示当前要放的位置，使用index-2检查重复了几项。与之类似的还有26题。</p><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><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">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">removeDuplicates</span><span class="params">(<span class="type">int</span>[] nums)</span> &#123;</span><br><span class="line">        <span class="type">int</span> <span class="variable">index</span> <span class="operator">=</span> <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> num : nums) &#123;</span><br><span class="line">            <span class="keyword">if</span> (index &lt; <span class="number">2</span> || nums[index - <span class="number">2</span>] &lt; num) &#123;</span><br><span class="line">                nums[index] = num;</span><br><span class="line">                index++;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> index;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3><span id="82-remove-duplicates-from-sorted-list-ii">82 Remove Duplicates from Sorted List II</span></h3><h4><span id="题目大意">题目大意</span></h4><p>删除所有重复的节点，使得重复出现的节点一个不剩。</p><h4><span id="解题思路">解题思路</span></h4><p>先把重复的删了之后，再把剩下的那个跳过。</p><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> ListNode <span class="title function_">deleteDuplicates</span><span class="params">(ListNode head)</span> &#123;</span><br><span class="line">        <span class="type">ListNode</span> <span class="variable">preHead</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">ListNode</span>(-<span class="number">1</span>);</span><br><span class="line">        preHead.next = head;</span><br><span class="line">        <span class="type">ListNode</span> <span class="variable">pre</span> <span class="operator">=</span> preHead;</span><br><span class="line">        <span class="keyword">while</span> (pre.next != <span class="literal">null</span>)&#123;</span><br><span class="line">            <span class="type">ListNode</span> <span class="variable">cur</span> <span class="operator">=</span> pre.next;</span><br><span class="line">            <span class="keyword">while</span> (cur.next != <span class="literal">null</span> &amp;&amp; cur.val == cur.next.val)&#123;</span><br><span class="line">                cur = cur.next;</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">if</span> (cur != pre.next)&#123;</span><br><span class="line">                pre.next = cur.next;</span><br><span class="line">            &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                pre = pre.next;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> preHead.next;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3><span id="83-remove-duplicates-from-sorted-lsit">83 Remove Duplicates from Sorted Lsit</span></h3><h4><span id="题目大意">题目大意</span></h4><p>给出一个排好序的链表，删除所有连续出现的节点，使得每个几点只出现一次。</p><h4><span id="解题思路">解题思路</span></h4><ol><li>递归：如果头节点重复了，删除头节点；否则的话，递归头节点的next。</li><li>迭代：找到一个删除一个。</li></ol><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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">/// 1 递归</span></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> ListNode <span class="title function_">deleteDuplicates</span><span class="params">(ListNode head)</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> (head == <span class="literal">null</span> || head.next == <span class="literal">null</span>)</span><br><span class="line">            <span class="keyword">return</span> head;</span><br><span class="line">        <span class="keyword">if</span> (head.val == head.next.val)</span><br><span class="line">            <span class="keyword">return</span> deleteDuplicates(head.next);</span><br><span class="line">        <span class="keyword">else</span> &#123;</span><br><span class="line">            head.next = deleteDuplicates(head.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><span class="line">&#125;</span><br><span class="line"><span class="comment">// 2 迭代</span></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> ListNode <span class="title function_">deleteDuplicates</span><span class="params">(ListNode head)</span> &#123;</span><br><span class="line">        <span class="type">ListNode</span> <span class="variable">cur</span> <span class="operator">=</span> head;</span><br><span class="line">        <span class="keyword">while</span> (cur != <span class="literal">null</span> &amp;&amp; cur.next != <span class="literal">null</span>) &#123;</span><br><span class="line">            <span class="comment">// 元素相同，删除</span></span><br><span class="line">            <span class="keyword">if</span> (cur.val == cur.next.val)</span><br><span class="line">                cur.next = cur.next.next;</span><br><span class="line">            <span class="comment">// 不相同，当前节点后移</span></span><br><span class="line">            <span class="keyword">else</span></span><br><span class="line">                cur = cur.next;</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">&#125;</span><br></pre></td></tr></table></figure><h3><span id="86-partitionlist">86 PartitionList</span></h3><h4><span id="题目大意">题目大意</span></h4><p>给定一个链表，将小于X的结点放到所有大于等于X的结点的前面，不要修改节点之间的顺序。</p><h4><span id="解题思路">解题思路</span></h4><ol><li>类似快排的思路，建立哨兵结点，找到第一个大于等于X的结点的位置，之后遍历结点，将所有小于值X的结点提到这个位置。</li><li>两个链表，小于分区点一个大于的一个。根据值的情况改变指针即可。</li></ol><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="comment">// 解法1</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> ListNode <span class="title function_">partition</span><span class="params">(ListNode head, <span class="type">int</span> x)</span> &#123;</span><br><span class="line">        <span class="type">ListNode</span> <span class="variable">preHead</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">ListNode</span>(<span class="number">0</span>);</span><br><span class="line">        preHead.next = head;</span><br><span class="line">        <span class="type">ListNode</span> <span class="variable">pre</span> <span class="operator">=</span> preHead;</span><br><span class="line">        <span class="type">ListNode</span> <span class="variable">cur</span> <span class="operator">=</span> head;</span><br><span class="line">        <span class="type">ListNode</span> <span class="variable">insPos</span> <span class="operator">=</span> <span class="literal">null</span>;</span><br><span class="line">        <span class="keyword">while</span> (cur != <span class="literal">null</span>) &#123;</span><br><span class="line">            <span class="keyword">if</span> (cur.val &gt;= x &amp;&amp; insPos == <span class="literal">null</span>) &#123;</span><br><span class="line">                insPos = pre;</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">if</span> (cur.val &lt; x &amp;&amp; insPos != <span class="literal">null</span>) &#123;</span><br><span class="line">                pre.next = pre.next.next;</span><br><span class="line">                cur.next = insPos.next;</span><br><span class="line">                insPos.next = cur;</span><br><span class="line">                insPos = insPos.next;</span><br><span class="line">                cur = pre.next;</span><br><span class="line">                <span class="keyword">continue</span>;</span><br><span class="line">            &#125;</span><br><span class="line">            pre = pre.next;</span><br><span class="line">            cur = cur.next;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> preHead.next;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">// 解法2</span></span><br><span class="line"><span class="keyword">public</span> ListNode <span class="title function_">partition</span><span class="params">(ListNode head, <span class="type">int</span> x)</span> &#123; </span><br><span class="line">    <span class="comment">//小于分区点的链表</span></span><br><span class="line">    <span class="type">ListNode</span> <span class="variable">min_head</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">ListNode</span>(<span class="number">0</span>);</span><br><span class="line">    <span class="type">ListNode</span> <span class="variable">min</span> <span class="operator">=</span> min_head;</span><br><span class="line">    <span class="comment">//大于等于分区点的链表</span></span><br><span class="line">    <span class="type">ListNode</span> <span class="variable">max_head</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">ListNode</span>(<span class="number">0</span>);</span><br><span class="line">    <span class="type">ListNode</span> <span class="variable">max</span> <span class="operator">=</span> max_head;</span><br><span class="line"></span><br><span class="line">    <span class="comment">//遍历整个链表</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">if</span> (head.val &lt; x) &#123;</span><br><span class="line">            min.next = head;</span><br><span class="line">            min = min.next;</span><br><span class="line">        &#125; <span class="keyword">else</span> &#123; </span><br><span class="line">            max.next = head;</span><br><span class="line">            max = max.next;</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        head = head.next;</span><br><span class="line">    &#125; </span><br><span class="line">    max.next = <span class="literal">null</span>;  <span class="comment">//这步不要忘记，不然链表就出现环了</span></span><br><span class="line">    <span class="comment">//两个链表接起来</span></span><br><span class="line">    min.next = max_head.next;</span><br><span class="line">    <span class="keyword">return</span> min_head.next;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3><span id="88-merge-sorted-array">88  Merge Sorted Array</span></h3><h4><span id="题目大意">题目大意</span></h4><p>合并两个有序vector。</p><h4><span id="解题思路">解题思路</span></h4><ol><li>将nums2复制进nums1然后排序。</li><li>高级一点，因为nums1预留了空间，所以可以从后往前存储。</li></ol><h4><span id="代码">代码</span></h4><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><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="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">   <span class="keyword">public</span>:</span><br><span class="line">    <span class="function"><span class="type">void</span> <span class="title">merge</span><span class="params">(vector&lt;<span class="type">int</span>&gt;&amp; nums1, <span class="type">int</span> m, vector&lt;<span class="type">int</span>&gt;&amp; nums2, <span class="type">int</span> n)</span> </span>&#123;</span><br><span class="line">        <span class="type">int</span> i = m - <span class="number">1</span>, j = n - <span class="number">1</span>, k = m + n - <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] &gt; nums2[j])</span><br><span class="line">                nums1[k--] = nums1[i--];</span><br><span class="line">            <span class="keyword">else</span></span><br><span class="line">                nums1[k--] = nums2[j--];</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">while</span> (j &gt;= <span class="number">0</span>) nums1[k--] = nums2[j--];</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><h3><span id="89-gray-code">89 Gray Code</span></h3><h4><span id="题目大意">题目大意</span></h4><p>给一个编码总位数n，打印格雷码序列，格雷码必须以0开头。</p><p>2——&gt;0，1，3，2/0，2，3，1</p><h4><span id="解题思路">解题思路</span></h4><h5><span id="解法一">解法一</span></h5><p><a href="https://blog.csdn.net/u012501459/article/details/46790683">参考链接</a> 将样例写出，找规律。</p><p><img src="https://img-blog.csdn.net/20150707154905591" alt="找规律"></p><p>当n=2时候，它的结果包括n=1时候结果左边补0，以及逆序遍历n=1时候的结果左边补1。根据规律可知，当n=k+1的情况下，对n=k的结果左边补0，然后逆序对n=k的结果左边补1即可。</p><h5><span id="解法二">解法二</span></h5><p>格雷码的数学计算方法，由对应的十进制求出。grayCode=i ^ (i &gt;&gt;1)，就是自己与自己右移一位进行异或。</p><h4><span id="代码">代码</span></h4><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> List&lt;Integer&gt; <span class="title">grayCode</span><span class="params">(<span class="type">int</span> n)</span> </span>&#123;</span><br><span class="line">        List&lt;Integer&gt; rs = <span class="keyword">new</span> <span class="built_in">ArrayList</span>&lt;Integer&gt;();</span><br><span class="line">        rs.<span class="built_in">add</span>(<span class="number">0</span>);</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">0</span>; i &lt; n; i++) &#123;</span><br><span class="line">            <span class="type">int</span> size = rs.<span class="built_in">size</span>();</span><br><span class="line">            <span class="keyword">for</span> (<span class="type">int</span> k = size - <span class="number">1</span>; k &gt;= <span class="number">0</span>; k--)</span><br><span class="line">                rs.<span class="built_in">add</span>(rs.<span class="built_in">get</span>(k) | <span class="number">1</span> &lt;&lt; i);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> rs;</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">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> List&lt;Integer&gt; <span class="title">grayCode</span><span class="params">(<span class="type">int</span> n)</span> </span>&#123;</span><br><span class="line">        List&lt;Integer&gt; rs = <span class="keyword">new</span> <span class="built_in">ArrayList</span>&lt;Integer&gt;();</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">0</span>; i &lt; <span class="number">1</span> &lt;&lt; n; i++)</span><br><span class="line">            rs.<span class="built_in">add</span>(i ^ i &gt;&gt; <span class="number">1</span>);</span><br><span class="line">        <span class="keyword">return</span> rs;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3><span id="90-子集-ii">90 子集 Ⅱ</span></h3><h4><span id="题目大意">题目大意</span></h4><p>给你一个整数数组 nums ，其中可能包含重复元素，请你返回该数组所有可能的子集（幂集）。</p><p>解集 不能 包含重复的子集。返回的解集中，子集可以按 任意顺序 排列。</p><h4><span id="解题思路">解题思路</span></h4><p>按照子集中元素个数逐个生成。每个元素都可以有或者没有。</p><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">private</span> List&lt;List&lt;Integer&gt;&gt; res = <span class="keyword">new</span> <span class="title class_">ArrayList</span>&lt;&gt;();</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> List&lt;List&lt;Integer&gt;&gt; <span class="title function_">subsetsWithDup</span><span class="params">(<span class="type">int</span>[] array)</span> &#123;</span><br><span class="line">        <span class="comment">//  排序方便去重</span></span><br><span class="line">        Arrays.sort(array);</span><br><span class="line">        List&lt;Integer&gt; path = <span class="keyword">new</span> <span class="title class_">ArrayList</span>&lt;&gt;();</span><br><span class="line">        <span class="comment">// i 表示子集长度，长度为n的集合的子集最长为n即全子集</span></span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt;= array.length; i++) &#123;</span><br><span class="line">            dfs(i, <span class="number">0</span>, array, path);</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="keyword">private</span> <span class="keyword">void</span> <span class="title function_">dfs</span><span class="params">(<span class="type">int</span> size, <span class="type">int</span> start, <span class="type">int</span>[] array, List&lt;Integer&gt; path)</span> &#123;</span><br><span class="line">        <span class="comment">// 跳出条件，空集或者已经找到的集合长度刚好是要找的长度</span></span><br><span class="line">        <span class="keyword">if</span> (size == <span class="number">0</span> || path.size() == size) &#123;</span><br><span class="line">            res.add(<span class="keyword">new</span> <span class="title class_">ArrayList</span>&lt;&gt;(path));</span><br><span class="line">            <span class="keyword">return</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="comment">// 从起点元素开始找</span></span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> start; i &lt; array.length; i++) &#123;</span><br><span class="line">            <span class="comment">// 去重</span></span><br><span class="line">            <span class="keyword">if</span> (i &gt; start &amp;&amp; array[i] == array[i - <span class="number">1</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="comment">// 包含当前节点</span></span><br><span class="line">            path.add(array[i]);</span><br><span class="line">            dfs(size, i + <span class="number">1</span>, array, path);</span><br><span class="line">            <span class="comment">// 不包含</span></span><br><span class="line">            path.remove(path.size() - <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><h3><span id="92-reverse-linked-list-ii">92 Reverse Linked List II</span></h3><h4><span id="题目大意">题目大意</span></h4><p>反转链表中的第 m 个到第 n 个。使用一次遍历。</p><h4><span id="解题思路">解题思路</span></h4><p>看代码吧，不好讲。</p><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> ListNode <span class="title function_">reverseBetween</span><span class="params">(ListNode head, <span class="type">int</span> m, <span class="type">int</span> n)</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> (head == <span class="literal">null</span> || head.next == <span class="literal">null</span> || m &gt; n || m &lt; <span class="number">0</span> || n &lt; <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="type">ListNode</span> <span class="variable">p</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">ListNode</span>(-<span class="number">1</span>);</span><br><span class="line">        p.next = head;</span><br><span class="line">        <span class="type">ListNode</span> <span class="variable">pre</span> <span class="operator">=</span> p;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">1</span>; i &lt; m; i++) &#123;</span><br><span class="line">            pre = pre.next;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="type">ListNode</span> <span class="variable">cur</span> <span class="operator">=</span> pre.next;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> m; i &lt; n; i++) &#123;</span><br><span class="line">            <span class="type">ListNode</span> <span class="variable">tmp</span> <span class="operator">=</span> cur.next;</span><br><span class="line">            cur.next = tmp.next;</span><br><span class="line">            tmp.next = pre.next;</span><br><span class="line">            pre.next = tmp;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> p.next;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3><span id="93-restore-ip-addresses">93 Restore IP Addresses</span></h3><h4><span id="题目大意">题目大意</span></h4><p>给一个没有分割的字符串，将其还原为 IP 地址。</p><h4><span id="解题思路">解题思路</span></h4><p>代码中有注释。</p><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="keyword">import</span> java.util.ArrayList;</span><br><span class="line"><span class="keyword">import</span> java.util.List;</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * s 字符串，n 还剩几个ip没分割，index 当前切到哪里了，ip 已经生成的ip， result 结果集</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">backtrack</span><span class="params">(String s, <span class="type">int</span> n, <span class="type">int</span> index, String ip, List&lt;String&gt; result)</span> &#123;</span><br><span class="line">        <span class="comment">// 生成完毕</span></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">if</span> (index == s.length()) &#123;</span><br><span class="line">                result.add(ip);</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 class="comment">// 切割验证，可以就继续回溯</span></span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> index + <span class="number">1</span>; i &lt; s.length() + <span class="number">1</span>; i++) &#123;</span><br><span class="line">            <span class="keyword">if</span> (isNum(s.substring(index, i))) &#123;</span><br><span class="line">                backtrack(s, n - <span class="number">1</span>, i, ip.equals(<span class="string">&quot;&quot;</span>) ? s.substring(index, i) : ip + <span class="string">&quot;.&quot;</span> + s.substring(index, i), result);</span><br><span class="line">            &#125; <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><br><span class="line">    <span class="comment">/**</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="keyword">public</span> <span class="keyword">static</span> <span class="type">boolean</span> <span class="title function_">isNum</span><span class="params">(String num)</span> &#123;</span><br><span class="line">        <span class="type">int</span> <span class="variable">n</span> <span class="operator">=</span> Integer.parseInt(num);</span><br><span class="line">        <span class="keyword">if</span> (n &gt;= <span class="number">0</span> &amp;&amp; n &lt;= <span class="number">255</span> &amp;&amp; String.valueOf(n).equals(num)) &#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> <span class="literal">false</span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> List&lt;String&gt; <span class="title function_">restoreIpAddresses</span><span class="params">(String s)</span> &#123;</span><br><span class="line">        List&lt;String&gt; list = <span class="keyword">new</span> <span class="title class_">ArrayList</span>&lt;&gt;();</span><br><span class="line">        <span class="keyword">if</span> (s == <span class="literal">null</span> || s.length() &lt; <span class="number">4</span> || s.length() &gt; <span class="number">12</span>) &#123;</span><br><span class="line">            <span class="keyword">return</span> list;</span><br><span class="line">        &#125;</span><br><span class="line">        backtrack(s, <span class="number">4</span>, <span class="number">0</span>, <span class="string">&quot;&quot;</span>, list);</span><br><span class="line">        <span class="keyword">return</span> list;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line">        System.out.println(restoreIpAddresses(<span class="string">&quot;25525511135&quot;</span>));</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3><span id="96-unique-binary-search-tree">96 Unique Binary Search Tree</span></h3><h4><span id="题目大意">题目大意</span></h4><p>给一个n，求1到n这些数可以构成多少个二叉搜索树。</p><h4><span id="解题思路">解题思路</span></h4><ol><li><p>递归</p></li><li><p>动态规划</p></li></ol><p>思路基本一致，都是分开左右子树算，不同的是动态规划储存了数组。还有一个要注意的是，左右子树的个数最终要相乘而不是想加。</p><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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">// 1 递归</span></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">private</span> <span class="type">int</span> <span class="title function_">getAns</span><span class="params">(<span class="type">int</span> n)</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> (n == <span class="number">1</span> || n == <span class="number">0</span>)</span><br><span class="line">            <span class="keyword">return</span> <span class="number">1</span>;</span><br><span class="line">        <span class="type">int</span> <span class="variable">sum</span> <span class="operator">=</span> <span class="number">0</span>;</span><br><span class="line">        <span class="comment">// 左子树从0到n-1，因为还得给根节点一个</span></span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; n; i++) &#123;</span><br><span class="line">            <span class="type">int</span> <span class="variable">left</span> <span class="operator">=</span> getAns(i);</span><br><span class="line">            <span class="type">int</span> <span class="variable">right</span> <span class="operator">=</span> getAns(n - i - <span class="number">1</span>);</span><br><span class="line">            sum += left * right;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> sum;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">numTrees</span><span class="params">(<span class="type">int</span> n)</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> (n == <span class="number">0</span>)</span><br><span class="line">            <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">return</span> getAns(n);</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">public</span> <span class="type">int</span> <span class="title function_">numTrees</span><span class="params">(<span class="type">int</span> n)</span> &#123;</span><br><span class="line">    <span class="type">int</span>[] dp = <span class="keyword">new</span> <span class="title class_">int</span>[n + <span class="number">1</span>];</span><br><span class="line">    dp[<span class="number">0</span>] = <span class="number">1</span>;</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="comment">// 长度为 1 到 n</span></span><br><span class="line">    <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">len</span> <span class="operator">=</span> <span class="number">1</span>; len &lt;= n; len++) &#123;</span><br><span class="line">        <span class="comment">// 将不同的数字作为根节点</span></span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">root</span> <span class="operator">=</span> <span class="number">1</span>; root &lt;= len; root++) &#123;</span><br><span class="line">            <span class="type">int</span> <span class="variable">left</span> <span class="operator">=</span> root - <span class="number">1</span>; <span class="comment">// 左子树的长度</span></span><br><span class="line">            <span class="type">int</span> <span class="variable">right</span> <span class="operator">=</span> len - root; <span class="comment">// 右子树的长度</span></span><br><span class="line">            dp[len] += dp[left] * dp[right];</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> dp[n];</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3><span id="110-balanced-binary-tree">110 Balanced Binary Tree</span></h3><h4><span id="题目大意">题目大意</span></h4><p>平衡二叉树</p><h4><span id="解题思路">解题思路</span></h4><p>老掉牙的题，之前在一篇博客上看过一种自底向上的算法，大大减少了计算次数。</p><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="type">boolean</span> <span class="title function_">isBalanced</span><span class="params">(TreeNode root)</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> ban(root) != -<span class="number">1</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">ban</span><span class="params">(TreeNode cur)</span>&#123;</span><br><span class="line">        <span class="keyword">if</span> (cur == <span class="literal">null</span>) <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">        <span class="type">int</span> <span class="variable">left</span> <span class="operator">=</span> ban(cur.left);</span><br><span class="line">        <span class="keyword">if</span> (left == -<span class="number">1</span>) <span class="keyword">return</span> -<span class="number">1</span>; </span><br><span class="line">        <span class="type">int</span> <span class="variable">right</span> <span class="operator">=</span> ban(cur.right);</span><br><span class="line">        <span class="keyword">if</span> (right == -<span class="number">1</span>) <span class="keyword">return</span> -<span class="number">1</span>;</span><br><span class="line">        <span class="keyword">return</span> Math.abs(left - right) &lt;= <span class="number">1</span>? Math.max(left, right) + <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="comment">// 递归算法</span></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="type">boolean</span> <span class="title function_">isBalanced</span><span class="params">(TreeNode root)</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> (root == <span class="literal">null</span>) <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line">        <span class="keyword">return</span> Math.abs(maxHigh(root.left) - maxHigh(root.right)) &lt;= <span class="number">1</span> &amp;&amp; isBalanced(root.left) &amp;&amp; isBalanced(root.right);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">maxHigh</span><span class="params">(TreeNode cur)</span>&#123;</span><br><span class="line">        <span class="keyword">if</span> (cur == <span class="literal">null</span>) <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">return</span> Math.max(maxHigh(cur.left), maxHigh(cur.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><h3><span id="121-best-time-to-buy-and-sell-stock">121 Best Time to Buy and Sell Stock</span></h3><h4><span id="题目大意">题目大意</span></h4><p>决定股票买卖最佳时机。</p><figure class="highlight plaintext"><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">Input: [7,1,5,3,6,4]</span><br><span class="line">Output: 5</span><br><span class="line">1 - 6</span><br></pre></td></tr></table></figure><h4><span id="解题思路">解题思路</span></h4><p>先确定一个买入点，以后假设第 i 天卖，正数就更新最大值，负数说明现在底谷期，不抛后面收益肯定小于等于现在，抄底冲。</p><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><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="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">maxProfit</span><span class="params">(<span class="type">int</span>[] prices)</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> (prices == <span class="literal">null</span> || prices.length == <span class="number">0</span>) <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">        <span class="type">int</span> <span class="variable">max</span> <span class="operator">=</span> <span class="number">0</span>;</span><br><span class="line">        <span class="type">int</span> <span class="variable">start</span> <span class="operator">=</span> prices[<span class="number">0</span>];</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">1</span>; i &lt; prices.length; i++)&#123;</span><br><span class="line">            <span class="keyword">if</span> (prices[i] - start &gt; max)&#123;</span><br><span class="line">                max = prices[i] - start;</span><br><span class="line">            &#125; <span class="keyword">else</span> <span class="keyword">if</span> (prices[i] - start &lt; <span class="number">0</span>) &#123;</span><br><span class="line">                start = prices[i];</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><h3><span id="123-best-time-to-buy-and-sell-stock-iii">123 Best Time to Buy and Sell Stock III</span></h3><h4><span id="题目大意">题目大意</span></h4><p>买卖股票问题，只允许最多两次买卖。</p><h4><span id="解题思路">解题思路</span></h4><ul><li><em>b<strong>u</strong>y</em>1=<em>m<strong>a</strong>x</em>(<em>b<strong>u</strong>y</em>1,−<em>p<strong>r</strong>i<strong>c</strong>e**s</em>[<em>i</em>])</li><li>sell1=max(sell1,buy1+prices[i])sell1 = max(sell1, buy1 + prices[i])<em>s<strong>e</strong>l**l</em>1=<em>m<strong>a</strong>x</em>(<em>s<strong>e</strong>l**l</em>1,<em>b<strong>u</strong>y</em>1+<em>p<strong>r</strong>i<strong>c</strong>e**s</em>[<em>i</em>])</li><li>buy2=max(buy2,sell1−prices[i])buy2 = max(buy2, sell1 - prices[i])<em>b<strong>u</strong>y</em>2=<em>m<strong>a</strong>x</em>(<em>b<strong>u</strong>y</em>2,<em>s<strong>e</strong>l**l</em>1−<em>p<strong>r</strong>i<strong>c</strong>e**s</em>[<em>i</em>])</li><li>sell2=max(sell2,buy2+prices[i])sell2 = max(sell2, buy2 + prices[i])<em>s<strong>e</strong>l**l</em>2=<em>m<strong>a</strong>x</em>(<em>s<strong>e</strong>l**l</em>2,<em>b<strong>u</strong>y</em>2+<em>p<strong>r</strong>i<strong>c</strong>e**s</em>[<em>i</em>])</li></ul><p>然后就是考虑边界问题，很显然<code>buy1[0]=-prices[0]</code>，而<code>sell1=0</code>（相当于买入后再卖出）、<code>buy2-prices[0]</code>（相当于买入后再卖出再买入）、<code>sell2=0</code>（相当于买入后再卖出再买入再卖出）。</p><p>注意这里 buy 是复数。</p><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><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="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">maxProfit</span><span class="params">(<span class="type">int</span>[] prices)</span> &#123;</span><br><span class="line">        <span class="type">int</span> <span class="variable">buy1</span> <span class="operator">=</span> -prices[<span class="number">0</span>];</span><br><span class="line">        <span class="type">int</span> <span class="variable">sell1</span> <span class="operator">=</span> <span class="number">0</span>;</span><br><span class="line">        <span class="type">int</span> <span class="variable">buy2</span> <span class="operator">=</span> -prices[<span class="number">0</span>];</span><br><span class="line">        <span class="type">int</span> <span class="variable">sell2</span> <span class="operator">=</span> <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">1</span>; i &lt; prices.length; i++) &#123;</span><br><span class="line">            buy1 = Math.max(buy1, -prices[i]);</span><br><span class="line">            sell1 = Math.max(sell1, buy1 + prices[i]);</span><br><span class="line">            buy2 = Math.max(buy2, sell1 - prices[i]);</span><br><span class="line">            sell2 = Math.max(sell2, buy2 + prices[i]);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> sell2;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3><span id="124-binary-tree-maximum-path-sum">124 Binary Tree Maximum Path Sum</span></h3><h4><span id="题目大意">题目大意</span></h4><p>给定非空二叉树，找到最大路径总和，可能不过根节点。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><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">Input: [-10,9,20,null,null,15,7]</span><br><span class="line"></span><br><span class="line">   -10</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><span class="line"></span><br><span class="line">Output: 42</span><br></pre></td></tr></table></figure><h4><span id="解题思路">解题思路</span></h4><p>一棵树的路径，从一个开始节点出发，向上走 0 或者 k 步， 到达某一个根节点，然后再往下走 0 或者 j 步。一旦它往下走。一旦它往下走，就不会再上升。因此，每个路径都有一个最高节点，也是这条路径上其他节点的最低公共祖先。</p><p>采用递归策略解决，对于某一个节点，我们会递归地计算它的左子树和右子树的最大的路径之和，然后判断当前节点作为根节点时，路径的值是否是当前所遍历到的所有节点的最大值。然后如果当它不是根节点，返回他作为一串链上的值。</p><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="type">int</span> <span class="variable">maxL</span> <span class="operator">=</span> Integer.MIN_VALUE;</span><br><span class="line">    <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">maxPathSum</span><span class="params">(TreeNode root)</span> &#123;</span><br><span class="line">        dfs(root);</span><br><span class="line">        <span class="keyword">return</span> maxL;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">dfs</span><span class="params">(TreeNode cur)</span>&#123;</span><br><span class="line">        <span class="keyword">if</span> (cur == <span class="literal">null</span>) <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">        <span class="type">int</span> <span class="variable">left</span> <span class="operator">=</span> dfs(cur.left);</span><br><span class="line">        left = left &gt; <span class="number">0</span>? left : <span class="number">0</span>;</span><br><span class="line">        <span class="type">int</span> <span class="variable">right</span> <span class="operator">=</span> dfs(cur.right);</span><br><span class="line">        right = right &gt; <span class="number">0</span>? right : <span class="number">0</span>;</span><br><span class="line">        <span class="comment">// 作为根节点，直接更新</span></span><br><span class="line">        maxL = Math.max(maxL, cur.val + left + right);</span><br><span class="line">        <span class="comment">// 返回往下的链的深度，参与它的父节点的运算</span></span><br><span class="line">        <span class="keyword">return</span> cur.val + Math.max(left, right);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3><span id="125-valid-palindrome">125 Valid Palindrome</span></h3><h4><span id="题目大意">题目大意</span></h4><p>给定一个字符串，判断是不是回文字符串，只考虑数字和字母且不考虑大小写。</p><h4><span id="解题思路">解题思路</span></h4><p>讲字符串清洗后，判断反转后是否相同即可。</p><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="type">boolean</span> <span class="title function_">isPalindrome</span><span class="params">(String s)</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>) <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line">        <span class="comment">// 处理空格</span></span><br><span class="line">        <span class="type">String</span> <span class="variable">tmp</span> <span class="operator">=</span> <span class="string">&quot;&quot;</span>;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; s.length(); i++) &#123;</span><br><span class="line">            <span class="keyword">if</span> ((s.charAt(i) &gt;= <span class="string">&#x27;A&#x27;</span> &amp;&amp; s.charAt(i) &lt;= <span class="string">&#x27;Z&#x27;</span>) || (s.charAt(i) &gt;= <span class="string">&#x27;0&#x27;</span> &amp;&amp; s.charAt(i) &lt;= <span class="string">&#x27;9&#x27;</span>)) &#123;</span><br><span class="line">                tmp += s.charAt(i);</span><br><span class="line">            &#125; <span class="keyword">else</span> <span class="keyword">if</span> (s.charAt(i) &gt;= <span class="string">&#x27;a&#x27;</span> &amp;&amp; s.charAt(i) &lt;= <span class="string">&#x27;z&#x27;</span>) &#123;</span><br><span class="line">                tmp += (<span class="type">char</span>) (s.charAt(i) - <span class="number">32</span>);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="type">StringBuilder</span> <span class="variable">sb</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">StringBuilder</span>(tmp);</span><br><span class="line">        System.out.println(sb.toString());</span><br><span class="line">        <span class="keyword">return</span> sb.toString().equals(sb.reverse().toString());</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3><span id="128-longest-consecutive-sequence">128 Longest Consecutive Sequence</span></h3><h4><span id="题目大意">题目大意</span></h4><p>给定一个未排序的数组，找出其中最长的连续子序列的长度，元素不必在一起。要求算法复杂度在O(n)。</p><figure class="highlight plaintext"><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">Input: [100, 4, 200, 1, 3, 2]</span><br><span class="line">Output: 4</span><br><span class="line">Explanation: The longest consecutive elements sequence is [1, 2, 3, 4]. Therefore its length is 4.</span><br></pre></td></tr></table></figure><h4><span id="解题思路">解题思路</span></h4><p>这道题是舍友发给我的，初上手没有思路，觉得排序之后寻找即可，排序算法nlogn显然不符合要求。</p><p>换做了 HashSet 虽然保证了有序和复杂度的问题，但是因为还要将数组转换为Set，相当于在logn外面又套了一个n。</p><p>最后看到了题解使用的 HashSet，而且在查找时候也有很强的优化。最差也是2n。下面摘自题解</p><p>仔细分析这个过程，我们会发现其中执行了很多不必要的枚举，如果已知有一个 x, x+1, x+2, \cdots, x+yx,x+1,x+2,⋯,x+y 的连续序列，而我们却重新从 x+1x+1，x+2x+2 或者是 x+yx+y 处开始尝试匹配，那么得到的结果肯定不会优于枚举 xx 为起点的答案，因此我们在外层循环的时候碰到这种情况跳过即可。</p><p>那么怎么判断是否跳过呢？由于我们要枚举的数 xx 一定是在数组中不存在前驱数 x-1x−1 的，不然按照上面的分析我们会从 x-1x−1 开始尝试匹配，因此我们每次在哈希表中检查是否存在 x-1x−1 即能判断是否需要跳过了。</p><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">longestConsecutive</span><span class="params">(<span class="type">int</span>[] nums)</span> &#123;</span><br><span class="line">        Set&lt;Integer&gt; set = <span class="keyword">new</span> <span class="title class_">HashSet</span>&lt;&gt;();</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> num : nums) &#123;</span><br><span class="line">            set.add(num);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="type">int</span> <span class="variable">longlen</span> <span class="operator">=</span> <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> num : nums) &#123;</span><br><span class="line">            <span class="keyword">if</span> (!set.contains(num - <span class="number">1</span>)) &#123;</span><br><span class="line">                <span class="type">int</span> <span class="variable">currentNum</span> <span class="operator">=</span> num;</span><br><span class="line">                <span class="type">int</span> <span class="variable">len</span> <span class="operator">=</span> <span class="number">1</span>;</span><br><span class="line">                <span class="keyword">while</span> (set.contains(currentNum + <span class="number">1</span>)) &#123;</span><br><span class="line">                    currentNum++;</span><br><span class="line">                    len++;</span><br><span class="line">                &#125;</span><br><span class="line">                longlen = Math.max(longlen, len);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> longlen;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3><span id="135-candy">135 Candy</span></h3><h4><span id="题目大意">题目大意</span></h4><p>老师给孩子们分糖果，有 N 个孩子。</p><ul><li>每个孩子至少分配一个糖果。</li><li>相邻的孩子中评分最高的必须获得更高的水果。</li></ul><p>问老师需要准备多少糖果。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><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">输入：[1,0,2]</span><br><span class="line">输出：5</span><br><span class="line">发2、1、2</span><br><span class="line">输入：[1,2,2]</span><br><span class="line">输出：4</span><br><span class="line">发1、2、1</span><br></pre></td></tr></table></figure><h4><span id="解题思路">解题思路</span></h4><ul><li>正序遍历，如果后一位比前一位高分，就给比前一位多1的糖果，否则给1。</li><li>再倒序遍历，如果前一位比后一位高分并且得到的糖果小于等于后一位，就给前一位孩子比后一位多一个糖果。</li></ul><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">candy</span><span class="params">(<span class="type">int</span>[] ratings)</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> (ratings == <span class="literal">null</span> || ratings.length == <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="type">int</span>[] tmp = <span class="keyword">new</span> <span class="title class_">int</span>[ratings.length];</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; tmp.length; i++) &#123;</span><br><span class="line">            tmp[i] = <span class="number">1</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="type">int</span> <span class="variable">resu</span> <span class="operator">=</span> <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">1</span>; i &lt; ratings.length; i++) &#123;</span><br><span class="line">            <span class="keyword">if</span> (ratings[i] &gt; ratings[i - <span class="number">1</span>]) &#123;</span><br><span class="line">                tmp[i] = tmp[i - <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">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> ratings.length - <span class="number">2</span>; i &gt;= <span class="number">0</span>; i--) &#123;</span><br><span class="line">            <span class="keyword">if</span> (ratings[i] &gt; ratings[i + <span class="number">1</span>] &amp;&amp; tmp[i] &lt;= tmp[i + <span class="number">1</span>]) &#123;</span><br><span class="line">                tmp[i] = tmp[i + <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">for</span> (<span class="type">int</span> t : tmp) &#123;</span><br><span class="line">            resu += t;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> resu;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3><span id="139-word-break">139 Word Break</span></h3><h4><span id="题目大意">题目大意</span></h4><p>判断字符串是否可以由字典里的字符串组成，可以重复。</p><h4><span id="解题思路">解题思路</span></h4><p>一开始想用递归写，但是发现好像结果的或不太好写。在别人的博客里看来了一种动态规划，看来 leetcode 上的题目，别问，解不出来就动态规划。</p><p>设置标记数组，dp[i] 表示第 i 个位置的结果。这里注意第 i 个应该是索引 + 1。对于每个以 i 结尾字串 A，判断是不是在字典里或者他是由一个已经由字典拼接的字符串和字典里的字符串拼接而成。</p><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="type">boolean</span> <span class="title function_">wordBreak</span><span class="params">(String s, List&lt;String&gt; wordDict)</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> (s == <span class="literal">null</span> || s.length() == <span class="number">0</span>) <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line">        <span class="type">boolean</span>[] result = <span class="keyword">new</span> <span class="title class_">boolean</span>[s.length() + <span class="number">1</span>];</span><br><span class="line">        result[<span class="number">0</span>] = <span class="literal">true</span>;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; s.length(); i++)&#123;</span><br><span class="line">            <span class="type">StringBuilder</span> <span class="variable">sb</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">StringBuilder</span>(s.substring(<span class="number">0</span>, i + <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="type">int</span> <span class="variable">j</span> <span class="operator">=</span> <span class="number">0</span>; j &lt;= i; j++)&#123;</span><br><span class="line">                <span class="keyword">if</span> (result[j] &amp;&amp; wordDict.contains(sb.toString()))&#123;</span><br><span class="line">                    <span class="comment">// 因为数组的索引从 0 开始，而结果数组的 i 表示次序，需要 + 1</span></span><br><span class="line">                    result[i + <span class="number">1</span>] = <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">                sb.deleteCharAt(<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> result[s.length()];</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3><span id="146-lru-cache">146 LRU Cache</span></h3><h4><span id="题目大意">题目大意</span></h4><p>根据给出的代码完善一个 LRUCache。</p><h4><span id="解题思路">解题思路</span></h4><p>通过使用 LinkedHashMap 实现顺序存放键值对，之后再实现 LRU 的特性。</p><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="keyword">class</span> <span class="title class_">LRUCache</span> &#123;</span><br><span class="line">    <span class="keyword">private</span> <span class="type">int</span> capacity;</span><br><span class="line">    <span class="keyword">private</span> LRULinkedHashMap&lt;Integer, Integer&gt; linkedHashMap = <span class="keyword">new</span> <span class="title class_">LRULinkedHashMap</span>&lt;&gt;();</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="title function_">LRUCache</span><span class="params">(<span class="type">int</span> capacity)</span> &#123;</span><br><span class="line">        <span class="built_in">this</span>.capacity = capacity;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 这里实现一个新的类，用于重写一个方法，通过覆盖该方法加入一定的条件，满足条件返回 true， 当 put 新的值返回 true，就移除该 map 中最老的键值对。</span></span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">class</span> <span class="title class_">LRULinkedHashMap</span>&lt;K, V&gt; <span class="keyword">extends</span> <span class="title class_">LinkedHashMap</span>&lt;K, V&gt; &#123;</span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="keyword">protected</span> <span class="type">boolean</span> <span class="title function_">removeEldestEntry</span><span class="params">(Map.Entry&lt;K, V&gt; eldest)</span> &#123;</span><br><span class="line">            <span class="keyword">if</span> (size() &gt; capacity) &#123;</span><br><span class="line">                <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line">            &#125; <span class="keyword">else</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">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">get</span><span class="params">(<span class="type">int</span> key)</span> &#123;</span><br><span class="line">        <span class="type">Integer</span> <span class="variable">value</span> <span class="operator">=</span> linkedHashMap.get(key);</span><br><span class="line">        <span class="keyword">if</span> (value == <span class="literal">null</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">        linkedHashMap.remove(key);</span><br><span class="line">        linkedHashMap.put(key, value);</span><br><span class="line">        <span class="keyword">return</span> value;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">put</span><span class="params">(<span class="type">int</span> key, <span class="type">int</span> value)</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> (linkedHashMap.containsKey(key))&#123;</span><br><span class="line">            linkedHashMap.remove(key);</span><br><span class="line">        &#125;</span><br><span class="line">        linkedHashMap.put(key, value);</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"> * 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.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><h3><span id="152-maximum-product-subarray">152 Maximum Product Subarray</span></h3><h4><span id="题目大意">题目大意</span></h4><p>寻找连续数组乘积的最大值。</p><h4><span id="解题思路">解题思路</span></h4><p>看起来和最大子序列和一致，但是又有不同。因为前面算出的负数一时不是最大值，但很有可能因为遇上一个负数，摇身一变就变成了一个正数。</p><p>因此使用数组记录下最大最小值，用来避免这种情况。这里使用 dp[i][] 来表示 i 位置的最大最小值。根据当前位置的正负来计算数组的最大最小值。当前位置为正数，与前一位的最大最小值的乘积显然还保持了最大最小值的乘积。但是如果当前的数是负数，最大值就变成了最小值。不仅如此，之前位置的最值得正负也有影响，因此需要最值函数获取一下。</p><p>因为数组当中存得是以 index 为结尾的数组最值，因此还需要挨个循环寻找最大值。</p><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">maxProduct</span><span class="params">(<span class="type">int</span>[] nums)</span> &#123;</span><br><span class="line">        <span class="type">int</span>[][] dp = <span class="keyword">new</span> <span class="title class_">int</span>[nums.length + <span class="number">1</span>][<span class="number">2</span>];</span><br><span class="line">        dp[<span class="number">0</span>][<span class="number">0</span>] = nums[<span class="number">0</span>];</span><br><span class="line">        dp[<span class="number">0</span>][<span class="number">1</span>] = nums[<span class="number">0</span>];</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">1</span>; i &lt; nums.length; i++) &#123;</span><br><span class="line">            <span class="type">int</span> <span class="variable">tmp</span> <span class="operator">=</span> nums[i];</span><br><span class="line">            <span class="keyword">if</span> (tmp &gt;= <span class="number">0</span>) &#123;</span><br><span class="line">                dp[i][<span class="number">0</span>] = Math.max(tmp, dp[i - <span class="number">1</span>][<span class="number">0</span>] * tmp);</span><br><span class="line">                dp[i][<span class="number">1</span>] = Math.min(tmp, dp[i - <span class="number">1</span>][<span class="number">1</span>] * tmp);</span><br><span class="line">            &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                dp[i][<span class="number">1</span>] = Math.min(tmp, dp[i - <span class="number">1</span>][<span class="number">0</span>] * tmp);</span><br><span class="line">                dp[i][<span class="number">0</span>] = Math.max(tmp, dp[i - <span class="number">1</span>][<span class="number">1</span>] * tmp);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="type">int</span> <span class="variable">resu</span> <span class="operator">=</span> Integer.MIN_VALUE;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; nums.length; i++) &#123;</span><br><span class="line">            resu = Math.max(resu, dp[i][<span class="number">0</span>]);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> resu;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3><span id="153-find-minimum-in-rotated-sorted-array">153 Find Minimum in Rotated Sorted Array</span></h3><h4><span id="题目大意">题目大意</span></h4><p>找出旋转数组的最小数字。</p><h4><span id="解题思路">解题思路</span></h4><p>二分查找，如果 mid &lt;= right，那一定在中间或者左边，5 6 7 0 1 2 3或者7 0 1 2 3 5 6。</p><p>左边连续的话，一定是在右边了。</p><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><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="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">findMin</span><span class="params">(<span class="type">int</span>[] nums)</span> &#123;</span><br><span class="line">        <span class="type">int</span> <span class="variable">left</span>  <span class="operator">=</span> <span class="number">0</span>, right = nums.length - <span class="number">1</span>;</span><br><span class="line">        <span class="keyword">while</span> (left &lt; right)&#123;</span><br><span class="line">            <span class="type">int</span> <span class="variable">mid</span> <span class="operator">=</span> left + (right - left) / <span class="number">2</span>;</span><br><span class="line">            <span class="keyword">if</span> (nums[mid] &lt;= nums[right])&#123;</span><br><span class="line">                right = mid;</span><br><span class="line">            &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                left = mid + <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[left];</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3><span id="172-factorial-trailing-zeroes">172 Factorial Trailing Zeroes</span></h3><h4><span id="题目大意">题目大意</span></h4><p>数阶乘后的数字末尾有多少个零。如3!=6，0个；5!=120，1个。</p><h4><span id="解题思路">解题思路</span></h4><p>事实上，你在使用暴力破解法的过程中就能发现规律：<strong>这 9 个数字中只有 2（它的倍数） 与 5 （它的倍数）相乘才有 0 出现</strong>。</p><p>所以，现在问题就变成了这个阶乘数中能配 <strong>多少对 2 与 5</strong>。</p><p>举个复杂点的例子：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">10！= 【 2 *（ 2 * 2 ）* 5 *（ 2 * 3 ）*（ 2 * 2 * 2 ）*（ 2 * 5）】</span><br></pre></td></tr></table></figure><p>在 10！这个阶乘数中可以匹配两对 2 * 5 ，所以10！末尾有 2 个 0。</p><p>可以发现，一个数字进行拆分后 2 的个数肯定是大于 5 的个数的，所以能匹配多少对取决于 5 的个数。（好比现在男女比例悬殊，最多能有多少对异性情侣取决于女生的多少）。</p><p>那么问题又变成了 <strong>统计阶乘数里有多少个 5 这个因子</strong>。</p><p>需要注意的是，像 25，125 这样的不只含有一个 5 的数字的情况需要考虑进去。</p><p>比如 <code>n = 15</code>。那么在 <code>15!</code> 中 有 <code>3</code> 个 <code>5</code> (来自其中的<code>5</code>, <code>10</code>, <code>15</code>)， 所以计算 <code>n/5</code> 就可以 。</p><p>但是比如 <code>n=25</code>，依旧计算 <code>n/5</code> ，可以得到 <code>5</code> 个<code>5</code>，分别来自其中的<code>5, 10, 15, 20, 25</code>，但是在 <code>25</code> 中其实是包含 <code>2</code>个 <code>5</code> 的，这一点需要注意。</p><p>所以除了计算 <code>n/5</code> ， 还要计算 <code>n/5/5 , n/5/5/5 , n/5/5/5/5 , ..., n/5/5/5,,,/5</code>直到商为0，然后求和即可。</p><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><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="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">trailingZeroes</span><span class="params">(<span class="type">int</span> n)</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> n == <span class="number">0</span> ? <span class="number">0</span> : n / <span class="number">5</span> + trailingZeroes(n / <span class="number">5</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3><span id="179-largest-number">179 Largest Number</span></h3><h4><span id="题目大意">题目大意</span></h4><p>非负整数全排列组成的数的最大值。</p><figure class="highlight plaintext"><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">Input: [3,30,34,5,9]</span><br><span class="line">Output: &quot;9534330&quot;</span><br></pre></td></tr></table></figure><h4><span id="解题思路">解题思路</span></h4><p>写一个比较器，硬比。</p><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="keyword">import</span> java.util.Arrays;</span><br><span class="line"><span class="keyword">import</span> java.util.Comparator;</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> String <span class="title function_">largestNumber</span><span class="params">(<span class="type">int</span>[] nums)</span> &#123;</span><br><span class="line">        String[] strings = <span class="keyword">new</span> <span class="title class_">String</span>[nums.length];</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; nums.length; i++) &#123;</span><br><span class="line">            strings[i] = String.valueOf(nums[i]);</span><br><span class="line">        &#125;</span><br><span class="line">        Arrays.sort(strings, <span class="keyword">new</span> <span class="title class_">Comparator</span>&lt;String&gt;() &#123;</span><br><span class="line">            <span class="meta">@Override</span></span><br><span class="line">            <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">compare</span><span class="params">(String o1, String o2)</span> &#123;</span><br><span class="line">                <span class="keyword">return</span> (o2 + o1).compareTo(o1 + o2);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;);</span><br><span class="line">        <span class="keyword">if</span> (strings[<span class="number">0</span>].equals(<span class="string">&quot;0&quot;</span>)) <span class="keyword">return</span> <span class="string">&quot;0&quot;</span>;</span><br><span class="line">        <span class="type">StringBuilder</span> <span class="variable">sb</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">StringBuilder</span>();</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; strings.length; i++) &#123;</span><br><span class="line">            sb.append(strings[i]);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> sb.toString();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3><span id="188-best-time-to-buy-and-sell-stock-iv">188 Best Time to Buy and Sell Stock IV</span></h3><h4><span id="题目大意">题目大意</span></h4><p>买卖股票问题，最多 k 笔交易，买之前必须要先卖掉手里股票。</p><h4><span id="解题思路">解题思路</span></h4><p>和123差不多的思路，因为一笔交易要买卖两次，所以当k大到一定程度时候，可以直接采用贪心，因为此时限制的就是天数了。</p><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="keyword">import</span> java.util.Arrays;</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">maxProfit</span><span class="params">(<span class="type">int</span> k, <span class="type">int</span>[] prices)</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> (k &gt;= prices.length / <span class="number">2</span>) &#123;</span><br><span class="line">            <span class="type">int</span> <span class="variable">res</span> <span class="operator">=</span> <span class="number">0</span>;</span><br><span class="line">            <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">1</span>; i &lt; prices.length; i++) &#123;</span><br><span class="line">                <span class="keyword">if</span> (prices[i] &gt; prices[i - <span class="number">1</span>]) &#123;</span><br><span class="line">                    res += prices[i] - prices[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">return</span> res;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="type">int</span>[] buy = <span class="keyword">new</span> <span class="title class_">int</span>[k + <span class="number">1</span>];</span><br><span class="line">        Arrays.fill(buy, -prices[<span class="number">0</span>]);</span><br><span class="line">        <span class="type">int</span>[] sell = <span class="keyword">new</span> <span class="title class_">int</span>[k + <span class="number">1</span>];</span><br><span class="line">        Arrays.fill(sell, <span class="number">0</span>);</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; prices.length; i++) &#123;</span><br><span class="line">            <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">j</span> <span class="operator">=</span> <span class="number">1</span>; j &lt;= k; j++) &#123;</span><br><span class="line">                buy[j] = Math.max(buy[j], sell[j - <span class="number">1</span>] - prices[i]);</span><br><span class="line">                sell[j] = Math.max(sell[j], buy[j] + prices[i]);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        Arrays.sort(sell);</span><br><span class="line">        <span class="keyword">return</span> sell[sell.length - <span class="number">1</span>];</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3><span id="189-旋转数组">189 旋转数组</span></h3><h4><span id="题目大意">题目大意</span></h4><p>给定一个数组，将数组中的元素向右移动 <em>k</em> 个位置，其中 <em>k</em> 是非负数。</p><h4><span id="解题思路">解题思路</span></h4><p>将数组从中间切割，分别转置，然后从头到尾转置。这里要注意当 k 大于数组长度时候的处理。否则会发生数组越界，k 的大小大于数组长度时候，前边的一部分是会移动回原地的，所以进行取模。</p><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">rotate</span><span class="params">(<span class="type">int</span>[] nums, <span class="type">int</span> k)</span> &#123;</span><br><span class="line">        k %= nums.length;</span><br><span class="line">        swap(nums, <span class="number">0</span>, nums.length - k - <span class="number">1</span>);</span><br><span class="line">        swap(nums, nums.length - k, nums.length -<span class="number">1</span>);</span><br><span class="line">        swap(nums, <span class="number">0</span>, nums.length-<span class="number">1</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">swap</span><span class="params">(<span class="type">int</span>[] nums, <span class="type">int</span> left, <span class="type">int</span> right)</span> &#123;</span><br><span class="line">        <span class="keyword">while</span> (left &lt; right) &#123;</span><br><span class="line">            <span class="type">int</span> <span class="variable">tmp</span> <span class="operator">=</span> nums[left];</span><br><span class="line">            nums[left] = nums[right];</span><br><span class="line">            nums[right] = tmp;</span><br><span class="line">            left++;</span><br><span class="line">            right--;</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><h3><span id="190-颠倒二进制位">190 颠倒二进制位</span></h3><h4><span id="题目大意">题目大意</span></h4><p>颠倒给定32位无符号整数的二进制位。</p><h4><span id="解题思路">解题思路</span></h4><p>将 n 视作一个长为32的二进制串，从低位往高位枚举 n 的每一位，倒序添加到翻转结果中。</p><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><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="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">reverseBits</span><span class="params">(<span class="type">int</span> n)</span> &#123;</span><br><span class="line">        <span class="comment">// 储存结果</span></span><br><span class="line">        <span class="type">int</span> <span class="variable">res</span> <span class="operator">=</span> <span class="number">0</span>;</span><br><span class="line">        <span class="comment">// 逐位翻转</span></span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; <span class="number">32</span> &amp;&amp; n != <span class="number">0</span>; i++) &#123;</span><br><span class="line">            <span class="comment">// 取最低位翻转放置</span></span><br><span class="line">            res |= (n &amp; <span class="number">1</span>) &lt;&lt; (<span class="number">31</span> - i);</span><br><span class="line">            <span class="comment">// 往右</span></span><br><span class="line">            n &gt;&gt;&gt;= <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></pre></td></tr></table></figure><h3><span id="204-count-primes">204 Count Primes</span></h3><h4><span id="题目大意">题目大意</span></h4><p>计算小于 n 的素数的个数。</p><h4><span id="解题思路">解题思路</span></h4><p>倍数法标记所有素数打表。</p><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="keyword">import</span> java.util.Arrays;</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="type">int</span> <span class="title function_">countPrimes</span><span class="params">(<span class="type">int</span> n)</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> (n &lt; <span class="number">2</span>) <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">        <span class="type">boolean</span>[] count = <span class="keyword">new</span> <span class="title class_">boolean</span>[n];</span><br><span class="line">        Arrays.fill(count, <span class="literal">true</span>);</span><br><span class="line">        count[<span class="number">0</span>] = <span class="literal">false</span>;</span><br><span class="line">        count[<span class="number">1</span>] = <span class="literal">false</span>;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">2</span>; i &lt; n; i++) &#123;</span><br><span class="line">            <span class="keyword">if</span> (count[i]) &#123;</span><br><span class="line">                <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">j</span> <span class="operator">=</span> i + i; j &lt; n; j += i) &#123;</span><br><span class="line">                    count[j] = <span class="literal">false</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="type">int</span> <span class="variable">result</span> <span class="operator">=</span> <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">2</span>; i &lt; n; i++) &#123;</span><br><span class="line">            <span class="keyword">if</span> (count[i]) &#123;</span><br><span class="line">                result += <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> result;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3><span id="206-reverse-linked-list">206 Reverse Linked List</span></h3><h4><span id="题目大意">题目大意</span></h4><p>反转链表。</p><h4><span id="解题思路">解题思路</span></h4><p>递归，如果链表为空或者单节点不用翻转，直接跳出。</p><p>否则就将当前节点放到翻转后的子链后面。这里主要是各个节点的关系有点乱。如代码中：</p><figure class="highlight plaintext"><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">head.next 是子链表的头节点，它翻转之后应该位于子链表的尾部，也就是head前</span><br><span class="line">所以在处理的时候，应该让这个节点后面接上head，然后head作为尾节点，也就是node定义完后的那几句话</span><br></pre></td></tr></table></figure><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><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">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> ListNode <span class="title function_">reverseList</span><span class="params">(ListNode head)</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> (head == <span class="literal">null</span> || head.next == <span class="literal">null</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="type">ListNode</span> <span class="variable">node</span> <span class="operator">=</span> reverseList(head.next);</span><br><span class="line">        head.next.next = head;</span><br><span class="line">        head.next = <span class="literal">null</span>;</span><br><span class="line">        <span class="keyword">return</span> node;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3><span id="215-kth-largest-element-in-an-array">215 Kth Largest Element in an Array</span></h3><h4><span id="题目大意">题目大意</span></h4><p>找到一个未排序数组中第k大的数。</p><h4><span id="解题思路">解题思路</span></h4><ol><li>最小堆，每当长度大于k了，就把最后一个弹出去。</li><li>使用快排，利用每次标记位归位的机会判断是不是在第k个位置上，注意重复情况的处理。</li></ol><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><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="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">findKthLargest</span><span class="params">(<span class="type">int</span>[] nums, <span class="type">int</span> k)</span> &#123;</span><br><span class="line">        PriorityQueue&lt;Integer&gt; queue = <span class="keyword">new</span> <span class="title class_">PriorityQueue</span>&lt;&gt;();</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> num : nums)&#123;</span><br><span class="line">            queue.add(num);</span><br><span class="line">            <span class="keyword">if</span> (queue.size() &gt; k) queue.poll();</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> queue.peek();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">findKthLargest</span><span class="params">(<span class="type">int</span>[] nums, <span class="type">int</span> k)</span> &#123;</span><br><span class="line">        QuickSort(nums, <span class="number">0</span>, nums.length - <span class="number">1</span>, nums.length - k);</span><br><span class="line">        <span class="keyword">return</span> nums[nums.length - k];</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">QuickSort</span><span class="params">(<span class="type">int</span>[] nums, <span class="type">int</span> start, <span class="type">int</span> end, <span class="type">int</span> k)</span> &#123;</span><br><span class="line">        <span class="type">int</span> <span class="variable">benchmark</span> <span class="operator">=</span> nums[start];</span><br><span class="line">        <span class="type">int</span> <span class="variable">left</span> <span class="operator">=</span> start;</span><br><span class="line">        <span class="type">int</span> <span class="variable">right</span> <span class="operator">=</span> end;</span><br><span class="line">        <span class="keyword">while</span> (left &lt; right) &#123;</span><br><span class="line">            <span class="keyword">while</span> (nums[right] &gt;= benchmark &amp;&amp; left &lt; right) &#123;</span><br><span class="line">                right--;</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">while</span> (nums[left] &lt;= benchmark &amp;&amp; left &lt; right) &#123;</span><br><span class="line">                left++;</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">if</span> (left &lt; right) &#123;</span><br><span class="line">                swap(nums, left, right);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        nums[start] = nums[left];</span><br><span class="line">        nums[left] = benchmark;</span><br><span class="line">        <span class="keyword">if</span> (left == k) &#123;</span><br><span class="line">            <span class="keyword">return</span>;</span><br><span class="line">        &#125; <span class="keyword">else</span> <span class="keyword">if</span> (left &lt; k) &#123;</span><br><span class="line">            QuickSort(nums, left + <span class="number">1</span>, end, k);</span><br><span class="line">        &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">            QuickSort(nums, start, left - <span class="number">1</span>, k);</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">public</span> <span class="keyword">void</span> <span class="title function_">swap</span><span class="params">(<span class="type">int</span>[] nums, <span class="type">int</span> left, <span class="type">int</span> right)</span> &#123;</span><br><span class="line">        <span class="type">int</span> <span class="variable">tmp</span> <span class="operator">=</span> nums[left];</span><br><span class="line">        nums[left] = nums[right];</span><br><span class="line">        nums[right] = tmp;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3><span id="230-kth-smallest-element-in-a-bst">230 Kth Smallest Element in a BST</span></h3><h4><span id="题目大意">题目大意</span></h4><p>二叉搜索树中找第 k 个最小的元素。</p><h4><span id="解题思路">解题思路</span></h4><p>想复杂了，上来就写了个PriorityQueue，中序遍历，加入到数组里，取 k - 1 即可。</p><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><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="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    List&lt;Integer&gt; arrayList = <span class="keyword">new</span> <span class="title class_">ArrayList</span>&lt;&gt;();</span><br><span class="line">    <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">kthSmallest</span><span class="params">(TreeNode root, <span class="type">int</span> k)</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> (root == <span class="literal">null</span> || k &lt;= <span class="number">0</span>) <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">        MidOrder(root);</span><br><span class="line">        <span class="keyword">return</span> arrayList.get(k - <span class="number">1</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">MidOrder</span><span class="params">(TreeNode root)</span>&#123;</span><br><span class="line">        <span class="keyword">if</span> (root == <span class="literal">null</span>) <span class="keyword">return</span>;</span><br><span class="line">        MidOrder(root.left);</span><br><span class="line">        arrayList.add(root.val);</span><br><span class="line">        MidOrder(root.right);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3><span id="231-power-of-two">231 Power of Two</span></h3><h4><span id="题目大意">题目大意</span></h4><p>判断一个数是不是2的幂。</p><h4><span id="解题思路">解题思路</span></h4><p>如果一个数是 2 的次方数的话，那么它的二进数必然是最高位为 1，其它都为 0 ，那么如果此时我们减 1 的话，则最高位会降一位，其余为 0 的位现在都为变为 1，那么我们把两数相与，就会得到 0。</p><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="type">boolean</span> <span class="title function_">isPowerOfTwo</span><span class="params">(<span class="type">int</span> n)</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> n &gt; <span class="number">0</span> &amp;&amp; ((n &amp; (n - <span class="number">1</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="comment">// 方法二</span></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="type">boolean</span> <span class="title function_">isPowerOfTwo</span><span class="params">(<span class="type">int</span> n)</span> &#123;</span><br><span class="line">        <span class="type">int</span> <span class="variable">flag</span> <span class="operator">=</span> <span class="number">0</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">if</span> ((n &amp; <span class="number">1</span>) == <span class="number">1</span>)&#123;</span><br><span class="line">                flag ++;</span><br><span class="line">            &#125;</span><br><span class="line">            n=n &gt;&gt; <span class="number">1</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> flag == <span class="number">1</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3><span id="236-lowest-common-ancestor-of-a-binary-tree">236 Lowest Common Ancestor of a Binary Tree</span></h3><h4><span id="题目大意">题目大意</span></h4><p>寻找两个节点的最近的公共祖先。</p><h4><span id="解题思路">解题思路</span></h4><p>递归查找，如果根节点为空或者是其中一个节点是根节点，那这个根节点就是结果。</p><p>否则的话，左右子树找一下，如果左右子树分别找到了，节点分布两边，说明这个节点就是祖先节点。如果都在一边，那找到的那个节点就是祖先节点了。</p><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><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">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> TreeNode <span class="title function_">lowestCommonAncestor</span><span class="params">(TreeNode root, TreeNode p, TreeNode q)</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> (root == <span class="literal">null</span> || p == root || q == root) <span class="keyword">return</span> root;</span><br><span class="line">        <span class="type">TreeNode</span> <span class="variable">left</span> <span class="operator">=</span> lowestCommonAncestor(root.left, p, q);</span><br><span class="line">        <span class="type">TreeNode</span> <span class="variable">right</span> <span class="operator">=</span> lowestCommonAncestor(root.right, p, q);</span><br><span class="line">        <span class="keyword">if</span> (left != <span class="literal">null</span> &amp;&amp; right != <span class="literal">null</span>) <span class="keyword">return</span> root;</span><br><span class="line">        <span class="keyword">return</span> left != <span class="literal">null</span>? left: right;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3><span id="242-valid-anagram">242 Valid Anagram</span></h3><h4><span id="题目大意">题目大意</span></h4><p>判断一个字符串是不是另一个字符串的全排列的一种，判断两个字符串的组成元素是不是一样的。</p><h4><span id="解题思路">解题思路</span></h4><ol><li>按照字符排序，判断是否相同。</li><li>统计不同元素出现的次数是不是一致。</li></ol><h4><span id="代码">代码</span></h4><h3><span id="268-missing-number">268 Missing Number</span></h3><h4><span id="题目大意">题目大意</span></h4><p>给定一个数组，包含了从0到n的不同数字，其中缺少一位，找到那个缺少的位置。</p><h4><span id="解题思路">解题思路</span></h4><ol><li>因为这道题都是从0开始的，可以直接用一模一样的不缺失的数异或，得到缺失的数。</li><li>一模一样的不缺失的数组求和，减掉原来数组的和。</li></ol><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><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">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">missingNumber</span><span class="params">(<span class="type">int</span>[] nums)</span> &#123;</span><br><span class="line">        <span class="type">int</span> <span class="variable">len</span> <span class="operator">=</span> nums.length;</span><br><span class="line">        <span class="type">int</span> <span class="variable">resu</span> <span class="operator">=</span> <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; len; i++)&#123;</span><br><span class="line">            resu ^= nums[i];</span><br><span class="line">            resu ^= (i+<span class="number">1</span>);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> resu;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><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">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">missingNumber</span><span class="params">(<span class="type">int</span>[] nums)</span> &#123;</span><br><span class="line">        <span class="type">int</span> <span class="variable">len</span> <span class="operator">=</span> nums.length;</span><br><span class="line">        <span class="type">int</span> <span class="variable">sum</span> <span class="operator">=</span> <span class="number">0</span>;</span><br><span class="line">        <span class="type">int</span> <span class="variable">resu</span> <span class="operator">=</span> <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; len; i++)&#123;</span><br><span class="line">            sum += nums[i];</span><br><span class="line">            resu += (i+<span class="number">1</span>);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> resu -sum;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3><span id="278-first-bad-version">278 First Bad Version</span></h3><h4><span id="题目大意">题目大意</span></h4><p>给定一个元素 n 代表有 [1, 2, …, n] 版本，在第 x 位置开始出现错误版本，导致后面的版本都错误。可以调用 isBadVersion(int x) 知道某个版本是否错误，要求找到第一个错误的版本。</p><h4><span id="解题思路">解题思路</span></h4><p>简单难度，主要在题意的理解上，还出现了调用已有函数这一形式。</p><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><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="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Solution</span> <span class="keyword">extends</span> <span class="title class_">VersionControl</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">firstBadVersion</span><span class="params">(<span class="type">int</span> n)</span> &#123;</span><br><span class="line">        <span class="type">int</span> <span class="variable">left</span> <span class="operator">=</span> <span class="number">1</span>, right = n;</span><br><span class="line">        <span class="keyword">while</span> (left &lt;= right)&#123;</span><br><span class="line">            <span class="type">int</span> <span class="variable">mid</span> <span class="operator">=</span> left + (right - left) / <span class="number">2</span>;</span><br><span class="line">            <span class="keyword">if</span> (isBadVersion(mid))&#123;</span><br><span class="line">                right = mid - <span class="number">1</span>;</span><br><span class="line">            &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                left = mid + <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> left;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3><span id="279-perfect-squares">279 Perfect Squares</span></h3><h4><span id="题目大意">题目大意</span></h4><p>给定正整数 n，找到若干个完全平方数（比如 1, 4, 9, 16, …）使得它们的和等于 n。你需要让组成和的完全平方数的个数最少。</p><p>12 = 4 + 4 + 4</p><p>13 = 4 + 9</p><h4><span id="解题思路">解题思路</span></h4><p>使用广度优先搜索方法，将 n 依次减去比 n 小的所有平方数，直至 n = 0 ，此时的层数即为最后的结果。</p><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">numSquares</span><span class="params">(<span class="type">int</span> n)</span> &#123;</span><br><span class="line">        Queue&lt;Integer&gt; queue = <span class="keyword">new</span> <span class="title class_">LinkedList</span>&lt;&gt;();</span><br><span class="line">        ArrayList&lt;Integer&gt; visited = <span class="keyword">new</span> <span class="title class_">ArrayList</span>&lt;&gt;();</span><br><span class="line">        <span class="type">int</span> <span class="variable">level</span> <span class="operator">=</span> <span class="number">0</span>;</span><br><span class="line">        queue.offer(n);</span><br><span class="line">        <span class="keyword">while</span> (!queue.isEmpty()) &#123;</span><br><span class="line">            <span class="type">int</span> <span class="variable">len</span> <span class="operator">=</span> queue.size();</span><br><span class="line">            <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; len; i++) &#123;</span><br><span class="line">                n = queue.poll();</span><br><span class="line">                <span class="keyword">if</span> (n == <span class="number">0</span>)</span><br><span class="line">                    <span class="keyword">return</span> level;</span><br><span class="line">                <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">j</span> <span class="operator">=</span> <span class="number">1</span>; j &lt; Math.sqrt(n) + <span class="number">1</span>; j++) &#123;</span><br><span class="line">                    <span class="type">int</span> <span class="variable">val</span> <span class="operator">=</span> n - j * j;</span><br><span class="line">                    <span class="keyword">if</span> (visited.contains(val))</span><br><span class="line">                        <span class="keyword">continue</span>;</span><br><span class="line">                    queue.offer(val);</span><br><span class="line">                    visited.add(val);</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">            level += <span class="number">1</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> level;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3><span id="292-nim-game">292 Nim Game</span></h3><h4><span id="题目大意">题目大意</span></h4><p>你和你的朋友在玩下面的Nim游戏:桌子上有一堆石头，每次你们中的一个人轮流移走1到3块石头。谁把最后一块石头移走，谁就赢。你将在第一个拐弯处移走石头。</p><p>你们俩都很聪明，在游戏中都有最佳的策略。写一个函数来确定你是否可以赢得游戏给定的石头堆的数量。</p><p>例如，4，无论如何你都会输掉，因为最后一块石头都会被朋友拿走。</p><h4><span id="解题思路">解题思路</span></h4><p>如果我能赢，那么最后轮到我取石子的时候必须要剩下 1~3 颗石子，这样我才能一把拿完。</p><p>如何营造这样的一个局面呢？显然，如果对手拿的时候只剩 4 颗石子，那么无论他怎么拿，总会剩下 1~3 颗石子，我就能赢。</p><p>如何逼迫对手面对 4 颗石子呢？要想办法，让我选择的时候还有 5~7 颗石子，这样的话我就有把握让对方不得不面对 4 颗石子。</p><p>如何营造 5~7 颗石子的局面呢？让对手面对 8 颗石子，无论他怎么拿，都会给我剩下 5~7 颗，我就能赢。</p><p>这样一直循环下去，我们发现只要踩到 4 的倍数，就落入了圈套，永远逃不出 4 的倍数，而且一定会输。</p><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><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="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">   bool <span class="title function_">canWinNim</span><span class="params">(<span class="type">int</span> n)</span> &#123;</span><br><span class="line">    <span class="comment">// 如果上来就踩到 4 的倍数，那就认输吧</span></span><br><span class="line">    <span class="comment">// 否则，可以把对方控制在 4 的倍数，必胜</span></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><h3><span id="300-最长递增子序列">300 最长递增子序列</span></h3><h4><span id="题目大意">题目大意</span></h4><p>给你一个整数数组 <code>nums</code> ，找到其中最长严格递增子序列的长度。</p><h4><span id="解题思路">解题思路</span></h4><p>注意这里数组可能不连续。</p><p>动态规划，以当前元素为结尾的数组长度等于前面最长的长度+1，或者当前元素不取，具体看代码内注释。</p><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">lengthOfLIS</span><span class="params">(<span class="type">int</span>[] nums)</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> (nums.length &lt;= <span class="number">1</span>) &#123;</span><br><span class="line">            <span class="keyword">return</span> nums.length;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="type">int</span> <span class="variable">result</span> <span class="operator">=</span> <span class="number">1</span>;</span><br><span class="line">        <span class="comment">// dpi表示以i为结尾的最长长度</span></span><br><span class="line">        <span class="type">int</span>[] dp = <span class="keyword">new</span> <span class="title class_">int</span>[nums.length];</span><br><span class="line">        dp[<span class="number">0</span>] = <span class="number">1</span>;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">1</span>; i &lt; nums.length; i++) &#123;</span><br><span class="line">            <span class="comment">// 当前位置初始化</span></span><br><span class="line">            dp[i] = <span class="number">1</span>;</span><br><span class="line">            <span class="comment">// 过往长度 + 1，从低往高算</span></span><br><span class="line">            <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">j</span> <span class="operator">=</span> <span class="number">0</span>; j &lt; i; j++) &#123;</span><br><span class="line">                <span class="keyword">if</span> (nums[i] &gt; nums[j]) &#123;</span><br><span class="line">                    dp[i] = Math.max(dp[i], dp[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="comment">// 更新每一位结果</span></span><br><span class="line">            result = Math.max(result, dp[i]);</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><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3><span id="319-bulb-switcher">319 Bulb Switcher</span></h3><h4><span id="题目大意">题目大意</span></h4><p>一开始有n个灯泡是关着的。首先打开所有的灯泡。第二轮，每隔一秒就关掉一个灯泡。在第三轮游戏中，每隔3个灯泡就切换一次(如果灯泡是关的，就打开;如果灯泡是开的，就关闭)。第i轮，你按下了所有的i灯泡。对于第n轮，您只切换最后一个灯泡。找出n轮后有多少灯泡是亮着的。</p><h4><span id="解题思路">解题思路</span></h4><p>首先，因为电灯一开始都是关闭的，所以某一盏灯最后如果是点亮的，必然要被按奇数次开关。</p><p>我们假设只有 6 盏灯，而且我们只看第 6 盏灯。需要进行 6 轮操作对吧，请问对于第 6 盏灯，会被按下几次开关呢？这不难得出，第 1 轮会被按，第 2 轮，第 3 轮，第 6 轮都会被按。</p><p>为什么第 1、2、3、6 轮会被按呢？因为 6 = 1×6 = 2×3。一般情况下，因子都是成对出现的，也就是说开关被按的次数一般是偶数次。但是有特殊情况，比如说总共有 16 盏灯，那么第 16 盏灯会被按几次?</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">16 = 1 × 16 = 2 × 8 = 4 × 4 </span><br></pre></td></tr></table></figure><p>其中因子 4 重复出现，所以第 16 盏灯会被按 5 次，奇数次。现在你应该理解这个问题为什么和平方根有关了吧？</p><p>不过，我们不是要算最后有几盏灯亮着吗，这样直接平方根一下是啥意思呢？稍微思考一下就能理解了。</p><p>就假设现在总共有 16 盏灯，我们求 16 的平方根，等于 4，这就说明最后会有 4 盏灯亮着，它们分别是第 1 × 1 = 1 盏、第 2 × 2=4 盏、第 3 × 3 = 9 盏和第 4 × 4 = 16盏。</p><p>我们不是想求有多少个可开方的数吗，4 是最大的平方根，那么小于 4 的正整数的平方都是在 1~16 内的，是会被按奇数次开关，最终亮着的灯。</p><p>就算有的 n 平方根结果是小数，强转成 int 型，也相当于一个最大整数上界，比这个上界小的所有整数，平方后的索引都是最后亮着的灯的索引。所以说我们直接把平方根转成整数，就是这个问题的答案。</p><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><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="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">bulbSwitch</span><span class="params">(<span class="type">int</span> n)</span> &#123;</span><br><span class="line">         <span class="keyword">return</span> (<span class="type">int</span>)Math.sqrt(n);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3><span id="322-coinchange">322 CoinChange</span></h3><h4><span id="题目大意">题目大意</span></h4><p>给定不同面额的硬币 <code>coins</code> 和金额 <code>amount</code>，计算凑成总金额所需的<strong>最少的硬币个数</strong>。如果没有任何一种方案能组成该金额，返回 -1。每种硬币的数量是无限的。</p><h4><span id="解题思路">解题思路</span></h4><p>将子问题定义为dp[k]即凑出k的最少的硬币数。显然dp[0]=0。对于k，我们可以尝试所有面额的硬币，例如，如果尝试了面额c的硬币，问题就变成了凑出金额k-c的问题。因此可以写出关系式：<br>$$<br>dp[k] = min_{c \in C}{1+dp(k-c)}<br>$$<br>可以看到，每一个数的结果都是由左边的问题计算出来的。</p><p>下面处理DP中的无效数组，例如，当我们只有2、5元硬币的时候，是凑不出3来的，所以这时候dp[3]为无效元素。因为要求最小值，我们可以将无效值设置为正无穷方便参与计算。在编程时候我们发现，k最多也就是由面额最小的全部兑换，例如k个1元，所以只需要大于k就可以看作无效因素。这里取k+1。</p><p><a href="https://mp.weixin.qq.com/s/pTMsIg9I0z102DQ4HMrYCA">参考文章</a></p><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><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="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">coinChange</span><span class="params">(<span class="type">int</span>[] coins, <span class="type">int</span> amount)</span> &#123;</span><br><span class="line">        <span class="type">int</span> dp[] = <span class="keyword">new</span> <span class="title class_">int</span>[amount+<span class="number">1</span>];</span><br><span class="line">        Arrays.fill(dp, amount+<span class="number">1</span>);</span><br><span class="line">        dp[<span class="number">0</span>] = <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">1</span>; i &lt;= amount; i++)&#123;</span><br><span class="line">            <span class="keyword">for</span> (<span class="type">int</span> coin : coins)&#123;</span><br><span class="line">                <span class="keyword">if</span> (i &gt;= coin)&#123;</span><br><span class="line">                    dp[i] =Math.min(dp[i], dp[i - coin] + <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[amount] &gt; amount ? -<span class="number">1</span> : dp[amount];</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3><span id="326-power-of-three">326 Power of Three</span></h3><h4><span id="题目大意">题目大意</span></h4><p>给一个整数，在不使用递归或者循环，判断是不是3的幂。</p><h4><span id="解题思路">解题思路</span></h4><p>正常的思路是不停地去除以 3，看最后的迭代商是否为 1。这种思路的代码使用到了循环，逼格不够高。</p><p>这里取巧的方法 <strong>用到了数论的知识：3 的幂次的质因子只有 3</strong>。</p><p>题目要求输入的是 int 类型，正数范围是 0 - 231，在此范围中允许的最大的 3 的次方数为 319 = 1162261467 ，那么只要看这个数能否被 n 整除即可。</p><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><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="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="type">boolean</span> <span class="title function_">isPowerOfThree</span><span class="params">(<span class="type">int</span> n)</span> &#123;</span><br><span class="line">         <span class="keyword">return</span> n &gt; <span class="number">0</span> &amp;&amp; <span class="number">1162261467</span> % n == <span class="number">0</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3><span id="329-longest-increasing-path-in-a-matrix">329 Longest Increasing Path in a Matrix</span></h3><h4><span id="题目大意">题目大意</span></h4><p>寻找矩阵中最长的递增序列。</p><h4><span id="解题思路">解题思路</span></h4><p>设置标志位，深度搜索并更新最大值。</p><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="type">int</span>[][] state = &#123;&#123;<span class="number">0</span>, <span class="number">1</span>&#125;, &#123;<span class="number">1</span>, <span class="number">0</span>&#125;, &#123;<span class="number">0</span>, -<span class="number">1</span>&#125;, &#123;-<span class="number">1</span>, <span class="number">0</span>&#125;&#125;;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">longestIncreasingPath</span><span class="params">(<span class="type">int</span>[][] matrix)</span> &#123;</span><br><span class="line">        <span class="type">int</span> <span class="variable">r</span> <span class="operator">=</span> matrix.length;</span><br><span class="line">        <span class="keyword">if</span> (r == <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="type">int</span> <span class="variable">c</span> <span class="operator">=</span> matrix[<span class="number">0</span>].length;</span><br><span class="line">        <span class="type">int</span>[][] dp = <span class="keyword">new</span> <span class="title class_">int</span>[r][c];</span><br><span class="line">        <span class="type">int</span> <span class="variable">max</span> <span class="operator">=</span> <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; r; i++) &#123;</span><br><span class="line">            <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">j</span> <span class="operator">=</span> <span class="number">0</span>; j &lt; c; j++) &#123;</span><br><span class="line">                <span class="comment">// 从i j出发</span></span><br><span class="line">                max = Math.max(max, dfs(dp, matrix, i, j));</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"></span><br><span class="line">    <span class="keyword">private</span> <span class="type">int</span> <span class="title function_">dfs</span><span class="params">(<span class="type">int</span>[][] dp, <span class="type">int</span>[][] matrix, <span class="type">int</span> i, <span class="type">int</span> j)</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> (dp[i][j] != <span class="number">0</span>) &#123;</span><br><span class="line">            <span class="keyword">return</span> dp[i][j];</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="comment">// 该位置访问，至少长度为1了</span></span><br><span class="line">        dp[i][j] = <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="type">int</span>[] s : state) &#123;</span><br><span class="line">            <span class="comment">// 新坐标</span></span><br><span class="line">            <span class="type">int</span> <span class="variable">x</span> <span class="operator">=</span> i + s[<span class="number">0</span>];</span><br><span class="line">            <span class="type">int</span> <span class="variable">y</span> <span class="operator">=</span> j + s[<span class="number">1</span>];</span><br><span class="line">            <span class="comment">// 坐标符合要求</span></span><br><span class="line">            <span class="keyword">if</span> (x &gt;= <span class="number">0</span> &amp;&amp; x &lt; matrix.length &amp;&amp; y &gt;= <span class="number">0</span> &amp;&amp; y &lt; matrix[x].length &amp;&amp; matrix[i][j] &lt; matrix[x][y]) &#123;</span><br><span class="line">                <span class="comment">// 要么当前值，要么就是往下走，长度需要加1</span></span><br><span class="line">                dp[i][j] = Math.max(dp[i][j], dfs(dp, matrix, x, y) + <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[i][j];</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3><span id="330-patching-array">330 Patching Array</span></h3><h4><span id="题目大意">题目大意</span></h4><p>给定一个已排序的正整数数组nums和一个整数n，在数组中添加补丁元素，使数组中某些元素的和可以构成包含在[1,n]范围内的任意数。返回所需的最小补丁数。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><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">Input: nums = [1,3], n = 6</span><br><span class="line">Output: 1, 补2</span><br><span class="line">Input: nums = [1,5,10], n = 20</span><br><span class="line">Output: 2</span><br><span class="line">Explanation: The two patches can be [2, 4].补24</span><br></pre></td></tr></table></figure><h4><span id="解题思路">解题思路</span></h4><p>这是贪心算法的一个应用。举个例子，对于数组 [1, 2, 3, 8] ：</p><ol><li><p>用一个miss来表示当前缺失的数，初始时为1，num[0] = 1，它的覆盖范围为 [1, 1] ，可以补足miss = 1</p></li><li><p>那么哪个数是num[0]达不到的呢？答案是：miss + nums[0] = 2。那么向数组申请一个新的数nums[1]，它们的覆盖范围为 [1, 3] 发现可以补足miss = 2。</p></li><li><p>那么哪个数是它们两达不到的呢？答案是：miss + nums[1] = 4。那么向数组申请一个新的数nums[2]，它们的覆盖范围为 [1, 6] 发现3可以补足miss = 4</p></li><li><p>那么哪个数是它们三达不到的呢？答案是：miss + nums[2] = 7。那么向数组申请一个新的数nums[3]，发现由于8大于7，因此miss要自己申请一个7，此时由于7的加入，覆盖范围变为了 [1, 13]</p></li><li><p>那么下一个 [1, 2, 3, 7]达不到的呢？答案是：miss + miss(补丁7) = 14。由于8 &lt; 14因此可以覆盖到14，且它们的覆盖范围变为[1, 21]</p></li></ol><p>概括来说，就是从1开始按照248的顺序开始追加，这是由数字的二进制规律得出的。如果遇到了数组有的数比当前要补充的小，那就先把这个数补充上。</p><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">minPatches</span><span class="params">(<span class="type">int</span>[] nums, <span class="type">int</span> n)</span> &#123;</span><br><span class="line">        <span class="type">int</span> <span class="variable">count</span> <span class="operator">=</span> <span class="number">0</span>;</span><br><span class="line">        <span class="type">long</span> <span class="variable">miss</span> <span class="operator">=</span> <span class="number">1</span>;</span><br><span class="line">        <span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">while</span> (miss &lt;= n)&#123;</span><br><span class="line">            <span class="keyword">if</span> (i &lt; nums.length &amp;&amp; nums[i] &lt;= miss)&#123;</span><br><span class="line">                miss += nums[i++];</span><br><span class="line">            &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                miss += miss;</span><br><span class="line">                count++;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> count;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3><span id="347-top-k-frequent-elements">347 Top K Frequent Elements</span></h3><h4><span id="题目大意">题目大意</span></h4><p>出现频率最高的 k 个元素</p><h4><span id="题解思路">题解思路</span></h4><p>设置若干个桶，每个桶存储出现频率相同的数。桶的下标表示数出现的频率，即第 i 个桶中存储的数出现的频率为 i。</p><p>把数都放到桶之后，从后向前遍历桶，最先得到的 k 个数就是出现频率最多的的 k 个数。</p><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="type">int</span>[] topKFrequent(<span class="type">int</span>[] nums, <span class="type">int</span> k) &#123;</span><br><span class="line">        Map&lt;Integer, Integer&gt; map = <span class="keyword">new</span> <span class="title class_">HashMap</span>&lt;&gt;();</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> num : nums)&#123;</span><br><span class="line">            map.put(num, map.getOrDefault(num, <span class="number">0</span>) + <span class="number">1</span>);</span><br><span class="line">        &#125;</span><br><span class="line">        List&lt;Integer&gt;[] bukets = <span class="keyword">new</span> <span class="title class_">ArrayList</span>[nums.length + <span class="number">1</span>];</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> key : map.keySet())&#123;</span><br><span class="line">            <span class="type">int</span> <span class="variable">fre</span>  <span class="operator">=</span> map.get(key);</span><br><span class="line">            <span class="keyword">if</span> (bukets[fre] == <span class="literal">null</span>)&#123;</span><br><span class="line">                bukets[fre] = <span class="keyword">new</span> <span class="title class_">ArrayList</span>&lt;&gt;();</span><br><span class="line">            &#125;</span><br><span class="line">            bukets[fre].add(key);</span><br><span class="line">        &#125;</span><br><span class="line">        List&lt;Integer&gt; result = <span class="keyword">new</span> <span class="title class_">ArrayList</span>&lt;&gt;();</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> bukets.length - <span class="number">1</span>; i &gt;= <span class="number">0</span> &amp;&amp; result.size() &lt; k; i--)&#123;</span><br><span class="line">            <span class="keyword">if</span> (bukets[i] == <span class="literal">null</span>) <span class="keyword">continue</span>;</span><br><span class="line">            <span class="keyword">if</span> (bukets[i].size() &lt;= k - result.size())&#123;</span><br><span class="line">                result.addAll(bukets[i]);</span><br><span class="line">            &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                result.addAll(bukets[i].subList(<span class="number">0</span>, k - result.size()));</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="type">int</span>[] r = <span class="keyword">new</span> <span class="title class_">int</span>[result.size()];</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; result.size(); i++)&#123;</span><br><span class="line">            r[i] = result.get(i);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> r;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3><span id="377-combination-sum-iv">377 Combination Sum IV</span></h3><h4><span id="题目大意">题目大意</span></h4><p>给定一个由正整数组成且不存在重复数字的数组 <code>nums</code>，找出和为给定目标正整数 <code>target</code> 的组合的个数。<strong>顺序不同的序列视作不同的组合</strong>。</p><h4><span id="解题思路">解题思路</span></h4><p>这题和322题硬币类似，只不过这题是求方案了。以凑硬币为例来看，对于f(k)是凑出金额k的方案数，考虑第一个硬币选哪个，如果硬币有1、3、5，那么放每个都是不同的方案。如果第一个硬币放的1，剩下k-1方案就是f(k-1)。可以得出递推关系式：<br>$$<br>f(k) = \sum_{c \in C}{f(k-c)}<br>$$<br>问题的base case：f(0) = 1。这个数组不存在什么无效元素，因此凑不出的金额直接0就可以了。</p><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><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="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">combinationSum4</span><span class="params">(<span class="type">int</span>[] nums, <span class="type">int</span> target)</span> &#123;</span><br><span class="line">        <span class="type">int</span> res[] = <span class="keyword">new</span> <span class="title class_">int</span>[target + <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">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">1</span>; i &lt;= target; i++)&#123;</span><br><span class="line">            <span class="keyword">for</span> (<span class="type">int</span> k : nums)&#123;</span><br><span class="line">                <span class="keyword">if</span> (i &gt;= k)&#123;</span><br><span class="line">                    res[i] += res[i - k];</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[target];</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3><span id="387-字符串中的第一个唯一字符">387 字符串中的第一个唯一字符</span></h3><h4><span id="题目大意">题目大意</span></h4><p>给定一个都是小写字母的字符串，找到它的第一个不重复的字符，并返回它的索引。如果不存在，则返回 -1。</p><p><strong>示例：</strong></p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><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">s = &quot;leetcode&quot;</span><br><span class="line">返回 0</span><br><span class="line"></span><br><span class="line">s = &quot;loveleetcode&quot;</span><br><span class="line">返回 2</span><br></pre></td></tr></table></figure><h4><span id="解题思路">解题思路</span></h4><p>采用哈希记录方法，记录每个字母出现的次数，然后遍历整个字符串找到第一次出现的次数为1的字母。</p><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><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="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">firstUniqChar</span><span class="params">(String s)</span> &#123;</span><br><span class="line">        <span class="type">int</span>[] map = <span class="keyword">new</span> <span class="title class_">int</span>[<span class="number">26</span>];</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; s.length(); i++) &#123;</span><br><span class="line">            map[s.charAt(i) - <span class="string">&#x27;a&#x27;</span>]++;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; s.length(); i++) &#123;</span><br><span class="line">            <span class="keyword">if</span> (map[s.charAt(i) - <span class="string">&#x27;a&#x27;</span>] == <span class="number">1</span>) &#123;</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><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><h3><span id="394-decode-string">394 Decode String</span></h3><h4><span id="题目大意">题目大意</span></h4><p>给定一个经过编码的字符串，返回它解码后的字符串。</p><p>编码规则为: <code>k[encoded_string]</code>，表示其中方括号内部的 <em>encoded_string</em> 正好重复 <em>k</em>次。注意 <em>k</em> 保证为正整数。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><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">Input: s = &quot;3[a]2[bc]&quot;</span><br><span class="line">Output: &quot;aaabcbc&quot;</span><br><span class="line">Input: s = &quot;3[a2[c]]&quot; // 注意这种嵌套的写法</span><br><span class="line">Output: &quot;accaccacc&quot;</span><br></pre></td></tr></table></figure><h4><span id="解题思路">解题思路</span></h4><p>分情况讨论，放了两个栈，一个存储数字，一个存储字符串。这里要注意，数字可能不止一位数。</p><p>当数字的时候，追加到前面的数字上。</p><p>遇到了左括号说明数字结束了，放到数字栈中，顺便归位，字符串也要归位准备放新串。</p><p>遇到了右括号说明当前字符串结束了，取出当前括号前的数字开始追加指定次数，然后放到保存字符串str中待保存。</p><p>注意嵌套行为，使用栈每次存放最里面括号得内容。</p><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="keyword">import</span> java.util.Stack;</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> String <span class="title function_">decodeString</span><span class="params">(String s)</span> &#123;</span><br><span class="line">        Stack&lt;Integer&gt; nums = <span class="keyword">new</span> <span class="title class_">Stack</span>&lt;&gt;();</span><br><span class="line">        Stack&lt;String&gt; strs = <span class="keyword">new</span> <span class="title class_">Stack</span>&lt;&gt;();</span><br><span class="line">        <span class="comment">// 当前数字</span></span><br><span class="line">        <span class="type">int</span> <span class="variable">num</span> <span class="operator">=</span> <span class="number">0</span>;</span><br><span class="line">        <span class="comment">// 当前字符串</span></span><br><span class="line">        <span class="type">String</span> <span class="variable">str</span> <span class="operator">=</span> <span class="string">&quot;&quot;</span>;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; s.length(); i++) &#123;</span><br><span class="line">            <span class="comment">// 如果是数字，计算，很有可能是n位数连续</span></span><br><span class="line">            <span class="keyword">if</span> (s.charAt(i) &lt;= <span class="string">&#x27;9&#x27;</span> &amp;&amp; s.charAt(i) &gt;= <span class="string">&#x27;0&#x27;</span>) &#123;</span><br><span class="line">                num = num * <span class="number">10</span> + (s.charAt(i) - <span class="string">&#x27;0&#x27;</span>);</span><br><span class="line">            &#125; <span class="keyword">else</span> <span class="keyword">if</span> (s.charAt(i) == <span class="string">&#x27;[&#x27;</span>) &#123;</span><br><span class="line">                <span class="comment">// 遇到左括号把当前算得数字和上一轮得字符串加进去，然后归位</span></span><br><span class="line">                nums.push(num);</span><br><span class="line">                strs.push(str);</span><br><span class="line">                num = <span class="number">0</span>;</span><br><span class="line">                str = <span class="string">&quot;&quot;</span>;</span><br><span class="line">            &#125; <span class="keyword">else</span> <span class="keyword">if</span> (s.charAt(i) == <span class="string">&#x27;]&#x27;</span>) &#123;</span><br><span class="line">                <span class="comment">// 遇到右括号说明当前字符串准备完了，把数字取出来，追加n遍保存到str</span></span><br><span class="line">                <span class="type">int</span> <span class="variable">n</span> <span class="operator">=</span> nums.pop();</span><br><span class="line">                <span class="type">String</span> <span class="variable">tmp</span> <span class="operator">=</span> strs.pop();</span><br><span class="line">                <span class="keyword">while</span> (n-- &gt; <span class="number">0</span>) &#123;</span><br><span class="line">                    tmp += str;</span><br><span class="line">                &#125;</span><br><span class="line">                str = tmp;</span><br><span class="line">            &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                <span class="comment">// 准备字符串</span></span><br><span class="line">                str += s.charAt(i);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> str;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3><span id="406-queue-reconstruction-by-height">406 Queue Reconstruction by Height</span></h3><h4><span id="题目大意">题目大意</span></h4><p>一个学生用两个分量 (h, k) 描述，h 表示身高，k 表示排在前面的有 k 个学生的身高比他高或者和他一样高。重建这个数组。</p><h4><span id="解题思路">解题思路</span></h4><p>为了使插入操作不影响后续的操作，身高较高的学生应该先做插入操作，否则身高较小的学生原先正确插入的第 k 个位置可能会变成第 k+1 个位置。</p><p>身高 h 降序、个数 k 值升序，然后将某个学生插入队列的第 k 个位置中。</p><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="type">int</span>[][] reconstructQueue(<span class="type">int</span>[][] people) &#123;</span><br><span class="line">        <span class="keyword">if</span> (people == <span class="literal">null</span> || people.length == <span class="number">0</span> || people[<span class="number">0</span>].length == <span class="number">0</span>)&#123;</span><br><span class="line">            <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">int</span>[<span class="number">0</span>][<span class="number">0</span>];</span><br><span class="line">        &#125;</span><br><span class="line">        Arrays.sort(people, <span class="keyword">new</span> <span class="title class_">Comparator</span>&lt;<span class="type">int</span>[]&gt;()&#123;</span><br><span class="line">            <span class="meta">@Override</span></span><br><span class="line">            <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">compare</span><span class="params">(<span class="type">int</span>[] o1, <span class="type">int</span>[] o2)</span>&#123;</span><br><span class="line">                <span class="keyword">if</span> (o1[<span class="number">0</span>] == o2[<span class="number">0</span>])</span><br><span class="line">                    <span class="keyword">return</span> o1[<span class="number">1</span>] - o2[<span class="number">1</span>];</span><br><span class="line">                <span class="keyword">return</span> o2[<span class="number">0</span>] - o1[<span class="number">0</span>];</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;);</span><br><span class="line">        List&lt;<span class="type">int</span>[]&gt; queue = <span class="keyword">new</span> <span class="title class_">ArrayList</span>&lt;&gt;();</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span>[] p : people) &#123;</span><br><span class="line">            queue.add(p[<span class="number">1</span>], p);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> queue.toArray(<span class="keyword">new</span> <span class="title class_">int</span>[queue.size()][]);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3><span id="435-non-overlapping-intervals">435 Non-overlapping Intervals</span></h3><h4><span id="题目大意">题目大意</span></h4><p>计算让一组区间不重叠所需要移除的区间个数。</p><h4><span id="解题思路">解题思路</span></h4><p>先计算最多能组成的不重叠区间个数，然后用区间总个数减去不重叠区间的个数。</p><p>在每次选择中，区间的结尾最为重要，选择的区间结尾越小，留给后面的区间的空间越大，那么后面能够选择的区间个数也就越大。</p><p>按区间的结尾进行排序，每次选择结尾最小，并且和前一个区间不重叠的区间。</p><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">eraseOverlapIntervals</span><span class="params">(<span class="type">int</span>[][] intervals)</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> (intervals.length == <span class="number">0</span>) <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">        Arrays.sort(intervals, <span class="keyword">new</span> <span class="title class_">Comparator</span>&lt;<span class="type">int</span>[]&gt;()&#123;</span><br><span class="line">            <span class="meta">@Override</span></span><br><span class="line">            <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">compare</span><span class="params">(<span class="type">int</span>[] o1, <span class="type">int</span>[] o2)</span>&#123;</span><br><span class="line">                <span class="keyword">return</span> o1[<span class="number">1</span>] - o2[<span class="number">1</span>];</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;);</span><br><span class="line">        <span class="type">int</span> <span class="variable">count</span> <span class="operator">=</span> <span class="number">1</span>;</span><br><span class="line">        <span class="type">int</span> <span class="variable">end</span> <span class="operator">=</span> intervals[<span class="number">0</span>][<span class="number">1</span>];</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; intervals.length; i++)&#123;</span><br><span class="line">            <span class="keyword">if</span> (intervals[i][<span class="number">0</span>] &gt;= end)&#123;</span><br><span class="line">                end = intervals[i][<span class="number">1</span>];</span><br><span class="line">                count ++;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> intervals.length - count;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3><span id="438-find-all-anagrams-in-a-string">438 Find All Anagrams in a String</span></h3><h4><span id="题目大意">题目大意</span></h4><p>给定一个字符串 s 和一个非空字符串 p，找到 s 中所有是 p 的字母异位词的子串，返回这些子串的起始索引。</p><h4><span id="解题思路">解题思路</span></h4><p>见异位词专题篇。</p><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> List&lt;Integer&gt; <span class="title function_">findAnagrams</span><span class="params">(String s, String p)</span> &#123;</span><br><span class="line">        List&lt;Integer&gt; list = <span class="keyword">new</span> <span class="title class_">ArrayList</span>&lt;&gt;();</span><br><span class="line">        <span class="keyword">if</span> (p.length() &gt; s.length()) <span class="keyword">return</span> list;</span><br><span class="line">        <span class="type">int</span>[] dic = <span class="keyword">new</span> <span class="title class_">int</span>[<span class="number">26</span>];</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">char</span> ch : p.toCharArray()) &#123;</span><br><span class="line">            dic[ch - <span class="string">&#x27;a&#x27;</span>]++;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="comment">// 子串长度</span></span><br><span class="line">        <span class="type">int</span> <span class="variable">len</span> <span class="operator">=</span> p.length();</span><br><span class="line">        <span class="type">int</span>[] cur = <span class="keyword">new</span> <span class="title class_">int</span>[<span class="number">26</span>];</span><br><span class="line">        <span class="comment">// 固定滑动窗口为 len，每次进一个出一个，保证滑动窗口的长度不变</span></span><br><span class="line">        <span class="type">int</span> <span class="variable">index</span> <span class="operator">=</span> <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; len; i++) &#123;</span><br><span class="line">            cur[s.charAt(i) - <span class="string">&#x27;a&#x27;</span>]++;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="comment">// i 表示末尾进来的元素</span></span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> len; i &lt; s.length(); i++) &#123;</span><br><span class="line">            <span class="keyword">if</span> (isSame(dic, cur)) list.add(i - len);</span><br><span class="line">            cur[s.charAt(i - len) - <span class="string">&#x27;a&#x27;</span>]--;</span><br><span class="line">            cur[s.charAt(i) - <span class="string">&#x27;a&#x27;</span>]++;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="comment">// 因为每次处理的都是i前面len个的，所以最后i+1时候才是最后一个，但是上边的循环会越界</span></span><br><span class="line">        <span class="keyword">if</span> (isSame(dic, cur)) list.add(s.length() - len);</span><br><span class="line">        <span class="keyword">return</span> list;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">// 判断拥有的元素数量都一致，就是异位词了</span></span><br><span class="line">    <span class="keyword">public</span> <span class="type">boolean</span> <span class="title function_">isSame</span><span class="params">(<span class="type">int</span>[] a, <span class="type">int</span>[] b)</span> &#123;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; <span class="number">26</span>; i++) &#123;</span><br><span class="line">            <span class="keyword">if</span> (a[i] != b[i]) <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><h3><span id="442-find-all-duplicates-in-an-array">442 Find All Duplicates in an Array</span></h3><h4><span id="题目大意">题目大意</span></h4><p>寻找数组中出现了两次的数。</p><h4><span id="解题思路">解题思路</span></h4><p>排序找，大佬用了标记法，有点像之前一道题，+len 然后膜一下的算法。</p><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> List&lt;Integer&gt; <span class="title function_">findDuplicates</span><span class="params">(<span class="type">int</span>[] nums)</span> &#123;</span><br><span class="line">        Arrays.sort(nums);</span><br><span class="line">        List&lt;Integer&gt; result = <span class="keyword">new</span> <span class="title class_">ArrayList</span>&lt;&gt;();</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">1</span>; i &lt; nums.length; 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">                result.add(nums[i]);</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><span class="line">&#125;</span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> List&lt;Integer&gt; <span class="title function_">findDuplicates</span><span class="params">(<span class="type">int</span>[] nums)</span> &#123;</span><br><span class="line">        List&lt;Integer&gt; resu = <span class="keyword">new</span> <span class="title class_">ArrayList</span>&lt;&gt;();</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; nums.length; i++) &#123;</span><br><span class="line">            <span class="type">int</span> <span class="variable">num</span> <span class="operator">=</span> Math.abs(nums[i]);</span><br><span class="line">            <span class="type">int</span> <span class="variable">num2</span> <span class="operator">=</span> nums[num - <span class="number">1</span>];</span><br><span class="line">            <span class="keyword">if</span> (num2 &lt;= <span class="number">0</span>) &#123;</span><br><span class="line">                resu.add(num);</span><br><span class="line">            &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                nums[num - <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> resu;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3><span id="451-sort-characters-by-frequency">451 Sort Characters By Frequency</span></h3><h4><span id="题目大意">题目大意</span></h4><p>按照字符出现次数从小到大对字符串进行排序。</p><h4><span id="解题思路">解题思路</span></h4><p>按照频率放进桶，从后往前取。</p><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> String <span class="title function_">frequencySort</span><span class="params">(String s)</span> &#123;</span><br><span class="line">        Map&lt;Character, Integer&gt; map = <span class="keyword">new</span> <span class="title class_">HashMap</span>&lt;&gt;();</span><br><span class="line">        <span class="type">char</span>[] a= s.toCharArray();</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">char</span> as : a)&#123;</span><br><span class="line">            map.put(as, map.getOrDefault(as, <span class="number">0</span>) + <span class="number">1</span>);</span><br><span class="line">        &#125;</span><br><span class="line">        List&lt;Character&gt;[] buckets = <span class="keyword">new</span> <span class="title class_">ArrayList</span>[s.length() + <span class="number">1</span>];</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">char</span> key : map.keySet())&#123;</span><br><span class="line">            <span class="type">int</span> <span class="variable">fre</span> <span class="operator">=</span> map.get(key);</span><br><span class="line">            <span class="keyword">if</span> (buckets[fre] == <span class="literal">null</span>)&#123;</span><br><span class="line">                buckets[fre] = <span class="keyword">new</span> <span class="title class_">ArrayList</span>&lt;&gt;();</span><br><span class="line">            &#125;</span><br><span class="line">            buckets[fre].add(key);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="type">StringBuilder</span> <span class="variable">result</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">StringBuilder</span>();</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> buckets.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> (buckets[i] != <span class="literal">null</span>)&#123;</span><br><span class="line">                <span class="keyword">for</span> (<span class="type">char</span> b : buckets[i])&#123;</span><br><span class="line">                    <span class="comment">// 这里要注意，每个位置存储的是出现i次的b要进行次数的还原，如果使用String这里会超内存</span></span><br><span class="line">                    <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">j</span> <span class="operator">=</span> <span class="number">0</span>; j &lt; i; j++)&#123;</span><br><span class="line">                        result.append(b);</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> result.toString();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3><span id="452-minimum-number-of-arrows-to-burst-balloons">452 Minimum Number of Arrows to Burst Balloons</span></h3><h4><span id="题目大意">题目大意</span></h4><p>气球在一个水平数轴上摆放，可以重叠，飞镖垂直投向坐标轴，使得路径上的气球都被刺破。求解最小的投飞镖次数使所有气球都被刺破。</p><h4><span id="解题思路">解题思路</span></h4><p>计算不重叠的区间个数，[1, 2] 和 [2, 3] 在本题中算是重叠区间。</p><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">findMinArrowShots</span><span class="params">(<span class="type">int</span>[][] points)</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> (points == <span class="literal">null</span> || points.length == <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">        Arrays.sort(points, <span class="keyword">new</span> <span class="title class_">Comparator</span>&lt;<span class="type">int</span>[]&gt;()&#123;</span><br><span class="line">            <span class="meta">@Override</span></span><br><span class="line">            <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">compare</span><span class="params">(<span class="type">int</span>[] o1, <span class="type">int</span>[] o2)</span>&#123;</span><br><span class="line">                <span class="keyword">return</span> o1[<span class="number">1</span>] - o2[<span class="number">1</span>];</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;);</span><br><span class="line">        <span class="type">int</span> <span class="variable">count</span> <span class="operator">=</span> <span class="number">1</span>, end = points[<span class="number">0</span>][<span class="number">1</span>];</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; points.length; i++)&#123;</span><br><span class="line">            <span class="keyword">if</span> (points[i][<span class="number">0</span>] &gt; end)&#123;</span><br><span class="line">                end = points[i][<span class="number">1</span>];</span><br><span class="line">                count ++;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> count;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3><span id="454-4-sum-ii">454 4 Sum Ⅱ</span></h3><h4><span id="题目大意">题目大意</span></h4><p>给定四个数组，包含很多元组，计算每个数组挑一个数后和为 0 的个数。</p><h4><span id="解题思路">解题思路</span></h4><p>把前两个算出来之后，放到map里然后，计算后两个的和寻找前面相反数的出现次数。</p><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="keyword">import</span> java.util.HashMap;</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">fourSumCount</span><span class="params">(<span class="type">int</span>[] A, <span class="type">int</span>[] B, <span class="type">int</span>[] C, <span class="type">int</span>[] D)</span> &#123;</span><br><span class="line">        HashMap&lt;Integer, Integer&gt; map = <span class="keyword">new</span> <span class="title class_">HashMap</span>&lt;Integer, Integer&gt;();</span><br><span class="line">        <span class="type">int</span> <span class="variable">result</span> <span class="operator">=</span> <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; A.length; i++) &#123;</span><br><span class="line">            <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">j</span> <span class="operator">=</span> <span class="number">0</span>; j &lt; B.length; j++) &#123;</span><br><span class="line">                map.put(A[i] + B[j], map.getOrDefault(A[i] + B[j], <span class="number">0</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">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; C.length; i++) &#123;</span><br><span class="line">            <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">j</span> <span class="operator">=</span> <span class="number">0</span>; j &lt; D.length; j++) &#123;</span><br><span class="line">                result += map.getOrDefault(<span class="number">0</span> - C[i] - D[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> result;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3><span id="455-assign-cookies">455 Assign Cookies</span></h3><h4><span id="题目大意">题目大意</span></h4><p>每个孩子都有一个满足度 grid，每个饼干都有一个大小 size，只有饼干的大小大于等于一个孩子的满足度，该孩子才会获得满足。求解最多可以获得满足的孩子数量。</p><h4><span id="解题思路">解题思路</span></h4><ol><li>给一个孩子的饼干应当尽量小并且又能满足该孩子，这样大饼干才能拿来给满足度比较大的孩子。</li><li>因为满足度最小的孩子最容易得到满足，所以先满足满足度最小的孩子。</li></ol><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><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">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line">        PriorityQueue&lt;Integer&gt; priorityQueue = <span class="keyword">new</span> <span class="title class_">PriorityQueue</span>&lt;&gt;(Collections.reverseOrder());</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; <span class="number">10</span>; i++) &#123;</span><br><span class="line">            priorityQueue.offer(i);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">while</span> (!priorityQueue.isEmpty()) &#123;</span><br><span class="line">            System.out.println(priorityQueue.poll());</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><h3><span id="456-123-模式">456 123 模式</span></h3><h4><span id="题目大意">题目大意</span></h4><p>判断数组中是否存在 1 3 2 这中大小关系的格式。即 nums[i]、nums[j]、nums[k] 中存在 nums[i] &lt; nums[k] &lt; nums[j]。</p><h4><span id="解题思路">解题思路</span></h4><h4><span id="代码">代码</span></h4><h3><span id="494-target-sum">494 Target Sum</span></h3><h4><span id="题目大意">题目大意</span></h4><p>通过 ± 组合数组中的数为目标数，求多少种组法。</p><h4><span id="解题思路">解题思路</span></h4><p>本来想强行排列组合，发现有人证明了一波。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><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">sum(P) 前面符号为+的集合；sum(N) 前面符号为减号的集合</span><br><span class="line"> 所以题目可以转化为</span><br><span class="line"> sum(P) - sum(N) = target </span><br><span class="line"> =&gt; sum(nums) + sum(P) - sum(N) = target + sum(nums)</span><br><span class="line"> =&gt; 2 * sum(P) = target + sum(nums) </span><br><span class="line">=&gt; sum(P) = (target + sum(nums)) / 2</span><br><span class="line">因此题目转化为01背包，也就是能组合成容量为sum(P)的方式有多少种</span><br></pre></td></tr></table></figure><p>给定集合nums={1,2,3,4,5}, 求解子集，使子集中元素之和等于9 = new_target = sum(P) = (target+sum(nums))/2</p><p>定义dp[10]数组, dp[10] = {1,0,0,0,0,0,0,0,0,0}</p><p>dp[i]表示子集合元素之和等于当前目标值的方案个数, 当前目标值等于9减去当前元素值</p><p>当前元素等于1时，dp[9] = dp[9] + dp[9-1]</p><p>dp[8] = dp[8] + dp[8-1]…</p><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">findTargetSumWays</span><span class="params">(<span class="type">int</span>[] nums, <span class="type">int</span> S)</span> &#123;</span><br><span class="line">        <span class="type">int</span> <span class="variable">sum</span> <span class="operator">=</span> <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> num : nums) &#123;</span><br><span class="line">            sum += num;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span> (sum &lt; S || (sum + S) % <span class="number">2</span> == <span class="number">1</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="type">int</span> <span class="variable">w</span> <span class="operator">=</span> (sum + S) / <span class="number">2</span>;</span><br><span class="line">        <span class="type">int</span>[] dp = <span class="keyword">new</span> <span class="title class_">int</span>[w + <span class="number">1</span>];</span><br><span class="line">        dp[<span class="number">0</span>] = <span class="number">1</span>;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> num : nums) &#123;</span><br><span class="line">            <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">j</span> <span class="operator">=</span> w; j &gt;= num; j--) &#123;</span><br><span class="line">                dp[j] += dp[j - num];</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> dp[w];</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><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">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">findTargetSumWays</span><span class="params">(<span class="type">int</span>[] nums, <span class="type">int</span> S)</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> dfs(<span class="number">0</span>, S, nums);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">dfs</span><span class="params">(<span class="type">int</span> index, <span class="type">int</span> target, <span class="type">int</span>[] nums)</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> (index == nums.length) &#123;</span><br><span class="line">            <span class="keyword">return</span> target == <span class="number">0</span> ? <span class="number">1</span> : <span class="number">0</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> dfs(index + <span class="number">1</span>, target - nums[index], nums) + dfs(index + <span class="number">1</span>, target + nums[index], nums);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3><span id="518-coin-change-2">518 Coin Change 2</span></h3><h4><span id="题目大意">题目大意</span></h4><p>依旧是兑换硬币，但是这次需要不重复的方案。</p><h4><span id="解题思路">解题思路</span></h4><p>这里我们考虑有顺序的方案，即从大到小排列，丢弃其他排列。因此为动态规划增加一个维度，用参数i表示可选前i个硬币进行兑换，即f(i, k)表示使用前i中硬币凑出k的方案数。</p><p>那么一开始i=m，可以选全部的硬币，如果当前一步选了面额第二大的硬币$C_m-1$，那么接下来i更新为m-1，限制接下来只能选择比$C_{m-1}$小的硬币。写出递推关系：</p><p>$$<br>f(i, k) = f(i, k - c_i) + f(i-1, k)<br>$$</p><p>这里第一项表示用最大面额凑硬币，因为第一个硬币可以拿多次，所以i不变，金额变小。第二项，不拿面额大的硬币，那后面只能拿倒数前i-1的硬币。</p><p>基础解，当k=0的时候，f(i, 0)  = 1，即凑出金额0的方案数为1。当i=0，f(0, k) = 0，硬币用完之后，凑不出任何金额。</p><p>从左往右从上往下解问题。</p><p><img src="https://pic.tyzhang.top/images/2020/06/25/_2020-06-25_22-32-42.jpg" alt></p><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="keyword">public</span> <span class="type">int</span> <span class="title function_">change</span><span class="params">(<span class="type">int</span> amount, <span class="type">int</span>[] coins)</span> &#123;</span><br><span class="line">    <span class="type">int</span> <span class="variable">m</span> <span class="operator">=</span> coins.length;</span><br><span class="line">    <span class="type">int</span>[][] dp = <span class="keyword">new</span> <span class="title class_">int</span>[m+<span class="number">1</span>][amount+<span class="number">1</span>];</span><br><span class="line"></span><br><span class="line">    <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt;= m; i++) &#123;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">k</span> <span class="operator">=</span> <span class="number">0</span>; k &lt;= amount; k++) &#123;</span><br><span class="line">            <span class="keyword">if</span> (k == <span class="number">0</span>) &#123;</span><br><span class="line">                dp[i][k] = <span class="number">1</span>; <span class="comment">// base case, 这里可以写在一起</span></span><br><span class="line">            &#125; <span class="keyword">else</span> <span class="keyword">if</span> (i == <span class="number">0</span>) &#123;</span><br><span class="line">                dp[i][k] = <span class="number">0</span>; <span class="comment">// base case</span></span><br><span class="line">            &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                dp[i][k] = dp[i-<span class="number">1</span>][k];</span><br><span class="line">                <span class="keyword">if</span> (k &gt;= coins[i-<span class="number">1</span>]) &#123;</span><br><span class="line">                    dp[i][k] += dp[i][k-coins[i-<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">    &#125;</span><br><span class="line">    <span class="keyword">return</span> dp[m][amount];</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">// 一维计算方法，要注意循环的先后顺序，比如121和112，两种回重复计算</span></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">change</span><span class="params">(<span class="type">int</span> amount, <span class="type">int</span>[] coins)</span> &#123;</span><br><span class="line">        <span class="type">int</span> [] dp = <span class="keyword">new</span> <span class="title class_">int</span>[amount + <span class="number">1</span>];</span><br><span class="line">        dp[<span class="number">0</span>] = <span class="number">1</span>;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> coin : coins)&#123;</span><br><span class="line">            <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">1</span>; i &lt;= amount; i++)&#123;</span><br><span class="line">                <span class="keyword">if</span> (i - coin &gt;= <span class="number">0</span>)&#123;</span><br><span class="line">                    dp[i] += dp[i - coin];</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[amount];</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3><span id="524-longest-word-in-dictionary-through-deleting">524 Longest Word in Dictionary through Deleting</span></h3><h4><span id="题目大意">题目大意</span></h4><p>给定一个字符串和一个字符串字典，找到字典里面最长的字符串，该字符串可以通过删除给定字符串的某些字符来得到。如果答案不止一个，返回长度最长且字典顺序最小的字符串。如果答案不存在，则返回空字符串。</p><h4><span id="解题思路">解题思路</span></h4><p>通过删除字符串 s 中的一个字符能得到字符串 t，可以认为 t 是 s 的子序列，我们可以使用双指针来判断一个字符串是否为另一个字符串的子序列。</p><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> String <span class="title function_">findLongestWord</span><span class="params">(String s, List&lt;String&gt; d)</span> &#123;</span><br><span class="line">        <span class="type">String</span> <span class="variable">result</span> <span class="operator">=</span> <span class="string">&quot;&quot;</span>;</span><br><span class="line">        <span class="keyword">for</span> (String sd : d)&#123;</span><br><span class="line">            <span class="type">int</span> <span class="variable">l1</span> <span class="operator">=</span> result.length(), l2 = sd.length();</span><br><span class="line">            <span class="keyword">if</span> (l1 &gt; l2 || (l1 == l2 &amp;&amp; result.compareTo(sd) &lt; <span class="number">0</span>)) <span class="keyword">continue</span>;</span><br><span class="line">            <span class="keyword">if</span> (isSubString(sd, s))&#123;</span><br><span class="line">                result = sd;</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><span class="line">    <span class="keyword">public</span> <span class="type">boolean</span> <span class="title function_">isSubString</span><span class="params">(String sub, String str)</span>&#123;</span><br><span class="line">        <span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>, j = <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">while</span> (i &lt; sub.length() &amp;&amp; j &lt; str.length())&#123;</span><br><span class="line">            <span class="keyword">if</span> (sub.charAt(i) == str.charAt(j))&#123;</span><br><span class="line">                i++;</span><br><span class="line">            &#125;</span><br><span class="line">            j++;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> i == sub.length();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">// result.compareTo(sd) &lt; 0 表示字典序升序，返回值是整型，它是先比较对应字符的大小(ASCII码顺序)，如果第一个字符和参数的第一个字符不等，结束比较，返回他们之间的差值，如果第一个字符和参数的第一个字符相等，则以第二个字符和参数的第二个字符做比较，以此类推，直至比较的字符或被比较的字符有一方结束。</span></span><br></pre></td></tr></table></figure><h3><span id="538-convert-bst-to-greater-tree">538 Convert BST to Greater Tree</span></h3><h4><span id="题目大意">题目大意</span></h4><p>把二叉搜索树的每个节点的值重新设置为所有比它值大的节点的值的和。</p><h4><span id="解题思路">解题思路</span></h4><p>因为二叉搜索树，所以左节点都比右节点小，所以修改次序应该为右中左，然后记录大节点的和。</p><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">private</span> <span class="type">int</span> <span class="variable">sum</span> <span class="operator">=</span> <span class="number">0</span>;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> TreeNode <span class="title function_">convertBST</span><span class="params">(TreeNode root)</span> &#123;</span><br><span class="line">        tree(root);</span><br><span class="line">        <span class="keyword">return</span> root;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">tree</span><span class="params">(TreeNode tree)</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> (tree == <span class="literal">null</span>) <span class="keyword">return</span>;</span><br><span class="line">        tree(tree.right);</span><br><span class="line">        sum += tree.val;</span><br><span class="line">        tree.val = sum;</span><br><span class="line">        tree(tree.left);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3><span id="540-single-element-in-a-sorted-array">540 Single Element in a Sorted Array</span></h3><h4><span id="题目大意">题目大意</span></h4><p>一个有序数组只有一个数不出现两次，找出这个数。</p><h4><span id="解题思路">解题思路</span></h4><ol><li>异或之后就剩单个的数了，直接起飞，算法复杂度为O(n)。</li><li>采用二分查找为O(logn)。因为有数是单个，因为01、23、34这样检查，如果没出现单个应该都是一样的，一旦出现了不一样说明这个数已经在左边出现过了。为了保证验证的每次都是偶数位置，写个 if 过滤一下。很巧妙的办法。</li></ol><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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">// 法 1</span></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">singleNonDuplicate</span><span class="params">(<span class="type">int</span>[] nums)</span> &#123;</span><br><span class="line">        <span class="type">int</span> <span class="variable">left</span> <span class="operator">=</span> <span class="number">0</span>, right = nums.length - <span class="number">1</span>;</span><br><span class="line">        <span class="keyword">while</span> (left &lt; right)&#123;</span><br><span class="line">            <span class="type">int</span> <span class="variable">mid</span> <span class="operator">=</span> left + (right - left) / <span class="number">2</span>;</span><br><span class="line">            <span class="keyword">if</span> (mid % <span class="number">2</span> == <span class="number">1</span>) &#123;</span><br><span class="line">                mid --;   <span class="comment">// 保证 l/h/m 都在偶数位，使得查找区间大小一直都是奇数</span></span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">if</span> (nums[mid] == nums[mid + <span class="number">1</span>])&#123;</span><br><span class="line">                left = mid + <span class="number">2</span>;</span><br><span class="line">            &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                right = mid;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> nums[left];</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">// 法 2</span></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">singleNonDuplicate</span><span class="params">(<span class="type">int</span>[] nums)</span> &#123;</span><br><span class="line">        <span class="type">int</span> <span class="variable">result</span> <span class="operator">=</span> <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> num : nums)&#123;</span><br><span class="line">            result ^= num;</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><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3><span id="547-省份数量">547 省份数量</span></h3><h4><span id="题目大意">题目大意</span></h4><p>有一些城市，使用二维矩阵表示这些省份的相连关系，1 表示相连。相连的城市组成在一起构成省份。求给定的二维矩阵中，有多少省份。</p><h4><span id="解题思路">解题思路</span></h4><p>找到一个没被访问过的节点，即看作一个省份，使用深度搜索将与之相连的城市全部找出并置访问标记。</p><p>这里要注意的是，虽然题目中给定了二维矩阵，但是城市的访问标记数组应当是一维的。</p><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">findCircleNum</span><span class="params">(<span class="type">int</span>[][] isConnected)</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> (isConnected == <span class="literal">null</span> || isConnected.length == <span class="number">0</span> || isConnected[<span class="number">0</span>].length == <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="type">int</span> <span class="variable">resu</span> <span class="operator">=</span> <span class="number">0</span>;</span><br><span class="line">        <span class="type">boolean</span>[] visited = <span class="keyword">new</span> <span class="title class_">boolean</span>[isConnected.length];</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; isConnected.length; i++) &#123;</span><br><span class="line">            <span class="keyword">if</span> (!visited[i]) &#123;</span><br><span class="line">                resu++;</span><br><span class="line">                visited[i] = <span class="literal">true</span>;</span><br><span class="line">                dfs(isConnected, visited, i);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> resu;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">dfs</span><span class="params">(<span class="type">int</span>[][] isConnected, <span class="type">boolean</span>[] visited, <span class="type">int</span> cur)</span> &#123;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; isConnected.length; i++) &#123;</span><br><span class="line">            <span class="keyword">if</span> (cur != i &amp;&amp; !visited[i] &amp;&amp; isConnected[i][cur] == <span class="number">1</span>) &#123;</span><br><span class="line">                visited[i] = <span class="literal">true</span>;</span><br><span class="line">                dfs(isConnected, visited, 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><h3><span id="560-subarray-sum-equals-k">560 Subarray Sum Equals K</span></h3><h4><span id="题目大意">题目大意</span></h4><p>给定一个整数数组 <code>nums</code> 和一个整数<code>k</code>，返回该数组中「和为<code>k</code>的连续子数组」的个数。</p><p>示例，输入: nums = [1,1,1], k = 2; 输出: 2; 解释: [1,1] 与 [1,1] 为两种不同的情况。</p><h4><span id="解题思路">解题思路</span></h4><p>我们可以首先求出所有的前缀和，然后根据前缀和求出所有可能的子数组之和。</p><p>内层循环实际上是在求「有多少个 满足 <code>presum[i]</code> 的值为 <code>presum[j] - k</code>」。而我们可以通过用哈希表存储每一个 <code>presum[i]</code> 的值，直接找到满足条件的 <code>presum[i]</code> 的个数，而不需要写一个循环。</p><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="keyword">public</span> <span class="type">int</span> <span class="title function_">subarraySum</span><span class="params">(<span class="type">int</span>[] nums, <span class="type">int</span> k)</span> &#123;</span><br><span class="line">    <span class="type">int</span> <span class="variable">N</span> <span class="operator">=</span> nums.length;</span><br><span class="line">    <span class="comment">// 计算前缀和数组</span></span><br><span class="line">    <span class="comment">// presum[k] 表示元素 nums[0..k) 之和</span></span><br><span class="line">    <span class="type">int</span>[] presum = <span class="keyword">new</span> <span class="title class_">int</span>[N+<span class="number">1</span>];</span><br><span class="line">    <span class="type">int</span> <span class="variable">sum</span> <span class="operator">=</span> <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; N; i++) &#123;</span><br><span class="line">        presum[i] = sum;</span><br><span class="line">        sum += nums[i];</span><br><span class="line">    &#125;</span><br><span class="line">    presum[N] = sum;</span><br><span class="line">    <span class="comment">// sum of nums[i..j) = sum of nums[0..j) - sum of nums[0..i)</span></span><br><span class="line">    <span class="type">int</span> <span class="variable">count</span> <span class="operator">=</span> <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt;= N; i++) &#123;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">j</span> <span class="operator">=</span> i+<span class="number">1</span>; j &lt;= N; j++) &#123;</span><br><span class="line">            <span class="comment">// 前缀和相减求子数组之和</span></span><br><span class="line">            <span class="keyword">if</span> (presum[j] - presum[i] == k) &#123;</span><br><span class="line">                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 class="keyword">return</span> count;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">subarraySum</span><span class="params">(<span class="type">int</span>[] nums, <span class="type">int</span> k)</span> &#123;</span><br><span class="line">        Map&lt;Integer, Integer&gt; map = <span class="keyword">new</span> <span class="title class_">HashMap</span>&lt;&gt;();</span><br><span class="line">        map.put(<span class="number">0</span>, <span class="number">1</span>);</span><br><span class="line">        <span class="type">int</span> <span class="variable">sum</span> <span class="operator">=</span> <span class="number">0</span>;</span><br><span class="line">        <span class="type">int</span> <span class="variable">resu</span> <span class="operator">=</span> <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> num : nums) &#123;</span><br><span class="line">            sum += num;</span><br><span class="line">            <span class="keyword">if</span> (map.containsKey(sum - k)) &#123;</span><br><span class="line">                resu += map.get(sum - k);</span><br><span class="line">            &#125;</span><br><span class="line">            map.put(sum, map.getOrDefault(sum, <span class="number">0</span>) + <span class="number">1</span>);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> resu;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3><span id="567-permutation-in-string">567 Permutation in String</span></h3><h4><span id="题目大意">题目大意</span></h4><p>给定两个字符串 <strong>s1</strong> 和 <strong>s2</strong>，写一个函数来判断 <strong>s2</strong> 是否包含 <strong>s1</strong> 的排列。换句话说，第一个字符串的排列之一是第二个字符串的子串。</p><figure class="highlight plaintext"><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">输入: s1 = &quot;ab&quot; s2 = &quot;eidbaooo&quot;</span><br><span class="line">输出: True</span><br><span class="line">解释: s2 包含 s1 的排列之一 (&quot;ba&quot;).</span><br></pre></td></tr></table></figure><h4><span id="解题思路">解题思路</span></h4><p>滑动窗口，比较元素个数是不是相同。</p><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="keyword">import</span> java.util.Arrays;</span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="type">boolean</span> <span class="title function_">checkInclusion</span><span class="params">(String s1, String s2)</span> &#123;</span><br><span class="line">        <span class="type">int</span> <span class="variable">l1</span> <span class="operator">=</span> s1.length();</span><br><span class="line">        <span class="type">int</span> <span class="variable">l2</span> <span class="operator">=</span> s2.length();</span><br><span class="line">        <span class="type">int</span>[] c1 = <span class="keyword">new</span> <span class="title class_">int</span>[<span class="number">26</span>];</span><br><span class="line">        <span class="type">int</span>[] c2 = <span class="keyword">new</span> <span class="title class_">int</span>[<span class="number">26</span>];</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">char</span> c : s1.toCharArray()) &#123;</span><br><span class="line">            c1[c - <span class="string">&#x27;a&#x27;</span>]++;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; l2; i++) &#123;</span><br><span class="line">            <span class="keyword">if</span> (i &gt;= l1) &#123;</span><br><span class="line">                <span class="comment">// 滑出的</span></span><br><span class="line">                c2[s2.charAt(i - l1) - <span class="string">&#x27;a&#x27;</span>]--;</span><br><span class="line">            &#125;</span><br><span class="line">            c2[s2.charAt(i) - <span class="string">&#x27;a&#x27;</span>]++;</span><br><span class="line">            <span class="keyword">if</span> (Arrays.equals(c1, c2)) &#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><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3><span id="605-can-place-flowers">605 Can Place Flowers</span></h3><h4><span id="题目大意">题目大意</span></h4><p>flowerbed 数组中 1 表示已经种下了花朵。花朵之间至少需要一个单位的间隔，求解是否能种下 n 朵花。</p><h4><span id="解题思路">解题思路</span></h4><ol><li><p>贪心，计算出能放花的个数，如果&gt;=n，OK。以中间位为基准，设置前后位来检查。</p></li><li><p>贪心，题目要求是否能在不打破规则的情况下插入n朵花，与直接计算不同，采用“跳格子”的解法只需遍历不到一遍数组，处理以下两种不同的情况即可：</p><p>【1】当遍历到index遇到1时，说明这个位置有花，那必然从index+2的位置才有可能种花，因此当碰到1时直接跳过下一格。<br>【2】当遍历到index遇到0时，由于每次碰到1都是跳两格，因此前一格必定是0，此时只需要判断下一格是不是1即可得出index这一格能不能种花，如果能种则令n减一，然后这个位置就按照遇到1时处理，即跳两格；如果index的后一格是1，说明这个位置不能种花且之后两格也不可能种花（参照【1】），直接跳过3格。</p><p>当n减为0时，说明可以种入n朵花，则可以直接退出遍历返回true；如果遍历结束n没有减到0，说明最多种入的花的数量小于n，则返回false。</p></li></ol><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><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="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="type">boolean</span> <span class="title function_">canPlaceFlowers</span><span class="params">(<span class="type">int</span>[] flowerbed, <span class="type">int</span> n)</span> &#123;</span><br><span class="line">        <span class="type">int</span> <span class="variable">count</span> <span class="operator">=</span> <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; flowerbed.length; i++)&#123;</span><br><span class="line">            <span class="keyword">if</span> (flowerbed[i] == <span class="number">1</span>) <span class="keyword">continue</span>;</span><br><span class="line">            <span class="type">int</span> <span class="variable">pre</span> <span class="operator">=</span> i == <span class="number">0</span> ? <span class="number">0</span> : flowerbed[i - <span class="number">1</span>];</span><br><span class="line">            <span class="type">int</span> <span class="variable">next</span> <span class="operator">=</span> flowerbed[i + <span class="number">1</span>];</span><br><span class="line">            <span class="keyword">if</span> (pre == <span class="number">0</span> &amp;&amp; next == <span class="number">0</span>)&#123;</span><br><span class="line">                count ++;</span><br><span class="line">                flowerbed[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">return</span> count &gt;= n;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="type">boolean</span> <span class="title function_">canPlaceFlowers</span><span class="params">(<span class="type">int</span>[] flowerbed, <span class="type">int</span> n)</span> &#123;</span><br><span class="line">        <span class="type">int</span> <span class="variable">index</span> <span class="operator">=</span> <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">while</span> (index &lt; flowerbed.length) &#123;</span><br><span class="line">            <span class="keyword">if</span> (flowerbed[index] == <span class="number">0</span>) &#123;</span><br><span class="line">                <span class="comment">// 防溢出，也是将flowerbed.length看作没有花</span></span><br><span class="line">                <span class="keyword">if</span> (index == flowerbed.length - <span class="number">1</span> || flowerbed[index + <span class="number">1</span>] == <span class="number">0</span>) &#123;</span><br><span class="line">                    n--;</span><br><span class="line">                    index += <span class="number">2</span>;</span><br><span class="line">                &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                    index += <span class="number">3</span>;</span><br><span class="line">                &#125;</span><br><span class="line">            &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                index += <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> n &lt;= <span class="number">0</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3><span id="647-palindromic-substrings">647 Palindromic Substrings</span></h3><h4><span id="题目大意">题目大意</span></h4><p>给定义一个字符串，计算有多少个回文子串。</p><figure class="highlight plaintext"><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">Input: &quot;aaa&quot;</span><br><span class="line">Output: 6</span><br><span class="line">Explanation: Six palindromic strings: &quot;a&quot;, &quot;a&quot;, &quot;a&quot;, &quot;aa&quot;, &quot;aa&quot;, &quot;aaa&quot;.</span><br></pre></td></tr></table></figure><h4><span id="解题思路">解题思路</span></h4><p>中间外扩法，分奇数和偶数两种情况外扩。</p><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="type">int</span> <span class="variable">result</span> <span class="operator">=</span> <span class="number">0</span>;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">countSubstrings</span><span class="params">(String s)</span> &#123;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; s.length(); i++) &#123;</span><br><span class="line">            count(s, i, i);</span><br><span class="line">            count(s, i, i + <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><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">count</span><span class="params">(String s, <span class="type">int</span> left, <span class="type">int</span> right)</span> &#123;</span><br><span class="line">        <span class="keyword">while</span> (left &gt;= <span class="number">0</span> &amp;&amp; right &lt; s.length() &amp;&amp; s.charAt(left) == s.charAt(right)) &#123;</span><br><span class="line">            left--;</span><br><span class="line">            right++;</span><br><span class="line">            result++;</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><h3><span id="665-non-decreasing-array">665 Non-decreasing Array</span></h3><h4><span id="题目大意">题目大意</span></h4><p>判断一个数组是否能只修改一个数就成为非递减数组。</p><h4><span id="解题思路">解题思路</span></h4><p>在出现 nums[i] &lt; nums[i - 1] 时，需要考虑的是应该修改数组的哪个数，使得本次修改能使 i 之前的数组成为非递减数组，并且 <strong>不影响后续的操作</strong> 。优先考虑令 nums[i - 1] = nums[i]，因为如果修改 nums[i] = nums[i - 1] 的话，那么 nums[i] 这个数会变大，就有可能比 nums[i + 1] 大，从而影响了后续操作。还有一个比较特别的情况就是 nums[i] &lt; nums[i - 2]，修改 nums[i - 1] = nums[i] 不能使数组成为非递减数组，只能修改 nums[i] = nums[i - 1]。</p><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="type">boolean</span> <span class="title function_">checkPossibility</span><span class="params">(<span class="type">int</span>[] nums)</span> &#123;</span><br><span class="line">        <span class="type">int</span> <span class="variable">count</span> <span class="operator">=</span> <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">1</span>; i &lt; nums.length &amp;&amp; count &lt; <span class="number">2</span>; i++)&#123;</span><br><span class="line">            <span class="keyword">if</span> (nums[i] &gt;= nums[i-<span class="number">1</span>])&#123;</span><br><span class="line">                <span class="keyword">continue</span>;</span><br><span class="line">            &#125;</span><br><span class="line">            count ++;</span><br><span class="line">            <span class="keyword">if</span> (i - <span class="number">2</span> &gt;= <span class="number">0</span> &amp;&amp; nums[i - <span class="number">2</span>] &gt; nums[i])&#123;</span><br><span class="line">                nums[i] = nums[i - <span class="number">1</span>];</span><br><span class="line">            &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                nums[i - <span class="number">1</span>] = nums[i];</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> count &lt;= <span class="number">1</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3><span id="674-longest-continuous-increasing-subsequence">674 Longest Continuous Increasing Subsequence</span></h3><h4><span id="题目大意">题目大意</span></h4><p>最长连续递增子序列。</p><figure class="highlight plaintext"><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">Input: [1,3,5,4,7]</span><br><span class="line">Output: 3</span><br></pre></td></tr></table></figure><h4><span id="解题思路">解题思路</span></h4><p>循环记录，断了就重新来。</p><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="type">int</span> <span class="title function_">findLengthOfLCIS</span><span class="params">(<span class="type">int</span>[] nums)</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> (nums == <span class="literal">null</span> || nums.length == <span class="number">0</span>) <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">        <span class="type">int</span> <span class="variable">res</span> <span class="operator">=</span> <span class="number">0</span>;</span><br><span class="line">        <span class="type">int</span> <span class="variable">tmp</span> <span class="operator">=</span> <span class="number">1</span>;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">1</span>; i &lt; nums.length; i++) &#123;</span><br><span class="line">            <span class="keyword">if</span> (nums[i] &gt; nums[i - <span class="number">1</span>]) &#123;</span><br><span class="line">                tmp++;</span><br><span class="line">            &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                res = Math.max(tmp, res);</span><br><span class="line">                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">return</span> Math.max(res, tmp);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line">        <span class="type">int</span>[] nums = &#123;<span class="number">1</span>, <span class="number">3</span>, <span class="number">5</span>, <span class="number">7</span>&#125;;</span><br><span class="line">        System.out.println(findLengthOfLCIS(nums));</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3><span id="680-valid-palindrome-ii">680 Valid Palindrome II</span></h3><h4><span id="题目大意">题目大意</span></h4><p>可以删除一个字符，判断是否能构成回文字符串。</p><h4><span id="解题思路">解题思路</span></h4><p>在判断是否为回文字符串时，左右剥皮判断，因为左指针左边和右指针右边的字符之前已经判断过具有对称性质，所以只需要判断中间的子字符串即可。在试着删除字符时，我们既可以删除左指针指向的字符，也可以删除右指针指向的字符。</p><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="type">boolean</span> <span class="title function_">validPalindrome</span><span class="params">(String s)</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> (s == <span class="literal">null</span> || s.length() == <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">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>, j = s.length()-<span class="number">1</span>; i&lt;j; i++,j--)&#123;</span><br><span class="line">            <span class="keyword">if</span> (s.charAt(i) != s.charAt(j))&#123;</span><br><span class="line">                <span class="keyword">return</span> isPalindrome(s, i, j - <span class="number">1</span>) || isPalindrome(s, 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 class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">public</span> <span class="type">boolean</span> <span class="title function_">isPalindrome</span><span class="params">(String s, <span class="type">int</span> left, <span class="type">int</span> right)</span>&#123;</span><br><span class="line">        <span class="keyword">while</span> (left &lt; right)&#123;</span><br><span class="line">            <span class="keyword">if</span> (s.charAt(left++) != s.charAt(right--))&#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">        &#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><h3><span id="695-max-area-of-island">695 Max Area of Island</span></h3><h4><span id="题目大意">题目大意</span></h4><p>给定一个包含了一些 <code>0</code> 和 <code>1</code> 的非空二维数组 <code>grid</code>。</p><p>一个<strong>岛屿</strong>是由一些相邻的 <code>1</code> (代表土地) 构成的组合，这里的「相邻」要求两个 <code>1</code> 必须在水平或者竖直方向上相邻。你可以假设 <code>grid</code> 的四个边缘都被 <code>0</code>（代表水）包围着。</p><p>找到给定的二维数组中最大的岛屿面积。(如果没有岛屿，则返回面积为 <code>0</code>。)</p><h4><span id="解题思路">解题思路</span></h4><p>这道题的主要思路是深度优先搜索。每次走到一个是 1 的格子，就搜索整个岛屿，并计算当前岛屿的面积。最后返回岛屿面积的最大值。</p><p>网格可以看成是一个无向图的结构，每个格子和它上下左右的四个格子相邻。如果四个相邻的格子坐标合法，且是陆地，就可以继续搜索。</p><p>在深度优先搜索的时候要注意避免重复遍历。我们可以把已经遍历过的陆地改成 2，这样遇到 2 我们就知道已经遍历过这个格子了，不进行重复遍历。</p><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">maxAreaOfIsland</span><span class="params">(<span class="type">int</span>[][] grid)</span> &#123;</span><br><span class="line">        <span class="type">int</span> <span class="variable">res</span> <span class="operator">=</span> <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; grid.length; i++) &#123;</span><br><span class="line">            <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">j</span> <span class="operator">=</span> <span class="number">0</span>; j &lt; grid[<span class="number">0</span>].length; j++) &#123;</span><br><span class="line">                <span class="keyword">if</span> (grid[i][j] == <span class="number">1</span>) &#123;</span><br><span class="line">                    <span class="type">int</span> <span class="variable">a</span> <span class="operator">=</span> getArea(grid, i, j);</span><br><span class="line">                    res = Math.max(res, a);</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 class="type">int</span> <span class="title function_">getArea</span><span class="params">(<span class="type">int</span>[][] grid, <span class="type">int</span> r, <span class="type">int</span> c)</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> (!isInArea(grid, r, c))</span><br><span class="line">            <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">if</span> (grid[r][c] != <span class="number">1</span>)</span><br><span class="line">            <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">        grid[r][c] = <span class="number">2</span>;</span><br><span class="line">        <span class="keyword">return</span> <span class="number">1</span> + getArea(grid, r - <span class="number">1</span>, c) + getArea(grid, r + <span class="number">1</span>, c) + getArea(grid, r, c - <span class="number">1</span>)</span><br><span class="line">                + getArea(grid, r, c + <span class="number">1</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="type">boolean</span> <span class="title function_">isInArea</span><span class="params">(<span class="type">int</span>[][] grid, <span class="type">int</span> r, <span class="type">int</span> c)</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> (r &gt;= <span class="number">0</span> &amp;&amp; r &lt; grid.length &amp;&amp; c &gt;= <span class="number">0</span> &amp;&amp; c &lt; grid[<span class="number">0</span>].length)</span><br><span class="line">            <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><h3><span id="739-daily-temperatures">739 Daily Temperatures</span></h3><h4><span id="题目大意">题目大意</span></h4><p>输入数组为温度序列，寻找对于每一天，后面较温暖的一天在哪。</p><p><code>T = [73, 74, 75, 71, 69, 72, 76, 73]</code>, your output should be <code>[1, 1, 4, 2, 1, 1, 0, 0]</code>.</p><h4><span id="解题思路">解题思路</span></h4><p>建立栈，用于存储那些还没有找到较温暖的天的索引。那么栈顶就是最近的一次没找到最近温度的索引。</p><p>遍历数组，如果当前位置温度还没有找到比他更暖和的，入栈，准备寻找下一个。每遍历一个新的温度，都去检查一下它和栈顶的关系，如果大于，说明他是离栈顶最近的一个暖和天气，往前寻找，因为可能也大于前面的天气。</p><p>这个栈在这里的作用就是建立了一个降序序列，每当遇到比降序序列最后一个元素大的元素的时候就向前不断地寻找所有较小地元素出栈。</p><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><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="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="type">int</span>[] dailyTemperatures(<span class="type">int</span>[] T) &#123;</span><br><span class="line">        Stack&lt;Integer&gt; stack = <span class="keyword">new</span> <span class="title class_">Stack</span>&lt;&gt;();</span><br><span class="line">        <span class="type">int</span>[] resu = <span class="keyword">new</span> <span class="title class_">int</span>[T.length];</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; T.length; i++) &#123;</span><br><span class="line">            <span class="keyword">while</span> (!stack.isEmpty() &amp;&amp; T[i] &gt; T[stack.peek()]) &#123;</span><br><span class="line">                resu[stack.peek()] = i - stack.peek();</span><br><span class="line">                stack.pop();</span><br><span class="line">            &#125;</span><br><span class="line">            stack.push(i);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> resu;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3><span id="744-find-smallest-letter-greater-than-target">744 Find Smallest Letter Greater Than Target</span></h3><h4><span id="题目大意">题目大意</span></h4><p>给定一个有序的字符数组 letters 和一个字符 target，要求找出 letters 中大于 target 的最小字符，如果找不到就返回第 1 个字符。</p><p>如，cfj 中找 c 返回 f，找 g 返回 j，找 z 返回 c。</p><h4><span id="解题思路">解题思路</span></h4><p>因为有序，想到二分查找。在查找过程中，因为 left 判断 &lt;= 的标准后 ++，所以最终结果应该在 left。</p><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><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="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="type">char</span> <span class="title function_">nextGreatestLetter</span><span class="params">(<span class="type">char</span>[] letters, <span class="type">char</span> target)</span> &#123;</span><br><span class="line">        <span class="type">int</span> <span class="variable">left</span> <span class="operator">=</span> <span class="number">0</span>, right = letters.length - <span class="number">1</span>;</span><br><span class="line">        <span class="keyword">while</span> (left &lt;= right)&#123;</span><br><span class="line">            <span class="type">int</span> <span class="variable">mid</span> <span class="operator">=</span> left + (right - left) / <span class="number">2</span>;</span><br><span class="line">            <span class="keyword">if</span> (letters[mid] &lt;= target)&#123;</span><br><span class="line">                left = mid + <span class="number">1</span>;</span><br><span class="line">            &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                right = mid - <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> left &lt; letters.length ? letters[left] : letters[<span class="number">0</span>];</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3><span id="763-partition-labels">763 Partition Labels</span></h3><h4><span id="题目大意">题目大意</span></h4><p>给你一个串， 要求分割尽量多份，使得每份中的字母只在该被分割部分出现。</p><h4><span id="解题思路">解题思路</span></h4><p>扫一遍串，用一个 map 存每个字母的最大 index 值</p><p>扫一遍串，lock 住 start 指针，更新即将被分割子串最大的last值，当 last == i， 则找到一个被分割子串。</p><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> List&lt;Integer&gt; <span class="title function_">partitionLabels</span><span class="params">(String s)</span> &#123;</span><br><span class="line">        List&lt;Integer&gt; result = <span class="keyword">new</span> <span class="title class_">ArrayList</span>&lt;&gt;();</span><br><span class="line">        <span class="keyword">if</span> (s == <span class="literal">null</span> || s.length() == <span class="number">0</span>) <span class="keyword">return</span> result;</span><br><span class="line">        Map&lt;Character, Integer&gt; map = <span class="keyword">new</span> <span class="title class_">HashMap</span>&lt;&gt;();</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; s.length(); i++)&#123;</span><br><span class="line">            map.put(s.charAt(i), i);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="type">int</span> <span class="variable">start</span> <span class="operator">=</span> <span class="number">0</span>, last = <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; s.length(); i++)&#123;</span><br><span class="line">            last = Math.max(last, map.get(s.charAt(i)));</span><br><span class="line">            <span class="keyword">if</span> (last == i)&#123;</span><br><span class="line">                result.add(last - start + <span class="number">1</span>);</span><br><span class="line">                start = 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">return</span> result;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3><span id="830-较大分组的位置">830 较大分组的位置</span></h3><h4><span id="题目大意">题目大意</span></h4><p>将字符串中所有包含大于等于三个连续字符的分组的位置坐标按照起始位置坐标递增排序后返回结果。</p><figure class="highlight plaintext"><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">输入：s = &quot;abbxxxxzzy&quot;</span><br><span class="line">输出：[[3,6]]</span><br><span class="line">解释：&quot;xxxx&quot; 是一个起始于 3 且终止于 6 的较大分组。</span><br></pre></td></tr></table></figure><h4><span id="解题思路">解题思路</span></h4><p>我们可以遍历该序列，并记录当前分组的长度。如果下一个字符与当前字符不同，或者已经枚举到字符串尾部，就说明当前字符为当前分组的尾部。每次找到当前分组的尾部时，如果该分组长度达到 33，我们就将其加入答案。</p><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> List&lt;List&lt;Integer&gt;&gt; <span class="title function_">largeGroupPositions</span><span class="params">(String s)</span> &#123;</span><br><span class="line">        <span class="type">int</span> <span class="variable">head</span> <span class="operator">=</span> <span class="number">0</span>, tail = <span class="number">1</span>;</span><br><span class="line">        List&lt;List&lt;Integer&gt;&gt; resu = <span class="keyword">new</span> <span class="title class_">ArrayList</span>&lt;&gt;();</span><br><span class="line">        <span class="keyword">while</span> (tail &lt; s.length()) &#123;</span><br><span class="line">            <span class="keyword">while</span> (tail &lt; s.length() &amp;&amp; s.charAt(tail) == s.charAt(head)) &#123;</span><br><span class="line">                tail++;</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">if</span> (tail - head &gt;= <span class="number">3</span>) &#123;</span><br><span class="line">                List&lt;Integer&gt; list = <span class="keyword">new</span> <span class="title class_">ArrayList</span>&lt;&gt;();</span><br><span class="line">                list.add(head);</span><br><span class="line">                list.add(tail - <span class="number">1</span>);</span><br><span class="line">                resu.add(list);</span><br><span class="line">            &#125;</span><br><span class="line">            head = tail++;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> resu;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3><span id="877-stone-game">877 Stone Game</span></h3><h4><span id="题目大意">题目大意</span></h4><p>亚历克斯和李用几堆石子在做游戏。偶数堆石子排成一行，每堆都有正整数颗石子 piles[i] 。</p><p>游戏以谁手中的石子最多来决出胜负。石子的总数是奇数，所以没有平局。</p><p>亚历克斯和李轮流进行，亚历克斯先开始。 每回合，玩家从行的开始或结束处取走整堆石头。 这种情况一直持续到没有更多的石子堆为止，此时手中石子最多的玩家获胜。</p><p>假设亚历克斯和李都发挥出最佳水平，当亚历克斯赢得比赛时返回 true ，当李赢得比赛时返回 false 。</p><p>输入：[5,3,4,5]<br>输出：true<br>解释：<br>亚历克斯先开始，只能拿前 5 颗或后 5 颗石子 。<br>假设他取了前 5 颗，这一行就变成了 [3,4,5] 。<br>如果李拿走前 3 颗，那么剩下的是 [4,5]，亚历克斯拿走后 5 颗赢得 10 分。<br>如果李拿走后 5 颗，那么剩下的是 [3,4]，亚历克斯拿走后 4 颗赢得 9 分。<br>这表明，取前 5 颗石子对亚历克斯来说是一个胜利的举动，所以我们返回 true 。</p><h4><span id="解题思路">解题思路</span></h4><p>这道题直接返回了 true 竟然就通过了。。。。</p><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><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="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="type">boolean</span> <span class="title function_">stoneGame</span><span class="params">(<span class="type">int</span>[] piles)</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></pre></td></tr></table></figure><h3><span id="1006-笨阶乘">1006 笨阶乘</span></h3><h4><span id="题目大意">题目大意</span></h4><p>我们以一个固定顺序的操作符序列来依次替换原有的乘法操作符：乘法(*)，除法(/)，加法(+)和减法(-)。</p><p>例如，clumsy(10) = 10 * 9 / 8 + 7 - 6 * 5 / 4 + 3 - 2 * 1。</p><h4><span id="解题思路">解题思路</span></h4><p>将多项式转化为多项和，即((10*9/8)+7+(-6*5/4)，显然可以通过栈解决。</p><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">clumsy</span><span class="params">(<span class="type">int</span> N)</span> &#123;</span><br><span class="line">        Stack&lt;Integer&gt; stack = <span class="keyword">new</span> <span class="title class_">Stack</span>&lt;&gt;();</span><br><span class="line">        stack.push(N);</span><br><span class="line">        N--;</span><br><span class="line">        <span class="type">int</span> <span class="variable">index</span> <span class="operator">=</span> <span class="number">0</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">if</span> (index % <span class="number">4</span> == <span class="number">0</span>) &#123;</span><br><span class="line">                stack.push(stack.pop() * N);</span><br><span class="line">            &#125; <span class="keyword">else</span> <span class="keyword">if</span> (index % <span class="number">4</span> == <span class="number">1</span>) &#123;</span><br><span class="line">                stack.push(stack.pop() / N);</span><br><span class="line">            &#125; <span class="keyword">else</span> <span class="keyword">if</span> (index % <span class="number">4</span> == <span class="number">2</span>) &#123;</span><br><span class="line">                stack.push(N);</span><br><span class="line">            &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                stack.push(-N);</span><br><span class="line">            &#125;</span><br><span class="line">            index++;</span><br><span class="line">            N--;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="type">int</span> <span class="variable">resu</span> <span class="operator">=</span> <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">while</span> (!stack.isEmpty()) &#123;</span><br><span class="line">            resu += stack.pop();</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> resu;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3><span id="1025-divisor-game">1025  Divisor Game</span></h3><h4><span id="题目大意">题目大意</span></h4><p>有数字N，对于两个游戏玩家轮流做以下动作：</p><ul><li>挑选一个X，使得X满足0&lt;X&lt;N并且N%x==0</li><li>将N替换为N-X</li></ul><p>如果有一个玩家不能继续玩了，游戏结束。爱丽丝先手，如果爱丽丝赢了返回True，假设两个玩家选择的都是最优。</p><h4><span id="解题思路">解题思路</span></h4><p>几个例子：</p><ul><li>假设 <code>N = 1</code>，爱丽丝没得选择，直接失败，即 <strong>鲍勃获胜</strong>；</li><li>假设 <code>N = 2</code>，爱丽丝有选择，她可以选择 <code>x = 1</code>，鲍勃面对的就是 <code>N = 2 - 1 = 1</code>，无法操作，<strong>爱丽丝获胜</strong>；</li><li>假设 <code>N = 3</code>，爱丽丝只能选择 <code>x = 1</code>，因为选 <code>x = 2</code> 不满足 <code>3 % 2 = 0</code>，鲍勃面对的就是 <code>N = 3 - 1 = 2</code>，参考上面 <code>N = 2</code> 的情形，此时鲍勃为 <code>N = 2</code> 的先手，<strong>鲍勃获胜</strong>；</li><li>假设 <code>N = 4</code>，爱丽丝可以选择 <code>x = 1</code> 来使鲍勃遇到 <code>N = 3</code> 的情况，<strong>爱丽丝获胜</strong>；</li></ul><p>似乎有个规律，N为偶数时候，爱丽丝获胜。</p><p>事实上，无论 N 为多大，最终都是在 <strong>N = 2</strong> 这个临界点结束的。谁最后面对的是 <strong>N = 2</strong> 的情形，谁就能获胜。</p><p>接下来，我们得知道一个数学小知识：<strong>奇数的因子（约数）只能是奇数，偶数的因子（约数）可以是奇数或偶数</strong>。</p><p><strong>千万不要忽略 1 也是因子！</strong></p><p>爱丽丝是游戏开始时的先手。</p><ul><li>当她面对的 N 为偶数时，她 <strong>一定可以</strong> 选到一个 N 的奇数因子 x（比如 1 ），将 N - x 这个奇数传给鲍勃；用 <code>N - x</code> 替换黑板上的数字 <code>N</code> ，鲍勃面对的就是奇数 N，只能选择 N 的奇数因子 x，<code>奇数 - 奇数 = 偶数</code>，此时传给爱丽丝的又是偶数。这样轮换下去爱丽丝会遇到 <strong>N = 2</strong> 的情形，然后获胜；</li><li>当爱丽丝遇到的 N 是奇数时，只能传给鲍勃偶数或无法操作 (N = 1) ，无法获胜。</li></ul><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><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="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="type">boolean</span> <span class="title function_">divisorGame</span><span class="params">(<span class="type">int</span> N)</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> N % <span class="number">2</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><h3><span id="1046-最后一块石头的重量">1046 最后一块石头的重量</span></h3><h4><span id="题目大意">题目大意</span></h4><p>有一堆石头，每块石头的重量都是正整数。每一回合，从中选出两块最重的石头，然后将它们一起粉碎。假设石头的重量分别为 x 和 y，且 x &lt;= y。那么粉碎的可能结果如下：</p><ul><li><p>如果 x == y，那么两块石头都会被完全粉碎；</p></li><li><p>如果 x != y，那么重量为 x 的石头将会完全粉碎，而重量为 y 的石头新重量为 y-x。</p></li></ul><p>最后，最多只会剩下一块石头。返回此石头的重量。如果没有石头剩下，就返回 0。</p><h4><span id="解题思路">解题思路</span></h4><ol><li>递归，处理到仅剩两块石头时候结束递归。</li><li>使用大顶堆模拟操作。</li></ol><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">lastStoneWeight</span><span class="params">(<span class="type">int</span>[] stones)</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> (stones.length == <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">if</span> (stones.length == <span class="number">1</span>) &#123;</span><br><span class="line">            <span class="keyword">return</span> stones[<span class="number">0</span>];</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span> (stones.length == <span class="number">2</span>) &#123;</span><br><span class="line">            <span class="keyword">return</span> Math.abs(stones[<span class="number">0</span>] - stones[<span class="number">1</span>]);</span><br><span class="line">        &#125;</span><br><span class="line">        Arrays.sort(stones);</span><br><span class="line">        <span class="keyword">if</span> (stones[stones.length - <span class="number">3</span>] == <span class="number">0</span>) &#123;</span><br><span class="line">            <span class="keyword">return</span> stones[stones.length - <span class="number">1</span>] - stones[stones.length - <span class="number">2</span>];</span><br><span class="line">        &#125;</span><br><span class="line">        stones[stones.length - <span class="number">2</span>] = stones[stones.length - <span class="number">1</span>] - stones[stones.length - <span class="number">2</span>];</span><br><span class="line">        stones[stones.length - <span class="number">1</span>] = <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">return</span> lastStoneWeight(stones);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">lastStoneWeight</span><span class="params">(<span class="type">int</span>[] stones)</span> &#123;</span><br><span class="line">        PriorityQueue&lt;Integer&gt; priorityQueue = <span class="keyword">new</span> <span class="title class_">PriorityQueue</span>&lt;&gt;(Collections.reverseOrder());</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> s : stones) &#123;</span><br><span class="line">            priorityQueue.offer(s);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">while</span> (priorityQueue.size() &gt; <span class="number">1</span>) &#123;</span><br><span class="line">            <span class="type">int</span> <span class="variable">top</span> <span class="operator">=</span> priorityQueue.poll();</span><br><span class="line">            <span class="type">int</span> <span class="variable">sec</span> <span class="operator">=</span> priorityQueue.poll();</span><br><span class="line">            <span class="keyword">if</span> (top &gt; sec) &#123;</span><br><span class="line">                priorityQueue.offer(top - sec);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> priorityQueue.size() == <span class="number">1</span> ? priorityQueue.peek() : <span class="number">0</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3><span id="1047-remove-all-adjacent-duplicates-in-string">1047 Remove All Adjacent Duplicates In String</span></h3><h4><span id="题目大意">题目大意</span></h4><p>删除字符串中相邻重复的字符，包括删除后新组成的字符串中重复的。例如“abbaca”删除后“ca”。</p><h4><span id="解题思路">解题思路</span></h4><p>使用栈存放已经处理完的字符，入栈检查是不是和上一个入栈相同，是就弹出。否则就入栈。</p><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> String <span class="title function_">removeDuplicates</span><span class="params">(String S)</span> &#123;</span><br><span class="line">        <span class="type">String</span> <span class="variable">resu</span> <span class="operator">=</span> <span class="string">&quot;&quot;</span>;</span><br><span class="line">        Stack&lt;Character&gt; stack = <span class="keyword">new</span> <span class="title class_">Stack</span>&lt;&gt;();</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; S.length(); i++) &#123;</span><br><span class="line">            <span class="keyword">if</span> (!stack.isEmpty() &amp;&amp; S.charAt(i) == stack.peek()) &#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.charAt(i));</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="type">StringBuilder</span> <span class="variable">sb</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">StringBuilder</span>();</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">char</span> c : stack) &#123;</span><br><span class="line">            sb.append(c);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> sb.toString();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3><span id="1095-find-in-mountain-array">1095 Find in Mountain Array</span></h3><h4><span id="题目大意">题目大意</span></h4><p>定义山峰数组，即中间往两边递减。求和目标值相等的最小索引。山峰数组定义如下。</p><figure class="highlight java"><table><tr><td class="gutter"><pre><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">interface</span> <span class="title class_">MountainArray</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">get</span><span class="params">(<span class="type">int</span> index)</span> &#123;&#125;</span><br><span class="line">    <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">length</span><span class="params">()</span> &#123;&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h4><span id="解题思路">解题思路</span></h4><p>先二分查出山峰来，再二分往左查，查不到右边再二分。</p><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">findInMountainArray</span><span class="params">(<span class="type">int</span> target, MountainArray mountainArr)</span> &#123;</span><br><span class="line">        <span class="type">int</span> <span class="variable">l</span> <span class="operator">=</span> <span class="number">0</span>;</span><br><span class="line">        <span class="type">int</span> <span class="variable">r</span> <span class="operator">=</span> mountainArr.length() - <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="type">int</span> <span class="variable">mid</span> <span class="operator">=</span> l + (r - l) / <span class="number">2</span>;</span><br><span class="line">            <span class="keyword">if</span> (mountainArr.get(mid) &gt; mountainArr.get(mid + <span class="number">1</span>)) &#123;</span><br><span class="line">                r = mid;</span><br><span class="line">            &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                l = mid + <span class="number">1</span>;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> find(mountainArr, target, <span class="number">0</span>, l, <span class="literal">true</span>);</span><br><span class="line">        <span class="keyword">return</span> i != -<span class="number">1</span> ? i : find(mountainArr, target, l + <span class="number">1</span>, mountainArr.length() - <span class="number">1</span>, <span class="literal">false</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">find</span><span class="params">(MountainArray mountainArray, <span class="type">int</span> t, <span class="type">int</span> l, <span class="type">int</span> r, <span class="type">boolean</span> asc)</span> &#123;</span><br><span class="line">        <span class="keyword">while</span> (l &lt; r) &#123;</span><br><span class="line">            <span class="type">int</span> <span class="variable">mid</span> <span class="operator">=</span> (l + r) &gt;&gt; <span class="number">1</span>;</span><br><span class="line">            <span class="keyword">if</span> ((asc &amp;&amp; mountainArray.get(mid) &gt;= t) || (!asc &amp;&amp; mountainArray.get(mid) &lt;= t)) &#123;</span><br><span class="line">                r = mid;</span><br><span class="line">            &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                l = mid + <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> (mountainArray.get(l) == t) &#123;</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">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><h3><span id="1143-longest-common-subsequence">1143 Longest Common Subsequence</span></h3><h4><span id="题目大意">题目大意</span></h4><p>两个字符串的最长公共子序列，可以不连续。</p><h4><span id="解题思路">解题思路</span></h4><p>动态规划解决，设置 dp 二维数组，dp[i][j] 表示串1在 i 和 i 前的字串与串2的最长公共子序列长度。</p><p>这道题就可以转化为，当两个子串当前位置相等的时候，等于上一个位置的长度 + 1，否则的话就是矩阵中上边和左边前两种状态的最大值。</p><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">longestCommonSubsequence</span><span class="params">(String text1, String text2)</span> &#123;</span><br><span class="line">        <span class="type">int</span> <span class="variable">len1</span> <span class="operator">=</span> text1.length(), len2 = text2.length();</span><br><span class="line">        <span class="keyword">if</span> (text1 == <span class="literal">null</span> || text2 == <span class="literal">null</span> || len1  == <span class="number">0</span> || len2 == <span class="number">0</span>)</span><br><span class="line">            <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">        <span class="type">int</span> [][] dp = <span class="keyword">new</span> <span class="title class_">int</span>[len1+<span class="number">1</span>][len2+<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="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">1</span>; i &lt;=len1; i++)&#123;</span><br><span class="line">            <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">j</span> <span class="operator">=</span> <span class="number">1</span>; j &lt;= len2; j++)&#123;</span><br><span class="line">                <span class="keyword">if</span> (text1.charAt(i-<span class="number">1</span>) == text2.charAt(j-<span class="number">1</span>))&#123;</span><br><span class="line">                    dp[i][j] = 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 class="keyword">else</span> &#123;</span><br><span class="line">                    dp[i][j] = Math.max(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[len1][len2];</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3><span id="1371-find-the-longest-substring-containing-vowels-in-even-counts">1371 Find the Longest Substring Containing Vowels in Even Counts</span></h3><h4><span id="题目大意">题目大意</span></h4><p>求每个元音字母出现零次或者偶数次的子串的最长长度。</p><h4><span id="解题思路">解题思路</span></h4><ul><li>字符串的子串里出现的元音字母奇偶的个数<code>设为状态码state</code>可以简化为一个五位的二进制数，<code>栗：'10000'代表 'a' 出现了奇数次，其他元音字母出现了偶数次，'11000'代表'a'，'e'出现了奇数次，其他偶数次</code>，偶数次可以用异或来计算，即异或运算后，即使子串的值不同，他们的状态码可以是相同的。</li><li>用一个哈希表或者数组<code>设为count</code>，<code>count</code>的下标代表状态的整数取值(最大为<strong>32</strong>)，<code>count</code>代表字符串<code>s</code>在下标为<code>count[state]</code>之前的状态码为<code>state</code>，这个也有点像前缀和，只不过是异或计算的。<strong>由于奇数之间相减为偶数，偶数之间相减也为偶数，所以在计算过程中，如果出现了与以前某次相同的状态码，说明以当前下标结尾的子串与之前下标结尾的子串出现的元音字母次数奇偶一致，所以他们两个相减就能获得一个元音字母出现次数为偶数的子串</strong></li><li>在每次计算时都比较一下两者的大小，最后获得满足要求的最长子串。</li></ul><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">findTheLongestSubstring</span><span class="params">(String s)</span> &#123;</span><br><span class="line">        <span class="type">int</span> <span class="variable">length</span> <span class="operator">=</span> s.length();</span><br><span class="line">        <span class="type">char</span>[] vos = &#123;<span class="string">&#x27;a&#x27;</span>, <span class="string">&#x27;e&#x27;</span>, <span class="string">&#x27;i&#x27;</span>, <span class="string">&#x27;o&#x27;</span>, <span class="string">&#x27;u&#x27;</span>&#125;;</span><br><span class="line">        Map&lt;Integer, Integer&gt; map = <span class="keyword">new</span> <span class="title class_">HashMap</span>&lt;&gt;();</span><br><span class="line">        map.put(<span class="number">0</span>, -<span class="number">1</span>);</span><br><span class="line">        <span class="type">int</span> <span class="variable">max</span> <span class="operator">=</span> <span class="number">0</span>;</span><br><span class="line">        <span class="type">int</span> <span class="variable">state</span> <span class="operator">=</span> <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; length; i++) &#123;</span><br><span class="line">            <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">j</span> <span class="operator">=</span> <span class="number">0</span>; j &lt; vos.length; j++) &#123;</span><br><span class="line">                <span class="keyword">if</span> (s.charAt(i) == vos[j]) &#123;</span><br><span class="line">                    state ^= <span class="number">1</span> &lt;&lt; j;</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">            map.putIfAbsent(state, i);</span><br><span class="line">            max = Math.max(max, i - map.get(state));</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><h3><span id="1545-find-kth-bit-in-nth-binary-string">1545 Find Kth Bit in Nth Binary String</span></h3><h4><span id="题目大意">题目大意</span></h4><ul><li><code>S1 = &quot;0&quot;</code></li><li><code>Si = Si-1 + &quot;1&quot; + reverse(invert(Si-1))</code> for <code>i &gt; 1</code></li></ul><p>返回第 k 个位置的数。</p><ul><li><code>S1 = &quot;0&quot;</code></li><li><code>S2 = &quot;011&quot;</code></li><li><code>S3 = &quot;011**1**001&quot;</code></li><li><code>S4 = &quot;011100110110001&quot;</code></li></ul><h4><span id="解题思路">解题思路</span></h4><ul><li>暴力模拟</li><li>找规律<ul><li>第一位肯定是0，中间一位肯定是1</li><li>如果是中间左边的，那也就是上一个字符串的第k个。如果是右边的，右边是左边的对称，所以计算位置反转。</li></ul></li></ul><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="type">char</span> <span class="title function_">findKthBit</span><span class="params">(<span class="type">int</span> n, <span class="type">int</span> k)</span> &#123;</span><br><span class="line">        <span class="type">String</span> <span class="variable">s</span> <span class="operator">=</span> <span class="string">&quot;0&quot;</span>;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">1</span>; i &lt; n; i++) &#123;</span><br><span class="line">            s = s + <span class="string">&#x27;1&#x27;</span> + solve(s);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> s.charAt(k - <span class="number">1</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> String <span class="title function_">solve</span><span class="params">(String s)</span> &#123;</span><br><span class="line">        <span class="type">StringBuilder</span> <span class="variable">sb</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">StringBuilder</span>();</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; s.length(); i++) &#123;</span><br><span class="line">            <span class="keyword">if</span> (s.charAt(i) == <span class="string">&#x27;1&#x27;</span>) &#123;</span><br><span class="line">                sb.append(<span class="string">&#x27;0&#x27;</span>);</span><br><span class="line">            &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                sb.append(<span class="string">&#x27;1&#x27;</span>);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> sb.reverse().toString();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="type">char</span> <span class="title function_">findKthBit</span><span class="params">(<span class="type">int</span> n, <span class="type">int</span> k)</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> (k == <span class="number">1</span>) &#123;</span><br><span class="line">            <span class="keyword">return</span> <span class="string">&#x27;0&#x27;</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="type">int</span> <span class="variable">mid</span> <span class="operator">=</span> (<span class="type">int</span>) Math.pow(<span class="number">2</span>, n - <span class="number">1</span>);</span><br><span class="line">        <span class="keyword">if</span> (k == mid) &#123;</span><br><span class="line">            <span class="keyword">return</span> <span class="string">&#x27;1&#x27;</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span> (k &lt; mid) &#123;</span><br><span class="line">            <span class="keyword">return</span> findKthBit(n - <span class="number">1</span>, k);</span><br><span class="line">        &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> f(findKthBit(n - <span class="number">1</span>, (<span class="type">int</span>) (Math.pow(<span class="number">2</span>, n) - k)));</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">public</span> <span class="keyword">static</span> <span class="type">char</span> <span class="title function_">f</span><span class="params">(<span class="type">char</span> a)</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> (a == <span class="string">&#x27;1&#x27;</span>) &#123;</span><br><span class="line">            <span class="keyword">return</span> <span class="string">&#x27;0&#x27;</span>;</span><br><span class="line">        &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> <span class="string">&#x27;1&#x27;</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>]]></content>
    
    
      
      
    <summary type="html">&lt;blockquote&gt;
&lt;p&gt;LeetCode 解题报告与每日打卡记录，顺便记录不太顺利或者有其他巧妙思路的题目。题目较多，渲染可能比较缓慢。&lt;font id=&quot;qusnum&quot;&gt;&lt;/font&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;script src=&quot;/js/jquery.</summary>
      
    
    
    
    
    <category term="解题报告" scheme="https://tyzhang.top/tags/%E8%A7%A3%E9%A2%98%E6%8A%A5%E5%91%8A/"/>
    
  </entry>
  
  <entry>
    <title>使用 EndNote 自动生成论文参考文献</title>
    <link href="https://tyzhang.top/article/endnote/"/>
    <id>https://tyzhang.top/article/endnote/</id>
    <published>2021-03-14T16:00:00.000Z</published>
    <updated>2021-03-18T11:29:22.000Z</updated>
    
    <content type="html"><![CDATA[<blockquote><p>写一下 EndNote 插入并生成参考文献与格式调整，适合乱改需求的甲方。</p></blockquote><h3><span id="0-为什么使用-endnote">0 为什么使用 EndNote</span></h3><p>在此之前，我使用了 Word 的<code>插入</code>→<code>交叉引用</code>功能，非常好用。他们都可以做到点击跳转。只不过交叉引用前期方便，只需要引入并设置好格式，后面还要自己找到合适的格式粘贴到参考文献的标号后面。</p><p>如果你使用交叉引用，我推荐谷歌学术和知网查询格式，并复制生成好的国标字符串。</p><p>注意该方法局限性较强，如参考文献格式发生修改，需要一个个逐个修改。</p><img src="https://pic.tyzhang.top/images/2021/03/18/image-20210318183800907.png" alt="image-20210318183800907" style="zoom: 50%;"><p>因此，后期改使用 EndNote，插入方便，而且模板可以自定义。我也建议使用该方法，当然因时间问题，可能有更好用的方法还没有探索到。即使更改参考文献的模板，也可以全篇通改，一劳永逸。</p><h3><span id="1-入门">1 入门</span></h3><p>先看段视频。</p><ul><li>基本用法与相关文件下载 <a href="https://www.bilibili.com/video/BV1Qa4y1i7pA">BV1Qa4y1i7pA</a></li></ul><p>如果使用谷歌学术下载对应文献的引用格式文件时，每个论文对应一个文件，逐个导入比较麻烦，这里提供一个脚本文件。将该文件放置在所有参考文献同一目录下运行即可。</p><ul><li><a href="http://download.tyzhang.top/files/EndNote%E4%B8%80%E9%94%AE%E5%AF%BC%E5%85%A5.bat">EndNote 批量导入</a></li></ul><h3><span id="2-格式修正">2 格式修正</span></h3><p>在掌握 EndNode 基本用法后，导入杭电硕士论文参考文献格式，即重复第二个文件导入的操作，将以上视频提供的参考文献格式替换为杭电标准格式 <code>GB/T 7714-2005</code>。</p><ul><li><a href="http://download.tyzhang.top/files/ZZ_MODIFIED_GEEBINF.ENS.zip">GB/T 7714-2005 格式文件下载</a></li></ul><p>在 Word 中选择导入主题，并更新文档。</p><img src="https://pic.tyzhang.top/images/2021/03/18/image-20210318182716284.png" alt="image-20210318182716284" style="zoom:67%;"><p>选择全部参考文献名录，设置段落悬挂缩进 <code>0.74 cm</code>，行距固定值 <code>20 磅</code>，如下图所示。</p><img src="https://pic.tyzhang.top/images/2021/03/18/image-20210318182610997.png" alt="image-20210318182610997" style="zoom:67%;"><p>经过本步骤设置后，所获得参考文献已经符合要求。</p><img src="https://pic.tyzhang.top/images/2021/03/18/image-20210318182836784.png" alt="image-20210318182836784" style="zoom: 50%;"><h3><span id="3-细节处理">3 细节处理</span></h3><h4><span id="31-格式自定义">3.1 格式自定义</span></h4><p>当格式有所更改或者与要求冲突时，可以自主编辑主题样式。<code>编辑</code>→<code>输出样式</code>→<code>编辑导入文件</code>。</p><img src="https://pic.tyzhang.top/images/2021/03/18/image-20210318182949762.png" alt="image-20210318182949762" style="zoom:50%;"><p>选择<code>参考文献</code>→<code>模板</code>，依次按照要求编辑调整格式。</p><img src="https://pic.tyzhang.top/images/2021/03/18/image-20210318183124185.png" alt="image-20210318183124185" style="zoom:67%;"><p>此外，还有许多自定义地方可以探索，如作者姓名显示方式。</p><img src="https://pic.tyzhang.top/images/2021/03/18/image-20210318183220866.png" alt="image-20210318183220866" style="zoom:50%;"><p>编辑过后记得<code>文件</code>→<code>保存</code>。</p><h4><span id="32-中英文混排时等与et-al">3.2 中英文混排时<code>等</code>与<code>et al</code></span></h4><p>如果中文文献较少，可以手动修改。或者参考 <a href="https://www.howsci.com/endnote-eng-cn-refer-etal.html">EndNote中英文混排时et al和等的3种解决方法</a></p><p>文件失效请 <a href="mailto:zhangty1996@163.com">E-Mail</a> 我。</p>]]></content>
    
    
      
      
    <summary type="html">&lt;blockquote&gt;
&lt;p&gt;写一下 EndNote 插入并生成参考文献与格式调整，适合乱改需求的甲方。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;&lt;span id=&quot;0-为什么使用-endnote&quot;&gt;0 为什么使用 EndNote&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;在此之前，我</summary>
      
    
    
    
    
    <category term="笔记" scheme="https://tyzhang.top/tags/%E7%AC%94%E8%AE%B0/"/>
    
  </entry>
  
  <entry>
    <title>彼时彼刻，正如此时此刻</title>
    <link href="https://tyzhang.top/article/letthebulletsfly/"/>
    <id>https://tyzhang.top/article/letthebulletsfly/</id>
    <published>2021-03-06T16:00:00.000Z</published>
    <updated>2021-03-08T12:46:44.000Z</updated>
    
    <content type="html"><![CDATA[<blockquote><p>最纯粹的革命者一定是那个一支枪对着自己，一支枪对着敌人，在心里装着最美好理想的人。</p></blockquote><p><img src="https://pic.tyzhang.top/images/2021/03/07/_20210307210215.jpg" alt></p><p>“大哥，我们去上海了。”<br>“不跟我回山里了？”<br>“还想回山里啊，您这腿脚都不利落啦。”</p><p>“你不是要跟我当麻匪到处发钱吗？”<br>“今天不是把钱都发光了吗？还有比今天更过瘾的？”<br>“这么说，你改主意了？”<br>“那还用说吗？”</p><p>“老三，你有什么打算？”<br>“我要替二哥娶她。”</p><p>“老三，你跟我在一起不高兴吗？”<br>“高兴，就是有点不轻松。”<br>“你们俩呢？”<br>“有点。”<br>“不轻松。”</p><p>“姑娘，你这么拿着枪，更好看。”</p><p><code>标签是未分类，因为我不知道它应该并最终往哪去。</code></p><hr><p>《这个照耀中国的理想主义者，我很怀念他》——乌鸦校尉</p><p>在张牧之来之前，鹅城是一个黑暗的地方。<br>富人和地主在城里为所欲为，而人民群众是他们的奴隶，打碎牙齿往肚子里咽。<br>老百姓只知道当地的黄四郎，不知道有什么县长。<br>县长敢反抗黄四郎，他们也不敢反抗，因为县长是流水的县长，黄四郎才是铁打的老爷。</p><p>有一个叫埃德加·斯诺的美国记者到了中国，民国的交通部长孙科给他安排沿着铁路旅行，希望他能写一写中国的风景。<br>然而，斯诺却忠实地记下了，他沿途看到的这个古老国家的落后和苦难：<br>道路两旁种满了罂粟，陕西军阀们为了赚钱，强迫农民把最肥的地拿出来种鸦片，一旦出现干旱，粮食就不够吃，在西北大饥荒的时候，几年时间就饿死了三百多万人;<br>西北是各种流行病的重灾区，在上路之前，为了安全，天花、伤寒、霍乱、鼠疫……斯诺把自己能打的预防针通通打了一个遍;<br>饥民为了换一点吃的，心甘情愿卖儿卖女，让自己能多活几天;他们饿死了以后，尸体还没有下葬就消失了，因为在一些村庄里，人肉是公开售卖的……<br>1936年四川饥荒的时候，四川靖化县县长于竹君头一次看见吃死尸、吃活人的惨像，从小读四书五经的于竹君被吓得精神失常，觉得鲁迅写的《狂人日记》痛斥吃人现象，简直是小题大做。<br>于是，这位学法律出身的县太爷写了一篇奇文，说“食人者不食人，则时刻有被人食之危险!”<br>所以，食人者不犯杀人罪，应正名为“正当防卫”。<br>四川人筹了141万赈灾的钱，但国民政府贪腐成性，连这点钱也不肯给到灾民头上，蓬溪县一个小小的公安局长陶子国，就贪掉了一万多元赈灾的钱。<br>四川省政府三番五次邀请慈善家尹昌龄主持川省赈务，却被对方屡屡严词回拒。<br>因为尹昌龄认为，四川之灾实为“人灾”，而非“天灾”，他一直在掏钱救自己身边的百姓，却始终不愿和国民政府合作。<br>“终是人灾一日不去，赈务一日难言”。<br>谁能拯救鹅城？这是一个当时很多人都在找，却没有人能回答的问题。<br>从洋务运动开始，这个国家的精英们探索了很多次，却没有一次能够成功。</p><h2><span id="1">1</span></h2><p>1918年，李大钊介绍了一个学生去北大当图书管理员。<br>这个当图书管理员的人很不安分，不光在图书馆里读了很多经典，还见到了许多新文化运动中的领袖来图书馆借书，有不少还是他的偶像。<br>每次他看见了自己的爱豆，都要凑上去想要和爱豆讨论学术问题。<br>可惜，没有大佬有时间听一个操着福南口音的年青人讲话。<br>“我的职位低微，大家都不理我。”<br>有一次，他去课堂旁听，壮着胆子向讲台上的胡适提问。<br>结果，得知他不是正式学生时，胡适直接拒绝回答。<br>这个到处碰壁的小透明，就是毛泽东。<br>在当时的中国，“胡适”这样所谓要救中国的民国大师比比皆是。<br>但是靠“胡适”这样的人，是推翻不了黄四郎的，因为他们嘴上说自己是麻匪的命，但实际上却怀着一颗师爷的心。<br>毛泽东在中共三大上说，要把农民作为革命的必要组成部分。<br>但是，党内的学院派知识分子们，守着本本不放，不理睬他。陈独秀就说：“农民是小资产阶级……如何能做共产主义的运动?”<br>觉得农民重要的，只有他一个人。<br>没办法，青年毛泽东只能再次回到湖南。<br>从1927年1月4日到2月5日，他用了一个多月的时间，跑到那熟悉的或不熟悉的乡村中间去，搀着农民的手，问他们痛苦些什么，问他们要些什么，仔细听他们讲话。<br>他很快就发现，很多汉口、长沙的知识分子说的道理，其实都是瞎想的，真实的农民说出来的和他们完全相反。<br>他把自己的所见所闻写成了一篇《湖南农民运动考察报告》。<br>但是，他是党内的少数分子，人微言轻，没有人接受他的主张。<br>1927年，中共五大，他提出“建立农民武装”，但再次遭到强烈反对，还被取消了投票表决权。<br>除了他，没有人真正意识到，广大的人民群众才是这个国家真正的主人。<br>正是这一年，蒋介石、汪精卫相继叛变革命，在全国大肆杀共产党。<br>秋收起义虽然如期举行，但还是失败了，尔后各大城市的起义也接连失利。<br>连续的失败终于让共产党明白了，在重兵防守的城市，共产党没有一点机会。<br>唯一的出路，是农村。<br>前面说到的美国记者埃德加·斯诺，后来在张学良的安排下，去了红军的根据地，他用自己在红军这里的真实见闻，写了一本《西行漫记》。<br>在《西行漫记》里，斯诺写道，自己见到了根据地一群年幼的孩子，就问那些还在玩耍的孩子：<br>“什么是共产党?”<br>“是帮着红军打白匪和日本的人。”一个八九岁的小孩脱口而出。<br>“还有呢?”<br>“他帮着打地主和资本家!”<br>“那什么是资本家?”<br>“资本家就是不自己干活，而让别人给他干活的人。”<br>“这里有地主或者资本家吗?”<br>“没有!”孩子们齐声一起大喊道：“他们都跑了!”<br>“跑了?干嘛跑了?”<br>“怕咱们的红军呗!”<br>一个小孩子，却说红军是“咱们的”军队，斯诺对此感到无比好奇。<br>斯诺又去问根据地的战士，为什么参加红军?喜欢红军吗?<br>战士说：“红军教我们读书和写字，教我们操纵无线电和怎么用步枪瞄准，红军是帮助穷人的。”<br>“红军待我们好，我们一回也没挨过打，这里人人都一样，不像在白区，穷人是地主和国民党的奴隶，这里人人打仗都是为了帮助穷人，为了救中国。<br>红军打地主，打白匪，红军打日本，怎么会有人不喜欢这样的队伍呢?”<br>红军每到一地，就会把土地分给穷人，减轻赋税，大规模兴办集体企业。<br>仅仅是1933年，江西一个省就有一千多个苏维埃合作社，在这里，妓女不再需要当妓女，农民不再需要种鸦片，儿童也不需要去地主家当奴婢。<br>红军的战士有来自四川的，有来自湖南的，有来自江西的。<br>这些战士要么是被地主剥削的农民，要么是被师傅虐待的学徒，要么是被国民党害死双亲的孩子。<br>战士没有衣服穿，毛泽东就把自己的衣服给他穿，战士没有鞋子，毛泽东就自己也不穿鞋子……<br>有个福建苏区的年轻战士，跟着红军走完了长征的全程，却一点都不把长征当回事，还说“如果红军再长征的话，我就再走两万五千里!”<br>这是受压迫的穷苦百姓第一次自己站起来，建立了一个属于自己的军队。<br>正是在红军这里，他们才第一次感受到，自己是被当做一个平等的人看待，能够有尊严地活着。<br>在红军刚到井冈山上的时候，井冈山上其实有两支农民武装。一个叫袁文才，一个叫王佐。<br>他们是当地的绿林好汉，占山为王。<br>一开始，有人觉得，需要消灭这两个人，他们觉得这就是两个土匪。<br>然而，毛泽东不这么认为，他调查过了，这个袁文才是客家人，因为反抗土豪劣绅的压迫参加了当地的马刀队，是被世道逼得落草为寇的，占山为王期间也是多次劫富济贫。<br>于是，毛泽东亲自去见了袁文才，和他聊了聊天，肯定了他反抗豪绅地主阶级的革命精神，然后告诉他光是占山为王是不够的，革命需要有组织有目标，最后还给他送了100多支枪。<br>袁文才当了多年的山大王，还是第一次碰到一个真正理解他苦衷的，了解他心意的人。<br>这一谈之后，不费一兵一卒，袁文才就主动欢迎红军来井冈山，愿意接受改编，从此跟着毛泽东。<br>毛泽东打心眼里把自己当成人民的一份子，人民也就心甘情愿地追随他。<br>斯诺采访的战士，一说起自己参军之后的故事都会兴高采烈，可以侃侃而谈每次战役的日期和过程。<br>但是一旦让他们讲述自己参军之前的事情，他们就需要回想好一阵子才能想起来。<br>用斯诺的话来说就是：<br>“他们倾向于把这段岁月视为黑暗年代，他们真正的生命，是从成为共产党人开始的!”<br>这样的一支队伍，在战场上无比坚韧。<br>飞夺泸定桥的时候，对岸的国民党军早已架好了机枪，第一批冲过去的人一定会被扫射而死，但是红军每一个人都知道，全军的生死都系于铁索桥上，这仗打不下来，自己和战友都要死。<br>于是，红军战士纷纷主动请战，背着手榴弹和毛瑟枪，攥着铁索一点一点往前挪。<br>第一个战士被打中，掉到急流中就没有了，紧接着是第二个第三个，但剩下的人还在不断顺着铁索前进，明知是死，也要夺下铁索桥!<br>对岸的川军从来没有见过这样打仗的人——这些光着脚，衣衫褴褛，只有十几岁的年轻人，当兵不是为了钱，不是为了混碗饭吃，而是为了胜利愿意舍生忘死。<br>打着打着，连对岸的川军都在默默盼望这些红军成功，红军冲过去朝国民党阵地进攻的时候，对岸有的国民党军立马扔下枪就投共了。<br>四渡赤水的时候，红军对国军是3万对40万，国军有飞机侦查，红军在当地没有原来根据地的群众基础，没有依靠。<br>国军对红军是压倒性的优势。<br>但是在毛泽东的指挥下，红军却能在国军的眼皮底子下晃点国军，把蒋介石骗得一愣一愣的。<br>美国作家索尔兹伯里曾在《长征：前所未闻的故事》中这么描写当时的场景：<br>“毛泽东故伎重演，而蒋介石却像巴甫洛夫训练出来的狗一样，毛泽东要他怎样，他就怎么样。”<br>毛主席用自己的实践，给出了那个无数前辈都没解决的问题的答案：<br>要拯救鹅城，推翻骑在人民头上的黄四郎，需要的是人民自己的力量，是一支由人民群众先锋队组成的军队。<br>在此之前的数千年，中国的执政者一直都解决不了中央权力到不了县、乡一级的问题，而在此之后，中国的十多亿人终于可以团结一心做大事。<br>在1925年，毛主席写下《沁园春·长沙》时，对于革命的前途还有点迷茫，虽心忧天下，但还是写道：<br>“怅寥廓，问苍茫大地，谁主沉浮?”<br>但仅仅到了1936年，他写《沁园春·雪》时，却已然成竹在胸，仿佛天下大势，尽在掌控：<br>“俱往矣，数风流人物，还看今朝!”</p><h2><span id="2">2</span></h2><p>在张牧之成为领导核心之后，打黄四郎的革命队伍就几乎再没有出过大战略判断上的失误。<br>如果有的话，可能是他觉得解放战争需要5年，但是蒋委员长鬼斧神工的操作把时间缩短到了3年。<br>无论是抗日战争还是解放战争中，革命队伍都面临过无数惊涛骇浪。<br>但你总能从毛泽东的诗句中感觉到，在一个充满光辉的理想主义者笔下，革命中那种血与火交织的浪漫感，会让一切风花雪月都黯然失色：<br>“五岭逶迤腾细浪，乌蒙磅礴走泥丸。金沙水拍云崖暖，大渡桥横铁索寒。”<br>“多少事，从来急;天地转，光阴迫。一万年太久，只争朝夕。四海翻腾云水怒，五洲震荡风雷激。”<br>“雄关漫道真如铁，而今迈步从头越。”……<br>新中国成立之前，从鸦片战争到日本侵华，随便一个工业国就可以骑在中国头上作威作福。<br>但是新中国刚刚成立，就可以在朝鲜半岛硬刚全世界最强大的军队，把对手一路逼退回三八线!<br>在前三十年里，印度、苏联、越南、美国都像以前的列强一样试探过中国，但新中国用自己的实力证明了，再强大的对手，也无法打断中国发展的脚步。<br>在革命的过程中，很多人都牺牲了，毛泽东的家人也不例外。<br>他的弟弟、他的妻子、他的妹妹、他的侄子，都是英烈，20多岁、30多岁就牺牲了。<br>毛岸英是毛泽东和杨开慧的长子，从小就吃过无数的苦，杨开慧被湖南军阀逮捕的时候，只有8岁的毛岸英也一同被抓进监狱。<br>后来，几经辗转，毛岸英被送到苏联学习。1941年，苏联和德国开打之后，尽管中苏之间有不让孩子服兵役的规定，但毛岸英还是主动要求参战。<br>1946年回到中国之后，毛岸英只跟在他的身边吃了两天饭，就被要求去机关食堂吃大灶。<br>后来，毛泽东又觉得儿子不仅要学知识，还要和工人一样参加劳动，“补上劳动大学这一课”。<br>毛岸英就按照父亲的要求，去解放区搞过土改，做过宣传工作，当过秘书，跟着李克农当过翻译，后来又去基层工厂当工人。<br>可以说，作为毛泽东的儿子，毛岸英从来没有享受过任何一点特权，反而总是战斗在最艰苦最危险的第一线。<br>朝鲜战争爆发后，毛岸英又主动要求，去参加了抗美援朝战争。<br>但不幸的是，1950年11月25日，在美军飞机的一次轰炸中，毛岸英牺牲了，成为了197653名志愿军烈士中的一个。<br>1951年，彭德怀回北京汇报第二次战役的时候，非常内疚地想要对毛主席道歉。<br>但是毛主席打断了彭德怀的话：“打仗哪有不死人的?志愿军战士死了成千上万，岸英就是属于牺牲了的成千上万革命烈士中的一员，一个普通的战士。<br>不要因为是我的儿子，就当成一件了不起的大事。不能因为是我的儿子，就不应该为中朝两国人民共同的事业而牺牲，哪儿有这样的道理?”<br>但其实，在刚得知毛岸英牺牲的时候，毛主席一度悲痛得吃不下饭，睡不着觉。<br>彭德怀离开之后，他站在窗前，默默地看着庭院里的松柏，无不伤感地念起了南朝庾信的《枯树赋》：<br>昔年种柳，依依汉南。今看摇落，凄怆江潭。<br>树犹如此，人何以堪!<br>毛岸英对自己的要求非常苛刻，即使自己已经付出了很多，已经非常优秀了，毛岸英还总是对自己不满意，想要做得更好。<br>毛岸英总是在日记里一遍一遍地问自己：“我做毛泽东的儿子合格吗?”。<br>在去朝鲜战场上之前，毛岸英又拿这个问题问了毛泽东一遍，但他只是说：“等你回来，爸爸给你个答复。”<br>谁成想，这次分别，就是天人永隔。<br>毛岸英牺牲之后，有无数的人往毛岸英的身上泼脏水，用各种各样编出来的“蛋炒饭”段子抹黑毛岸英，说毛岸英去朝鲜战场是去“镀金”的。<br>在很多影视作品里，毛岸英这个角色一出现，往往都被塑造成一个唯唯诺诺跟在父亲身边的木偶，完全不是真实的鲜活的人。<br>反而是蒋介石的儿子蒋经国，总是被拍成一个风度翩翩又能力超群的公子哥，什么“台湾民主之父”。<br>一个把自己的一切都奉献给了这个国家，每每战斗在最前线的人，被人说是镀金，要搞世袭。<br>一个正儿八经子承父业搞世袭的人，却被奉为“民主先锋”。<br>这简直是天大的讽刺。<br>可能在某些人的眼里，身为“他”的儿子，就是一种罪过，哪怕把心掏出来把肺掏出来，也是罪过。<br>毛岸英牺牲之后，毛泽东瞒着所有人，把儿子留下的两件棉衣、一双袜子、一顶军帽和一条毛巾，叠得整整齐齐，悄悄地收在了一个小箱子里。<br>这个箱子，他一直带在身边，珍藏了20多年，从来没有丢掉过。<br>也许，夜深人静的时候，毛主席还会拿出这些东西细细地看，想象着自己的儿子还活着，还在自己身边。<br>一直到1990年，在整理他的遗物时，工作人员才发现了这些东西。<br>我想，如果能重来一次，毛主席肯定想以一个父亲的身份，好好对毛岸英说上一句他心里想了很久，却始终没有机会说出口的话：<br>“儿子，爸爸为你感到骄傲。”</p><h2><span id="3">3</span></h2><p>鹅城和平了，张牧之赶走了黄四郎，也在朝鲜打跑了十八国联军。<br>但这并不代表革命就此结束，反而只是万里长征第一步的开始。<br>天底下没有人不会犯错，一个队伍壮大了，总会被腐蚀，总会出现有别的心思的人。<br>打倒了黄四郎，张牧之还想回山里，继续当他的革命者，可是张牧之的手下不干了。<br>老三老四不想回到山里，他们想去上海，他们想拿着师爷那里来的委任状，去当新的县长。<br>《让子弹飞》的最后，老三拉着和电影开头汤师爷一样的列车，奔往上海，留下了张牧之一个人。<br>而穿着汤师爷衣服的黄四郎，又坐在了列车后面。<br>历史的车轮还在滚滚前进，黄四郎的身影依然盘踞在革命者身边，阴魂不散。<br>历朝历代的故事，免不了都要落入同一个宿命：<br>屠龙的勇士守着如山的财宝，自己也逐渐变成了恶龙，然后等待下一个屠龙者来终结自己，数千年的封建王朝历史，都是如此地循环往复。<br>革命者始终无法回避的一个问题是——代表人民群众的先锋队被腐蚀了，该怎么办?<br>1965年，已经阔别井冈山36年的他突然提出：“我老了，经常梦到井冈山，很想回去看看……”<br>5月22日，他沿着当年秋收起义的路线，重新回到了那个让他魂牵梦绕的地方。<br>真正的革命者，始终要一把枪对着敌人，另一把枪对着自己。<br>在井冈山上，他挥毫写下了一首词——《水调歌头·重上井冈山》： 久有凌云志，重上井冈山。千里来寻故地，旧貌变新颜。 到处莺歌燕舞，更有潺潺流水，高路入云端。 过了黄洋界，险处不须看。 风雷动，旌旗奋，是人寰。 三十八年过去，弹指一挥间。 可上九天揽月，可下五洋捉鳖，谈笑凯歌还。 世上无难事，只要肯登攀。<br>张牧之又一次背叛了自己既得利益者的身份，再一次站到了人民这一边。<br>那时的他，还是那么豪情万丈，意气风发。<br>在他眼里，只要自己想做，这世上就没有什么事，是自己做不成的!<br>哪怕这次的对手，是亘古不变的兴亡铁律。<br>它看不见、摸不着，它盘亘在人心里，比国民党，比斯大林，比美帝，比他面对过的这个世界上任何一个敌人都更强大、更可怕!<br>但他依然敢说，“世上无难事，只要肯登攀!”<br>“今日欢呼孙大圣，只缘妖雾又重来”<br>其实，从参加革命的那一天起，毛泽东就是其中的“异类”。<br>革命的路上危险重重，并不是每个人都有坚定无比的信仰，大多数人都没有能够坚持走到最后。<br>一大一共13名代表，其中有4人牺牲，有3人叛变投敌，有2人成为汉奸，有2人脱离革命后又迷途知返。<br>从那条小船上坚定不移地走到新中国成立的人，只有他和董必武两个人。<br>1975年4月2日，董必武去世。<br>董必武去世的当天，毛主席把一首送别词，反复听了一整天，是南宋张元干的《贺新郎·送胡邦衡待制赴新州》：<br>梦绕神州路。怅秋风、连营画角，故宫离黍。<br>底事昆仑倾砥柱，九地黄流乱注。聚万落、千村狐兔。<br>天意从来高难问，况人情老易悲如许。更南浦，送君去。 凉生岸柳催残暑。耿斜河、疏星淡月，断云微度。 万里江山知何处，回首对床夜语。雁不到、书成谁与。 目尽青天怀今古，肯儿曹、恩怨相尔汝。举大白，听金缕。<br>也许是觉得最后“举大白，听金缕”两句太过伤感，他忍不住提起笔，把这两句改成了“君且去，休回顾”。<br>目尽青天怀今古，肯儿曹、恩怨相尔汝。君且去，休回顾。<br>这次也一样，张牧之依然是少数，他要净化被腐蚀的先锋队，老三和老四并不同意。<br>不止老三老四，当初一起上山的人，有的人已经忘了自己本也是穷苦人的出身，又开始骑到穷苦人身上作威作福。<br>从革命队伍诞生那一天起，这个问题就如影随形。<br>红军时期有个战士叫肖玉璧，穷苦人出身，给地主放马的，参加红军以后是有名的战斗英雄，战功赫赫，身上有90多处伤疤。<br>他受伤住院的时候，毛主席曾去医院看望他，当看到这个战斗英雄骨瘦如柴的时候，毛主席眼眶湿润，把自己特批的半斤牛奶全部送给了他。<br>然而，后来他居功自傲，当税务分局局长时贪污受贿，还把根据地很紧缺的粮、油偷偷倒卖给国民党，从中牟利。<br>事发被捕之后，按红军法院陕甘宁高等法院的判决是死刑。有很多战士给肖玉璧求情，说他是战斗英雄，希望网开一面，但毛泽东表示坚决拥护法院的判决，一定要枪毙他。<br>有的人没有忘，但“革命者内心潜藏的黄四郎”看不见摸不着，张牧之以往让他们打谁，他们说一不二。<br>但这次的对手，他们一辈子都没有碰到过，即使想打，他也不知道这样虚无缥缈的对手，要从哪里打起。<br>只有老二，始终站在张牧之的身边。<br>不少曾经的战友，成为了自己的敌人，他支持的人民群众也不理解他。<br>在《亮剑》里，1967年，李云龙的部队换了一个新政委，叫马天生。<br>让李云龙觉得奇怪的是，这个马政委1955年还是上校，怎么才过了12年，就爬到了正军级的位子?<br>结果一出事，李云龙就明白了。<br>这个马政委最大的本事，就是挑动其他人不要“文斗”，要去“武斗”，不要光写口号写大字报，要拿枪拿炮去“斗”，最好拼个你死我活。<br>明明本来是要自我净化，有些人却把事情扩大化，拿战友和人民的血换自己的前程。<br>马天生正是这种人，才会升官升得这么快。<br>人民群众的力量是伟大的，但是需要引导，没有引导的群众力量失控，就不可避免地会造成混乱。<br>“革命”可以，但是不能只会“革命”不会“生产”，只会“造反”，不会“建设”。<br>原先的战友不再和他站在一边，新起来的人有很多也不是真的理解他的本意，只是找到了一条升官很快的大路，只是想做一个“马天生”。<br>有好人被打成了坏人，有坏人被洗成了好人;有人公报私仇，有人趁机上位;有人只想“文斗”，有人醉心“武斗”……<br>事情发展到这个地步，已经彻底脱离了他原来的初衷。<br>他不得不重新拿起了笔，写了很多文件，告诉人民要怎么在“革命”的同时不要忘记生产，不要忘记建设。<br>但是他老了，他太势单力薄了，那些文件推行不下去，成了一张又一张的废纸。<br>张牧之举目四望，发现自己无比的孤独。<br>“四海龙王”水淹陈塘关<br>1975年，他已经垂垂老矣，做完白内障手术没多久，一只眼睛刚刚能看东西，他就去看书。<br>有一天，眼科大夫陪他看书，却发现看着看着，他突然发出一阵呜咽声。<br>大夫赶忙抬头，他不知为何，捧着古书哭了出来。<br>大夫赶紧起身去劝：“你不能哭，千万不能哭，眼睛要坏的!”<br>但是他还是控制不住自己，抱着古书，一时间哭得老泪纵横，肝肠寸断。<br>大夫靠近去看，他读的是南宋陈亮的词《念奴娇·登多景楼》：<br>危楼还望，叹此意、今古几人曾会。鬼设神施，浑认作、天限南疆北界。<br>一水横陈，连岗三面，做出争雄势。六朝何事，只成门户私计。 因笑王谢诸人，登高怀远，也学英雄涕。凭却长江管不到，河洛腥膻无际。<br>正好长驱，不须反顾，寻取中流誓。小儿破贼，势成宁问疆场。<br>六朝何事?只成门户私计。<br>那一刻，岁月塌了下来，重重地压在了他的身上。<br>他老了，他的时间不够了，他一个人的肩膀再也无法扛起这片天了。<br>他努力过，战斗过，和数千年的兴亡铁律殊死搏斗过，他真的如同太阳一样，把自己的生命都燃烧殆尽，只想要为天下苍生驱逐黑暗，鞠躬尽瘁，死而后已!<br>但是在残酷的现实面前，在顽固的人性面前，他一败涂地。</p><h2><span id="尾声">尾声</span></h2><p>1976年9月9日凌晨10分，他与世长辞。<br>他诞生的时候，这个国家积贫积弱，人均寿命只有35岁，全国80%的人都是文盲，有钢厂也找不到能胜任的工人。<br>随便一个帝国主义就可以逼得中国像饥民一样卖儿卖女，最繁华的上海滩，年年都是饿殍遍地，人们的眼前一片黑暗，看不到未来的出路。<br>他离开的时候，这个国家已经有了一整套完整的工业体系，人均寿命达到了65岁，文盲率降低到了20%，有数以亿计的产业工人。<br>大家能吃饱穿暖，能有尊严地活着，再没有国家能够欺负我们，后来的开放和飞速增长都有足够的基础，前途一片光明。<br>他引以为傲的两件大事之一虽然失败了，却提醒了后来的执政者，要在内部建立有效的自查自省的机制，时时注意自我纠正，防止无产阶级的先锋队腐蚀变质，不要走历朝历代的老路。<br>很多人年少的时候读不懂他，但时间越久，懂他的人就越多;时间越久，怀念他的人就越多。<br>没有黄四郎，对鹅城很重要。<br>在他死后，有无数宵小之辈又换了一身装束，重新粉墨登场，想要再在这个时代再当一次黄四郎。<br>他活着的时候，这些宵小都被治得服服帖帖，唯有在他死后，这些人才敢出来对他指指点点，阴阳怪气。<br>但是这些人也知道，他在人民群众心中的地位很高，直接攻击不成，这些人就编出各种各样的段子，旁敲侧击，抹黑他的战友，污蔑他的儿子，这些谣言七拐八拐，最终都会拐到他的身上。<br>但是，是非曲直，人民心中自有一杆秤。<br>他活着的时候，一直反对个人崇拜，老百姓对他喊万岁，他却总是回答说“人民万岁!”<br>如果没有他，今天的中国很可能会是另外一个模样。<br>但他却时刻提醒我们，功劳属于全体人民，虽然我们一个人的力量无比渺小，但是只要我们团结起来，那谁也无法欺负我们。<br>无论身前身后，全世界都有无数他的粉丝，景仰他、崇拜他的人数不胜数，无论是敌是友，对他的评价都极高。<br>但他却时时提醒我们，对谁也不要跪，这世上从来就没有什么救世主，也不靠神仙皇帝，要创造人类的幸福，全靠我们自己。<br>每一年的这个时候，都会有数万民众不惜坐十几个小时的火车，不惜翻山越岭，从全国各地自发赶去湖南韶山纪念他。<br>真正一心为民的人，人民永远不会忘记他。</p>]]></content>
    
    
      
      
    <summary type="html">&lt;blockquote&gt;
&lt;p&gt;最纯粹的革命者一定是那个一支枪对着自己，一支枪对着敌人，在心里装着最美好理想的人。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src=&quot;https://pic.tyzhang.top/images/2021/03/07/_20210307</summary>
      
    
    
    
    
    <category term="未分类" scheme="https://tyzhang.top/tags/%E6%9C%AA%E5%88%86%E7%B1%BB/"/>
    
  </entry>
  
  <entry>
    <title>我会玩个屁的星露谷物语</title>
    <link href="https://tyzhang.top/article/stardew/"/>
    <id>https://tyzhang.top/article/stardew/</id>
    <published>2021-01-17T16:00:00.000Z</published>
    <updated>2021-03-07T13:31:56.000Z</updated>
    
    <content type="html"><![CDATA[<blockquote><p>从网上搜罗来的星露谷物语的攻略，请让我快速变有钱吧。</p></blockquote><p>没想到我有一天会更新一篇游戏的博客。</p><p>在玩 NS 上的星露谷物语，玩了好久，花钱如流水挣钱如抽丝，很肝但就是攒不下钱来。网上找了一些玩法发现自己玩了个寂寞，网上找到了这篇攻略，放到这方便随时翻看。</p><p><strong>T。T 爷爷的心留在了星露谷，我的肝永远留在了星露谷 。</strong></p><h4><span id="基本框架">基本框架</span></h4><p><img src="https://pic.tyzhang.top/images/2021/01/18/1.jpg" alt="1.jpg"><br><img src="https://pic.tyzhang.top/images/2021/01/18/2.jpg" alt="2.jpg"><br><img src="https://pic.tyzhang.top/images/2021/01/18/3.jpg" alt="3.jpg"><br><img src="https://pic.tyzhang.top/images/2021/01/18/4.jpg" alt="4.jpg"><br><img src="https://pic.tyzhang.top/images/2021/01/18/5.jpg" alt="5.jpg"><br><img src="https://pic.tyzhang.top/images/2021/01/18/6.jpg" alt="6.jpg"><br><img src="https://pic.tyzhang.top/images/2021/01/18/7.jpg" alt="7.jpg"><br><img src="https://pic.tyzhang.top/images/2021/01/18/8.jpg" alt="8.jpg"></p><h4><span id="季节篇">季节篇</span></h4><p><img src="https://pic.tyzhang.top/images/2021/01/18/13c91de072cdaee80.jpg" alt="13c91de072cdaee80.jpg"><br><img src="https://pic.tyzhang.top/images/2021/01/18/296145ae8b125c795.jpg" alt="296145ae8b125c795.jpg"><br><img src="https://pic.tyzhang.top/images/2021/01/18/34c8953c33482e604.jpg" alt="34c8953c33482e604.jpg"><br><img src="https://pic.tyzhang.top/images/2021/01/18/47f0bba33e9573347.jpg" alt="47f0bba33e9573347.jpg"><br><img src="https://pic.tyzhang.top/images/2021/01/18/5e787e7f6263befba.jpg" alt="5e787e7f6263befba.jpg"><br><img src="https://pic.tyzhang.top/images/2021/01/18/6cd65edad0fda8250.jpg" alt="6cd65edad0fda8250.jpg"></p><h4><span id="职业篇">职业篇</span></h4><p><img src="https://pic.tyzhang.top/images/2021/01/18/10ded853bd8fe675b.jpg" alt="10ded853bd8fe675b.jpg"><br><img src="https://pic.tyzhang.top/images/2021/01/18/2f4f59dd125f9db0b.jpg" alt="2f4f59dd125f9db0b.jpg"><br><img src="https://pic.tyzhang.top/images/2021/01/18/3c9db9f4cf641000f.jpg" alt="3c9db9f4cf641000f.jpg"><br><img src="https://pic.tyzhang.top/images/2021/01/18/444cc820b6bf37fba.jpg" alt="444cc820b6bf37fba.jpg"><br><img src="https://pic.tyzhang.top/images/2021/01/18/5d41bdef00fef196c.jpg" alt="5d41bdef00fef196c.jpg"></p><hr><p>来源链接：<a href="https://www.xiaohongshu.com/discovery/item/5c67c384000000000d02c57b">https://www.xiaohongshu.com/discovery/item/5c67c384000000000d02c57b</a></p>]]></content>
    
    
      
      
    <summary type="html">&lt;blockquote&gt;
&lt;p&gt;从网上搜罗来的星露谷物语的攻略，请让我快速变有钱吧。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;没想到我有一天会更新一篇游戏的博客。&lt;/p&gt;
&lt;p&gt;在玩 NS 上的星露谷物语，玩了好久，花钱如流水挣钱如抽丝，很肝但就是攒不下钱来。网上找了一些玩法发</summary>
      
    
    
    
    
    <category term="游戏" scheme="https://tyzhang.top/tags/%E6%B8%B8%E6%88%8F/"/>
    
  </entry>
  
  <entry>
    <title>Word 中无法插入/打开 Visio 的解决</title>
    <link href="https://tyzhang.top/article/visioinword/"/>
    <id>https://tyzhang.top/article/visioinword/</id>
    <published>2021-01-10T16:00:00.000Z</published>
    <updated>2021-01-18T13:15:00.000Z</updated>
    
    <content type="html"><![CDATA[<blockquote><p>解决 Word 中”用于创建此对象的程序是 Visio，您的计算机尚未安装此程序。若要编辑此对象，您必须安装可以打开此对象的程序“。本方法不具备通用性，只是阐述一种解决的可能。</p></blockquote><p>今天在画图的时候发现我的 Word 没法正常插入 Visio，也没法对已有的 Visio 进行编辑。一直显示如下提示：</p><p><img src="https://img-blog.csdnimg.cn/20210111185612522.png" alt="Visio"></p><p>在网上查了好多方案，基本都是建议重装兼容版本或者按住 Alt 使用左键双击可解，不过对我都无济于事。</p><p>在我单独打开 Visio 时候发现了一个现象，Visio 询问是否允许使用管理员运行，但是 Word 直接就打开了。猜测因为 Word 权限不够没法调用，于是修改了一下 Visio 属性中的兼容性。</p><p>具体，右键 Visio/Word，属性，兼容性，取消勾选横线所示选项，意外解决。</p><p><img src="https://pic.tyzhang.top/images/2021/01/11/20210111185834914.png" alt="Visio"></p><p>注意本方法不具备通用性，只是阐述一种解决的可能。</p>]]></content>
    
    
      
      
    <summary type="html">&lt;blockquote&gt;
&lt;p&gt;解决 Word 中”用于创建此对象的程序是 Visio，您的计算机尚未安装此程序。若要编辑此对象，您必须安装可以打开此对象的程序“。本方法不具备通用性，只是阐述一种解决的可能。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;今天在画图的时候发现我的 W</summary>
      
    
    
    
    
    <category term="笔记" scheme="https://tyzhang.top/tags/%E7%AC%94%E8%AE%B0/"/>
    
  </entry>
  
  <entry>
    <title>2020 秋招笔记资料整理</title>
    <link href="https://tyzhang.top/article/notebook/"/>
    <id>https://tyzhang.top/article/notebook/</id>
    <published>2020-12-23T16:00:00.000Z</published>
    <updated>2021-03-17T11:31:14.000Z</updated>
    
    <content type="html"><![CDATA[<blockquote><p>这篇文章主要整理一下个人秋招过程中复习到的用到的资料、知识点。</p></blockquote><p>组里没有技术生态，缺乏找工作的祖传资料，特写此贴。</p><p>这些东西基本我都有看过，加粗为重点仔细看过，基础比较重要，文档后面的查漏补缺、锦上添花。还有一些内容我也有分类整理，在我的博客中可以查看。出来混迟早是要还的。</p><p>注意，本文主要是在准备找工作时候提纲挈领复习，而不是在技术积累的时候，即使用，也应该当作一个指路大纲使用。</p><p>更新于 2021年01月26日。</p><h3><span id="文档">文档</span></h3><ul><li><p><strong>Java 秋招必备.pdf</strong></p></li><li><p><strong>Java 面试手册.pdf</strong></p></li><li><p><strong>Java基础核心总结.pdf</strong></p></li><li><p><strong>JAVA核心面试知识整理.pdf</strong></p></li><li><p><strong>Java面试总结.pdf</strong></p></li><li><p>Redis精讲.pdf</p></li><li><p>数据库核心.pdf</p></li><li><p>杂.pdf</p></li><li><p>狂神说Spring.pdf</p></li><li><p>狂神说SpringMVC.pdf</p></li><li><p>计算机操作系统.pdf</p></li><li><p>计算机网络核心.pdf</p></li><li><p>重学Java设计模式.pdf</p><p><a href="http://download.tyzhang.top/files/JavaDocs.zip">下载</a></p></li></ul><h3><span id="基础">基础</span></h3><ul><li><strong><a href="https://blog.csdn.net/qq_41936805/article/details/104140091">Java校招面试知识点总结</a></strong></li><li><strong><a href="https://blog.csdn.net/u011240877/category_6447444.html">Java 集合源码深入理解系列</a></strong></li><li><a href="http://c.biancheng.net/view/1317.html">设计模式</a></li><li><a href="https://www.cnblogs.com/wuqinglong/p/9456193.html">Java 泛型类型擦除以及类型擦除带来的问题</a></li><li><a href="https://blog.csdn.net/whgtheone/article/details/82990139">解析——为什么单元素的枚举类型是单例模式的最佳实现</a></li><li><a href="https://blog.csdn.net/qq_45401061/article/details/104415653?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.channel_param&amp;depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.channel_param">为什么 synchronized 无法禁止指令重排，却能保证有序性?</a></li><li><a href="https://www.cnblogs.com/liyutian/p/10196044.html">Java 终止线程的三种方式</a></li><li><a href="https://www.cnblogs.com/xiuzhublog/p/12837168.html">Java 容器源码分析及常见面试题笔记</a></li></ul><h3><span id="刷题">刷题</span></h3><ul><li><strong><a href="https://www.nowcoder.com/ta/coding-interviews">剑指 Offer</a></strong></li><li><strong><a href="https://www.nowcoder.com/ta/sql">数据库 SQL 实战</a></strong></li><li><strong><a href="https://leetcode.com/">LeetCode</a> <a href="https://leetcode-cn.com/">中文站</a></strong></li><li><a href="https://coordinate.blog.csdn.net/">推荐结题报告</a></li></ul><h3><span id="框架">框架</span></h3><ul><li><a href="https://www.cnblogs.com/xrq730/category/941473.html">Spring 源码分析</a></li><li><a href="https://www.cnblogs.com/xrq730/category/994185.html">MyBatis 源码分析</a></li></ul><h3><span id="面经">面经</span></h3><ul><li><a href="https://www.nowcoder.com/discuss/120239">各大公司 Java 面试整理对应问题博客整理</a></li><li><a href="https://www.cnblogs.com/chen1005/p/10481102.html">Java 面试 208 题</a></li><li><a href="https://github.com/yifeikong/reverse-interview-zh">反向面试</a></li><li><a href="https://blog.csdn.net/qq_41735004/article/details/87199651?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param&amp;depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param">Java SSM 框架精选 50 道面试题</a></li><li><a href="https://blog.csdn.net/qq_41735004/article/details/86633997#comments_12556154">Java 基础精选 50 道面试题</a></li><li><a href="https://www.nowcoder.com/discuss/445445?channel=666&amp;source_id=home_feed">字节跳动面试手撕汇总</a></li></ul><h3><span id="主页">主页</span></h3><ul><li><a href="https://www.cnblogs.com/jyroy/">木偶Roy</a></li><li><a href="https://www.javanav.com/28.html">ConstXiong</a></li><li><a href="https://zx950519.github.io/">ZhouXiang</a></li><li><a href="https://zhenhuic.github.io/">Jeffrey</a></li><li><a href="https://blog.csdn.net/cheidou123">菜丸子</a></li></ul><h3><span id="bilibili-大学">Bilibili 大学</span></h3><ul><li><strong><a href="https://www.bilibili.com/video/BV1yE411Z7AP">深入理解 JVM</a></strong></li><li><a href="https://www.bilibili.com/video/BV16J411h7Rd">Java 并发编程</a></li><li><a href="https://space.bilibili.com/9880352/video">花花酱的LeetCode</a></li></ul><h3><span id="github-大学">GitHub 大学</span></h3><ul><li><strong><a href="https://github.com/ZingBug/Java-Notes">Java-Notes</a></strong></li><li><a href="https://github.com/doocs/advanced-java">Java 进阶</a></li><li><a href="https://github.com/Snailclimb/JavaGuide">Java Guide</a></li><li><strong><a href="https://cyc2018.github.io/CS-Notes/#/">CS-Node</a></strong></li><li><a href="https://github.com/justjavac/free-programming-books-zh_CN">编程书籍下载</a></li><li><strong><a href="https://github.com/afatcoder/LeetcodeTop">互联网公司 LeetCode 热门题目</a></strong></li><li><a href="https://doocs.github.io/jvm/#/">Java 虚拟机底层原理知识总结</a></li></ul><p><img src="https://pic.tyzhang.top/images/2020/12/06/20201203151632.jpg" alt></p>]]></content>
    
    
      
      
    <summary type="html">&lt;blockquote&gt;
&lt;p&gt;这篇文章主要整理一下个人秋招过程中复习到的用到的资料、知识点。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;组里没有技术生态，缺乏找工作的祖传资料，特写此贴。&lt;/p&gt;
&lt;p&gt;这些东西基本我都有看过，加粗为重点仔细看过，基础比较重要，文档后面的查漏补缺</summary>
      
    
    
    
    
    <category term="笔记" scheme="https://tyzhang.top/tags/%E7%AC%94%E8%AE%B0/"/>
    
  </entry>
  
  <entry>
    <title>Typora + PicGo 自动上传图片到 Chevereto 图床</title>
    <link href="https://tyzhang.top/article/autoupload/"/>
    <id>https://tyzhang.top/article/autoupload/</id>
    <published>2020-12-02T16:00:00.000Z</published>
    <updated>2021-01-18T13:15:50.000Z</updated>
    
    <content type="html"><![CDATA[<blockquote><p>Typora 配合 PicGo 自动上传图片到自己搭建的 Chevereto 图床指定的用户的相册下。</p></blockquote><p>看见刁总写的 <a href="http://diaowenjie.cn/2020/12/02/pictureGo.html">PicGo + Aliyun 的图床解决方案</a>，本来想着转移到他这个解决方案算了，想了想自己搭的图床，再折腾折腾吧。</p><p>在查找方案的时候，发现现行方案大多不如意，诸如只能上传到访客网络，下面的方案将解决这个问题，将图片上传至指定用户下的指定相册。分两部分介绍，一适用于仅自己使用的图床，图片将上传至访客相册，二是使用了别人搭建的图床并拥有帐号新建了相册，如果搭建者希望可以按照相册分门别类或者图床可以对所有用户 PicGo 有效，可直接参看二。</p><h3><span id="1-环境要求">1. 环境要求</span></h3><ul><li>Node.js</li><li>Chevereto 图床</li><li><a href="https://github.com/Molunerfinn/PicGo/releases">PicGo</a></li><li>Markdown 编辑工具 Typora</li></ul><h3><span id="2-自己搭建简略版">2.  自己搭建(简略版)</span></h3><ol><li><p>在 GUI 页面中安装 PicGo 插件支持第三方 API  <a href="https://github.com/yuki-xin/picgo-plugin-web-uploader">picgo-plugin-web-uploader</a>，或者 chevereto。</p><img src="https://pic.tyzhang.top/images/2020/12/03/20201203105931.png" alt="image-20201203105931412" style="zoom:50%;"></li><li><p>在自定义插件区设置自己使用的图床参数：</p><img src="https://pic.tyzhang.top/images/2020/12/02/image-20201202212549939.png" alt="image-20201202212549939" style="zoom:50%;"><p>对应的参数为，以 Chevereto 为例，API Key 在管理员控制台仪表盘设置中可以看到：</p><figure class="highlight properties"><table><tr><td class="gutter"><pre><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="attr">API</span> <span class="string">地址: https://your-site/api/1/upload</span></span><br><span class="line"><span class="attr">POST</span> <span class="string">参数名: source</span></span><br><span class="line"><span class="attr">JSON</span> <span class="string">路径: image.url</span></span><br><span class="line"><span class="attr">自定义</span> <span class="string">Body: &#123;&quot;key&quot;:&quot;API Key&quot;&#125;</span></span><br></pre></td></tr></table></figure><p>chevereto 设置如下：</p><img src="https://pic.tyzhang.top/images/2020/12/03/20201203143210.png" alt="image-20201203143210682" style="zoom:50%;"></li><li><p>修改 Typora 偏好设置中的图像设置，使用 PicGo 自动上传。</p><img src="https://pic.tyzhang.top/images/2020/12/02/image-20201202213328066.png" alt="image-20201202213328066" style="zoom:50%;"></li></ol><h3><span id="3-使用不属于自己搭建的图床">3. 使用不属于自己搭建的图床</span></h3><p>本节介绍当你使用了别人搭建的图床，如果想将图片上传至自己的账号下，详细设置方法。也可以作为搭建者，完善图床代码供所有用户使用 PicGo 方便上传。</p><ol><li><p>搭建者修改 Chevereto 源代码。</p><p>将网站根目录下<code>/app/routes/route.api.php</code>复制到同目录下的<code>/overrides</code>文件夹。该步骤使得复制后的文件在不替换的情况下更新，既保存源文件，又使修改后的代码能在源代码保留的情况下运行。</p><p>修改<code>/overrides/route.api.php</code>源代码如下，±对应新增删除代码，该步骤将接受来自客户端的用户名和相册 ID 参数，避免上传至访客相册：</p><p>网上大多解决方案写死了用户名和相册，这里修改为了可传参。</p><figure class="highlight php"><table><tr><td class="gutter"><pre><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="variable">$version</span> = <span class="variable">$handler</span>-&gt;request[<span class="number">0</span>];</span><br><span class="line"><span class="variable">$action</span> = <span class="variable">$handler</span>-&gt;request[<span class="number">1</span>];</span><br><span class="line">+ <span class="variable">$user</span> = <span class="variable">$_REQUEST</span>[<span class="string">&#x27;user&#x27;</span>];<span class="comment">// 新增</span></span><br><span class="line">+ <span class="variable">$album</span> = <span class="variable">$_REQUEST</span>[<span class="string">&#x27;album&#x27;</span>];<span class="comment">//新增</span></span><br></pre></td></tr></table></figure><figure class="highlight php"><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="comment">// CHV\Image::uploadToWebsite($source, &#x27;username&#x27;, [params]) to inject API uploads to a given username</span></span><br><span class="line">- <span class="variable">$uploaded_id</span> = CHV<span class="title class_">\Image</span>::<span class="title function_ invoke__">uploadToWebsite</span>(<span class="variable">$source</span>);</span><br><span class="line">+ <span class="variable">$uploaded_id</span> = CHV<span class="title class_">\Image</span>::<span class="title function_ invoke__">uploadToWebsite</span>(<span class="variable">$source</span>, <span class="variable">$user</span>, <span class="keyword">array</span>(<span class="string">&#x27;album_id&#x27;</span>=&gt;<span class="variable">$album</span>));</span><br></pre></td></tr></table></figure></li><li><p>使用者配置 PicGo。</p><ol><li><p>GUI版(Windows)</p><ol><li><p>下载安装 PicGo GUI 版，前往图床新建相册并获取相册 ID。</p><img src="https://pic.tyzhang.top/images/2020/12/03/image-20201203104821061.png" alt="image-20201203104821061" style="zoom:50%;"></li><li><p>在 <code>PicGo</code> 追加用户名和相册 ID，格式为<code>&#123;&quot;key&quot;:&quot;your key&quot;, &quot;user&quot;:&quot;username&quot;, &quot;album&quot;:&quot;albumid&quot;&#125;</code>。</p><img src="https://pic.tyzhang.top/images/2020/12/03/20201203105104.png" alt="image-20201203105039996" style="zoom:50%;"></li><li><p>在 <code>Typora</code> 偏好设置中测试。</p></li></ol></li><li><p>CLI 版(Windows &amp; macOS)</p><ol><li><p>在 Typora 安装 PicGo Core。</p><img src="https://pic.tyzhang.top/images/2020/12/03/image-20201203201355355.png" alt="image-20201203201355355" style="zoom:67%;"></li><li><p>修改配置文件如下，相应位置 key\user\album\url 也做替换。</p><figure class="highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="punctuation">&#123;</span></span><br><span class="line">  <span class="attr">&quot;picBed&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">    <span class="attr">&quot;uploader&quot;</span><span class="punctuation">:</span> <span class="string">&quot;web-uploader&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;current&quot;</span><span class="punctuation">:</span> <span class="string">&quot;web-uploader&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;transformer&quot;</span><span class="punctuation">:</span> <span class="string">&quot;path&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;web-uploader&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">      <span class="attr">&quot;customBody&quot;</span><span class="punctuation">:</span> <span class="string">&quot;&#123;\&quot;key\&quot;:\&quot;your key\&quot;, \&quot;user\&quot;:\&quot;ztygalaxy\&quot;, \&quot;album\&quot;:\&quot;1\&quot;&#125;&quot;</span><span class="punctuation">,</span></span><br><span class="line">      <span class="attr">&quot;customHeader&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">null</span></span><span class="punctuation">,</span></span><br><span class="line">      <span class="attr">&quot;jsonPath&quot;</span><span class="punctuation">:</span> <span class="string">&quot;image.url&quot;</span><span class="punctuation">,</span></span><br><span class="line">      <span class="attr">&quot;paramName&quot;</span><span class="punctuation">:</span> <span class="string">&quot;source&quot;</span><span class="punctuation">,</span></span><br><span class="line">      <span class="attr">&quot;url&quot;</span><span class="punctuation">:</span> <span class="string">&quot;https://your-site/api/1/upload&quot;</span></span><br><span class="line">    <span class="punctuation">&#125;</span></span><br><span class="line">  <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;picgoPlugins&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">    <span class="attr">&quot;picgo-plugin-web-uploader&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">true</span></span></span><br><span class="line">  <span class="punctuation">&#125;</span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br></pre></td></tr></table></figure></li><li><p>在 Windows 和 macOS 验证。</p><img src="https://pic.tyzhang.top/images/2020/12/03/image-20201203201719058eb0be95a8bd7b6e4.png" alt="image-20201203201719058" style="zoom:50%;"><img src="https://pic.tyzhang.top/images/2020/12/03/B6060F5824921FE6B6C6DDC22EB12CCF.png" alt="img" style="zoom: 33%;"></li></ol></li></ol></li></ol><h3><span id="4-参考">4. 参考</span></h3><ul><li><a href="https://blog.frytea.com/archives/459/">https://blog.frytea.com/archives/459/</a></li><li><a href="https://blog.csdn.net/qq_19564393/article/details/108506062">https://blog.csdn.net/qq_19564393/article/details/108506062</a></li><li>使用其他载体图床可参考：<a href="http://diaowenjie.cn/2020/12/02/pictureGo.html">http://diaowenjie.cn/2020/12/02/pictureGo.html</a></li></ul>]]></content>
    
    
      
      
    <summary type="html">&lt;blockquote&gt;
&lt;p&gt;Typora 配合 PicGo 自动上传图片到自己搭建的 Chevereto 图床指定的用户的相册下。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;看见刁总写的 &lt;a href=&quot;http://diaowenjie.cn/2020/12/02/pic</summary>
      
    
    
    
    
    <category term="笔记" scheme="https://tyzhang.top/tags/%E7%AC%94%E8%AE%B0/"/>
    
  </entry>
  
  <entry>
    <title>在 iPhone 自带邮箱上设置阿里企业邮箱</title>
    <link href="https://tyzhang.top/article/popmail/"/>
    <id>https://tyzhang.top/article/popmail/</id>
    <published>2020-11-17T16:00:00.000Z</published>
    <updated>2021-01-18T13:16:12.000Z</updated>
    
    <content type="html"><![CDATA[<blockquote><p>查了很多资料，基本上都无疾而终，这次成功了赶紧记录一下。</p></blockquote><p>在此之前配置好邮箱，确保能够网页正常登录。</p><p>打开 iPhone 设置 → 邮箱 → 添加账户，选择其他账户，添加邮件账户。</p><p>输入自己的账号和密码，其他会自动填写。</p><img src="https://pic.tyzhang.top/images/2020/11/18/_20201118175822.jpg" style="zoom: 33%;"><p>下一步填写其他信息，选择 POP，只需要红框内的信息即可，账号密码依旧是自己的。</p><p>其中服务器信息如下：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><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">POP 服务器 # pop3.mxhichina.com 端口110 SSL加密端口995</span><br><span class="line">IMAP 服务器 # imap.mxhichina.com 端口143 SSL加密端口993</span><br><span class="line">发件服务器</span><br><span class="line">SMTP 服务器 # smtp.mxhichina.com 端口25 SSL加密端口465</span><br></pre></td></tr></table></figure><img src="https://pic.tyzhang.top/images/2020/11/18/_20201118175817.jpg" style="zoom:33%;">]]></content>
    
    
      
      
    <summary type="html">&lt;blockquote&gt;
&lt;p&gt;查了很多资料，基本上都无疾而终，这次成功了赶紧记录一下。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;在此之前配置好邮箱，确保能够网页正常登录。&lt;/p&gt;
&lt;p&gt;打开 iPhone 设置 → 邮箱 → 添加账户，选择其他账户，添加邮件账户。&lt;/p&gt;
&lt;</summary>
      
    
    
    
    
    <category term="笔记" scheme="https://tyzhang.top/tags/%E7%AC%94%E8%AE%B0/"/>
    
  </entry>
  
  <entry>
    <title>也谈 URL 访问流程</title>
    <link href="https://tyzhang.top/article/url_road/"/>
    <id>https://tyzhang.top/article/url_road/</id>
    <published>2020-09-09T16:00:00.000Z</published>
    <updated>2021-01-18T13:16:38.000Z</updated>
    
    <content type="html"><![CDATA[<blockquote><p>当一个 URL 被敲进浏览器地址栏，会发生什么？这个问题回答起来不难，但是想讲清楚却不容易。</p></blockquote><h3><span id="引子">引子</span></h3><p>当一个 URL 被敲进浏览器地址栏，会发生什么？这个问题回答起来不难，但是想讲清楚却不容易。</p><p>最近面试的时候也有很多次被问到，总结一下，当然下文中也不是很全面，其中提到的一些知识点，还需要诸君自己探索。</p><p>很多时候被问问题不管什么问题，都有人觉得这玩意没什么讲的，这也需要讲？简简单单讲完了，自以为讲明白了。这里面一个很大的逻辑问题就是，你默认自己讲的就是标准答案了所以看到别人的面经会产生上边的疑问，实际上尽可能得多讲都不一定达到面试官想要的效果。笔者虽然面试经历不是很多，但大多数面试官对基础表示认可，有时间会写写自以为的面试经验。</p><h3><span id="流程">流程</span></h3><p>在打开网页过程中，较为简单的网页会直接发起请求并加载，有些较为复杂或者做过优化的网页，可能会有两种情况：</p><ul><li>HTML 页面加载</li><li>网页静态资源的加载</li></ul><p>下面是结合了一些博客之后总结下来的。</p><h4><span id="1-大概流程">1. 大概流程</span></h4><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><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">st=&gt;start: 开始</span><br><span class="line">end=&gt;end: 结束</span><br><span class="line">s1=&gt;operation: DNS 解析</span><br><span class="line">s2=&gt;operation: 负载均衡</span><br><span class="line">s3=&gt;operation: TCP 连接</span><br><span class="line">s4=&gt;operation: 发送 HTTP 请求</span><br><span class="line">s5=&gt;operation: Web 服务器处理请求</span><br><span class="line">s6=&gt;operation: 返回报文</span><br><span class="line">s7=&gt;operation: 浏览器渲染</span><br><span class="line">s8=&gt;operation: TCP 断开连接</span><br><span class="line">st-&gt;s1-&gt;s2-&gt;s3-&gt;s4-&gt;s5-&gt;s6-&gt;s7-&gt;s8-&gt;end</span><br></pre></td></tr></table></figure><h4><span id="2-页面加载具体分析">2. 页面加载具体分析</span></h4><h5><span id="21-dns-解析">2.1 DNS 解析</span></h5><p>输入 URL 之后，通常浏览器会进行 URL 解析，URL，例如 <code>https://tyzhang.top/posts/</code>一般包括几大部分：</p><ul><li>Protocol：协议头，例如，HTTP、HTTPS、FTP 等。</li><li>Host：主机域名或者直接是 IP 地址。</li><li>Port：端口号，一般都省略了，比如 80、8080、443。</li><li>Path：要访问的目录在网站的路径。</li></ul><p>解析完成后就要去进行 DNS 解析。何为 DNS 解析，网络中的主机都是使用 IP 地址来标识的，即 IP 地址才是主机在网络中的位置。域名只是为了方便记忆使用的。比如，我们访问 <a href="http://taobao.com">taobao.com</a>，要比访问它的 IP 地址容易得多，毕竟我们根本记不住那么多的 IP 地址。这也是为什么较短的域名比较值钱的原因。像早先罗永浩的锤子手机因为 LOGO 是个锤子 T 所以注册了 <code>t.tt</code>。我们接着看 DNS 的解析，解析遵循先己后他，由近到远的原则进行：</p><ol><li><p>浏览器拿到地址会首先搜索浏览器自身缓存的 DNS 记录，例如 Chrome 可以通过 <code>chrome://net-internals/#dns</code> 查看。</p></li><li><p>如果浏览器缓存中没有找到，则去查看 HOSTS 文件和操作系统的缓存。</p><ul><li>操作系统缓存，Windows 下可以使用 <code>ipconfig /displaydns</code> 查看。</li><li>其次在系统的指定位置，可以查看 HOSTS 文件，里面记录了域名和 IP 的对应结果。我们可以通过修改此文件的内容，更改映射关系，从而科学上网。</li></ul></li><li><p>如果 2 中的操作没有找到，就向域名服务器发送请求。</p><p>当前两步都没有命中的时候，开始向 DNS 服务器发送请求，即平时设置中填写的那个 DNS 服务器。这时候才算真正意义上的解析流程开始。一般用户都会去使用附近的域名解析服务器。</p></li><li><p>如果域名服务器也没有记录，开始递归 + 迭代解析。</p><p>先看一个架构图：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><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">graph TD</span><br><span class="line">top(根域服务器) --- l11(.com 域服务器)</span><br><span class="line">top(根域服务器) --- l13(...)</span><br><span class="line">top(根域服务器) --- l12(.cn 域服务器)</span><br><span class="line">l11(.com域服务器) --- l21(google.com 服务器)</span><br><span class="line">l11(.com域服务器) --- l22(...)</span><br><span class="line">l21(google.com 服务器) --- l31(mail.google.com 服务器)</span><br><span class="line">l21(google.com 服务器) --- l32(...)</span><br></pre></td></tr></table></figure><ul><li><p>首先我们的域名解析服务器会向根域服务器（全球只有 13 台）发出请求。显然，仅凭 13 台服务器不可能把全球所有IP都记录下来。所以根域服务器记录的是 com 域服务器的 IP、cn 域服务器的 IP、org 域服务器的 IP。如果我们要查找 .com 结尾的域名，那么我们可以到 com 域服务器去进一步解析。所以其实这部分的域名解析过程是一个树形的搜索过程。</p></li><li><p>根域服务器告诉我们 com 域服务器的 IP。接着我们的域名解析服务器会向 com 域服务器发出请求。<a href="http://xn--mail-u29f53r7ycxzupysbb86y50s.google.com">根域服务器并没有mail.google.com</a> 的 IP，但是却有 <a href="http://google.com">google.com</a> 域服务器的 IP。接着我们的域名解析服务器会向 <a href="http://google.com">google.com</a> 域服务器发出请求。如此重复，直到获得 <a href="http://mail.google.com">mail.google.com</a> 的 IP 地址。</p><p>为什么是递归：问题由一开始的本机要解析 <a href="http://mail.google.com">mail.google.com</a> 变成域名解析服务器要解析 <a href="http://mail.google.com">mail.google.com</a>，这是递归。</p><p>为什么是迭代：问题由向根域服务器发出请求变成向 com 域服务器发出请求再变成向 <a href="http://google.com">google.com</a> 域发出请求，这是迭代。</p></li></ul></li><li><p>获取域名对应的 IP 后，一步步向上返回，直到返回给浏览器。</p></li></ol><h5><span id="22-发起-tcp-请求">2.2 发起 TCP 请求</span></h5><p>浏览器会选择一个大于1024的本机端口向目标 IP 地址的 80 端口发起 TCP 连接请求。经过标准的 TCP 握手流程，建立 TCP 连接。这一部分就不再赘述，大家都是老建立链接了。</p><h5><span id="23-发起-http-请求">2.3 发起 HTTP 请求</span></h5><p><strong>流程：请求 -&gt; 请求报文 -&gt; 响应报文 -&gt; HTML 解析，构建 DOM 树 -&gt; 静态资源加载</strong></p><p>构建 HTTP 请求报文并通过 TCP 协议发送到服务器指定端口。</p><p>HTTP 请求报文是由三部分组成的，请求行、请求报头和请求正文。</p><p>请求行：常用方法有 GET, POST, PUT, DELETE, OPTIONS, HEAD。</p><p><strong>补充：POST 和 GET 的区别。</strong></p><p>请求报头：允许客户端向服务器传递请求的附加信息和客户端自身的信息。</p><p>请求正文：当使用 POST, PUT 等方法时，通常需要客户端向服务器传递数据。这些数据就储存在请求正文中。在请求包头中有一些与请求正文相关的信息，例如: 现在的 Web 应用通常采用 Rest 架构，请求的数据格式一般为 json。这时就需要设置 Content-Type: application/json。</p><p>服务器处理请求并返回 HTTP 报文。HTTP 响应报文也是由三部分组成：状态码,、响应报头和响应报文。</p><p><strong>状态码</strong></p><ul><li>1xx 【消息】服务器收到请求，需要请求者继续执行操作</li><li>2xx 【成功】请求已成功被服务器接收、理解、并接受。</li><li>3xx 【重定向】客户端需要采取进一步的操作以完成请求</li><li>4xx 【客户端请求错误】客户端错误，请求包含语法错误或无法完成请求</li><li>5xx 【服务器错误】服务器在处理请求的过程中发生了错误</li></ul><p><strong>HTTPS</strong></p><p>这里面会牵扯一些诸如 HTTP 和 HTTPS，HTTP 各个版本的差异，这里简单写一下。</p><p>简单来讲，HTTPS 和 HTTP 区别就是 HTTPS 会建立 SSL 链接，保证接下来的通信都是加密的，无法被截取分析。下面简述一下 SSL 握手过程。</p><ol><li>浏览器请求建立 SSL 链接，并向服务端发送一个随机数 A 和客户端支持的加密方法，比如 RSA 加密，此时是明文传输。</li><li>服务器从中选出一组加密算法和 Hash 算法，回复一个随机数 B，并将自己的身份信息以证书的形式发回给浏览器。证书中包含了网站地址、非对称加密公钥以及证书颁发机构等信息。</li><li>浏览器收到服务器的证书之后：<ol><li>验证证书的合法性。</li><li>用户接收证书之后，浏览器会产生新的随机数 C，然后使用证书中的公钥以及指定的加密方法加密 C 发给服务器。</li><li>利用 ABC 通过一定的算法生成 HTTP 链接数据传输的对称加密 Key。</li><li>使用约定好的 Hash 算法计算握手信息，并且使用生成的 Key 对消息进行加密，最后将之前生成的所有信息发送给服务端。</li></ol></li><li>服务器端操作：<ol><li>利用已知加解密方式与自己的私钥进行解密，获取 C。</li><li>和浏览器相同规则生成 Key。</li><li>使用 Key 解密浏览器握手消息，并验证 Hash 是否一致。</li><li>使用 Key 加密一段握手消息发送给浏览器。</li></ol></li><li>浏览器节米并计算握手消息的 Hash 值，如果和服务器发来的 Hash 值一致，握手结束。</li><li>此后都使用 Key 进行对称加密。</li></ol><p><strong>请求到请求被服务器接收</strong></p><ul><li>在<strong>应用层</strong>发送http请求；DNS 解析 IP 发送 HTTP 请求</li><li>到<strong>传输层</strong>通过三次握手建立 TCP/IP 连接；UDP</li><li>到<strong>网络层</strong>的IP寻址；IP 和 ARP</li><li>到<strong>数据链路层</strong>的封装成帧；</li><li>到<strong>物理层</strong>的利用物理介质传输；</li></ul><h5><span id="24-四次挥手结束">2.4 四次挥手结束</span></h5><h3><span id="3-静态资源加载">3. 静态资源加载</span></h3><p>什么是 CDN？如果我在山东访问杭州的淘宝网，跨省的通信必然造成延迟。如果淘宝网能在广东建立一个服务器，静态资源我可以直接从就近的广东服务器获取，必然能提高整个网站的打开速度，这就是 CDN。CDN 叫内容分发网络，是依靠部署在各地的边缘服务器，使用户就近获取所需内容，降低网络拥塞，提高用户访问响应速度。</p>]]></content>
    
    
      
      
    <summary type="html">&lt;blockquote&gt;
&lt;p&gt;当一个 URL 被敲进浏览器地址栏，会发生什么？这个问题回答起来不难，但是想讲清楚却不容易。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;&lt;span id=&quot;引子&quot;&gt;引子&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;当一个 URL 被敲进浏览器地址栏，会发生什么</summary>
      
    
    
    
    
    <category term="笔记" scheme="https://tyzhang.top/tags/%E7%AC%94%E8%AE%B0/"/>
    
  </entry>
  
  <entry>
    <title>算法解题报告 2020</title>
    <link href="https://tyzhang.top/article/algo/"/>
    <id>https://tyzhang.top/article/algo/</id>
    <published>2020-09-08T16:00:00.000Z</published>
    <updated>2021-01-18T13:23:14.000Z</updated>
    
    <content type="html"><![CDATA[<blockquote><p>人生短短两三年，转眼又到夏天，轮到我上战场了，本篇主要用于笔试面试中编程复盘。</p></blockquote><h3><span id="1-回文素数">1. 回文素数</span></h3><h4><span id="题目大意">题目大意</span></h4><p>现有一个正整数，希望去掉这个数中的某一个数字之后可以得到一个回文素数。</p><p>现在给两个数，在 [1, 1000000] 之间的满足上述条件的个数。</p><p>例如 110 120，他们之间的110、111、112、113、114、115、116、117、118、119去掉最后一位都是11回文素数。120 去掉哪一位都不行。</p><h4><span id="解题思路">解题思路</span></h4><p>当场暴力，27% 的样例，应该是数据量太大了，计算耗时。</p><p>下面题解的代码来源牛客，打表判断素数，然后每次取值计算回文就可以了。</p><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> java.util.Scanner;</span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Main</span> &#123;</span><br><span class="line">    <span class="keyword">final</span> <span class="keyword">static</span> <span class="type">int</span> <span class="variable">maxn</span> <span class="operator">=</span> <span class="number">1000000</span> + <span class="number">10</span>;</span><br><span class="line">    <span class="comment">// 素数备忘录</span></span><br><span class="line">    <span class="keyword">static</span> <span class="type">boolean</span>[] isp = <span class="keyword">new</span> <span class="title class_">boolean</span>[maxn];</span><br><span class="line">    <span class="keyword">static</span> <span class="type">int</span>[] pow = <span class="keyword">new</span> <span class="title class_">int</span>[<span class="number">10</span>];</span><br><span class="line"></span><br><span class="line">    <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">init</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="comment">// 打表，备忘录，全部初始化给 false</span></span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; maxn; i++) &#123;</span><br><span class="line">            isp[i] = <span class="literal">true</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        isp[<span class="number">0</span>] = <span class="literal">false</span>;</span><br><span class="line">        isp[<span class="number">1</span>] = <span class="literal">false</span>;</span><br><span class="line">        <span class="comment">// 素数的倍数就不是素数，一并处理</span></span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">2</span>; i &lt; maxn; i++) &#123;</span><br><span class="line">            <span class="keyword">if</span> (isp[i] == <span class="literal">true</span>) &#123;</span><br><span class="line">                <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">j</span> <span class="operator">=</span> i + i; j &lt; maxn; j += i) &#123;</span><br><span class="line">                    isp[j] = <span class="literal">false</span>;</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        pow[<span class="number">0</span>] = <span class="number">1</span>;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">1</span>; i &lt; <span class="number">8</span>; i++) &#123;</span><br><span class="line">            pow[i] = pow[i - <span class="number">1</span>] * <span class="number">10</span>;</span><br><span class="line">        &#125;</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="keyword">static</span> <span class="type">int</span> <span class="title function_">solve</span><span class="params">(<span class="type">int</span> i, <span class="type">int</span> j)</span> &#123;</span><br><span class="line">        <span class="comment">// 123456 要扣掉 4 即 i = 2的时候，pow = 100，12356 = (56 = 123456 % 100) + (12300 = 123456 / 1000 * 100)</span></span><br><span class="line">        <span class="type">int</span> <span class="variable">ans</span> <span class="operator">=</span> <span class="number">0</span>;</span><br><span class="line">        ans += i % pow[j];</span><br><span class="line">        ans += i / pow[j + <span class="number">1</span>] * pow[j];</span><br><span class="line">        <span class="keyword">return</span> ans;</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">static</span> <span class="type">boolean</span> <span class="title function_">isr</span><span class="params">(String num)</span> &#123;</span><br><span class="line">        <span class="type">boolean</span> <span class="variable">res</span> <span class="operator">=</span> <span class="literal">true</span>;</span><br><span class="line">        <span class="type">int</span> <span class="variable">length</span> <span class="operator">=</span> num.length();</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; length / <span class="number">2</span>; i++) &#123;</span><br><span class="line">            <span class="keyword">if</span> (num.charAt(i) != num.charAt(length - i - <span class="number">1</span>)) &#123;</span><br><span class="line">                res = <span class="literal">false</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">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line">        init();</span><br><span class="line">        <span class="type">int</span> n, m;</span><br><span class="line">        <span class="type">Scanner</span> <span class="variable">sc</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">Scanner</span>(System.in);</span><br><span class="line">        n = sc.nextInt();</span><br><span class="line">        m = sc.nextInt();</span><br><span class="line">        <span class="type">int</span> <span class="variable">ans</span> <span class="operator">=</span> <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> n; i &lt;= m; i++) &#123;</span><br><span class="line">            <span class="comment">// 长度</span></span><br><span class="line">            <span class="type">int</span> <span class="variable">length</span> <span class="operator">=</span> String.valueOf(i).length();</span><br><span class="line">            <span class="comment">// 从 最后一个位置开始扣</span></span><br><span class="line">            <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">j</span> <span class="operator">=</span> <span class="number">0</span>; j &lt; length; j++) &#123;</span><br><span class="line">                <span class="type">int</span> <span class="variable">buf</span> <span class="operator">=</span> solve(i, j);</span><br><span class="line">                <span class="comment">// 处理后的数既要是素数也要是会问</span></span><br><span class="line">                <span class="keyword">if</span> (isp[buf] &amp;&amp; isr(String.valueOf(buf))) &#123;</span><br><span class="line">                    <span class="comment">// 有就行</span></span><br><span class="line">                    ans++;</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">        System.out.println(ans);</span><br><span class="line">        sc.close();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3><span id="2-求数字在数组中第一次出现的位置">2. 求数字在数组中第一次出现的位置</span></h3><h4><span id="题目大意">题目大意</span></h4><p>给定数组 a = { 3,4,5,6,5,6,7,8,9,8}， <strong>这个数组相邻元素之差都为1</strong>， 给定数字9， 它在数组中第一次出现的位置下标为8。</p><h4><span id="解题思路">解题思路</span></h4><ol><li>蛮力法，直接for，复杂度为O(n)。</li><li>跳跃搜索法，首先用数组中第一个元素3和9比较，差值为6，由于相邻两个元素的差值为1，因此9在数组中出现的最早的位置必定为1+6=第七个位置，下标为6。如果数组是递增的，那么数组第七个元素为9，否则肯定在第七个后面。</li></ol><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><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="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">findIndex</span><span class="params">(<span class="type">int</span>[] a, <span class="type">int</span> val)</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> (a == <span class="literal">null</span> || a.length == <span class="number">0</span>) <span class="keyword">return</span> -<span class="number">1</span>;</span><br><span class="line">        <span class="type">int</span> <span class="variable">len</span> <span class="operator">=</span> a.length;</span><br><span class="line">        <span class="type">int</span> <span class="variable">index</span> <span class="operator">=</span> <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">while</span> (index &lt; len) &#123;</span><br><span class="line">            <span class="keyword">if</span> (a[index] == val) &#123;</span><br><span class="line">                <span class="keyword">return</span> index;</span><br><span class="line">            &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                index += Math.abs(val - a[index]);</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><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3><span id="3-咖啡店买咖啡">3. 咖啡店买咖啡</span></h3><h4><span id="题目大意">题目大意</span></h4><p>每杯咖啡 5 元，每位客户只买一杯咖啡，支付面额为5，10，20，购物之后根据面额给客户找零。开始备用零钱为0。</p><p>按照客户购买顺序，返回是否可以正确找零钱以及当前客户顺序号。</p><p>如果能正确找零，就返回最后一个客户的顺序号，如果不能找零，返回当前客户的顺序号。客户编号从1开始。</p><p>约束，顾客数量限制在100以内。</p><p>输入一串数字，表示每次顾客支付的金额。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><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">输入：5,5,5,10</span><br><span class="line">输出：true,4</span><br><span class="line">输入：10,10</span><br><span class="line">输出：false,1</span><br><span class="line">输入：3,5</span><br><span class="line">输出：false,1// 因为3不够，直接拜拜</span><br></pre></td></tr></table></figure><h4><span id="解题思路">解题思路</span></h4><p>这道题在现场做题的时候，卡了很久，说越界，我就怎么也找不到越界。后来快交卷时候才发现，数字用，分割的。</p><p>开始想现在有多少的零钱就可以了，每次买就更新。但实际上，很有可能钱足够但是没法找零，例如手中有20整钱但是没法找给别人15。</p><p>主要还是模拟找零。</p><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Coffe</span> &#123;</span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">static</span> <span class="type">int</span> <span class="variable">five</span> <span class="operator">=</span> <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">static</span> <span class="type">int</span> <span class="variable">ten</span> <span class="operator">=</span> <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">static</span> <span class="type">int</span> <span class="variable">twenty</span> <span class="operator">=</span> <span class="number">0</span>;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="type">boolean</span> <span class="title function_">buy</span><span class="params">(<span class="type">int</span> givenMoney)</span> &#123;</span><br><span class="line">        <span class="keyword">switch</span> (givenMoney) &#123;</span><br><span class="line">            <span class="keyword">case</span> <span class="number">5</span>:</span><br><span class="line">                five++;</span><br><span class="line">                <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line">            <span class="keyword">case</span> <span class="number">10</span>:</span><br><span class="line">                <span class="keyword">if</span> (five &gt; <span class="number">0</span>) &#123;</span><br><span class="line">                    ten++;</span><br><span class="line">                    five--;</span><br><span class="line">                    <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line">                &#125; <span class="keyword">else</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">case</span> <span class="number">20</span>:</span><br><span class="line">                <span class="keyword">if</span> (five &gt; <span class="number">0</span> &amp;&amp; ten &gt; <span class="number">0</span>) &#123;</span><br><span class="line">                    five--;</span><br><span class="line">                    ten--;</span><br><span class="line">                    twenty++;</span><br><span class="line">                    <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line">                &#125; <span class="keyword">else</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">default</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><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">solve</span><span class="params">(List&lt;Integer&gt; lists)</span> &#123;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; lists.size(); i++) &#123;</span><br><span class="line">            <span class="keyword">if</span> (!buy(lists.get(i))) &#123;</span><br><span class="line">                System.out.println(<span class="string">&quot;false,&quot;</span> + (++i));</span><br><span class="line">                <span class="keyword">return</span>;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        System.out.println(<span class="string">&quot;true,&quot;</span> + (lists.size()));</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line">        <span class="type">Scanner</span> <span class="variable">sc</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">Scanner</span>(System.in);</span><br><span class="line">        String[] strs = sc.nextLine().split(<span class="string">&quot;,&quot;</span>);</span><br><span class="line">        ArrayList&lt;Integer&gt; arrayList = <span class="keyword">new</span> <span class="title class_">ArrayList</span>&lt;&gt;();</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; strs.length; i++) &#123;</span><br><span class="line">            arrayList.add(Integer.parseInt(strs[i]));</span><br><span class="line">        &#125;</span><br><span class="line">        solve(arrayList);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3><span id="4-固定步长走迷宫">4. 固定步长走迷宫</span></h3><h4><span id="题目大意">题目大意</span></h4><p>小明要通过一个未完工的矩形路面，只有部分地区铺设了地板砖，判断能否按照固定步长N通过该区域。</p><p>输入，第一行为步长S，S&gt;0。</p><p>第二行为区域矩阵的行数 M 和列数 N，0 &lt; M,N &lt;= 100。</p><p>第三行开始为 M*N 的矩阵，0表示没有地砖，无法下脚，1表示可以落脚。小明从左上角出发，要到右下角，这两个角保证为1。</p><p>可以输出1，不可以输出0。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><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><br><span class="line">2</span><br><span class="line">3 5</span><br><span class="line">1 0 1 0 0</span><br><span class="line">0 1 1 0 1</span><br><span class="line">0 0 1 0 1</span><br><span class="line">输出：</span><br><span class="line">1</span><br><span class="line">小明可以沿着(0,0)(0,2)(2,2)(2,4)</span><br></pre></td></tr></table></figure><h4><span id="解题思路">解题思路</span></h4><p>这道题其实是一道深搜题目，就是把步长变为了指定的。同时因为瓷砖有些不能过，所以给一个备忘录，记录谁被访问了，谁没有瓷砖不能访问，这里使用了原数组置为2表示访问过了。</p><p>找的时候就要找，没访问过的还要有瓷砖的，即1的。当找到右下角的瓷砖的话，就更新找到的flag。</p><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="keyword">import</span> java.util.Scanner;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Main</span> &#123;</span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">static</span> <span class="type">int</span> s, m, n;</span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">static</span> <span class="type">int</span>[][] grid;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">dfs</span><span class="params">(<span class="type">int</span> i, <span class="type">int</span> j)</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> (i &gt;= m || j &gt;= n || grid[i][j] == <span class="number">2</span>) &#123;</span><br><span class="line">            <span class="keyword">return</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        grid[i][j] = <span class="number">2</span>;</span><br><span class="line">        <span class="keyword">if</span> (j + s &lt; n &amp;&amp; grid[i][j + s] == <span class="number">1</span>) &#123;</span><br><span class="line">            dfs(i, j + s);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span> (i + s &lt; m &amp;&amp; grid[i + s][j] == <span class="number">1</span>) &#123;</span><br><span class="line">            dfs(i + s, j);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span> (j &gt;= s &amp;&amp; grid[i][j - s] == <span class="number">1</span>) &#123;</span><br><span class="line">            dfs(i, j - s);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span> (i &gt;= s &amp;&amp; grid[i - s][j] == <span class="number">1</span>) &#123;</span><br><span class="line">            dfs(i - s, 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">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line">        <span class="type">Scanner</span> <span class="variable">sc</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">Scanner</span>(System.in);</span><br><span class="line">        s = sc.nextInt();</span><br><span class="line">        m = sc.nextInt();</span><br><span class="line">        n = sc.nextInt();</span><br><span class="line">        grid = <span class="keyword">new</span> <span class="title class_">int</span>[m][n];</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; m; i++) &#123;</span><br><span class="line">            <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">j</span> <span class="operator">=</span> <span class="number">0</span>; j &lt; n; j++) &#123;</span><br><span class="line">                grid[i][j] = sc.nextInt();</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        dfs(<span class="number">0</span>, <span class="number">0</span>);</span><br><span class="line">        System.out.println(grid[m - <span class="number">1</span>][n - <span class="number">1</span>] == <span class="number">2</span>?<span class="number">1</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><h3><span id="5-按照要求输出">5. 按照要求输出</span></h3><h4><span id="题目大意">题目大意</span></h4><p>给定一个字符串以及一个奇数数字表示奇数列，按照从左到右从上到下的顺序排成指定的列数。例如，EVERYTHINGGOESWELL，指定列数为3的情况下，排列为：</p><p><img src="https://pic.tyzhang.top/images/2020/08/13/image.png" alt="按照要求输出"></p><p>然后按列读取拼接字符串，ERHGEEETNOWLVYIGSL。</p><h4><span id="解题思路">解题思路</span></h4><p>全模拟，使用arraylist作为桶容器，按照对向输出添加。从两边往中间靠拢，相遇后离开。</p><p><img src="https://pic.tyzhang.top/images/2020/08/13/image395b3aca974206a1.png" alt="按照要求输出"></p><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="keyword">import</span> java.util.ArrayList;</span><br><span class="line"><span class="keyword">import</span> java.util.Scanner;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line">        <span class="comment">// 输入格式处理</span></span><br><span class="line">        <span class="type">Scanner</span> <span class="variable">sc</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">Scanner</span>(System.in);</span><br><span class="line">        <span class="type">String</span> <span class="variable">str</span> <span class="operator">=</span> sc.nextLine();</span><br><span class="line">        String strs[] = str.split(<span class="string">&quot;,&quot;</span>);</span><br><span class="line">        str = strs[<span class="number">0</span>];</span><br><span class="line">        <span class="type">int</span> <span class="variable">n</span> <span class="operator">=</span> Integer.parseInt(strs[<span class="number">1</span>]);</span><br><span class="line">        <span class="comment">// 使用ArrayList作为每一列的桶容器</span></span><br><span class="line">        ArrayList&lt;Character&gt;[] arrayLists = <span class="keyword">new</span> <span class="title class_">ArrayList</span>[n];</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">k</span> <span class="operator">=</span> <span class="number">0</span>; k &lt; n; k++) &#123;</span><br><span class="line">            arrayLists[k] = <span class="keyword">new</span> <span class="title class_">ArrayList</span>&lt;&gt;();</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>;</span><br><span class="line">        <span class="comment">// 靠拢标准，true表示靠拢</span></span><br><span class="line">        <span class="type">boolean</span> <span class="variable">flag</span> <span class="operator">=</span> <span class="literal">true</span>;</span><br><span class="line">        <span class="comment">// 桶索引</span></span><br><span class="line">        <span class="type">int</span> <span class="variable">l</span> <span class="operator">=</span> <span class="number">0</span>, r = n - <span class="number">1</span>;</span><br><span class="line">        <span class="keyword">while</span> (i &lt; str.length()) &#123;</span><br><span class="line">            <span class="comment">// 两边相遇，加到桶里，同时置靠拢标志false</span></span><br><span class="line">            <span class="keyword">if</span> (l == r) &#123;</span><br><span class="line">                arrayLists[l].add(str.charAt(i++));</span><br><span class="line">                l--;</span><br><span class="line">                r++;</span><br><span class="line">                flag = <span class="literal">false</span>;</span><br><span class="line">                <span class="keyword">continue</span>;</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="comment">// 当l=0，表示l已经归位，需要重新靠拢</span></span><br><span class="line">            <span class="keyword">if</span> (l == <span class="number">0</span>) &#123;</span><br><span class="line">                flag = <span class="literal">true</span>;</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="comment">// 靠拢，因为涉及i++，所以第一行语句执行完，需要判断边界。</span></span><br><span class="line">            <span class="keyword">if</span> (flag) &#123;</span><br><span class="line">                arrayLists[l++].add(str.charAt(i++));</span><br><span class="line">                <span class="keyword">if</span> (i == str.length()) <span class="keyword">break</span>;</span><br><span class="line">                arrayLists[r--].add(str.charAt(i++));</span><br><span class="line">            &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                <span class="comment">// 离散</span></span><br><span class="line">                arrayLists[l--].add(str.charAt(i++));</span><br><span class="line">                <span class="keyword">if</span> (i == str.length()) <span class="keyword">break</span>;</span><br><span class="line">                arrayLists[r++].add(str.charAt(i++));</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="type">StringBuilder</span> <span class="variable">sb</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">StringBuilder</span>();</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">k</span> <span class="operator">=</span> <span class="number">0</span>; k &lt; arrayLists.length; k++) &#123;</span><br><span class="line">            <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">j</span> <span class="operator">=</span> <span class="number">0</span>; j &lt; arrayLists[k].size(); j++) &#123;</span><br><span class="line">                sb.append(arrayLists[k].get(j));</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        System.out.println(sb.toString());</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3><span id="6-最近斐波那契数">6. 最近斐波那契数</span></h3><h4><span id="题目描述">题目描述</span></h4><p>找出给定数字最近的斐波那契数。</p><h4><span id="解题思路">解题思路</span></h4><p>常数空间解斐波那契数的时候，会存放两个值，一个小f1一个大f2，找到n位于中间的时候，比较一下两个谁最近就好了。</p><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><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="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Main</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line">        <span class="type">int</span> <span class="variable">n</span> <span class="operator">=</span> <span class="number">8</span>;</span><br><span class="line">        <span class="type">int</span> <span class="variable">f1</span> <span class="operator">=</span> <span class="number">1</span>;</span><br><span class="line">        <span class="type">int</span> <span class="variable">f2</span> <span class="operator">=</span> <span class="number">1</span>;</span><br><span class="line">        <span class="keyword">while</span> (n &gt;= f2) &#123;</span><br><span class="line">            <span class="type">int</span> <span class="variable">tmp</span> <span class="operator">=</span> f1;</span><br><span class="line">            f1 = f2;</span><br><span class="line">            f2 = f2 + tmp;</span><br><span class="line">        &#125;</span><br><span class="line">        System.out.println((Math.min(n - f1, f2 - n) == n - f1)? f1: f2);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3><span id="7-24-点">7. 24 点</span></h3><h4><span id="题目大意">题目大意</span></h4><p>LeetCode 679，有 4 张写有 1 到 9 数字的牌。你需要判断是否能通过 *，/，+，-，(，) 的运算得到 24。</p><h4><span id="解题思路">解题思路</span></h4><p>暴力搜索。</p><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="keyword">import</span> java.util.ArrayList;</span><br><span class="line"><span class="keyword">import</span> java.util.HashSet;</span><br><span class="line"><span class="keyword">import</span> java.util.List;</span><br><span class="line"><span class="keyword">import</span> java.util.Set;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="type">boolean</span> <span class="title function_">judgePoint24</span><span class="params">(<span class="type">int</span>[] nums)</span> &#123;</span><br><span class="line">        List&lt;Double&gt; numbers = <span class="keyword">new</span> <span class="title class_">ArrayList</span>&lt;Double&gt;();</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> num : nums) &#123;</span><br><span class="line">            numbers.add((<span class="type">double</span>) num);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> solve(numbers);</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 class="doctag">@description</span> 回溯法，从数组中选出两个数，把运算结果加到数组中</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="keyword">private</span> <span class="type">boolean</span> <span class="title function_">solve</span><span class="params">(List&lt;Double&gt; numbers)</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> (numbers.size() == <span class="number">1</span>) &#123;<span class="comment">//数组中只剩下一个数的时候判断结果</span></span><br><span class="line">            <span class="keyword">return</span> Math.abs(numbers.get(<span class="number">0</span>) - <span class="number">24</span>) &lt; <span class="number">1e-6</span>;<span class="comment">//看是否与24相等</span></span><br><span class="line">        &#125;</span><br><span class="line">        <span class="comment">//从numbers中取出两个数，把结果放入数组中</span></span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; numbers.size(); i++) &#123;</span><br><span class="line">            <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">j</span> <span class="operator">=</span> <span class="number">0</span>; j &lt; numbers.size(); j++) &#123;</span><br><span class="line">                <span class="keyword">if</span> (i != j) &#123;<span class="comment">//取不同的两个数</span></span><br><span class="line">                    <span class="comment">//如果回溯的话，还要恢复现场，把数插回原位置，所以不如直接生成一个新数组</span></span><br><span class="line">                    List&lt;Double&gt; nums = <span class="keyword">new</span> <span class="title class_">ArrayList</span>&lt;Double&gt;();</span><br><span class="line">                    <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">k</span> <span class="operator">=</span> <span class="number">0</span>; k &lt; numbers.size(); k++) &#123;</span><br><span class="line">                        <span class="keyword">if</span> (k != i &amp;&amp; k != j) &#123;<span class="comment">//把剩下的数加入到新数组</span></span><br><span class="line">                            nums.add(numbers.get(k));</span><br><span class="line">                        &#125;</span><br><span class="line">                    &#125;</span><br><span class="line">                    Set&lt;Double&gt; doubles = calculate(numbers.get(i), numbers.get(j));<span class="comment">//获取两个数运算的结果集</span></span><br><span class="line">                    <span class="keyword">for</span> (Double aDouble : doubles) &#123;</span><br><span class="line">                        nums.add(aDouble);<span class="comment">//把两个数运算的结果，分别加入到新数组中</span></span><br><span class="line">                        <span class="keyword">if</span> (solve(nums)) &#123;<span class="comment">//找到一个结果，立即返回</span></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">                        nums.remove(nums.size() - <span class="number">1</span>);<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 class="keyword">return</span> <span class="literal">false</span>;<span class="comment">//如果没有找到结果，返回false</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">     * <span class="doctag">@description</span> 返回两个数计算得到的结果集</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="keyword">private</span> Set&lt;Double&gt; <span class="title function_">calculate</span><span class="params">(<span class="type">double</span> a, <span class="type">double</span> b)</span> &#123;</span><br><span class="line">        Set&lt;Double&gt; res = <span class="keyword">new</span> <span class="title class_">HashSet</span>&lt;Double&gt;();</span><br><span class="line">        res.add(a - b);</span><br><span class="line">        res.add(b - a);</span><br><span class="line">        res.add(a + b);</span><br><span class="line">        res.add(a * b);</span><br><span class="line">        <span class="keyword">if</span> (a != <span class="number">0</span>) &#123;</span><br><span class="line">            res.add(b / a);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span> (b != <span class="number">0</span>) &#123;</span><br><span class="line">            res.add(a / b);</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><h3><span id="8-括号匹配">8. 括号匹配</span></h3><h4><span id="题目大意">题目大意</span></h4><p>判断字符串中的括号是不是符合成对出现的规律。</p><h4><span id="解题思路">解题思路</span></h4><p>直接用栈判断就可以了，利用 HashMap 的 containsKey 和 value 函数解决括号匹配。</p><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="type">boolean</span> <span class="title function_">isValid</span><span class="params">(String s)</span> &#123;</span><br><span class="line">        HashMap&lt;Character, Character&gt; map = <span class="keyword">new</span> <span class="title class_">HashMap</span>&lt;&gt;();</span><br><span class="line">        map.put(<span class="string">&#x27;&#123;&#x27;</span>,<span class="string">&#x27;&#125;&#x27;</span>);</span><br><span class="line">        map.put(<span class="string">&#x27;(&#x27;</span>,<span class="string">&#x27;)&#x27;</span>);</span><br><span class="line">        map.put(<span class="string">&#x27;[&#x27;</span>,<span class="string">&#x27;]&#x27;</span>);</span><br><span class="line">        Stack&lt;Character&gt; stack = <span class="keyword">new</span> <span class="title class_">Stack</span>&lt;&gt;();</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i&lt; s.length(); i++)&#123;</span><br><span class="line">            <span class="type">char</span> <span class="variable">sa</span> <span class="operator">=</span> s.charAt(i);</span><br><span class="line">            <span class="comment">// 判断是不是左括号，左括号压入</span></span><br><span class="line">            <span class="keyword">if</span> (map.containsKey(sa))&#123;</span><br><span class="line">                stack.push(sa);</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> (map.containsValue(sa))&#123;</span><br><span class="line">                <span class="comment">// 下面要取，先判断一下是不是空，非空直接返回false，防止空指针。</span></span><br><span class="line">                <span class="keyword">if</span> (stack.isEmpty()) <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">                <span class="type">char</span> <span class="variable">tmp</span> <span class="operator">=</span> stack.peek();</span><br><span class="line">                <span class="comment">// 判断括号是不是匹配，匹配弹出</span></span><br><span class="line">                <span class="keyword">if</span> (map.get(tmp) == sa)&#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">                    <span class="comment">// 不匹配</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><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> stack.isEmpty();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3><span id="9-找零钱">9. 找零钱</span></h3><h4><span id="题目描述">题目描述</span></h4><p>面值1元、4元、16元、64元共计四种硬币，以及面值1024元的纸币，现在A使用1024的纸币购买了一件价值为N的商品，0&lt;N&lt;=1024，请问他最少会收到多少枚硬币。</p><h4><span id="解题思路">解题思路</span></h4><p>贪心，因为没限制硬币个数，先找最大硬币，找到不够为止。</p><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><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="type">int</span> <span class="variable">n</span> <span class="operator">=</span> sc.nextInt();</span><br><span class="line"><span class="type">int</span> cnum1,cnum2,cnum3,cnum4;</span><br><span class="line">cnum1=(<span class="number">1024</span>-n)/<span class="number">64</span>;                          <span class="comment">//64元硬币的数量</span></span><br><span class="line">cnum2=((<span class="number">1024</span>-n)%<span class="number">64</span>)/<span class="number">16</span>;                     <span class="comment">//16元硬币的数量</span></span><br><span class="line">cnum3=((<span class="number">1024</span>-n)%<span class="number">16</span>)/<span class="number">4</span>;                 <span class="comment">//4元硬币的数量</span></span><br><span class="line">cnum4=(<span class="number">1024</span>-n)-(cnum1*<span class="number">64</span>+cnum2*<span class="number">16</span>+cnum3*<span class="number">4</span>); <span class="comment">//1元硬币的数量</span></span><br><span class="line">System.out.println(cnum1+cnum2+cnum3+cnum4);</span><br></pre></td></tr></table></figure><h3><span id="10-连续子区间和">10. 连续子区间和</span></h3><h4><span id="题目大意">题目大意</span></h4><p>小M给你一串含有c个正整数的数组, 想让你帮忙求出有多少个下标的连续区间, 它们的和大于等于x。</p><figure class="highlight plaintext"><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">第一行两个整数c x（0 &lt; c &lt;= 1000000, 0 &lt;= x &lt;= 100000000)</span><br><span class="line">第二行有c个正整数（每个正整数小于等于100)。</span><br></pre></td></tr></table></figure><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><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><br><span class="line">3 6</span><br><span class="line">2 4 7</span><br><span class="line">输出</span><br><span class="line">4</span><br><span class="line">2 = 2</span><br><span class="line">4 = 4</span><br><span class="line">7 = 7</span><br><span class="line">2 + 4 = 6</span><br><span class="line">4 + 7 = 11</span><br><span class="line">2 + 4 + 7 = 13</span><br></pre></td></tr></table></figure><h4><span id="解题思路">解题思路</span></h4><p>滑动窗口。</p><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="keyword">import</span> java.util.Scanner;</span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line">        <span class="type">Scanner</span> <span class="variable">sc</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">Scanner</span>(System.in);</span><br><span class="line">        <span class="type">int</span> <span class="variable">c</span> <span class="operator">=</span> sc.nextInt();</span><br><span class="line">        <span class="type">int</span> <span class="variable">x</span> <span class="operator">=</span> sc.nextInt();</span><br><span class="line">        <span class="type">int</span>[] arr = <span class="keyword">new</span> <span class="title class_">int</span>[c];</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; c; i++) &#123;</span><br><span class="line">            arr[i] = sc.nextInt();</span><br><span class="line">        &#125;</span><br><span class="line">        System.out.println(solu(arr, x));</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="type">long</span> <span class="title function_">solu</span><span class="params">(<span class="type">int</span>[] arr, <span class="type">int</span> x)</span> &#123;</span><br><span class="line">        <span class="type">long</span> <span class="variable">resu</span> <span class="operator">=</span> <span class="number">0</span>;</span><br><span class="line">        <span class="type">int</span> <span class="variable">start</span> <span class="operator">=</span> <span class="number">0</span>;</span><br><span class="line">        <span class="type">int</span> <span class="variable">end</span> <span class="operator">=</span> <span class="number">0</span>;</span><br><span class="line">        <span class="type">int</span> <span class="variable">sum</span> <span class="operator">=</span> arr[start];</span><br><span class="line">        <span class="keyword">while</span> (start &lt; arr.length) &#123;</span><br><span class="line">            <span class="keyword">if</span> (sum &gt;= x) &#123;</span><br><span class="line">                resu += (arr.length - end);</span><br><span class="line">                sum -= arr[start++];</span><br><span class="line">            &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                end++;</span><br><span class="line">                <span class="keyword">if</span> (end &gt;= arr.length) &#123;</span><br><span class="line">                    <span class="keyword">break</span>;</span><br><span class="line">                &#125;</span><br><span class="line">                sum += arr[end];</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> resu;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3><span id="11-循环有序的链表插入">11. 循环有序的链表插入</span></h3><h4><span id="题目大意">题目大意</span></h4><p>在循环有序的链表中插入结点，要求插入结点后，链表仍保持有序且循环。链表为空的时候，插入节点要生成一个新的循环链表。</p><h4><span id="解题思路">解题思路</span></h4><ol><li><p>链表为空，新建一个节点，将 next 指针指向自己。</p></li><li><p>不为空，分情况讨论：</p><ol><li>要插入的结点值在两个有序结点值[a, b]之间，那么只要满足 a &lt;= insertVal &lt;= b 即可。</li><li>由于是循环有序的链表，结点值不会一直上升，到某一个结点的时候，是最大值，但是下一个结点就是最小值了。其大于等于最大值，或者小于等于最小值。例如123450，插入6或者-1时候。</li></ol><p>找到插入的位置插入即可。</p></li></ol><h4><span id="代码">代码</span></h4><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function">Node* <span class="title">insert</span><span class="params">(Node* head, <span class="type">int</span> insertVal)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">if</span> (!head) &#123;</span><br><span class="line">            head = <span class="keyword">new</span> <span class="built_in">Node</span>(insertVal, <span class="literal">NULL</span>);</span><br><span class="line">            head-&gt;next = head;</span><br><span class="line">            <span class="keyword">return</span> head;</span><br><span class="line">        &#125;</span><br><span class="line">        Node *pre = head, *cur = pre-&gt;next;</span><br><span class="line">        <span class="keyword">while</span> (cur != head) &#123;</span><br><span class="line">            <span class="keyword">if</span> (pre-&gt;val &lt;= insertVal &amp;&amp; cur-&gt;val &gt;= insertVal) <span class="keyword">break</span>;</span><br><span class="line">            <span class="keyword">if</span> (pre-&gt;val &gt; cur-&gt;val &amp;&amp; (pre-&gt;val &lt;= insertVal || cur-&gt;val &gt;= insertVal)) <span class="keyword">break</span>;</span><br><span class="line">            pre = cur;</span><br><span class="line">            cur = cur-&gt;next;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="comment">// 以下操作未验证，因LeetCode这道题加锁了。</span></span><br><span class="line">        Node node = <span class="keyword">new</span> <span class="built_in">Node</span>(insertVal);</span><br><span class="line">        node-&gt;next = cur-&gt;next;</span><br><span class="line">        cur-&gt;next = node-&gt;next;</span><br><span class="line">        node-&gt;next = pre-&gt;next;</span><br><span class="line">        pre-&gt;next = node-&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><h3><span id="12-队列和栈的相互实现">12. 队列和栈的相互实现</span></h3><h4><span id="题目大意">题目大意</span></h4><p>两个栈实现队列，两个队列实现栈。</p><h4><span id="解题思路">解题思路</span></h4><p>美团面试的题目，写过两个栈实现一个队列，写两个队列实现栈脑子没转过来。</p><h4><span id="代码">代码</span></h4><p>两个栈实现队列，开始时候，每次添加队尾元素到 stack1 中去。</p><p>如果需要弹出队头元素，则将 stack1 中的元素弹出并 push 到 stack2 中，再将 stack2 的栈顶元素弹出，即弹出来队头的元素。</p><p>如果 stack2 中非空，再在队尾添加元素的时候仍然添加到 stack1 中，再从 stack2 中弹出队头元素。</p><p>如果 stack2 为空，弹出队头元素才需要将 stack1 中的元素转移到 stack2 中。</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><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="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    Stack&lt;Integer&gt; stack1 = <span class="keyword">new</span> <span class="title class_">Stack</span>&lt;&gt;();</span><br><span class="line">    Stack&lt;Integer&gt; stack2 = <span class="keyword">new</span> <span class="title class_">Stack</span>&lt;&gt;();</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">push</span><span class="params">(<span class="type">int</span> node)</span> &#123;</span><br><span class="line">        stack1.push(node);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">pop</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> (stack2.size() == <span class="number">0</span>) &#123;</span><br><span class="line">            <span class="keyword">while</span> (stack1.size() &gt; <span class="number">0</span>) &#123;</span><br><span class="line">                stack2.push(stack1.pop());</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> stack2.pop();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>两个队列实现栈，弹出元素的时候，把队列中的元素放到另一个队列中，删除最后一个元素。</p><p>两个队列始终保持只有一个队列是有数据的。</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    Queue&lt;Integer&gt; queue1 = <span class="keyword">new</span> <span class="title class_">LinkedList</span>&lt;&gt;();</span><br><span class="line">    Queue&lt;Integer&gt; queue2 = <span class="keyword">new</span> <span class="title class_">LinkedList</span>&lt;&gt;();</span><br><span class="line">    <span class="keyword">public</span> <span class="type">boolean</span> <span class="title function_">push</span><span class="params">(<span class="type">int</span> node)</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> (!queue1.isEmpty()) &#123;</span><br><span class="line">            <span class="keyword">return</span> queue1.offer(node);</span><br><span class="line">        &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> queue2.offer(node);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">pop</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> (queue1.isEmpty() &amp;&amp; queue2.isEmpty()) &#123;</span><br><span class="line">            <span class="keyword">throw</span> <span class="keyword">new</span> <span class="title class_">RuntimeException</span>(<span class="string">&quot;栈为空&quot;</span>);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span> (!queue1.isEmpty() &amp;&amp; queue2.isEmpty()) &#123;</span><br><span class="line">            <span class="keyword">while</span> (queue1.size() != <span class="number">1</span>) &#123;</span><br><span class="line">                queue2.offer(queue1.poll());</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">return</span> queue1.poll();</span><br><span class="line">        &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">            <span class="keyword">while</span> (queue2.size() != <span class="number">1</span>) &#123;</span><br><span class="line">                queue1.offer(queue2.poll());</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">return</span> queue2.poll();</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><h3><span id="13-二叉搜索树搜索">13. 二叉搜索树搜索</span></h3><h4><span id="题目大意">题目大意</span></h4><p>在二叉搜索树中找最小的大于某个key值的节点，如：</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><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="number">8</span></span><br><span class="line">    / \</span><br><span class="line">   <span class="number">6</span>   <span class="number">12</span></span><br><span class="line">  /   /   \</span><br><span class="line"><span class="number">2</span>    <span class="number">11</span>    <span class="number">14</span></span><br><span class="line">         </span><br><span class="line">key = <span class="number">8</span> 返回<span class="number">11</span></span><br><span class="line">key = <span class="number">1</span> 返回<span class="number">2</span></span><br><span class="line">key = <span class="number">16</span> 返回NULL</span><br></pre></td></tr></table></figure><h4><span id="解题思路">解题思路</span></h4><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> TreeNode <span class="title function_">FindCeiling</span><span class="params">(TreeNode root, <span class="type">int</span> key)</span> &#123;</span><br><span class="line">        <span class="type">TreeNode</span> <span class="variable">ceiling</span> <span class="operator">=</span> <span class="literal">null</span>;</span><br><span class="line">        <span class="type">TreeNode</span> <span class="variable">cur</span> <span class="operator">=</span> root;</span><br><span class="line">        <span class="keyword">while</span> (cur != <span class="literal">null</span>) &#123;</span><br><span class="line">            <span class="keyword">if</span> (cur.val &lt;= key) &#123;</span><br><span class="line">                cur = cur.right;</span><br><span class="line">            &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                ceiling = cur;</span><br><span class="line">                cur = cur.left;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> ceiling;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> TreeNode <span class="title function_">FindCeilingD</span><span class="params">(TreeNode root, <span class="type">int</span> key)</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="literal">null</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span> (root.val &lt;= key) &#123;</span><br><span class="line">            <span class="keyword">return</span> FindCeilingD(root.right, key);</span><br><span class="line">        &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">            <span class="type">TreeNode</span> <span class="variable">ceiling</span> <span class="operator">=</span> FindCeilingD(root.left, key);</span><br><span class="line">            <span class="keyword">return</span> ceiling != <span class="literal">null</span> ? ceiling : <span class="literal">null</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><h3><span id="14-第-k-个全排列">14. 第 k 个全排列</span></h3><h4><span id="题目大意">题目大意</span></h4><p>输出以 1 开始的 n 个正整数 (1,2,…,n) 的第 k 个排列。</p><h4><span id="解题思路">解题思路</span></h4><p>套用求下一个排列的算法，增加次数判断，下一个排列可以看 leetcode 31 的解法。</p><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">nextPermutation</span><span class="params">(<span class="type">int</span>[] nums, <span class="type">int</span> count, <span class="type">int</span> target)</span> &#123;</span><br><span class="line">        <span class="type">int</span> <span class="variable">n</span> <span class="operator">=</span> nums.length;</span><br><span class="line">        <span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> n - <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="type">int</span> <span class="variable">j</span> <span class="operator">=</span> n - <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, j);</span><br><span class="line">        &#125;</span><br><span class="line">        reverse(nums, i + <span class="number">1</span>, n - <span class="number">1</span>);</span><br><span class="line">        count++;</span><br><span class="line">        <span class="keyword">if</span> (count == target - <span class="number">1</span>) &#123;</span><br><span class="line">            <span class="keyword">return</span>;</span><br><span class="line">        &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">            nextPermutation(nums, count, target);</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">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">swap</span><span class="params">(<span class="type">int</span>[] nums, <span class="type">int</span> left, <span class="type">int</span> right)</span> &#123;</span><br><span class="line">        <span class="type">int</span> <span class="variable">tmp</span> <span class="operator">=</span> nums[left];</span><br><span class="line">        nums[left] = nums[right];</span><br><span class="line">        nums[right] = tmp;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">reverse</span><span class="params">(<span class="type">int</span>[] nums, <span class="type">int</span> left, <span class="type">int</span> right)</span> &#123;</span><br><span class="line">        <span class="keyword">while</span> (left &lt; right) &#123;</span><br><span class="line">            swap(nums, left++, right--);</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">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line">        <span class="type">int</span>[] nums = &#123;<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>&#125;;</span><br><span class="line">        nextPermutation(nums, <span class="number">0</span>, <span class="number">5</span>);</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> num : nums) &#123;</span><br><span class="line">            System.out.print(num);</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><h3><span id="15-字符串查找">15. 字符串查找</span></h3><h4><span id="题目大意">题目大意</span></h4><p>找出一个字符串中出现次数最多的字符，如果有多个出现次数相同的字符，那就找出最先出现的字符。</p><h4><span id="解题思路">解题思路</span></h4><p>最开始的思路是先遍历了三次，第一次记录次数，第二次找最大值，第三次返回字符。</p><p>这道题可以用 map 来实时记录当前的每个节点的个数，然后更新实时最大值。</p><h4><span id="代码">代码</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="keyword">import</span> java.util.HashMap;</span><br><span class="line"><span class="keyword">import</span> java.util.Map;</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="type">char</span> <span class="title function_">serachMaxChar</span><span class="params">(String str)</span> &#123;</span><br><span class="line">        <span class="type">int</span> <span class="variable">max</span> <span class="operator">=</span> <span class="number">0</span>;</span><br><span class="line">        <span class="type">char</span> <span class="variable">resu</span> <span class="operator">=</span> str.charAt(<span class="number">0</span>);</span><br><span class="line">        Map&lt;Character, Integer&gt; map = <span class="keyword">new</span> <span class="title class_">HashMap</span>&lt;&gt;();</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; str.length(); i++) &#123;</span><br><span class="line">            map.put(str.charAt(i), map.getOrDefault(str.charAt(i), <span class="number">0</span>) + <span class="number">1</span>);</span><br><span class="line">            <span class="keyword">if</span> (map.get(str.charAt(i)) &gt; max) &#123;</span><br><span class="line">                max = map.get(str.charAt(i));</span><br><span class="line">                resu = str.charAt(i);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> resu;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line">        System.out.println(serachMaxChar(<span class="string">&quot;a1a2a3bbbcccdddeeefffddda23112211&quot;</span>));</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">// d</span></span><br></pre></td></tr></table></figure><h3><span id="来源">来源</span></h3><ul><li>1 2020京东秋招编程2</li><li>3-5 华为未来星秋招</li><li>6 牛客</li><li>7-9 哔哩哔哩2020秋招</li><li>10-11面经</li></ul>]]></content>
    
    
      
      
    <summary type="html">&lt;blockquote&gt;
&lt;p&gt;人生短短两三年，转眼又到夏天，轮到我上战场了，本篇主要用于笔试面试中编程复盘。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;&lt;span id=&quot;1-回文素数&quot;&gt;1. 回文素数&lt;/span&gt;&lt;/h3&gt;
&lt;h4&gt;&lt;span id=&quot;题目大意&quot;&gt;题目大意</summary>
      
    
    
    
    
    <category term="解题报告" scheme="https://tyzhang.top/tags/%E8%A7%A3%E9%A2%98%E6%8A%A5%E5%91%8A/"/>
    
  </entry>
  
  <entry>
    <title>深拷贝和浅拷贝</title>
    <link href="https://tyzhang.top/article/clone/"/>
    <id>https://tyzhang.top/article/clone/</id>
    <published>2020-08-26T16:00:00.000Z</published>
    <updated>2021-01-18T13:19:58.000Z</updated>
    
    <content type="html"><![CDATA[<blockquote><p>梳理一下深拷贝和浅拷贝。</p></blockquote><h3><span id="引子">引子</span></h3><p>先定义两个环境类，这里就以 <code>Student</code> 和 <code>Major</code> 为例，表示学生和学生所学专业，它们应该是包含关系。</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><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">class</span> <span class="title class_">Student</span>&#123;</span><br><span class="line">    <span class="keyword">public</span> String name;</span><br><span class="line">    <span class="keyword">public</span> Major major;</span><br><span class="line">    <span class="comment">// 省略 constructor, getter 和 setter，下同</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Major</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> String major;</span><br><span class="line">    <span class="keyword">public</span> String majorid;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>先看一种写法：</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><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="type">Major</span> <span class="variable">major</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">Major</span>(<span class="string">&quot;1&quot;</span>, <span class="string">&quot;2&quot;</span>);</span><br><span class="line"><span class="type">Student</span> <span class="variable">student</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">Student</span>(<span class="string">&quot;zty&quot;</span>, major);</span><br><span class="line"><span class="type">Student</span> <span class="variable">student2</span> <span class="operator">=</span> student;</span><br><span class="line">System.out.println(student == student2);</span><br><span class="line"><span class="comment">// true</span></span><br></pre></td></tr></table></figure><p>严格来讲，这其实并不是“拷贝”，只是给了 <code>student2</code> 一个引用关系，因为没有生成新的实际对象，验证：</p><figure class="highlight java"><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">student2.setName(<span class="string">&quot;galaxy&quot;</span>);</span><br><span class="line">System.out.println(student.getName());</span><br><span class="line"><span class="comment">// galaxy</span></span><br></pre></td></tr></table></figure><p>可以看到修改 <code>student2</code> 后 <code>student</code> 也被影响。</p><h3><span id="浅拷贝">浅拷贝</span></h3><p>浅，就是对于一个对象来说，值类型的字段会复制一份，但是引用类型的字段拷贝的仅仅是引用地址，引用的对象没有被拷贝，只有一份。</p><img src="https://pic.tyzhang.top/images/2020/08/27/image.png" alt="浅拷贝" style="zoom: 50%;"><h4><span id="实现方式">实现方式</span></h4><p>让被复制对象的类实现 <code>Cloneable</code> 接口，并重写 <code>clone()</code> 方法。</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><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="keyword">class</span> <span class="title class_">Student</span> <span class="keyword">implements</span> <span class="title class_">Cloneable</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> String name;</span><br><span class="line">    <span class="keyword">public</span> Major major;</span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">protected</span> Object <span class="title function_">clone</span><span class="params">()</span> <span class="keyword">throws</span> CloneNotSupportedException &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="built_in">super</span>.clone();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><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="type">Major</span> <span class="variable">major</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">Major</span>(<span class="string">&quot;1&quot;</span>, <span class="string">&quot;2&quot;</span>);</span><br><span class="line"><span class="type">Student</span> <span class="variable">student</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">Student</span>(<span class="string">&quot;zty&quot;</span>, major);</span><br><span class="line"><span class="type">Student</span> <span class="variable">student3</span> <span class="operator">=</span> (Student) student.clone();</span><br><span class="line">System.out.println(student == student3);</span><br><span class="line">student3.setName(<span class="string">&quot;galaxy&quot;</span>);</span><br><span class="line">student3.major.setMajor(<span class="string">&quot;fdsfds&quot;</span>);</span><br><span class="line">System.out.println(student.getName() + <span class="string">&quot; &quot;</span> + student3.getName());</span><br><span class="line">System.out.println(student.getMajor() == student3.getMajor());</span><br><span class="line"><span class="comment">// false</span></span><br><span class="line"><span class="comment">// zty galaxy</span></span><br><span class="line"><span class="comment">// true</span></span><br></pre></td></tr></table></figure><p>可以看到克隆了一个新对象，且值类型不再于原对象关联，但是引用类型仍然是一个。</p><h3><span id="深拷贝">深拷贝</span></h3><p>深，就是除了值类型，引用也会复制一个副本出来。<code>clone()</code> 默认是浅拷贝，要想实现深拷贝，就要重写，进行深度遍历复制。</p><img src="https://pic.tyzhang.top/images/2020/08/27/image8c1d6406cfe1d490.png" alt="深拷贝" style="zoom:50%;"><h4><span id="实现方式">实现方式</span></h4><p>先对 <code>Major</code> 类进行改造，这里 <code>Major</code> 里面没东西了，直接浅拷贝：</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><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="keyword">class</span> <span class="title class_">Major</span> <span class="keyword">implements</span> <span class="title class_">Cloneable</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> String major;</span><br><span class="line">    <span class="keyword">public</span> String majorid;</span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">protected</span> Object <span class="title function_">clone</span><span class="params">()</span> <span class="keyword">throws</span> CloneNotSupportedException &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="built_in">super</span>.clone();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>在 <code>Student</code> 中重写 <code>clone</code> 方法，实现深拷贝：</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><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">@Override</span></span><br><span class="line"><span class="keyword">protected</span> Object <span class="title function_">clone</span><span class="params">()</span> <span class="keyword">throws</span> CloneNotSupportedException &#123;</span><br><span class="line">    <span class="type">Student</span> <span class="variable">student</span> <span class="operator">=</span> (Student) <span class="built_in">super</span>.clone();</span><br><span class="line">    student.setMajor((Major) major.clone());</span><br><span class="line">    <span class="keyword">return</span> student;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>测试：</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><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="type">Student</span> <span class="variable">student3</span> <span class="operator">=</span> (Student) student.clone();</span><br><span class="line">System.out.println(student == student3);</span><br><span class="line">student3.setName(<span class="string">&quot;galaxy&quot;</span>);</span><br><span class="line">student3.major.setMajor(<span class="string">&quot;fdsfds&quot;</span>);</span><br><span class="line">System.out.println(student.getName() + <span class="string">&quot; &quot;</span> + student3.getName());</span><br><span class="line">System.out.println(student.getMajor() == student3.getMajor());</span><br><span class="line">student3.getMajor().setMajor(<span class="string">&quot;xiugai&quot;</span>);</span><br><span class="line">System.out.println(student.getMajor().getMajor() + <span class="string">&quot; &quot;</span> + student3.getMajor().getMajor());</span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment">false</span></span><br><span class="line"><span class="comment">zty galaxy</span></span><br><span class="line"><span class="comment">false</span></span><br><span class="line"><span class="comment">1 xiugai</span></span><br><span class="line"><span class="comment">**/</span></span><br></pre></td></tr></table></figure><h4><span id="序列化实现深拷贝">序列化实现深拷贝</span></h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="keyword">class</span> <span class="title class_">Student</span> <span class="keyword">implements</span> <span class="title class_">Serializable</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> String name;</span><br><span class="line">    <span class="keyword">public</span> Major major;</span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">public</span> Student <span class="title function_">clone</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            <span class="comment">// 将对象序列化到字节流</span></span><br><span class="line">            <span class="type">ByteArrayOutputStream</span> <span class="variable">byteArrayOutputStream</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">ByteArrayOutputStream</span>();</span><br><span class="line">            <span class="type">ObjectOutputStream</span> <span class="variable">objectOutputStream</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">ObjectOutputStream</span>(byteArrayOutputStream);</span><br><span class="line">            objectOutputStream.writeObject(<span class="built_in">this</span>);</span><br><span class="line">            <span class="comment">// 反序列化回对象</span></span><br><span class="line">            <span class="type">ByteArrayInputStream</span> <span class="variable">byteArrayInputStream</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">ByteArrayInputStream</span>(byteArrayOutputStream.toByteArray());</span><br><span class="line">            <span class="type">ObjectInputStream</span> <span class="variable">objectInputStream</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">ObjectInputStream</span>(byteArrayInputStream);</span><br><span class="line">            <span class="keyword">return</span> (Student) objectInputStream.readObject();</span><br><span class="line">        &#125; <span class="keyword">catch</span> (IOException | ClassNotFoundException e) &#123;</span><br><span class="line">            e.printStackTrace();</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><p>注意，此种方法，<code>Major</code> 类也要实现序列化。</p>]]></content>
    
    
      
      
    <summary type="html">&lt;blockquote&gt;
&lt;p&gt;梳理一下深拷贝和浅拷贝。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;&lt;span id=&quot;引子&quot;&gt;引子&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;先定义两个环境类，这里就以 &lt;code&gt;Student&lt;/code&gt; 和 &lt;code&gt;Major&lt;/code&gt; 为</summary>
      
    
    
    
    
    <category term="笔记" scheme="https://tyzhang.top/tags/%E7%AC%94%E8%AE%B0/"/>
    
  </entry>
  
  <entry>
    <title>LRU 算法的两种实现方式</title>
    <link href="https://tyzhang.top/article/lrucache/"/>
    <id>https://tyzhang.top/article/lrucache/</id>
    <published>2020-08-16T16:00:00.000Z</published>
    <updated>2021-01-18T13:19:38.000Z</updated>
    
    <content type="html"><![CDATA[<blockquote><p>LRUCache 的两种实现方式，借助和不借助 LinkedHashMap。</p></blockquote><h3><span id="hashmap-linkedlist">HashMap + LinkedList</span></h3><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> java.util.HashMap;</span><br><span class="line"><span class="keyword">import</span> java.util.LinkedList;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Main</span> &#123;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">static</span> <span class="keyword">class</span> <span class="title class_">LRUCache</span>&lt;K, V&gt; &#123;</span><br><span class="line">        <span class="comment">// 缓冲容量</span></span><br><span class="line">        <span class="keyword">private</span> <span class="keyword">final</span> <span class="type">int</span> cacheSize;</span><br><span class="line">        <span class="comment">// 双向链表，存储缓存</span></span><br><span class="line">        <span class="keyword">private</span> LinkedList&lt;K&gt; cacheList = <span class="keyword">new</span> <span class="title class_">LinkedList</span>&lt;&gt;();</span><br><span class="line">        <span class="comment">// 储存缓存的key，用来计算是否命中，命中率则遍历链表</span></span><br><span class="line">        <span class="keyword">private</span> HashMap&lt;K, V&gt; map = <span class="keyword">new</span> <span class="title class_">HashMap</span>&lt;&gt;();</span><br><span class="line"></span><br><span class="line">        <span class="keyword">public</span> <span class="title function_">LRUCache</span><span class="params">(<span class="type">int</span> cacheSize)</span> &#123;</span><br><span class="line">            <span class="built_in">this</span>.cacheSize = cacheSize;</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">public</span> <span class="keyword">synchronized</span> <span class="keyword">void</span> <span class="title function_">put</span><span class="params">(K key, V val)</span> &#123;</span><br><span class="line">            <span class="comment">// 未命中</span></span><br><span class="line">            <span class="keyword">if</span> (!map.containsKey(key)) &#123;</span><br><span class="line">                <span class="comment">// 如果超过了缓存，将最少访问的移除</span></span><br><span class="line">                <span class="keyword">if</span> (map.size() &gt;= cacheSize) &#123;</span><br><span class="line">                    map.remove(cacheList.removeLast());</span><br><span class="line">                &#125;</span><br><span class="line">                cacheList.addFirst(key);</span><br><span class="line">                map.put(key, val);</span><br><span class="line">            &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                <span class="comment">// 命中，将链表元素往前移动，更新map</span></span><br><span class="line">                moveToFirst(key);</span><br><span class="line">                map.put(key, val);</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">public</span> V <span class="title function_">get</span><span class="params">(K key)</span> &#123;</span><br><span class="line">            <span class="comment">// 是否命中</span></span><br><span class="line">            <span class="keyword">if</span> (!map.containsKey(key)) &#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="comment">// 移动到前面来</span></span><br><span class="line">            moveToFirst(key);</span><br><span class="line">            <span class="keyword">return</span> map.get(key);</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">private</span> <span class="keyword">synchronized</span> <span class="keyword">void</span> <span class="title function_">moveToFirst</span><span class="params">(K key)</span> &#123;</span><br><span class="line">            cacheList.remove(key);</span><br><span class="line">            cacheList.addFirst(key);</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="keyword">public</span> String <span class="title function_">toString</span><span class="params">()</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> cacheList.toString();</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">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line">        LRUCache&lt;String, String&gt; lruCache = <span class="keyword">new</span> <span class="title class_">LRUCache</span>&lt;String, String&gt;(<span class="number">4</span>);</span><br><span class="line">        lruCache.put(<span class="string">&quot;C&quot;</span>, <span class="literal">null</span>);</span><br><span class="line">        lruCache.put(<span class="string">&quot;A&quot;</span>, <span class="literal">null</span>);</span><br><span class="line">        lruCache.put(<span class="string">&quot;D&quot;</span>, <span class="literal">null</span>);</span><br><span class="line">        lruCache.put(<span class="string">&quot;B&quot;</span>, <span class="literal">null</span>);</span><br><span class="line">        lruCache.put(<span class="string">&quot;E&quot;</span>, <span class="literal">null</span>);</span><br><span class="line">        lruCache.put(<span class="string">&quot;B&quot;</span>, <span class="literal">null</span>);</span><br><span class="line">        lruCache.put(<span class="string">&quot;A&quot;</span>, <span class="literal">null</span>);</span><br><span class="line">        lruCache.put(<span class="string">&quot;B&quot;</span>, <span class="literal">null</span>);</span><br><span class="line">        lruCache.put(<span class="string">&quot;C&quot;</span>, <span class="literal">null</span>);</span><br><span class="line">        lruCache.put(<span class="string">&quot;D&quot;</span>, <span class="literal">null</span>);</span><br><span class="line">        System.out.println(lruCache);</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">[D, C, B, A]</span></span><br><span class="line"><span class="comment">**/</span></span><br></pre></td></tr></table></figure><h3><span id="linkedhashmap">LinkedHashMap</span></h3><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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">class</span> <span class="title class_">LRUCache</span> <span class="keyword">extends</span> <span class="title class_">LinkedHashMap</span>&lt;Integer, Integer&gt; &#123;</span><br><span class="line">    <span class="keyword">private</span> <span class="type">int</span> capacity;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="title function_">LRUCache</span><span class="params">(<span class="type">int</span> capacity)</span> &#123;</span><br><span class="line">        <span class="built_in">super</span>(capacity, <span class="number">0.75f</span>, <span class="literal">true</span>);</span><br><span class="line">        <span class="built_in">this</span>.capacity = capacity;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">get</span><span class="params">(<span class="type">int</span> key)</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="built_in">super</span>.getOrDefault(key, -<span class="number">1</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">put</span><span class="params">(<span class="type">int</span> key, <span class="type">int</span> val)</span> &#123;</span><br><span class="line">        <span class="built_in">super</span>.put(key, val);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">protected</span> <span class="type">boolean</span> <span class="title function_">removeEldestEntry</span><span class="params">(Map.Entry&lt;Integer, Integer&gt; eldest)</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> size() &gt; capacity;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>]]></content>
    
    
      
      
    <summary type="html">&lt;blockquote&gt;
&lt;p&gt;LRUCache 的两种实现方式，借助和不借助 LinkedHashMap。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;&lt;span id=&quot;hashmap-linkedlist&quot;&gt;HashMap + LinkedList&lt;/span&gt;&lt;/h3&gt;
</summary>
      
    
    
    
    
    <category term="笔记" scheme="https://tyzhang.top/tags/%E7%AC%94%E8%AE%B0/"/>
    
  </entry>
  
  <entry>
    <title>操作系统相关</title>
    <link href="https://tyzhang.top/article/OS/"/>
    <id>https://tyzhang.top/article/OS/</id>
    <published>2020-08-03T16:00:00.000Z</published>
    <updated>2021-01-18T13:19:26.000Z</updated>
    
    <content type="html"><![CDATA[<blockquote><p>学啊，学无止境，太深了。</p></blockquote><h2><span id="概述">概述</span></h2><h3><span id="基本特征">基本特征</span></h3><ol><li><p>并发</p><p>并发是指宏观上在一段时间内能同时运行多个程序，而并行则指同一时刻能运行多个指令。</p><p>并行需要硬件支持，如多流水线、多核处理器或者分布式计算系统。</p><p>操作系统通过引入进程和线程，使得程序能够并发运行。</p></li><li><p>共享</p><p>共享是指系统中的资源可以被多个并发进程共同使用。</p><p>有两种共享方式：互斥共享和同时共享。</p><p>互斥共享的资源称为临界资源，例如打印机等，在同一时刻只允许一个进程访问，需要用同步机制来实现互斥访问。</p></li><li><p>虚拟</p><p>虚拟技术把一个物理实体转换为多个逻辑实体。</p><p>主要有两种虚拟技术：时（时间）分复用技术和空（空间）分复用技术。</p><p>多个进程能在同一个处理器上并发执行使用了时分复用技术，让每个进程轮流占用处理器，每次只执行一小个时间片并快速切换。</p><p>虚拟内存使用了空分复用技术，它将物理内存抽象为地址空间，每个进程都有各自的地址空间。地址空间的页被映射到物理内存，地址空间的页并不需要全部在物理内存中，当使用到一个没有在物理内存的页时，执行页面置换算法，将该页置换到内存中。</p></li><li><p>异步</p><p>异步指进程不是一次性执行完毕，而是走走停停，以不可知的速度向前推进。</p></li></ol><h3><span id="基本功能">基本功能</span></h3><ol><li><p>进程管理</p><p>进程控制、进程同步、进程通信、死锁处理、处理机调度等。</p></li><li><p>内存管理</p><p>内存分配、地址映射、内存保护与共享、虚拟内存等。</p></li><li><p>文件管理</p><p>文件存储空间的管理、目录管理、文件读写管理和保护等。</p></li><li><p>设备管理</p><p>完成用户的 I/O 请求，方便用户使用各种设备，并提高设备的利用率。</p><p>主要包括缓冲管理、设备分配、设备处理、虛拟设备等。</p></li></ol><h3><span id="大内核和微内核">大内核和微内核</span></h3><ol><li><p>大内核</p><p>大内核是将操作系统功能作为一个紧密结合的整体放到内核。</p><p>由于各模块共享信息，因此有很高的性能。</p></li><li><p>微内核</p><p>由于操作系统不断复杂，因此将一部分操作系统功能移出内核，从而降低内核的复杂性。移出的部分根据分层的原则划分成若干服务，相互独立。</p><p>在微内核结构下，操作系统被划分成小的、定义良好的模块，只有微内核这一个模块运行在内核态，其余模块运行在用户态。</p><p>因为需要频繁地在用户态和核心态之间进行切换，所以会有一定的性能损失。</p></li></ol><h3><span id="中断分类">中断分类</span></h3><ol><li><p>外中断</p><p>由 CPU 执行指令以外的事件引起，如 I/O 完成中断，表示设备输入/输出处理已经完成，处理器能够发送下一个输入/输出请求。此外还有时钟中断、控制台中断等。</p></li><li><p>异常</p><p>由 CPU 执行指令的内部事件引起，如非法操作码、地址越界、算术溢出等。</p></li><li><p>陷入</p><p>在用户程序中使用系统调用。</p></li></ol><h2><span id="进程管理">进程管理</span></h2><h3><span id="进程和线程">进程和线程</span></h3><ol><li><p>进程</p><p>进程是资源分配的基本单位。</p><p>进程控制块 (Process Control Block, PCB) 描述进程的基本信息和运行状态，所谓的创建进程和撤销进程，都是指对 PCB 的操作。</p></li><li><p>线程</p><p>线程是独立调度的基本单位。</p><p>一个进程中可以有多个线程，它们共享进程资源。</p></li><li><p>区别</p><ul><li>进程是资源分配的基本单位，但是线程不拥有资源，线程可以访问隶属进程的资源。</li><li>线程是独立调度的基本单位，在同一进程中，线程的切换不会引起进程切换，从一个进程中的线程切换到另一个进程中的线程时，会引起进程切换。</li><li>由于创建或撤销进程时，系统都要为之分配或回收资源，如内存空间、I/O 设备等，所付出的开销远大于创建或撤销线程时的开销。类似地，在进行进程切换时，涉及当前执行进程 CPU 环境的保存及新调度进程 CPU 环境的设置，而线程切换时只需保存和设置少量寄存器内容，开销很小。</li><li>线程间可以通过直接读写同一进程中的数据进行通信，但是进程通信需要借助 IPC。</li></ul></li></ol><p>为什么有了进程还要线程？</p><p>进程有很多优点，它提供了多道编程，让我们感觉我们每个人都拥有自己的CPU和其他资源，可以提高计算机的利用率。</p><ul><li>进程只能在一个时间干一件事，如果想同时干两件事或多件事，进程就无能为力了。</li><li>进程在执行的过程中如果阻塞，例如等待输入，整个进程就会挂起，即使进程中有些工作不依赖于输入的数据，也将无法执行。</li></ul><h4><span id="线程的同步与阻塞关系">线程的同步与阻塞关系</span></h4><p>没有任何关系。</p><p>同步和异步关注的是消息通信机制。同步调用在没有得到返回值的时候不会返回；异步会立刻返回，由被调者通知它。</p><p>阻塞和非阻塞关注的是在等待返回结果时线程的状态。阻塞会挂起线程，也就是卡在这里不往下面执行了；但是，非阻塞调用不会卡住，虽然没有得到返回值，但是依然可以继续往下执行。</p><h4><span id="线程和进程切换的开销">线程和进程切换的开销</span></h4><p>进程切换开销：</p><ol><li>切换虚拟地址空间</li><li>切换CPU上下文</li><li>切换内核栈</li></ol><p>线程切换开销：</p><ol><li>切换CPU上下文</li><li>切换内核栈</li></ol><h4><span id="线程之间的共享资源和独占资源">线程之间的共享资源和独占资源</span></h4><p>共享资源</p><ul><li>进程申请的堆内存</li><li>进程打开的文件描述符</li><li>进程的全局数据，可以用于线程之间的通信</li><li>进程 ID 和进程组 ID</li><li>进程目录</li><li>信号处理器</li></ul><p>独占资源</p><ul><li>线程 ID</li><li>寄存器组的值</li><li>线程堆栈</li><li>错误返回码</li><li>信号屏壁码</li><li>线程的优先级</li></ul><h4><span id="僵尸进程和孤儿进程">僵尸进程和孤儿进程</span></h4><ul><li><p>孤儿进程</p><p>无危害，一个父进程退出，而它的一个或者多个子进程还在运行，那么那些子进程将成为孤儿进程。孤儿进程将被 init 进程 (进程号为 1) 所收养，并由 init 进程对它们完成状态收集工作（也就是清理进程号）。</p></li><li><p>僵尸进程</p><p>有危害，一个进程使用 fork 创建子进程，如果子进程退出，而父进程并没有调用 wait 或 waitpid 获取子进程的状态信息，那么子进程的进程描述符（如进程号、运行时间等）仍然保存在系统中。这种进程称之为僵尸进程（进程号就会一直被占用，导致无法产生新的进程）。</p></li><li><p>僵尸进程解决办法</p><ul><li>信号机制：子进程退出时候，向父进程发送信号，父进程立马 wait 它</li><li>找到产生僵尸进程的父进程，kill 掉，init 进程会处理僵尸进程</li><li>重启</li></ul></li></ul><h3><span id="进程状态切换">进程状态切换</span></h3><p><img src="https://pic.tyzhang.top/images/2020/08/03/ProcessState.md.png" alt="进程状态切换"></p><ul><li><p>就绪状态（ready）：等待被调度</p></li><li><p>运行状态（running）</p></li><li><p>阻塞状态（waiting）：等待资源</p></li><li><p><strong>只有就绪态和运行态可以相互转换</strong>，其它的都是单向转换。就绪状态的进程通过调度算法从而获得 CPU 时间，转为运行状态；而运行状态的进程，在分配给它的 CPU 时间片用完之后就会转为就绪状态，等待下一次调度。</p></li><li><p>阻塞状态是缺少需要的资源从而由运行状态转换而来，但是该资源不包括 CPU 时间，缺少 CPU 时间会从运行态转换为就绪态。</p></li></ul><h3><span id="进程调度算法">进程调度算法</span></h3><ol><li><p>先来先服务 first-come first-serverd（FCFS）</p><p>非抢占式的调度算法，按照请求的顺序进行调度。</p><p>有利于长作业，但不利于短作业，因为短作业必须一直等待前面的长作业执行完毕才能执行，而长作业又需要执行很长时间，造成了短作业等待时间过长。</p></li><li><p>短作业优先 shortest job first（SJF）</p><p>非抢占式的调度算法，按估计运行时间最短的顺序进行调度。</p><p>长作业有可能会饿死，处于一直等待短作业执行完毕的状态。因为如果一直有短作业到来，那么长作业永远得不到调度。</p></li><li><p>最短剩余时间优先 shortest remaining time next（SRTN）</p><p>最短作业优先的抢占式版本，按剩余运行时间的顺序进行调度。 当一个新的作业到达时，其整个运行时间与当前进程的剩余时间作比较。如果新的进程需要的时间更少，则挂起当前进程，运行新的进程。否则新的进程等待。</p></li><li><p>时间片轮转</p><p>将所有就绪进程按 FCFS 的原则排成一个队列，每次调度时，把 CPU 时间分配给队首进程，该进程可以执行一个时间片。当时间片用完时，由计时器发出时钟中断，调度程序便停止该进程的执行，并将它送往就绪队列的末尾，同时继续把 CPU 时间分配给队首的进程。</p></li><li><p>优先级调度</p><p>为每个进程分配一个优先级，按优先级进行调度。</p><p>为了防止低优先级的进程永远等不到调度，可以随着时间的推移增加等待进程的优先级。</p></li><li><p>最高相应比优先</p><p>R=(w+s)/s （R为响应比，w为等待处理的时间，s为预计的服务时间）</p><p>当前进程完成或被阻塞时，选择R值最大的就绪进程，它说明了进程的年龄。当偏向短作业时，长进程由于得不到服务，等待时间不断增加，从而增加比值，最终在竞争中赢了短进程。</p></li><li><p>多级反馈队列</p><p>多级队列是为需要连续执行多个时间片的进程考虑，它设置了多个队列，每个队列时间片大小都不同，例如 1,2,4,8,…。进程在第一个队列没执行完，就会被移到下一个队列。这种方式下，之前的进程只需要交换 7 次。</p><p>每个队列优先权也不同，最上面的优先权最高。因此只有上一个队列没有进程在排队，才能调度当前队列上的进程。</p><p>可以将这种调度算法看成是时间片轮转调度算法和优先级调度算法的结合。</p><p><img src="https://pic.tyzhang.top/images/2020/08/03/042cf928-3c8e-4815-ae9c-f2780202c68f.png" alt="多级反馈队列"></p></li></ol><h3><span id="进程同步">进程同步</span></h3><ol><li><p>临界区</p><p>对临界资源进行访问的那段代码称为临界区。</p><p>为了互斥访问临界资源，每个进程在进入临界区之前，需要先进行检查。</p></li><li><p>同步和互斥</p><ul><li>同步：多个进程因为合作产生的直接制约关系，使得进程有一定的先后执行关系。</li><li>互斥：多个进程在同一时刻只有一个进程能进入临界区。</li></ul></li><li><p>信号量</p><p>信号量（Semaphore）是一个整型变量，可以对其执行 down 和 up 操作，也就是常见的 P 和 V 操作。</p><ul><li><strong>down</strong> : 如果信号量大于 0 ，执行 -1 操作；如果信号量等于 0，进程睡眠，等待信号量大于 0；</li><li><strong>up</strong> ：对信号量执行 +1 操作，唤醒睡眠的进程让其完成 down 操作。</li></ul><p>down 和 up 操作需要被设计成原语，不可分割，通常的做法是在执行这些操作的时候屏蔽中断。</p><p>如果信号量的取值只能为 0 或者 1，那么就成为了 <strong>互斥量（Mutex）</strong> ，0 表示临界区已经加锁，1 表示临界区解锁。</p></li><li><p>管程</p><p>管程把控制的代码独立出来，不仅不容易出错，也使得客户端代码调用更容易。</p><p>在一个时刻只能有一个进程使用管程。进程在无法继续执行的时候不能一直占用管程，否则其它进程永远不能使用管程。</p><p>在一个时刻只能有一个进程使用管程。进程在无法继续执行的时候不能一直占用管程，否则其它进程永远不能使用管程。</p></li></ol><h2><span id="进程通信">进程通信</span></h2><p><strong>进程间资源是独立的，关注的是通讯问题。</strong></p><p><strong>线程间资源是共享的，关注的是安全问题。</strong></p><ul><li>进程同步：控制多个进程按一定顺序执行；</li><li>进程通信：进程间传输信息。</li></ul><p>进程通信是一种手段，而进程同步是一种目的。也可以说，为了能够达到进程同步的目的，需要让进程进行通信，传输一些进程同步所需要的信息。</p><ol><li><p>管道</p><p>管道的通知机制有些类似于缓存，一个进程将数据存储于缓存当中，然后等待另外一个进程去拿。类似的，一个进程将数据放于管道中，然后等另一个进程从管道中获取，并且管道是<strong>单向传输</strong>的，也就是说，数据只能从A到B，或者从B到A，并不能做到A和B相互发送和接收。</p><p>从管道的机制以及它单向传输的特点，不难分析出来，管道十分简单，但是不适合频繁的进程通信，进程间如果通过管道进行通信的话，效率会很低。</p></li><li><p>FIFO</p><p>FIFO文件通常也称为命名管道（named pipe）。命名管道是一种特殊类型的文件，它在文件系统中以文件名的形式存在。</p></li><li><p>消息队列</p><p>我们可以通过将进程A所需要发送的信息存入对应的消息队列当中，进程B需要时再去对应的消息队列当中获取。这样便能够把进程的数据放在消息队列中，而不需要等待其他进程来取便可以继续进行后续的操作。</p></li><li><p>共享内存</p><p>系统在加载一个进程的时候，分配给进程的内存是虚拟内存空间，因此，可以让互相通信的两个进程各拿出一块虚拟地址空间，映射到相同的物理内存当中，从而完成内存共享机制。</p><p>当两个进程共享内存之后，不可避免地便会出现多进程竞争资源的问题，类似于线程安全问题。</p></li><li><p>信号量</p><p>信号量的本质就是一个计数器，用于实现进程间的互斥于同步，信号量只能进行操作等待V(sv)和发送信号P(sv)两种操作。</p></li><li><p>Socket</p><p>管道、消息队列、共享内存、信号量这四种方式，都是多个进程在同一台主机之间的通信，当涉及到不同主机的进程间通信时，则需要使用Socket，Socket会指定所需要通信的进程所对应的IP地址及其所监听/发送的端口号。</p></li></ol><h2><span id="死锁">死锁</span></h2><p>锁是多用户环境中对数据访问的控制。</p><p>指两个或两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程。</p><ul><li>系统资源不足</li><li>资源分配不当</li><li>进程推进顺序不当</li></ul><h3><span id="客情占资源">客情占资源</span></h3><ol><li>可抢占资源：可以从拥有它的进程中抢占而不会产生任何副作用。</li><li>不可抢占资源：在不引起相关的计算失败的情况下，无法把它从占有它进程处抢占过来。</li></ol><h3><span id="必要条件">必要条件</span></h3><ul><li>互斥：每个资源要么已经分配给了一个进程，要么就是可用的。</li><li>占有和等待：已经得到了某个资源的进程可以再请求新的资源。</li><li>不可抢占：已经分配给一个进程的资源不能强制性地被抢占，它只能被占有它的进程显式地释放。</li><li>循环等待：有两个或者两个以上的进程组成一条环路，该环路中的每个进程都在等待下一个进程所占有的资源。</li></ul><h3><span id="处理方法">处理方法</span></h3><ul><li>鸵鸟策略</li><li>死锁检测与死锁恢复</li><li>死锁预防</li><li>死锁避免</li></ul><h3><span id="鸵鸟策略">鸵鸟策略</span></h3><p>把头埋在沙子里，假装根本没发生问题。</p><p>因为解决死锁问题的代价很高，因此鸵鸟策略这种不采取任务措施的方案会获得更高的性能。</p><p>当发生死锁时不会对用户造成多大影响，或发生死锁的概率很低，可以采用鸵鸟策略。</p><p>大多数操作系统，包括 Unix，Linux 和 Windows，处理死锁问题的办法仅仅是忽略它。</p><h3><span id="死锁恢复">死锁恢复</span></h3><ul><li>利用抢占恢复</li><li>利用回滚恢复</li><li>通过杀死进程恢复</li></ul><h3><span id="死锁预防">死锁预防</span></h3><p>在程序运行之前预防发生死锁。</p><ul><li><p>破坏互斥条件</p><p>例如假脱机打印机技术允许若干个进程同时输出，唯一真正请求物理打印机的进程是打印机守护进程。</p></li><li><p>破坏占有和等待条件</p><p>一种实现方式是规定所有进程在开始执行前请求所需要的全部资源。</p></li><li><p>破坏不可抢占条件</p></li><li><p>破坏环路等待</p><p>给资源统一编号，进程只能按编号顺序来请求资源。</p></li></ul><h3><span id="死锁避免">死锁避免</span></h3><ol><li><p>安全状态</p><p>如果没有死锁发生，并且即使所有进程突然请求对资源的最大需求，也仍然存在某种调度次序能够使得每一个进程运行完毕，则称该状态是安全的。</p></li><li><p>单个资源的银行家算法</p><p>一个小城镇的银行家，他向一群客户分别承诺了一定的贷款额度，算法要做的是判断对请求的满足是否会进入不安全状态，如果是，就拒绝请求；否则予以分配。</p></li><li><p>多个资源银行家算法</p></li></ol><h2><span id="内存管理">内存管理</span></h2><h3><span id="虚拟内存">虚拟内存</span></h3><p>虚拟内存的目的是为了让物理内存扩充成更大的逻辑内存，从而让程序获得更多的可用内存。</p><h3><span id="虚拟内存-共享内存和常驻内存">虚拟内存、共享内存和常驻内存</span></h3><ul><li>虚拟内存 VIRT：进程“需要的”虚拟内存大小，包括进程使用的库、代码、数据，以及malloc、new分配的堆空间和分配的栈空间等。</li><li>常驻内存 RES：进程当前使用的内存大小，包括使用中的malloc、new分配的堆空间和分配的栈空间。</li><li>共享内存 SHR：除了自身进程的共享内存，也包括其他进程的共享内存。计算某个进程所占的物理内存大小公式：RES – SHR。</li></ul><h3><span id="虚拟地址-逻辑地址和物理地址">虚拟地址、逻辑地址和物理地址</span></h3><p><img src="https://pic.tyzhang.top/images/2020/08/03/20141007100931931.md.png" alt="虚拟地址到物理地址的转换"></p><ul><li>虚拟地址是由程序产生的由段选择符和段内偏移地址组成的地址。这两部分组成的地址并没有直接访问物理内存，而是要通过分段地址的变换处理后才会对应到相应的物理内存地址。</li><li>逻辑地址指由程序产生的段内偏移地址。有时把逻辑地址当成虚拟地址，两者并没有明确的界限。</li><li>线性地址是逻辑地址到物理地址变换之间的中间层。程序代码会产生逻辑地址，或者说是段中的偏移地址，加上相应段的基地址就生成了一个线性地址。</li><li>物理地址是指现在 CPU 外部地址总线上的寻址物理内存的地址信号，是地址变换的最终结果。</li></ul><h3><span id="页面置换算法">页面置换算法</span></h3><p>页面置换算法的主要目标是使页面置换频率最低（也可以说缺页率最低）。</p><ol><li><p>OPT</p></li><li><p>LRU</p></li><li><p>FIFO</p></li><li><p>SCR, 第二次机会算法</p><p>第二次机会算法可视为一个环形队列。用一个指针指示哪一页是下面要淘汰的。当需要一个存储块时，指针就前进，直至找到访问位是0的页。随着指针的前进，把访问位就清为0。在最坏的情况下，所有的访问位都是1，指针要通过整个队列一周，每个页都给第二次机会。这时就退化成FIFO算法了。</p></li></ol><h4><span id="分页储存管理方式">分页储存管理方式</span></h4><p>在该方式中，将用户程序地址空间分为若干固定大小的区域，称为“页”或“页面”。典型的页面大小为1KB。相应的，也将内存空间分为若干个物理块或页框（frame），页和块的大小相同。这样可将用户程序的任一页放入任一物理块中，实现了离散分配。</p><h4><span id="分段储存管理方式">分段储存管理方式</span></h4><p>这是为了满足用户要求而形成的一种储存管理方式。它把用户程序的地址空间分为若干个大小不同的段，每段可定义一组相对完整的信息。在储存器分配时，以段为单位，这些段在内存中可以不相邻接，所以也同样实现了离散分配。</p><h3><span id="分段">分段</span></h3><p>虚拟内存采用的是分页技术，也就是将地址空间划分成固定大小的页，每一页再与内存进行映射。</p><p>分段的做法是把每个表分成段，一个段构成一个独立的地址空间。每个段的长度可以不同，并且可以动态增长。</p><h3><span id="段页式">段页式</span></h3><p>这是分页和分段两种储存管理方式相结合的产物。程序的地址空间划分为多个拥有独立地址空间的段，每个段上的地址空间划分为大小相同的页。这样既拥有分段系统的共享保护，又拥有分页系统的虚拟内存功能。它兼具两者的优点，是目前应用较为广泛的一种储存管理方式。</p><p>对用户而言，分段是对内存的有效使用；而对于计算机而言，分页可以提高内存的使用效率。在段页式存储中，每个分段又被分成若干个固定大小的页。页面大小等于页框。地址结构：段号 + 页号 + 页内位移。</p><p>优点:</p><p>(1) 它提供了大量的虚拟存储空间。</p><p>(2) 能有效地利用主存，为组织多道程序运行提供了方便。</p><p>缺点：</p><p>(1) 增加了硬件成本、系统的复杂性和管理上的开消。</p><p>(2) 存在着系统发生抖动的危险。</p><p>(3) 存在着内碎片。</p><p>(4) 还有各种表格要占用主存空间。</p><h3><span id="分页和分段">分页和分段</span></h3><ul><li>对程序员的透明性：分页透明，但是分段需要程序员显式划分每个段。</li><li>地址空间的维度：分页是一维地址空间，分段是二维的。</li><li>大小是否可以改变：页的大小不可变，段的大小可以动态改变。</li><li>出现的原因：分页主要用于实现虚拟内存，从而获得更大的地址空间；分段主要是为了使程序和数据可以被划分为逻辑上独立的地址空间并且有助于共享和保护。</li></ul><h2><span id="设备管理">设备管理</span></h2><h3><span id="磁盘调度算法">磁盘调度算法</span></h3><p>读写一个磁盘块的时间的影响因素有：</p><ul><li>旋转时间（主轴转动盘面，使得磁头移动到适当的扇区上）</li><li>寻道时间（制动手臂移动，使得磁头移动到适当的磁道上）</li><li>实际的数据传输时间</li></ul><p>其中，寻道时间最长，因此磁盘调度的主要目标是使磁盘的平均寻道时间最短。</p><ol><li><p>先来先服务</p><p>FIFO，按照磁盘请求的顺序进行调度。</p><p>优点是公平和简单。缺点也很明显，因为未对寻道做任何优化，使平均寻道时间可能较长。</p></li><li><p>最短寻道时间优先</p><p>SSTF，优先调度与当前磁头所在磁道距离最近的磁道。</p><p>虽然平均寻道时间比较低，但是不够公平。如果新到达的磁道请求总是比一个在等待的磁道请求近，那么在等待的磁道请求会一直等待下去，也就是出现饥饿现象。具体来说，两端的磁道请求更容易出现饥饿现象。</p><p><img src="https://pic.tyzhang.top/images/2020/08/03/4e2485e4-34bd-4967-9f02-0c093b797aaa.md.png" alt="最短寻道时间优先"></p></li><li><p>电梯算法</p><p>SCAN，电梯总是保持一个方向运行，直到该方向没有请求为止，然后改变运行方向。</p><p>电梯算法（扫描算法）和电梯的运行过程类似，总是按一个方向来进行磁盘调度，直到该方向上没有未完成的磁盘请求，然后改变方向。</p><p>因为考虑了移动方向，因此所有的磁盘请求都会被满足，解决了 SSTF 的饥饿问题。</p><p><img src="https://pic.tyzhang.top/images/2020/08/03/271ce08f-c124-475f-b490-be44fedc6d2e.md.png" alt="电梯算法"></p></li><li><p>循环扫描</p></li></ol><h2><span id="场景">场景</span></h2><h3><span id="遍历二维数组按行遍历和按列遍历效率是否不同">遍历二维数组，按行遍历和按列遍历效率是否不同</span></h3><p>二维数组的内存地址是连续的，当前行的尾与下一行的头相邻</p><p>现代计算机，在CPU与内存之间还有一种存储机制，那就是CPU缓存（cache）。CPU缓存的容量比内存小的多但是交换速度却比内存要快得多。缓存的出现主要是为了解决CPU运算速度与内存读写速度不匹配的矛盾，因为CPU运算速度要比内存读写速度快很多，这样会使CPU花费很长时间等待数据到来或把数据写入内存。</p><p>访问数组元素时，CPU不会每次只从内存中读取一个元素，而是读取一个区域的元素。假设二维数组的大小为（10 x 10），访问第一个元素时，CPU也会读取它的相邻元素，因为这个数组比较小，CPU一次就可以把所有元素缓存，因此无论是按行访问数组还是按列访问数组，CPU访问主存的数量都相同。随着数组元素越来越多，CPU缓存一次只能读取数组不到一行的数据，因此按列访问元素时每访问一个元素都要访问内存，因此速度就会慢很多。</p><h3><span id="32-位系统最大寻址空间">32 位系统最大寻址空间</span></h3><p>寻址空间一般指的是CPU对于<a href="http://baike.baidu.com/view/757253.htm">内存寻址</a>的能力。通俗地说，就是能最多用到多少内存的一个问题。数据在<a href="http://baike.baidu.com/view/87697.htm">存储器</a>(RAM)中存放是有规律的 ，CPU在运算的时候需要把数据提取出来就需要知道数据在那里 ，这时候就需要挨家挨户的找，这就叫做寻址，但如果地址太多超出了CPU的能力范围，CPU就无法找到数据了。 CPU最大能查找多大范围的地址叫做寻址能力 ，CPU的寻址能力以<a href="http://baike.baidu.com/view/60408.htm">字节</a>为单位 ，如32位寻址的CPU可以寻址2的32次方大小的地址也就是4G，这也是为什么32位的CPU最大能搭配4G内存的原因 ，再多的话CPU就找不到了。</p><h3><span id="内存泄漏">内存泄漏</span></h3><p>内存泄露是指：内存泄漏也称作&quot;存储渗漏&quot;，用动态存储分配函数动态开辟的空间，在使用完毕后未释放，结果导致一直占据该内存单元。直到程序结束。(其实说白了就是该内存空间使用完毕之后未回收)即所谓内存泄漏。</p><ol><li><p>单例造成的内存泄露</p><p>由于单例的静态特性使得其生命周期和应用的生命周期一样长，如果一个对象已经不再需要使用了，而单例对象还持有该对象的引用，就会使得该对象不能被正常回收，从而导致了内存泄漏。</p></li><li><p>非静态内部类创建静态实例造成的内存泄漏</p></li><li><p>资源未关闭造成的内存泄漏</p></li><li><p>静态集合类引起内存泄漏，有存无放</p></li><li><p>当集合里面的对象属性被修改后，再调用 remove() 方法时不起作用</p></li><li><p>各种连接如数据库等没有关闭</p></li></ol><h3><span id="用户态和内核态切换代价大">用户态和内核态切换代价大</span></h3><p>在用户态有一个用户态调用栈，当需要进行系统函数调用的时候，就会从用户态进入内核态，也就是需要切换到内核态栈，内核代码对用户不信任，需要进行额外的检查。系统调用的返回过程有很多额外工作，如：保存现场、恢复现场，切换栈等。所以导致了切换的开销大。</p><p>中断技术实现了切换。</p><h3><span id="id-发号器">ID 发号器</span></h3><p>对 ID 的要求</p><ul><li><p>全局唯一</p></li><li><p>按照时间粗略有序</p></li><li><p>尽可能短</p></li></ul><p>实现策略</p><ul><li><p>参考 Twitter 的雪花算法：64 位的比特，第 0 位空着，接下来的 41 位为 Unix 时间戳，然后接下来的 10 位为机器的id，最后 12 位为计数用的</p></li><li><p>使用 UUID 算法</p></li><li><p>多台 MySQL 主键自增实现 ID 唯一</p></li></ul>]]></content>
    
    
      
      
    <summary type="html">&lt;blockquote&gt;
&lt;p&gt;学啊，学无止境，太深了。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;&lt;span id=&quot;概述&quot;&gt;概述&lt;/span&gt;&lt;/h2&gt;
&lt;h3&gt;&lt;span id=&quot;基本特征&quot;&gt;基本特征&lt;/span&gt;&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;并发&lt;/p&gt;
&lt;p&gt;</summary>
      
    
    
    
    
    <category term="笔记" scheme="https://tyzhang.top/tags/%E7%AC%94%E8%AE%B0/"/>
    
  </entry>
  
  <entry>
    <title>几种生产者-消费者模型</title>
    <link href="https://tyzhang.top/article/producer/"/>
    <id>https://tyzhang.top/article/producer/</id>
    <published>2020-07-31T16:00:00.000Z</published>
    <updated>2021-01-18T13:19:04.000Z</updated>
    
    <content type="html"><![CDATA[<blockquote><p>几种生产者消费者模型总结，还有一个采用该模式的线程池实现。</p></blockquote><h3><span id="生产者消费者模型">生产者消费者模型</span></h3><p>生产者生产数据到缓冲区去，消费者从缓冲区中取数据。</p><p>如果缓冲区满了，生产者线程阻塞。</p><p>如果缓冲区为空，那么消费者线程阻塞。</p><h3><span id="采用-wait-notify-实现">采用 wait() / notify() 实现</span></h3><ol><li><p>Resource 资源类，类中包含资源池大小和已经有的数量。生产者和消费者通过持有资源类的成员变量，Main 方法通过构造函数传入，线程 run 方法中操作资源类的新加和减少。</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Resource</span> &#123;</span><br><span class="line">    <span class="keyword">private</span> <span class="type">int</span> <span class="variable">num</span> <span class="operator">=</span> <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">private</span> <span class="type">int</span> <span class="variable">size</span> <span class="operator">=</span> <span class="number">10</span>;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">synchronized</span> <span class="keyword">void</span> <span class="title function_">remove</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> (num &gt; <span class="number">0</span>) &#123;</span><br><span class="line">            num--;</span><br><span class="line">            System.out.println(<span class="string">&quot;消费者&quot;</span> + Thread.currentThread().getName() + <span class="string">&quot;消耗了一个资源，还剩&quot;</span> + num);</span><br><span class="line">            notifyAll();</span><br><span class="line">        &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">            <span class="keyword">try</span> &#123;</span><br><span class="line">                wait();</span><br><span class="line">                System.out.println(<span class="string">&quot;消费者&quot;</span> + Thread.currentThread().getName() + <span class="string">&quot;等待中“);</span></span><br><span class="line"><span class="string">            &#125; catch (InterruptedException e) &#123;</span></span><br><span class="line"><span class="string">                e.printStackTrace();</span></span><br><span class="line"><span class="string">            &#125;</span></span><br><span class="line"><span class="string">        &#125;</span></span><br><span class="line"><span class="string">    &#125;</span></span><br><span class="line"><span class="string">    public synchronized void add() &#123;</span></span><br><span class="line"><span class="string">        if (num &lt; size) &#123;</span></span><br><span class="line"><span class="string">            num++;</span></span><br><span class="line"><span class="string">            System.out.println(&quot;</span>生产者<span class="string">&quot; + Thread.currentThread().getName() + &quot;</span>生产了一个资源，当前有<span class="string">&quot; + num);</span></span><br><span class="line"><span class="string">            notifyAll();</span></span><br><span class="line"><span class="string">        &#125; else &#123;</span></span><br><span class="line"><span class="string">            try &#123;</span></span><br><span class="line"><span class="string">                wait();</span></span><br><span class="line"><span class="string">                System.out.println(&quot;</span>生产者<span class="string">&quot; + Thread.currentThread().getName() + &quot;</span>等待中“);</span><br><span class="line">            &#125; <span class="keyword">catch</span> (InterruptedException e) &#123;</span><br><span class="line">                e.printStackTrace();</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></li><li><p>消费者线程</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="keyword">public</span> <span class="keyword">class</span> <span class="title class_">ConsumerThread</span> <span class="keyword">extends</span> <span class="title class_">Thread</span> &#123;</span><br><span class="line">    <span class="keyword">private</span> Resource resource;</span><br><span class="line">    <span class="keyword">public</span> <span class="title function_">ConsumerThread</span><span class="params">(Resource resource)</span> &#123;</span><br><span class="line">        <span class="built_in">this</span>.resource = resource;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">run</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="keyword">while</span> (<span class="literal">true</span>) &#123;</span><br><span class="line">            <span class="keyword">try</span> &#123;</span><br><span class="line">                Thread.sleep(<span class="number">1000</span>);</span><br><span class="line">            &#125; <span class="keyword">catch</span> (InterruptedException e) &#123;</span><br><span class="line">                e.printStackTrace();</span><br><span class="line">            &#125;</span><br><span class="line">            resource.remove();</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></li><li><p>生产者线程</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="keyword">public</span> <span class="keyword">class</span> <span class="title class_">ProducerThread</span> <span class="keyword">extends</span> <span class="title class_">Thread</span> &#123;</span><br><span class="line">    <span class="keyword">private</span> Resource resource;</span><br><span class="line">    <span class="keyword">public</span> <span class="title function_">ProducerThread</span><span class="params">(Resource resource)</span> &#123;</span><br><span class="line">        <span class="built_in">this</span>.resource = resource;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">run</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="keyword">while</span> (<span class="literal">true</span>) &#123;</span><br><span class="line">            <span class="keyword">try</span> &#123;</span><br><span class="line">                Thread.sleep(<span class="number">1000</span>);</span><br><span class="line">            &#125; <span class="keyword">catch</span> (InterruptedException e) &#123;</span><br><span class="line">                e.printStackTrace();</span><br><span class="line">            &#125;</span><br><span class="line">            resource.add();</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></li><li><p>测试类</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><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="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line">    <span class="type">Resource</span> <span class="variable">resource</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">Resource</span>();</span><br><span class="line">    <span class="type">ProducerThread</span> <span class="variable">producerThread</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">ProducerThread</span>(resource);</span><br><span class="line">    <span class="type">ProducerThread</span> <span class="variable">producerThread1</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">ProducerThread</span>(resource);</span><br><span class="line">    <span class="type">ProducerThread</span> <span class="variable">producerThread2</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">ProducerThread</span>(resource);</span><br><span class="line">    <span class="type">ConsumerThread</span> <span class="variable">consumerThread</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">ConsumerThread</span>(resource);</span><br><span class="line">    <span class="type">ConsumerThread</span> <span class="variable">consumerThread1</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">ConsumerThread</span>(resource);</span><br><span class="line">    producerThread.start();</span><br><span class="line">    producerThread1.start();</span><br><span class="line">    producerThread2.start();</span><br><span class="line">    consumerThread.start();</span><br><span class="line">    consumerThread1.start();</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></li></ol><h3><span id="采用-lock-和-condition">采用 Lock 和 Condition</span></h3><p>修改 Resource 如下：</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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">public</span> <span class="keyword">class</span> <span class="title class_">Resource</span> &#123;</span><br><span class="line">    <span class="keyword">private</span> <span class="type">int</span> <span class="variable">num</span> <span class="operator">=</span> <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">private</span> <span class="type">int</span> <span class="variable">size</span> <span class="operator">=</span> <span class="number">10</span>;</span><br><span class="line">    <span class="keyword">private</span> Lock lock;</span><br><span class="line">    <span class="keyword">private</span> Condition consumerCondition;</span><br><span class="line">    <span class="keyword">private</span> Condition producerCondition;</span><br><span class="line">    <span class="keyword">public</span> <span class="title function_">Resource</span><span class="params">(Lock lock, Condition consumerCondition, Condition producerCondition)</span> &#123;</span><br><span class="line">        <span class="built_in">this</span>.lock = lock;</span><br><span class="line">        <span class="built_in">this</span>.consumerCondition = consumerCondition;</span><br><span class="line">        <span class="built_in">this</span>.producerCondition = producerCondition;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">remove</span><span class="params">()</span> &#123;</span><br><span class="line">        lock.lock();</span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            <span class="keyword">if</span> (num &gt; <span class="number">0</span>) &#123;</span><br><span class="line">                num--;</span><br><span class="line">                System.out.println(<span class="string">&quot;消费者&quot;</span> + Thread.currentThread().getName() + <span class="string">&quot;消耗了一个资源，现在有&quot;</span> + num);</span><br><span class="line">                producerCondition.signalAll();</span><br><span class="line">            &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                consumerCondition.await();</span><br><span class="line">                System.out.println(<span class="string">&quot;消费者&quot;</span> + Thread.currentThread().getName() + <span class="string">&quot;等待中&quot;</span>);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125; <span class="keyword">catch</span> (InterruptedException e) &#123;</span><br><span class="line">            e.printStackTrace();</span><br><span class="line">        &#125; <span class="keyword">finally</span> &#123;</span><br><span class="line">            lock.unlock();</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">add</span><span class="params">()</span> &#123;</span><br><span class="line">        lock.lock();</span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            <span class="keyword">if</span> (num &lt; size) &#123;</span><br><span class="line">                num++;</span><br><span class="line">                System.out.println(<span class="string">&quot;生产者&quot;</span> + Thread.currentThread().getName() + <span class="string">&quot;生产了一个资源，现在有&quot;</span> + num);</span><br><span class="line">                consumerCondition.signalAll();</span><br><span class="line">            &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                producerCondition.await();</span><br><span class="line">                System.out.println(<span class="string">&quot;生产者&quot;</span> + Thread.currentThread().getName() + <span class="string">&quot;进入等待&quot;</span>);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125; <span class="keyword">catch</span> (InterruptedException e) &#123;</span><br><span class="line">            e.printStackTrace();</span><br><span class="line">        &#125; <span class="keyword">finally</span> &#123;</span><br><span class="line">            lock.unlock();</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>测试：</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><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="type">Lock</span> <span class="variable">lock</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">ReentrantLock</span>();</span><br><span class="line"><span class="type">Condition</span> <span class="variable">consumerCondition</span> <span class="operator">=</span> lock.newCondition();</span><br><span class="line"><span class="type">Condition</span> <span class="variable">producerCondition</span> <span class="operator">=</span> lock.newCondition();</span><br><span class="line"><span class="type">Resource</span> <span class="variable">resource</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">Resource</span>(lock, consumerCondition, producerCondition);</span><br><span class="line"><span class="type">ProducerThread</span> <span class="variable">producerThread</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">ProducerThread</span>(resource);</span><br><span class="line"><span class="type">ProducerThread</span> <span class="variable">producerThread1</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">ProducerThread</span>(resource);</span><br><span class="line"><span class="type">ProducerThread</span> <span class="variable">producerThread2</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">ProducerThread</span>(resource);</span><br><span class="line"><span class="type">ConsumerThread</span> <span class="variable">consumerThread</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">ConsumerThread</span>(resource);</span><br><span class="line">producerThread.start();</span><br><span class="line">producerThread1.start();</span><br><span class="line">producerThread2.start();</span><br><span class="line">consumerThread.start();</span><br></pre></td></tr></table></figure><h3><span id="使用-blockingqueue">使用 BlockingQueue</span></h3><table><thead><tr><th></th><th>抛出异常</th><th>特殊值</th><th>阻塞</th><th>超时</th></tr></thead><tbody><tr><td>插入</td><td><a href="https://blog.csdn.net/wei_ya_wen/article/details/19344939"><code>add(e)</code></a></td><td><a href="https://blog.csdn.net/wei_ya_wen/article/details/19344939"><code>offer(e)</code></a></td><td><a href="https://blog.csdn.net/wei_ya_wen/article/details/19344939"><code>put(e)</code></a></td><td><a href="https://blog.csdn.net/wei_ya_wen/article/details/19344939"><code>offer(e, time, unit)</code></a></td></tr><tr><td>移除</td><td><a href="https://blog.csdn.net/wei_ya_wen/article/details/19344939"><code>remove()</code></a></td><td><a href="https://blog.csdn.net/wei_ya_wen/article/details/19344939"><code>poll()</code></a></td><td><a href="https://blog.csdn.net/wei_ya_wen/article/details/19344939"><code>take()</code></a></td><td><a href="https://blog.csdn.net/wei_ya_wen/article/details/19344939"><code>poll(time, unit)</code></a></td></tr><tr><td>检查</td><td><a href="https://blog.csdn.net/wei_ya_wen/article/details/19344939"><code>element()</code></a></td><td><a href="https://blog.csdn.net/wei_ya_wen/article/details/19344939"><code>peek()</code></a></td><td>不可用</td><td>不可用</td></tr></tbody></table><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Resource</span> &#123;</span><br><span class="line">    <span class="keyword">private</span> BlockingQueue&lt;Integer&gt; blockingQueue = <span class="keyword">new</span> <span class="title class_">LinkedBlockingDeque</span>&lt;&gt;(<span class="number">10</span>);</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">add</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            blockingQueue.put(<span class="number">1</span>);</span><br><span class="line">            System.out.println(<span class="string">&quot;生产者&quot;</span> + Thread.currentThread().getName() + <span class="string">&quot;生产了一个资源，当前有&quot;</span> + blockingQueue.size());</span><br><span class="line">        &#125; <span class="keyword">catch</span> (InterruptedException e) &#123;</span><br><span class="line">            e.printStackTrace();</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">remove</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            blockingQueue.take();</span><br><span class="line">            System.out.println(<span class="string">&quot;消费者&quot;</span> + Thread.currentThread().getName() + <span class="string">&quot;消费了一个资源，当前有&quot;</span> + blockingQueue.size());</span><br><span class="line">        &#125; <span class="keyword">catch</span> (InterruptedException e) &#123;</span><br><span class="line">            e.printStackTrace();</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>因为这里使用了泛型，所以可以基于 BlockQueue 手写一个自定义线程池。</p><h3><span id="手写线程池">手写线程池</span></h3><img src="https://pic.tyzhang.top/images/2020/06/23/866bf38c4fd1f818e4d20ab95999d74f.jpg" style="zoom:67%;"><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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></pre></td><td class="code"><pre><span class="line"><span class="meta">@Slf4j</span></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">BlockingQueue</span>&lt;T&gt; &#123;</span><br><span class="line">    <span class="comment">// 任务队列</span></span><br><span class="line">    <span class="keyword">private</span> Deque&lt;T&gt; queue = <span class="keyword">new</span> <span class="title class_">ArrayDeque</span>&lt;&gt;();</span><br><span class="line">    <span class="comment">// 锁</span></span><br><span class="line">    <span class="keyword">private</span> <span class="type">ReentrantLock</span> <span class="variable">lock</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">ReentrantLock</span>();</span><br><span class="line">    <span class="comment">// 生产者条件变量，添加线程，满的时候等待</span></span><br><span class="line">    <span class="keyword">private</span> <span class="type">Condition</span> <span class="variable">producerCondition</span> <span class="operator">=</span> lock.newCondition();</span><br><span class="line">    <span class="comment">// 消费者条件变量，执行线程，空的时候等待</span></span><br><span class="line">    <span class="keyword">private</span> <span class="type">Condition</span> <span class="variable">consumerCondition</span> <span class="operator">=</span> lock.newCondition();</span><br><span class="line">    <span class="comment">// 容量</span></span><br><span class="line">    <span class="keyword">private</span> <span class="type">int</span> capcity;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="title function_">BlockingQueue</span><span class="params">(<span class="type">int</span> capcity)</span> &#123;</span><br><span class="line">        <span class="built_in">this</span>.capcity = capcity;</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">public</span> T <span class="title function_">task</span><span class="params">()</span> &#123;</span><br><span class="line">        lock.lock();</span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            <span class="keyword">while</span> (queue.isEmpty()) &#123;</span><br><span class="line">                <span class="keyword">try</span> &#123;</span><br><span class="line">                    consumerCondition.await();</span><br><span class="line">                &#125; <span class="keyword">catch</span> (InterruptedException e) &#123;</span><br><span class="line">                    e.printStackTrace();</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="type">T</span> <span class="variable">t</span> <span class="operator">=</span> queue.removeFirst();</span><br><span class="line">            producerCondition.signal();</span><br><span class="line">            <span class="keyword">return</span> t;</span><br><span class="line">        &#125; <span class="keyword">finally</span> &#123;</span><br><span class="line">            lock.unlock();</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="keyword">public</span> T <span class="title function_">poll</span><span class="params">(<span class="type">long</span> timeout, TimeUnit unit)</span> &#123;</span><br><span class="line">        lock.lock();</span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            <span class="type">long</span> <span class="variable">nanos</span> <span class="operator">=</span> unit.toNanos(timeout);</span><br><span class="line">            <span class="keyword">while</span> (queue.isEmpty()) &#123;</span><br><span class="line">                <span class="keyword">try</span> &#123;</span><br><span class="line">                    <span class="keyword">if</span> (nanos &lt;= <span class="number">0</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">                    nanos = consumerCondition.awaitNanos(nanos);</span><br><span class="line">                &#125; <span class="keyword">catch</span> (InterruptedException e) &#123;</span><br><span class="line">                    e.printStackTrace();</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="type">T</span> <span class="variable">t</span> <span class="operator">=</span> queue.removeFirst();</span><br><span class="line">            producerCondition.signal();</span><br><span class="line">            <span class="keyword">return</span> t;</span><br><span class="line">        &#125; <span class="keyword">finally</span> &#123;</span><br><span class="line">            lock.unlock();</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="keyword">public</span> <span class="keyword">void</span> <span class="title function_">put</span><span class="params">(T task)</span> &#123;</span><br><span class="line">        lock.lock();</span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            <span class="keyword">while</span> (queue.size() == capcity) &#123;</span><br><span class="line">                <span class="keyword">try</span> &#123;</span><br><span class="line">                    producerCondition.await();</span><br><span class="line">                    log.debug(<span class="string">&quot;等待任务加入队列&#123;&#125;&quot;</span>, task);</span><br><span class="line">                &#125; <span class="keyword">catch</span> (InterruptedException e) &#123;</span><br><span class="line">                    e.printStackTrace();</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">            log.debug(<span class="string">&quot;加入任务队列&#123;&#125;&quot;</span>, task);</span><br><span class="line">            queue.addLast(task);</span><br><span class="line">            consumerCondition.signal();</span><br><span class="line">        &#125; <span class="keyword">finally</span> &#123;</span><br><span class="line">            lock.unlock();</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="keyword">public</span> <span class="type">boolean</span> <span class="title function_">offer</span><span class="params">(T task, <span class="type">long</span> timeout, TimeUnit timeUnit)</span> &#123;</span><br><span class="line">        lock.lock();</span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            <span class="type">long</span> <span class="variable">nanos</span> <span class="operator">=</span> timeUnit.toNanos(timeout);</span><br><span class="line">            <span class="keyword">while</span> (queue.size() == capcity) &#123;</span><br><span class="line">                <span class="keyword">try</span> &#123;</span><br><span class="line">                    <span class="keyword">if</span> (nanos &lt;= <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">                    log.debug(<span class="string">&quot;等待加入队列&#123;&#125;&quot;</span>, task);</span><br><span class="line">                    nanos = producerCondition.awaitNanos(nanos);</span><br><span class="line">                &#125; <span class="keyword">catch</span> (InterruptedException e) &#123;</span><br><span class="line">                    e.printStackTrace();</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">            log.debug(<span class="string">&quot;加入任务队列&#123;&#125;&quot;</span>, task);</span><br><span class="line">            queue.addLast(task);</span><br><span class="line">            consumerCondition.signal();</span><br><span class="line">            <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line">        &#125; <span class="keyword">finally</span> &#123;</span><br><span class="line">            lock.unlock();</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="keyword">public</span> <span class="type">int</span> <span class="title function_">size</span><span class="params">()</span> &#123;</span><br><span class="line">        lock.lock();</span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> queue.size();</span><br><span class="line">        &#125; <span class="keyword">finally</span> &#123;</span><br><span class="line">            lock.unlock();</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 java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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></pre></td><td class="code"><pre><span class="line"><span class="meta">@Slf4j</span></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">ThreadPool</span> &#123;</span><br><span class="line">    <span class="comment">// 任务队列</span></span><br><span class="line">    <span class="keyword">private</span> BlockingQueue&lt;Runnable&gt; taskQueue;</span><br><span class="line">    <span class="comment">// 线程集合</span></span><br><span class="line">    <span class="keyword">private</span> HashSet&lt;Worker&gt; workers = <span class="keyword">new</span> <span class="title class_">HashSet</span>&lt;&gt;();</span><br><span class="line">    <span class="comment">// 核心线程数</span></span><br><span class="line">    <span class="keyword">private</span> <span class="type">int</span> coreSize;</span><br><span class="line">    <span class="comment">// 获取任务时的超时时间</span></span><br><span class="line">    <span class="keyword">private</span> <span class="type">long</span> timeout;</span><br><span class="line">    <span class="keyword">private</span> TimeUnit timeUnit;</span><br><span class="line">    <span class="keyword">private</span> RejectPolicy&lt;Runnable&gt; rejectPolicy;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="title function_">ThreadPool</span><span class="params">(<span class="type">int</span> coreSize, <span class="type">long</span> timeout, TimeUnit timeUnit, RejectPolicy&lt;Runnable&gt; rejectPolicy, <span class="type">int</span> queueCapcity)</span> &#123;</span><br><span class="line">        <span class="built_in">this</span>.coreSize = coreSize;</span><br><span class="line">        <span class="built_in">this</span>.timeout = timeout;</span><br><span class="line">        <span class="built_in">this</span>.timeUnit = timeUnit;</span><br><span class="line">        <span class="built_in">this</span>.rejectPolicy = rejectPolicy;</span><br><span class="line">        <span class="built_in">this</span>.taskQueue = <span class="keyword">new</span> <span class="title class_">BlockingQueue</span>&lt;&gt;(queueCapcity);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">// 执行任务</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">execute</span><span class="params">(Runnable task)</span> &#123;</span><br><span class="line">        <span class="keyword">synchronized</span> (workers) &#123;</span><br><span class="line">            <span class="keyword">if</span> (workers.size() &lt; coreSize) &#123;</span><br><span class="line">                <span class="type">Worker</span> <span class="variable">worker</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">Worker</span>(task);</span><br><span class="line">                log.debug(<span class="string">&quot;新增worker&#123;&#125;&quot;</span>, worker);</span><br><span class="line">                workers.add(worker);</span><br><span class="line">                worker.start();</span><br><span class="line">            &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                taskQueue.tryPut(rejectPolicy, task);</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="keyword">class</span> <span class="title class_">Worker</span> <span class="keyword">extends</span> <span class="title class_">Thread</span> &#123;</span><br><span class="line">        <span class="keyword">private</span> Runnable task;</span><br><span class="line">        <span class="keyword">public</span> <span class="title function_">Worker</span><span class="params">(Runnable task)</span> &#123;</span><br><span class="line">            <span class="built_in">this</span>.task = task;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">run</span><span class="params">()</span> &#123;</span><br><span class="line">            <span class="comment">// 当task不为空，执行任务；当task执行完毕，从任务队列中获取任务并执行</span></span><br><span class="line">            <span class="keyword">while</span> (task != <span class="literal">null</span> || (task = taskQueue.poll(timeout, timeUnit)) != <span class="literal">null</span>) &#123;</span><br><span class="line">                <span class="keyword">try</span> &#123;</span><br><span class="line">                    log.debug(<span class="string">&quot;正在执行&#123;&#125;&quot;</span>, task);</span><br><span class="line">                    task.run();</span><br><span class="line">                &#125; <span class="keyword">catch</span> (Exception e) &#123;</span><br><span class="line">                    e.printStackTrace();</span><br><span class="line">                &#125; <span class="keyword">finally</span> &#123;</span><br><span class="line">                    task = <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">synchronized</span> (workers) &#123;</span><br><span class="line">                log.debug(<span class="string">&quot;worker被移除&#123;&#125;&quot;</span>, <span class="built_in">this</span>);</span><br><span class="line">                workers.remove(<span class="built_in">this</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></pre></td></tr></table></figure>]]></content>
    
    
      
      
    <summary type="html">&lt;blockquote&gt;
&lt;p&gt;几种生产者消费者模型总结，还有一个采用该模式的线程池实现。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;&lt;span id=&quot;生产者消费者模型&quot;&gt;生产者消费者模型&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;生产者生产数据到缓冲区去，消费者从缓冲区中取数据。&lt;/p</summary>
      
    
    
    
    
    <category term="笔记" scheme="https://tyzhang.top/tags/%E7%AC%94%E8%AE%B0/"/>
    
  </entry>
  
</feed>