<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>Beendless ~ 快节奏,慢生活,无止境</title>
  
  <subtitle>Move Fast, Live Happily, With No End</subtitle>
  <link href="http://blog.beendless.com/atom.xml" rel="self"/>
  
  <link href="http://blog.beendless.com/"/>
  <updated>2024-08-02T03:48:22.077Z</updated>
  <id>http://blog.beendless.com/</id>
  
  <author>
    <name>Ym &amp; Yf</name>
    
  </author>
  
  <generator uri="https://hexo.io/">Hexo</generator>
  
  <entry>
    <title>Build Your Own Video Compression Service with Rust WASM</title>
    <link href="http://blog.beendless.com/2024/08/02/Build%20Your%20Own%20Video%20Compression%20Service%20with%20Rust%20WASM/"/>
    <id>http://blog.beendless.com/2024/08/02/Build%20Your%20Own%20Video%20Compression%20Service%20with%20Rust%20WASM/</id>
    <published>2024-08-02T10:15:24.000Z</published>
    <updated>2024-08-02T03:48:22.077Z</updated>
    
    <content type="html"><![CDATA[<p>Yesterday I explained how to use FFMPEG to compress video efficiently. How to deploy a video compression service? Here we can try to leverage the existing technologies like Rust, Wasm.</p><p>To create a Rust application that compiles to WebAssembly (WASM) and runs the ffmpeg command to convert an MP4 file, you will need to use a few crates and tools:</p><ul><li>FFmpeg: To manipulate video files.</li><li>Wasm-pack: To build the Rust code into WebAssembly.</li><li>wasm-bindgen: To interact between Rust and JavaScript.</li><li>WebAssembly System Interface (WASI): To enable system calls from WebAssembly.</li></ul><p>However, directly running ffmpeg from within WASM is quite complex due to the nature of WASM and the need for system calls. Instead, it’s more common to call out to an existing ffmpeg WebAssembly port or use an appropriate WebAssembly-compatible library.</p><p>For this example, we’ll use the ffmpeg.wasm project, which provides FFmpeg compiled to WebAssembly. The Rust part will focus on preparing the environment and handling the necessary JavaScript interop.</p><p>First, let’s create a Rust project:</p><ol><li>Create a new Rust project:</li></ol><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">cargo new wasm_ffmpeg</span><br><span class="line"><span class="built_in">cd</span> wasm_ffmpeg</span><br></pre></td></tr></table></figure><ol start="2"><li>Add the necessary dependencies to your Cargo.toml:</li></ol><figure class="highlight toml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="section">[dependencies]</span></span><br><span class="line"><span class="attr">wasm-bindgen</span> = <span class="string">&quot;0.2&quot;</span></span><br></pre></td></tr></table></figure><ol start="3"><li>Install wasm-pack if you haven’t already:</li></ol><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">cargo install wasm-pack</span><br></pre></td></tr></table></figure><ol start="4"><li>Update src&#x2F;lib.rs to define a function that will be called from JavaScript:</li></ol><figure class="highlight rust"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><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">use</span> wasm_bindgen::prelude::*;</span><br><span class="line"></span><br><span class="line"><span class="meta">#[wasm_bindgen]</span></span><br><span class="line"><span class="keyword">pub</span> <span class="keyword">fn</span> <span class="title function_">process_video</span>(input_file: &amp;<span class="type">str</span>, output_file: &amp;<span class="type">str</span>) <span class="punctuation">-&gt;</span> <span class="type">String</span> &#123;</span><br><span class="line">    <span class="built_in">format!</span>(</span><br><span class="line">        <span class="string">&quot;ffmpeg -i &#123;&#125; -c:v libx264 -tag:v avc1 -movflags faststart -crf 30 -preset superfast &#123;&#125;&quot;</span>,</span><br><span class="line">        input_file, output_file</span><br><span class="line">    )</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><ol start="5"><li>Build the project using wasm-pack:</li></ol><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">wasm-pack build --target web</span><br></pre></td></tr></table></figure><ol start="6"><li>Set up html to consume the js above</li></ol><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><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></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;!DOCTYPE <span class="keyword">html</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">html</span> <span class="attr">lang</span>=<span class="string">&quot;en&quot;</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">head</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">meta</span> <span class="attr">charset</span>=<span class="string">&quot;UTF-8&quot;</span> /&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">meta</span> <span class="attr">name</span>=<span class="string">&quot;viewport&quot;</span> <span class="attr">content</span>=<span class="string">&quot;width=device-width, initial-scale=1.0&quot;</span> /&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">title</span>&gt;</span>WASM FFmpeg Example<span class="tag">&lt;/<span class="name">title</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;/<span class="name">head</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">body</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">h1</span>&gt;</span>WASM FFmpeg Example<span class="tag">&lt;/<span class="name">h1</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">input</span> <span class="attr">type</span>=<span class="string">&quot;file&quot;</span> <span class="attr">id</span>=<span class="string">&quot;inputFile&quot;</span> <span class="attr">accept</span>=<span class="string">&quot;video/mp4&quot;</span> /&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">button</span> <span class="attr">id</span>=<span class="string">&quot;convertButton&quot;</span>&gt;</span>Convert<span class="tag">&lt;/<span class="name">button</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">script</span> <span class="attr">src</span>=<span class="string">&quot;https://cdn.jsdelivr.net/npm/@ffmpeg/ffmpeg@0.10.0/dist/ffmpeg.min.js&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">script</span> <span class="attr">type</span>=<span class="string">&quot;module&quot;</span>&gt;</span><span class="language-javascript"></span></span><br><span class="line"><span class="language-javascript">      <span class="keyword">import</span> init, &#123; process_video &#125; <span class="keyword">from</span> <span class="string">&quot;./pkg/wasm_ffmpeg.js&quot;</span>;</span></span><br><span class="line"><span class="language-javascript"></span></span><br><span class="line"><span class="language-javascript">      <span class="keyword">const</span> &#123; createFFmpeg, fetchFile &#125; = <span class="title class_">FFmpeg</span>;</span></span><br><span class="line"><span class="language-javascript">      <span class="keyword">const</span> ffmpeg = <span class="title function_">createFFmpeg</span>(&#123; <span class="attr">log</span>: <span class="literal">true</span> &#125;);</span></span><br><span class="line"><span class="language-javascript"></span></span><br><span class="line"><span class="language-javascript">      <span class="keyword">async</span> <span class="keyword">function</span> <span class="title function_">main</span>(<span class="params"></span>) &#123;</span></span><br><span class="line"><span class="language-javascript">        <span class="keyword">await</span> <span class="title function_">init</span>();</span></span><br><span class="line"><span class="language-javascript"></span></span><br><span class="line"><span class="language-javascript">        <span class="variable language_">document</span></span></span><br><span class="line"><span class="language-javascript">          .<span class="title function_">getElementById</span>(<span class="string">&quot;convertButton&quot;</span>)</span></span><br><span class="line"><span class="language-javascript">          .<span class="title function_">addEventListener</span>(<span class="string">&quot;click&quot;</span>, <span class="keyword">async</span> () =&gt; &#123;</span></span><br><span class="line"><span class="language-javascript">            <span class="keyword">const</span> inputFileElement = <span class="variable language_">document</span>.<span class="title function_">getElementById</span>(<span class="string">&quot;inputFile&quot;</span>);</span></span><br><span class="line"><span class="language-javascript">            <span class="keyword">const</span> inputFile = inputFileElement.<span class="property">files</span>[<span class="number">0</span>];</span></span><br><span class="line"><span class="language-javascript">            <span class="keyword">if</span> (inputFile) &#123;</span></span><br><span class="line"><span class="language-javascript">              <span class="keyword">const</span> inputFilePath = <span class="variable constant_">URL</span>.<span class="title function_">createObjectURL</span>(inputFile);</span></span><br><span class="line"><span class="language-javascript"></span></span><br><span class="line"><span class="language-javascript">              <span class="keyword">await</span> ffmpeg.<span class="title function_">load</span>();</span></span><br><span class="line"><span class="language-javascript">              ffmpeg.<span class="title function_">FS</span>(</span></span><br><span class="line"><span class="language-javascript">                <span class="string">&quot;writeFile&quot;</span>,</span></span><br><span class="line"><span class="language-javascript">                <span class="string">&quot;input.mp4&quot;</span>,</span></span><br><span class="line"><span class="language-javascript">                <span class="keyword">await</span> <span class="title function_">fetchFile</span>(inputFilePath)</span></span><br><span class="line"><span class="language-javascript">              );</span></span><br><span class="line"><span class="language-javascript"></span></span><br><span class="line"><span class="language-javascript">              <span class="keyword">const</span> ffmpegCommand = <span class="title function_">process_video</span>(<span class="string">&quot;input.mp4&quot;</span>, <span class="string">&quot;output.mp4&quot;</span>);</span></span><br><span class="line"><span class="language-javascript">              <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">`Running command: <span class="subst">$&#123;ffmpegCommand&#125;</span>`</span>);</span></span><br><span class="line"><span class="language-javascript"></span></span><br><span class="line"><span class="language-javascript">              <span class="keyword">await</span> ffmpeg.<span class="title function_">run</span>(</span></span><br><span class="line"><span class="language-javascript">                <span class="string">&quot;-i&quot;</span>,</span></span><br><span class="line"><span class="language-javascript">                <span class="string">&quot;input.mp4&quot;</span>,</span></span><br><span class="line"><span class="language-javascript">                <span class="string">&quot;-c:v&quot;</span>,</span></span><br><span class="line"><span class="language-javascript">                <span class="string">&quot;libx264&quot;</span>,</span></span><br><span class="line"><span class="language-javascript">                <span class="string">&quot;-tag:v&quot;</span>,</span></span><br><span class="line"><span class="language-javascript">                <span class="string">&quot;avc1&quot;</span>,</span></span><br><span class="line"><span class="language-javascript">                <span class="string">&quot;-movflags&quot;</span>,</span></span><br><span class="line"><span class="language-javascript">                <span class="string">&quot;faststart&quot;</span>,</span></span><br><span class="line"><span class="language-javascript">                <span class="string">&quot;-crf&quot;</span>,</span></span><br><span class="line"><span class="language-javascript">                <span class="string">&quot;30&quot;</span>,</span></span><br><span class="line"><span class="language-javascript">                <span class="string">&quot;-preset&quot;</span>,</span></span><br><span class="line"><span class="language-javascript">                <span class="string">&quot;superfast&quot;</span>,</span></span><br><span class="line"><span class="language-javascript">                <span class="string">&quot;output.mp4&quot;</span></span></span><br><span class="line"><span class="language-javascript">              );</span></span><br><span class="line"><span class="language-javascript"></span></span><br><span class="line"><span class="language-javascript">              <span class="keyword">const</span> data = ffmpeg.<span class="title function_">FS</span>(<span class="string">&quot;readFile&quot;</span>, <span class="string">&quot;output.mp4&quot;</span>);</span></span><br><span class="line"><span class="language-javascript">              <span class="keyword">const</span> video = <span class="variable language_">document</span>.<span class="title function_">createElement</span>(<span class="string">&quot;video&quot;</span>);</span></span><br><span class="line"><span class="language-javascript">              video.<span class="property">src</span> = <span class="variable constant_">URL</span>.<span class="title function_">createObjectURL</span>(</span></span><br><span class="line"><span class="language-javascript">                <span class="keyword">new</span> <span class="title class_">Blob</span>([data.<span class="property">buffer</span>], &#123; <span class="attr">type</span>: <span class="string">&quot;video/mp4&quot;</span> &#125;)</span></span><br><span class="line"><span class="language-javascript">              );</span></span><br><span class="line"><span class="language-javascript">              video.<span class="property">controls</span> = <span class="literal">true</span>;</span></span><br><span class="line"><span class="language-javascript">              <span class="variable language_">document</span>.<span class="property">body</span>.<span class="title function_">appendChild</span>(video);</span></span><br><span class="line"><span class="language-javascript">            &#125; <span class="keyword">else</span> &#123;</span></span><br><span class="line"><span class="language-javascript">              <span class="title function_">alert</span>(<span class="string">&quot;Please select an input file.&quot;</span>);</span></span><br><span class="line"><span class="language-javascript">            &#125;</span></span><br><span class="line"><span class="language-javascript">          &#125;);</span></span><br><span class="line"><span class="language-javascript">      &#125;</span></span><br><span class="line"><span class="language-javascript"></span></span><br><span class="line"><span class="language-javascript">      <span class="title function_">main</span>();</span></span><br><span class="line"><span class="language-javascript">    </span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;/<span class="name">body</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">html</span>&gt;</span></span><br></pre></td></tr></table></figure><ol start="7"><li>We also need to set up a server to serve this html file. Let’s try <code>express</code>.</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><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><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">const express = require(&#x27;express&#x27;);</span><br><span class="line">const path = require(&#x27;path&#x27;);</span><br><span class="line">const app = express();</span><br><span class="line"></span><br><span class="line">const PORT = 8080;</span><br><span class="line"></span><br><span class="line">app.use((req, res, next) =&gt; &#123;</span><br><span class="line">    res.setHeader(&#x27;Cross-Origin-Opener-Policy&#x27;, &#x27;same-origin&#x27;);</span><br><span class="line">    res.setHeader(&#x27;Cross-Origin-Embedder-Policy&#x27;, &#x27;require-corp&#x27;);</span><br><span class="line">    next();</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line">app.use(express.static(path.join(__dirname, &#x27;./dist&#x27;)));</span><br><span class="line"></span><br><span class="line">app.listen(PORT, () =&gt; &#123;</span><br><span class="line">    console.log(`Server is running on http://localhost:$&#123;PORT&#125;`);</span><br><span class="line">&#125;);</span><br><span class="line"></span><br></pre></td></tr></table></figure><p>We just need to copy the js and html files under dist folder.</p><p>Here is the code base <a href="https://github.com/blessdyb/video-compression-wasm-app">https://github.com/blessdyb/video-compression-wasm-app</a></p>]]></content>
    
    
      
      
    <summary type="html">&lt;p&gt;Yesterday I explained how to use FFMPEG to compress video efficiently. How to deploy a video compression service? Here we can try to leve</summary>
      
    
    
    
    <category term="CS" scheme="http://blog.beendless.com/categories/CS/"/>
    
    
    <category term="FFMPEG" scheme="http://blog.beendless.com/tags/FFMPEG/"/>
    
    <category term="Rust" scheme="http://blog.beendless.com/tags/Rust/"/>
    
    <category term="WASM" scheme="http://blog.beendless.com/tags/WASM/"/>
    
  </entry>
  
  <entry>
    <title>The Secret of Video Compression with FFMPEG</title>
    <link href="http://blog.beendless.com/2024/08/01/The%20Secret%20of%20Video%20Compression%20with%20FFMPEG/"/>
    <id>http://blog.beendless.com/2024/08/01/The%20Secret%20of%20Video%20Compression%20with%20FFMPEG/</id>
    <published>2024-08-02T06:15:24.000Z</published>
    <updated>2024-08-02T03:30:35.477Z</updated>
    
    <content type="html"><![CDATA[<p>Recently there’s a hot tweet talking about video compression (<a href="https://x.com/mortenjust/status/1817991110544744764">https://x.com/mortenjust/status/1817991110544744764</a>). The author shows that how he could compress most of the MP4 videos down to 10% of the original size.</p><p>If you check the site <a href="https://tools.rotato.app/compress">https://tools.rotato.app/compress</a>, actually he didn’t invent anything new. It’s a WASM version of ffmpeg which is using command</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">ffmpeg -i &quot;input.mp4&quot; -c:v libx264 -tag:v avc1 -movflags faststart -crf 30 -preset superfast &quot;output.mp4&quot;</span><br></pre></td></tr></table></figure><p>The FFmpeg command above is used to transcode a video file (<code>input.mp4</code>) into another video file (<code>output.mp4</code>) using specific encoding settings. Here’s a breakdown of what each part of the command does:</p><h3 id="Command-Breakdown"><a href="#Command-Breakdown" class="headerlink" title="Command Breakdown"></a>Command Breakdown</h3><ol><li><p><strong><code>ffmpeg</code></strong>:</p><ul><li>This is the command-line tool used for processing video and audio files.</li></ul></li><li><p><strong><code>-i &quot;input.mp4&quot;</code></strong>:</p><ul><li><code>-i</code> specifies the input file. In this case, it is <code>&quot;input.mp4&quot;</code>. This is the video file you want to convert or process.</li></ul></li><li><p><strong><code>-c:v libx264</code></strong>:</p><ul><li><code>-c:v</code> specifies the video codec to use for the output. <code>libx264</code> is a widely used library for encoding H.264 video, which is known for its good compression and quality.</li></ul></li><li><p><strong><code>-tag:v avc1</code></strong>:</p><ul><li>This sets the codec tag for the video stream to <code>avc1</code>, which is the identifier used in MP4 containers for H.264 video. It ensures compatibility with certain players and devices that require this tag.</li></ul></li><li><p><strong><code>-movflags faststart</code></strong>:</p><ul><li>This option moves some metadata to the beginning of the output file. This makes the video start playing faster when streamed over the internet because the metadata needed to start playback is located at the start of the file, rather than at the end.</li></ul></li><li><p><strong><code>-crf 30</code></strong>:</p><ul><li><code>-crf</code> stands for Constant Rate Factor. This option controls the quality of the output video when using the x264 encoder. The CRF value ranges from 0 to 51, where lower values result in better quality at the cost of larger file sizes, and higher values result in worse quality and smaller file sizes. A CRF value of <code>30</code> is relatively high, indicating a moderate quality level, resulting in a smaller file size.</li></ul></li><li><p><strong><code>-preset superfast</code></strong>:</p><ul><li><code>-preset</code> determines the speed of the encoding process and the compression efficiency. The <code>superfast</code> preset prioritizes speed over compression efficiency, resulting in faster encoding times at the expense of a larger file size. This is useful if you need a quick encoding process and are not as concerned about file size.</li></ul></li><li><p><strong><code>&quot;output.mp4&quot;</code></strong>:</p><ul><li>This specifies the name of the output file. In this case, the processed video will be saved as <code>&quot;output.mp4&quot;</code>.</li></ul></li></ol><h3 id="Summary"><a href="#Summary" class="headerlink" title="Summary"></a>Summary</h3><p>This command takes an input video file and transcodes it to H.264 format using the <code>libx264</code> encoder. It sets the video stream tag for compatibility, optimizes the file for streaming, and uses a preset that balances speed and quality. The output will be a moderately compressed video suitable for streaming or uploading where file size and encoding speed are more important than the highest possible quality.</p>]]></content>
    
    
      
      
    <summary type="html">&lt;p&gt;Recently there’s a hot tweet talking about video compression (&lt;a href=&quot;https://x.com/mortenjust/status/1817991110544744764&quot;&gt;https://x.com</summary>
      
    
    
    
    <category term="CS" scheme="http://blog.beendless.com/categories/CS/"/>
    
    
    <category term="FFMPEG" scheme="http://blog.beendless.com/tags/FFMPEG/"/>
    
  </entry>
  
  <entry>
    <title>NodeJS Http-Proxy with WebSocket</title>
    <link href="http://blog.beendless.com/2023/07/17/NodeJS%20Http-Proxy%20with%20WebSocket/"/>
    <id>http://blog.beendless.com/2023/07/17/NodeJS%20Http-Proxy%20with%20WebSocket/</id>
    <published>2023-07-18T06:15:24.000Z</published>
    <updated>2023-07-18T05:21:44.396Z</updated>
    
    <content type="html"><![CDATA[<p>WebSocket has been supported widely in the past few years. More and more applications are embracing this and using it to replace AJAX &#x2F; Commit &#x2F; LongPooling. Set up a NodeJS server with WebSocket is easier, but how to do it correctly especially when your application is behind web proxies? Here I’m going to use a simple http server and websocket native implementaion <a href="https://github.com/websockets/ws"><code>ws</code></a>, a http proxy based on <a href="https://github.com/http-party/node-http-proxy"><code>http-proxy</code></a> .</p><ol><li>Run below commands to start a small project</li></ol><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">mkdir nodejs-proxy-websocket &amp;&amp; cd nodejs-proxy-websocket &amp;&amp; npm init -y</span><br><span class="line">npm i --save ws http-proxy</span><br></pre></td></tr></table></figure><ol start="2"><li>Create a file <code>index.html</code> with code below. So we set up a websocket connection which will display the message pushed from server and send it back</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><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">&lt;div id=&quot;message&quot;&gt;&lt;/div&gt;</span><br><span class="line">&lt;script&gt;</span><br><span class="line">    // Init a websocket object</span><br><span class="line">    let ws = new WebSocket(location.href.replace(&#x27;http&#x27;, &#x27;ws&#x27;));</span><br><span class="line">    // Open the connection</span><br><span class="line">    ws.onopen = (event)=&gt;&#123;</span><br><span class="line">        ws.send(&quot;Init the server connection&quot;)</span><br><span class="line">    &#125;</span><br><span class="line">    // Receive / Send messages</span><br><span class="line">    ws.onmessage = (message)=&gt;&#123;</span><br><span class="line">        document.querySelector(&#x27;#message&#x27;).innerHTML = new Date(+message.data).toISOString().substr(0, 19);</span><br><span class="line">        ws.send(message.data);</span><br><span class="line">    &#125;</span><br><span class="line">&lt;/script&gt;</span><br><span class="line"></span><br></pre></td></tr></table></figure><ol start="3"><li>Create a file <code>server.js</code> with code below. We share the same server between websocket server and http application server.</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><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br></pre></td><td class="code"><pre><span class="line">const http = require(&quot;http&quot;);</span><br><span class="line">const fs = require(&quot;fs&quot;);</span><br><span class="line">const ws = require(&quot;ws&quot;);</span><br><span class="line"></span><br><span class="line">// Render index.html as content for all requests</span><br><span class="line">const server = http.createServer((req, res) =&gt; &#123;</span><br><span class="line">  fs.readFile(&quot;index.html&quot;, &quot;utf8&quot;, (err, data) =&gt; &#123;</span><br><span class="line">    if (err) &#123;</span><br><span class="line">      res.statusCode = 500;</span><br><span class="line">      res.end(&quot;Internal Server Error&quot;);</span><br><span class="line">      return;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    res.statusCode = 200;</span><br><span class="line">    res.setHeader(&quot;Content-Type&quot;, &quot;text/html&quot;);</span><br><span class="line">    res.end(data);</span><br><span class="line">  &#125;);</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line">// Handle websocket requests</span><br><span class="line">const wss = new ws.WebSocketServer(&#123; noServer: true &#125;);</span><br><span class="line">wss.on(&quot;connection&quot;, (websocket, req) =&gt; &#123;</span><br><span class="line">  setInterval(</span><br><span class="line">    () =&gt; websocket.send(+new Date()),</span><br><span class="line">    1000</span><br><span class="line">  );</span><br><span class="line">  websocket.on(&quot;message&quot;, (data) =&gt; &#123;</span><br><span class="line">    console.log(data.toString());</span><br><span class="line">  &#125;);</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line">server.on(&quot;upgrade&quot;, (req, socket, head) =&gt; &#123;</span><br><span class="line">  wss.handleUpgrade(req, socket, head, (websocket) =&gt; &#123;</span><br><span class="line">    wss.emit(&quot;connection&quot;, websocket, req);</span><br><span class="line">  &#125;);</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line">server.listen(3001);</span><br><span class="line"></span><br></pre></td></tr></table></figure><ol start="4"><li><p>Now if you run <code>node server.js</code> and open <code>http://localhost:3001</code> you will see a clock string displaying on the page and refreshing every second</p></li><li><p>Let’s continue our journey, create a file named <code>proxy.js</code> with content below</p></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><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><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">const http = require(&quot;http&quot;);</span><br><span class="line">const httpProxy = require(&#x27;http-proxy&#x27;);</span><br><span class="line">// Set up a proxy</span><br><span class="line">var proxy = new httpProxy.createProxyServer(&#123;</span><br><span class="line">  target: &#123;</span><br><span class="line">    host: &#x27;localhost&#x27;,</span><br><span class="line">    port: 3001</span><br><span class="line">  &#125;</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line">// Create a proxy server</span><br><span class="line">var proxyServer = http.createServer(function (req, res) &#123;</span><br><span class="line">  proxy.web(req, res);</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line">proxyServer.on(&#x27;upgrade&#x27;, function (req, socket, head) &#123;</span><br><span class="line">  proxy.ws(req, socket, head);</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line">proxyServer.listen(8001)</span><br></pre></td></tr></table></figure><p>Here we use <code>http-proxy</code> to set up a simple proxy server which proxying all requests (including websocket) to our application server (server.js <a href="http://localhost:3001/">http://localhost:3001</a>). </p><ol start="6"><li>Now if you open <code>http://localhost:8001</code> you will see the same page as #4. We successfully make websocket requests pass through a proxy in nodejs.</li></ol>]]></content>
    
    
      
      
    <summary type="html">&lt;p&gt;WebSocket has been supported widely in the past few years. More and more applications are embracing this and using it to replace AJAX &amp;#x</summary>
      
    
    
    
    <category term="CS" scheme="http://blog.beendless.com/categories/CS/"/>
    
    
    <category term="NodeJS" scheme="http://blog.beendless.com/tags/NodeJS/"/>
    
    <category term="WebSocket" scheme="http://blog.beendless.com/tags/WebSocket/"/>
    
    <category term="HttpProxy" scheme="http://blog.beendless.com/tags/HttpProxy/"/>
    
  </entry>
  
  <entry>
    <title>Set up Kubeadm on MacOS with Vagrant and VirtualBox</title>
    <link href="http://blog.beendless.com/2021/11/15/Set%20up%20Kubeadm%20on%20Macbook%20with%20Vagrant/"/>
    <id>http://blog.beendless.com/2021/11/15/Set%20up%20Kubeadm%20on%20Macbook%20with%20Vagrant/</id>
    <published>2021-11-15T08:45:23.000Z</published>
    <updated>2023-03-08T05:05:31.151Z</updated>
    
    <content type="html"><![CDATA[<p>Based on <a href="https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/install-kubeadm/">kubeadm</a> installation instructions, we can’t directly install it on MacOS. But with the help of Vagrant and VirtualBox, we can quickly create a local kubenetes cluster.</p><ol><li>Install <a href="https://www.virtualbox.org/">VirtualBox</a> and Vagrant(<a href="https://www.vagrantup.com/">https://www.vagrantup.com</a>)</li><li>Create three virtualbox instances, one as a master node and the other two as workder nodes. You can use this <a href="https://github.com/kodekloudhub/certified-kubernetes-administrator-course/blob/master/Vagrantfile">Vagrantfile</a>. Basically we will:<br>  a. Use ubuntu&#x2F;bionic64 as the OS<br>  b. Set up a private network and use IP subnet “192.168.5.X” (master nodes will use 192.168.5.1X, worker nodes will use 192.168.5.2X)<br>  c. Update &#x2F;etc&#x2F;hosts to set up the host record to all nodes<br>  d. Add Google’s open dns to &#x2F;etc&#x2F;resolver.conf file<br>  e. Once you finish the above process, you can run <code>vagrant status</code>, you will get something like below  <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">   kubemaster                running (virtualbox)</span><br><span class="line">kubenode01                running (virtualbox)</span><br><span class="line">kubenode02                running (virtualbox)</span><br></pre></td></tr></table></figure></li><li>Install Docker runtime on all three instances by following <a href="https://docs.docker.com/engine/install/ubuntu/">https://docs.docker.com/engine/install/ubuntu/</a></li><li>Follow <a href="https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/install-kubeadm/">https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/install-kubeadm/</a> to install the kubeadm.<br>a. Letting iptables see bridged traffic<br>b. Installing kubeadm&#x2F;kubelet and kubectl</li><li>Follow <a href="https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/create-cluster-kubeadm/">https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/create-cluster-kubeadm/</a> to create a cluster.<br>a. Initializing a control-plane node <code>kubeadm init --pod-network-cid=10.244.0.0/16 --apiserver-advertise-address=192.1168.5.11</code> . Here <code>10.244.0.0/16</code> specifies the subnet for pods on worker nodes. You can give a different one. Once it’s installed successfully, you can run <code>kubectl get nodes</code> and the master nodes will be displayed as <code>NotReady</code> as expected<br>b. Installing a Pod network add-on by following <a href="https://kubernetes.io/docs/concepts/cluster-administration/networking/#how-to-implement-the-kubernetes-networking-model">https://kubernetes.io/docs/concepts/cluster-administration/networking/#how-to-implement-the-kubernetes-networking-model</a>. Here we choose <a href="https://www.weave.works/docs/net/latest/kubernetes/kube-addon/">WeaveNet</a> which doesn’t need any additional configuration.<br>c. Join the worker nodes to the cluster. If you forget the tokens, you can run <code>kubeadm token create --print-join-command</code> and run the <code>kubeadm join</code> command in all worker nodes.</li><li>Now if you run <code>kubectl get nodes</code>, you can get a result as below. <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">NAME         STATUS   ROLES                  AGE   VERSION</span><br><span class="line">kubemaster   Ready    control-plane,master   9h    v1.22.3</span><br><span class="line">kubenode01   Ready    &lt;none&gt;                 9h    v1.22.3</span><br><span class="line">kubenode02   Ready    &lt;none&gt;                 9h    v1.22.3</span><br></pre></td></tr></table></figure></li></ol>]]></content>
    
    
      
      
    <summary type="html">&lt;p&gt;Based on &lt;a href=&quot;https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/install-kubeadm/&quot;&gt;kubeadm&lt;/a&gt; installation instru</summary>
      
    
    
    
    <category term="CS" scheme="http://blog.beendless.com/categories/CS/"/>
    
    
    <category term="Kubernetes" scheme="http://blog.beendless.com/tags/Kubernetes/"/>
    
  </entry>
  
  <entry>
    <title>MMM, Ma-Po Tofu !</title>
    <link href="http://blog.beendless.com/2021/10/26/Ma-Po%20Tofu/"/>
    <id>http://blog.beendless.com/2021/10/26/Ma-Po%20Tofu/</id>
    <published>2021-10-26T07:00:24.000Z</published>
    <updated>2023-03-08T05:05:31.147Z</updated>
    
    <content type="html"><![CDATA[<p>It might be a dish foreign for you; in fact, it was foreign to me too. Ma-Po tofu originates from a region in China but far away from my hometown. The first time that I had it was in my first year of college. It and me, both had left home, just met in a small restaurant next to our campus. Gladly, I was not alone, neither was the dish. There were new friends of mine sitting around a table, and Ma-Po Tofu took the center, having always had the charm to attract people from all over the country. It may be welcomed by people from all over the world one day.</p><p>On a simple plate with certain depth was Ma-Po tofu resting. The white plate made a perfect extension of the dish as the tofu was white itself yet the sauce all over it was flame red. The depth of the plate had to be perfect too as the sauce could be a little glutinous and soupy at the same time. A flat plate too shallow would not match the thickness of Ma-Po tofu. The tofu was cut into small cubes like dice and partly immersed in spicy vegetable oil. Red chili powder and green onion bits decorated the tofu cubes, like sprinkles, adding not only rich flavors but also festivity to the dish. Chopped garlic and ginger pieces may be easily ignored at the first glance, but they were still easier to detect than tiny, ground meat. The meat had been crisped in hot oil, being prepared to support the main role of tofu. Yes, the meat had to surrender and obey the spicy and fragrant of the rest of ingredients. The only purpose for all the ingredients was to give a wondrous taste for tofu that is usually considered the least tasty bean-based curd. While the original flavor of tofu retained, a variety of spices that marked the Sichuan region, from which the Ma-Po tofu originated, wrapped each piece of tofu. Aha! The wondrous taste had its most contribution from a special spice, Chinese pepper, the kind that numbs my tongue! It was ground and dredged on the ready dish at last. The brown powder camouflaged itself until my first bite. Anyone can recognize its distinctiveness.</p><p>The most recommended way to take Ma-Po tofu is to dip the tofu in the sauce a bit or to just use a spoon to take one piece of tofu and the sauce together. The essence in the taste was an incredible integration of different types of spicy tastes at different layers. The numbing sense gave it special magic to level up that mixed taste. Several small pieces of meat occasionally clung to the tofu or garlic. Although very small, the meat was crispy outside and tender inside, adding a playful element to other ingredients. Besides the dynamic flavors, tofu was still being itself: it was tender, smooth, pleasantly chewy, soft yet firm, just as it was before it was cooked. The texture of the tofu for this dish was something in-between of marshmallows and cheese. The tenderness and firmness remained; yet another level of slipperiness was built upon it because now the tofu was made hot, not only hot as spicy but also hot in temperature. At least it was warm enough that I wanted to take my time before taking anything from it. While the rich taste fills every corner of my mouth at once the first bite that I just had would smoothly slide to reach my throat and esophagus. Usually, eaters could not resist the fragrant warmth as soon as the dish was served, so they jumped into it. Just like taking an adventure in a wonder land of spices, you might want to do it slowly before suddenly getting your tongue, throat, and esophagus numbed or burned. Don’t ask me how I know it!</p><p>I remembered my lesson ever since but not always successful in applying it; my husband knows that because I sometimes make it at home now. Ma-Po tofu is a test even for masters as making tofu colorful and tasty is inherently a difficult task. But you do not have to make it as stylish as a chef’s signature, it is a treat itself. As a classic in the region where it originates, Ma-Po tofu is an easy, simple, low-key dish that everyone can make very home. It is popular but also homey. Its warmth and amora reminds eaters everything about home. This might have been the reason that we ordered a Ma-Po tofu at the dinner table when a bunch of first-year college students became friends and shared meals together.</p>]]></content>
    
    
      
      
    <summary type="html">&lt;p&gt;It might be a dish foreign for you; in fact, it was foreign to me too. Ma-Po tofu originates from a region in China but far away from my </summary>
      
    
    
    
    <category term="Recipe" scheme="http://blog.beendless.com/categories/Recipe/"/>
    
    
    <category term="Chinese Food" scheme="http://blog.beendless.com/tags/Chinese-Food/"/>
    
  </entry>
  
  <entry>
    <title>Multi-Stage Golang Docker Image Build and Kubernetes Deployment</title>
    <link href="http://blog.beendless.com/2021/10/19/Multi-Stage%20Golang%20Docker%20Image/"/>
    <id>http://blog.beendless.com/2021/10/19/Multi-Stage%20Golang%20Docker%20Image/</id>
    <published>2021-10-19T18:15:24.000Z</published>
    <updated>2023-03-08T05:05:31.149Z</updated>
    
    <content type="html"><![CDATA[<p>If we have a tiny web service which return the host name as below.  We can use golang image and build the executable package, then move it into a basic linux container like alpine.</p><figure class="highlight golang"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><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">package</span> main</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> (</span><br><span class="line">    <span class="string">&quot;fmt&quot;</span></span><br><span class="line">    <span class="string">&quot;log&quot;</span></span><br><span class="line">    <span class="string">&quot;net/http&quot;</span></span><br><span class="line">    <span class="string">&quot;os&quot;</span></span><br><span class="line">    <span class="string">&quot;time&quot;</span></span><br><span class="line"></span><br><span class="line">    <span class="string">&quot;github.com/gorilla/mux&quot;</span></span><br><span class="line">)</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">handler</span><span class="params">(w http.ResponseWriter, r *http.Request)</span></span> &#123;</span><br><span class="line">    name, err := os.Hostname()</span><br><span class="line">    <span class="keyword">if</span> err != <span class="literal">nil</span> &#123;</span><br><span class="line">        fmt.Fprintf(w, <span class="string">&quot;Can&#x27;t get hostname&quot;</span>)</span><br><span class="line">    &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">        fmt.Fprintf(w, <span class="string">&quot;Go Hostname: %s\n&quot;</span>, name)</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span> &#123;</span><br><span class="line">    r := mux.NewRouter()</span><br><span class="line">    r.PathPrefix(<span class="string">&quot;/&quot;</span>).HandlerFunc(handler)</span><br><span class="line">    srv := &amp;http.Server&#123;</span><br><span class="line">        Handler: r,</span><br><span class="line">        Addr:    <span class="string">&quot;:8000&quot;</span>,</span><br><span class="line">        <span class="comment">// Good practice: enforce timeouts for servers you create!</span></span><br><span class="line">        WriteTimeout: <span class="number">15</span> * time.Second,</span><br><span class="line">        ReadTimeout:  <span class="number">15</span> * time.Second,</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    log.Fatal(srv.ListenAndServe())</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><figure class="highlight dockerfile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><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">FROM</span> golang:<span class="number">1.17</span> AS builder</span><br><span class="line"><span class="comment"># https://stackoverflow.com/questions/61515186/when-using-cgo-enabled-is-must-and-what-happens</span></span><br><span class="line"><span class="comment"># https://gist.github.com/blessdyb/ebe59987e4a4632b28c10ec74a1eda0c</span></span><br><span class="line"><span class="keyword">ENV</span> CGO_ENABLED=<span class="number">0</span></span><br><span class="line"><span class="keyword">WORKDIR</span><span class="language-bash"> /build</span></span><br><span class="line"><span class="keyword">COPY</span><span class="language-bash"> .  .</span></span><br><span class="line"><span class="keyword">RUN</span><span class="language-bash"> go mod download</span></span><br><span class="line"><span class="keyword">RUN</span><span class="language-bash"> go build -o app</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">FROM</span> alpine:latest  </span><br><span class="line"><span class="keyword">WORKDIR</span><span class="language-bash"> /app</span></span><br><span class="line"><span class="keyword">COPY</span><span class="language-bash"> --from=builder /build/app .</span></span><br><span class="line"><span class="keyword">EXPOSE</span> <span class="number">8000</span></span><br><span class="line"><span class="keyword">CMD</span><span class="language-bash"> [<span class="string">&quot;./app&quot;</span>]</span></span><br></pre></td></tr></table></figure><p>Once we have the docker file, we can build an image with command <code>docker build -t whoami-web .</code> . Now, we can use Kubernetes to deploy it</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><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><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">apiVersion: apps/v1</span><br><span class="line">kind: Deployment</span><br><span class="line">metadata:</span><br><span class="line">  name: whoami</span><br><span class="line">  labels:</span><br><span class="line">    app: whoami</span><br><span class="line">    version: v1</span><br><span class="line">spec:</span><br><span class="line">  selector:</span><br><span class="line">    matchLabels:</span><br><span class="line">      app: whoami</span><br><span class="line">      version: v1</span><br><span class="line">  template:</span><br><span class="line">    metadata:</span><br><span class="line">      labels:</span><br><span class="line">        app: whoami</span><br><span class="line">        version: v1</span><br><span class="line">    spec:</span><br><span class="line">      containers:</span><br><span class="line">        - name: whoami-web</span><br><span class="line">          image: whoami-web</span><br><span class="line">          imagePullPolicy: Never</span><br></pre></td></tr></table></figure><p>Run <code>kubectl apply -f deployment.yml</code> we will have the deployment running.</p><p>Run <code>kubectl port-forward deploy/whoami 8001:8000</code> , then we can check <code>localhost:8001</code> in our browser.</p><p>You can compare the result of the real container name by running below commands:</p><p><code>kubectl get pods -o custom-columns=NAME:metadata.name</code><br><code>kubectl exec deploy/whoami -- sh -c &#39;hostname&#39;</code></p>]]></content>
    
    
      
      
    <summary type="html">&lt;p&gt;If we have a tiny web service which return the host name as below.  We can use golang image and build the executable package, then move i</summary>
      
    
    
    
    <category term="CS" scheme="http://blog.beendless.com/categories/CS/"/>
    
    
    <category term="Golang" scheme="http://blog.beendless.com/tags/Golang/"/>
    
    <category term="Docker" scheme="http://blog.beendless.com/tags/Docker/"/>
    
    <category term="Kubernetes" scheme="http://blog.beendless.com/tags/Kubernetes/"/>
    
  </entry>
  
  <entry>
    <title>Mastering Go Notes</title>
    <link href="http://blog.beendless.com/2021/10/18/Mastering%20Go%20Notes/"/>
    <id>http://blog.beendless.com/2021/10/18/Mastering%20Go%20Notes/</id>
    <published>2021-10-18T18:15:24.000Z</published>
    <updated>2023-03-08T05:05:31.147Z</updated>
    
    <content type="html"><![CDATA[<ol><li><p>If you have to check godoc offline, you could install gdoc <code>go get golang.org/x/tools/cmd/godoc</code> and then run <code>godoc -http :8001</code> in termilal.</p></li><li><p>Go consider the <code>main()</code> function the entry point to the application and begins the execution of the applicaiton with the code found in the <code>main()</code> function of the <code>main</code> package.</p></li><li><p>Everything that begins with a lowercase letter is considered private and is accessible in the current package only.</p></li><li><p>If no initial value is given to a variable, the Go compiler will automatically initialize that variable to the zero value of its data type.</p></li><li><p>The <code>var</code> keyword is mostly used for declaring global or local variables without an initial value. Since every statement that exists outside of the code of a function must begin with a keywoprd such as <code>func</code>, <code>const</code> or <code>var</code>, you can’t use short assignment statement <code>:=</code> outside of the function.</p></li><li><p>The <code>os.Args</code> <code>string</code> slice is properly initialized by Go and is available to the program when referenced.</p></li></ol>]]></content>
    
    
      
      
    <summary type="html">&lt;ol&gt;
&lt;li&gt;&lt;p&gt;If you have to check godoc offline, you could install gdoc &lt;code&gt;go get golang.org/x/tools/cmd/godoc&lt;/code&gt; and then run &lt;code&gt;g</summary>
      
    
    
    
    <category term="CS" scheme="http://blog.beendless.com/categories/CS/"/>
    
    
    <category term="Golang" scheme="http://blog.beendless.com/tags/Golang/"/>
    
    <category term="Mastering Go" scheme="http://blog.beendless.com/tags/Mastering-Go/"/>
    
  </entry>
  
  <entry>
    <title>Monotonic Stack</title>
    <link href="http://blog.beendless.com/2021/10/16/Monotonic%20Stack/"/>
    <id>http://blog.beendless.com/2021/10/16/Monotonic%20Stack/</id>
    <published>2021-10-16T18:15:24.000Z</published>
    <updated>2023-03-08T05:05:31.149Z</updated>
    
    <content type="html"><![CDATA[<p>Monotonic Stack is the best time complexity solution for many “range queries in an array” problems. Because every element in the array could only enter the monotonic stack once, the time complexity is O(N). (N represents the length of the array).</p><h2 id="739-Daily-Temperatures"><a href="#739-Daily-Temperatures" class="headerlink" title="739. Daily Temperatures"></a><a href="https://leetcode.com/problems/daily-temperatures/">739. Daily Temperatures</a></h2><p>Since we want to get the first larger element after the current element, we can consider using the monotonic stack.</p><figure class="highlight golang"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><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="function"><span class="keyword">func</span> <span class="title">dailyTemperatures</span><span class="params">(temperatures []<span class="type">int</span>)</span></span> []<span class="type">int</span> &#123;</span><br><span class="line">    n := <span class="built_in">len</span>(temperatures)</span><br><span class="line">    result := <span class="built_in">make</span>([]<span class="type">int</span>, n)</span><br><span class="line">    stack := []<span class="type">int</span>&#123;&#125;</span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">0</span>; i &lt; n; i++ &#123;</span><br><span class="line">        <span class="keyword">for</span> <span class="built_in">len</span>(stack) &gt; <span class="number">0</span> &amp;&amp; temperatures[i] &gt; temperatures[stack[<span class="built_in">len</span>(stack) - <span class="number">1</span>]]&#123;</span><br><span class="line">            last := stack[<span class="built_in">len</span>(stack) - <span class="number">1</span>]</span><br><span class="line">            result[last] = i - last</span><br><span class="line">            stack = stack[:<span class="built_in">len</span>(stack) - <span class="number">1</span>]</span><br><span class="line">        &#125;</span><br><span class="line">        stack = <span class="built_in">append</span>(stack, 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></pre></td></tr></table></figure><h2 id="496-Next-Greater-Element-I"><a href="#496-Next-Greater-Element-I" class="headerlink" title="496. Next Greater Element I"></a><a href="https://leetcode.com/problems/next-greater-element-i/">496. Next Greater Element I</a></h2><p>We use a monotonic stack to iterate over the nums2 array. During the iteration, if we find that the top stack value is lower than the current value and the top stack value exist in nums1, it means we get the one result in nums1. Since all elements are unique, we don’t need to worry about the override risk.</p><figure class="highlight golang"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><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="function"><span class="keyword">func</span> <span class="title">nextGreaterElement</span><span class="params">(nums1 []<span class="type">int</span>, nums2 []<span class="type">int</span>)</span></span> []<span class="type">int</span> &#123;</span><br><span class="line">    result := <span class="built_in">make</span>([]<span class="type">int</span>, <span class="built_in">len</span>(nums1))   </span><br><span class="line">    hash := <span class="built_in">make</span>(<span class="keyword">map</span>[<span class="type">int</span>]<span class="type">int</span>)</span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">0</span>; i &lt; <span class="built_in">len</span>(nums1); i++ &#123;</span><br><span class="line">        result[i] = <span class="number">-1</span></span><br><span class="line">        hash[nums1[i]] = i</span><br><span class="line">    &#125;</span><br><span class="line">    stack := []<span class="type">int</span>&#123;<span class="number">0</span>&#125;</span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">1</span>; i &lt; <span class="built_in">len</span>(nums2); i++ &#123;</span><br><span class="line">        <span class="keyword">if</span> nums2[i] &lt;= nums2[stack[<span class="built_in">len</span>(stack) - <span class="number">1</span>]] &#123; </span><br><span class="line">            stack = <span class="built_in">append</span>(stack, i)</span><br><span class="line">        &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">            <span class="keyword">for</span> <span class="built_in">len</span>(stack) &gt; <span class="number">0</span> &amp;&amp; nums2[i] &gt; nums2[stack[<span class="built_in">len</span>(stack) - <span class="number">1</span>]] &#123; <span class="comment">// unique values in both nums1 and nums2</span></span><br><span class="line">                <span class="keyword">if</span> index, ok := hash[nums2[stack[<span class="built_in">len</span>(stack) - <span class="number">1</span>]]] &#123;</span><br><span class="line">                    result[index] = nums2[i]</span><br><span class="line">                &#125;</span><br><span class="line">                stack = stack[:<span class="built_in">len</span>(stack) - <span class="number">1</span>]</span><br><span class="line">            &#125;</span><br><span class="line">            stack = <span class="built_in">append</span>(stack, 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></pre></td></tr></table></figure><h2 id="503-Next-Greater-Element-II"><a href="#503-Next-Greater-Element-II" class="headerlink" title="503. Next Greater Element II"></a><a href="https://leetcode.com/problems/next-greater-element-ii/">503. Next Greater Element II</a></h2><p>We can concat two nums2 to one and get a longer list of result, then reduce the result size to half. It will be a same problem as the above one. We can also use mod operator to get the correct index</p><figure class="highlight golang"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="function"><span class="keyword">func</span> <span class="title">nextGreaterElements</span><span class="params">(nums []<span class="type">int</span>)</span></span> []<span class="type">int</span> &#123;</span><br><span class="line">    n := <span class="built_in">len</span>(nums)</span><br><span class="line">    stack := []<span class="type">int</span>&#123;<span class="number">0</span>&#125;</span><br><span class="line">    result := <span class="built_in">make</span>([]<span class="type">int</span>, n)</span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">0</span>; i &lt; n; i++ &#123;</span><br><span class="line">        result[i] = <span class="number">-1</span></span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">1</span>; i &lt; <span class="number">2</span> * n; i++ &#123;</span><br><span class="line">        <span class="keyword">for</span> <span class="built_in">len</span>(stack) &gt; <span class="number">0</span> &amp;&amp; nums[i % n] &gt; nums[stack[<span class="built_in">len</span>(stack) - <span class="number">1</span>]] &#123;</span><br><span class="line">            result[stack[<span class="built_in">len</span>(stack) - <span class="number">1</span>]] = nums[i % n]</span><br><span class="line">            stack = stack[:<span class="built_in">len</span>(stack) - <span class="number">1</span>]</span><br><span class="line">        &#125;</span><br><span class="line">        stack = <span class="built_in">append</span>(stack, i % n)</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> result</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="42-Trapping-Rain-Water"><a href="#42-Trapping-Rain-Water" class="headerlink" title="42. Trapping Rain Water"></a><a href="https://leetcode.com/problems/trapping-rain-water">42. Trapping Rain Water</a></h2><p>Based on the requirment, for each column, we will need to get the highest value on its left and right and then get the smaller one.</p><p>a. Dynamic Programming</p><figure class="highlight golang"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><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="function"><span class="keyword">func</span> <span class="title">trap</span><span class="params">(height []<span class="type">int</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">    n := <span class="built_in">len</span>(height)   </span><br><span class="line">    left := <span class="built_in">make</span>([]<span class="type">int</span>, n)</span><br><span class="line">    right := <span class="built_in">make</span>([]<span class="type">int</span>, n)</span><br><span class="line">    left[<span class="number">0</span>] = height[<span class="number">0</span>]</span><br><span class="line">    right[n - <span class="number">1</span>] = height[n - <span class="number">1</span>]</span><br><span class="line">    max := <span class="function"><span class="keyword">func</span><span class="params">(a, b <span class="type">int</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> a &gt; b &#123;</span><br><span class="line">            <span class="keyword">return</span> a</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> b</span><br><span class="line">    &#125;</span><br><span class="line">    min := <span class="function"><span class="keyword">func</span><span class="params">(a, b <span class="type">int</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> a &gt; b &#123;</span><br><span class="line">            <span class="keyword">return</span> b</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> a</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">1</span>; i &lt; n; i++ &#123;</span><br><span class="line">        left[i] = max(height[i], left[i - <span class="number">1</span>])</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">for</span> i := n - <span class="number">2</span>; i &gt;= <span class="number">0</span>; i-- &#123;</span><br><span class="line">        right[i] = max(height[i], right[i + <span class="number">1</span>])</span><br><span class="line">    &#125;</span><br><span class="line">    result := <span class="number">0</span></span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">0</span>; i &lt; n; i++ &#123;</span><br><span class="line">        diff := min(left[i], right[i]) - height[i]</span><br><span class="line">        <span class="keyword">if</span> diff &gt; <span class="number">0</span> &#123;</span><br><span class="line">            result += diff</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> result</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>b. Monotonic Stack</p><p>We will get the water layer by layer vertically for each item. [<a href="https://leetcode.wang/leetCode-42-Trapping-Rain-Water.html]">https://leetcode.wang/leetCode-42-Trapping-Rain-Water.html]</a>. Basically, the idea is we have at least two items in the stack, if the stack top is smaller than the current one, it means the stack top is the bottom of the rain trapper, and the second top one in stack is the left bounary and the current one is the right boundary.</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"> ___</span><br><span class="line">5| |</span><br><span class="line">4| |     ___ </span><br><span class="line">3| |     | |</span><br><span class="line">2| |__   | |</span><br><span class="line">1|____|__|_|</span><br><span class="line"> a b  c  d e</span><br></pre></td></tr></table></figure><p>so result &#x3D; (min(d, c) - 0) * (d - c) + (min(d, b) - c ) * (d - b)</p><figure class="highlight golang"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><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="function"><span class="keyword">func</span> <span class="title">trap</span><span class="params">(height []<span class="type">int</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">    result := <span class="number">0</span></span><br><span class="line">    n := <span class="built_in">len</span>(height)</span><br><span class="line">    stack := []<span class="type">int</span>&#123;&#125;</span><br><span class="line">    min := <span class="function"><span class="keyword">func</span><span class="params">(a, b <span class="type">int</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> a &gt; b &#123;</span><br><span class="line">            <span class="keyword">return</span> b</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> a</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">0</span>; i &lt; n; i++ &#123;</span><br><span class="line">        <span class="keyword">for</span> <span class="built_in">len</span>(stack) &gt; <span class="number">0</span> &amp;&amp; height[i] &gt; height[stack[<span class="built_in">len</span>(stack) - <span class="number">1</span>]] &#123;</span><br><span class="line">            bottom := height[stack[<span class="built_in">len</span>(stack) - <span class="number">1</span>]]</span><br><span class="line">            stack = stack[:<span class="built_in">len</span>(stack) - <span class="number">1</span>]</span><br><span class="line">            <span class="keyword">if</span> <span class="built_in">len</span>(stack) &gt; <span class="number">0</span> &#123;</span><br><span class="line">                w := i - stack[<span class="built_in">len</span>(stack) - <span class="number">1</span>] - <span class="number">1</span>;</span><br><span class="line">                h := min(height[stack[<span class="built_in">len</span>(stack) - <span class="number">1</span>]], height[i])</span><br><span class="line">                result += w * (h - bottom)</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        stack = <span class="built_in">append</span>(stack, 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></pre></td></tr></table></figure><p>c. Two pointers</p><figure class="highlight golang"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><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="function"><span class="keyword">func</span> <span class="title">trap</span><span class="params">(height []<span class="type">int</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">    result := <span class="number">0</span></span><br><span class="line">    n := <span class="built_in">len</span>(height)</span><br><span class="line">    max := <span class="function"><span class="keyword">func</span><span class="params">(a, b <span class="type">int</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> a &gt; b &#123;</span><br><span class="line">            <span class="keyword">return</span> a</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> b</span><br><span class="line">    &#125;</span><br><span class="line">    min := <span class="function"><span class="keyword">func</span><span class="params">(a, b <span class="type">int</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> a &gt; b &#123;</span><br><span class="line">            <span class="keyword">return</span> b</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> a</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">1</span>; i &lt; n - <span class="number">1</span>; i++ &#123;</span><br><span class="line">        left := height[i]</span><br><span class="line">        <span class="keyword">for</span> l := i - <span class="number">1</span>; l &gt;= <span class="number">0</span>; l-- &#123;</span><br><span class="line">            left = max(left, height[l])</span><br><span class="line">        &#125;</span><br><span class="line">        right := height[i]</span><br><span class="line">        <span class="keyword">for</span> r := i + <span class="number">1</span>; r &lt; <span class="built_in">len</span>(height); r++ &#123;</span><br><span class="line">            right = max(right, height[r])</span><br><span class="line">        &#125;</span><br><span class="line">        amount := min(left, right) - height[i]</span><br><span class="line">        <span class="keyword">if</span> amount &gt; <span class="number">0</span> &#123;</span><br><span class="line">            result += amount</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> result</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="84-Largest-Rectangle-in-Histogram"><a href="#84-Largest-Rectangle-in-Histogram" class="headerlink" title="84. Largest Rectangle in Histogram"></a><a href="https://leetcode.com/problems/largest-rectangle-in-histogram/">84. Largest Rectangle in Histogram</a></h2><p>For each item, we need to get the first lower value than the current one on it’s left and right. With this we can get the width of the rectangle.</p><p>a. Dynamic Programming</p><figure class="highlight golang"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><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="function"><span class="keyword">func</span> <span class="title">largestRectangleArea</span><span class="params">(heights []<span class="type">int</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">    n := <span class="built_in">len</span>(heights)</span><br><span class="line">    left := <span class="built_in">make</span>([]<span class="type">int</span>, n)</span><br><span class="line">    left[<span class="number">0</span>] = <span class="number">-1</span></span><br><span class="line">    right := <span class="built_in">make</span>([]<span class="type">int</span>, n)</span><br><span class="line">    right[n - <span class="number">1</span>] = n</span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">1</span>; i &lt; n; i++ &#123;</span><br><span class="line">        t := i - <span class="number">1</span></span><br><span class="line">        <span class="keyword">for</span> t &gt;= <span class="number">0</span> &amp;&amp; heights[t] &gt;= heights[i] &#123;</span><br><span class="line">            t = left[t]</span><br><span class="line">        &#125;</span><br><span class="line">        left[i] = t</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">for</span> i := n - <span class="number">2</span>; i &gt;= <span class="number">0</span>; i-- &#123;</span><br><span class="line">        t := i + <span class="number">1</span></span><br><span class="line">        <span class="keyword">for</span> t &lt; n &amp;&amp; heights[t] &gt;= heights[i] &#123;</span><br><span class="line">            t = right[t]</span><br><span class="line">        &#125;</span><br><span class="line">        right[i] = t</span><br><span class="line">    &#125;</span><br><span class="line">    result := <span class="number">0</span></span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">0</span>; i &lt; n; i++ &#123;</span><br><span class="line">        area := heights[i] * (right[i] - left[i] - <span class="number">1</span>)</span><br><span class="line">        <span class="keyword">if</span> result &lt; area &#123;</span><br><span class="line">            result = area</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> result</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>b. Monotonic Stack solution</p><p>We can use a monotonic stack to maintain the higher bars’s indices in ascending order. When encounter a lower bar, pop the tallest bar and use it as the bottleneck to compute the area.</p><figure class="highlight golang"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><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="function"><span class="keyword">func</span> <span class="title">largestRectangleArea</span><span class="params">(heights []<span class="type">int</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">    <span class="comment">// The reason we have a 0 at the end is if the given heights is a sorted ascending array, we will push everything to the stack without doing anything.</span></span><br><span class="line">    heights := <span class="built_in">append</span>(heights, <span class="number">0</span>)</span><br><span class="line">    n := <span class="built_in">len</span>(heights)</span><br><span class="line">    result := <span class="number">0</span></span><br><span class="line">    stack := []<span class="type">int</span>&#123;&#125;</span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">0</span>; i &lt; n; i++ &#123;</span><br><span class="line">        <span class="keyword">for</span> <span class="built_in">len</span>(stack) &gt; <span class="number">0</span> &amp;&amp; height[i] &lt; height[stack[<span class="built_in">len</span>(stack) - <span class="number">1</span>]] &#123;</span><br><span class="line">            h := heights[stack[<span class="built_in">len</span>(stack) - <span class="number">1</span>]]</span><br><span class="line">            stack = stack[:<span class="built_in">len</span>(stack) - <span class="number">1</span>]</span><br><span class="line">            w := i</span><br><span class="line">            <span class="keyword">if</span> <span class="built_in">len</span>(stack) &gt; <span class="number">0</span> &#123;</span><br><span class="line">                w = i - stack[<span class="built_in">len</span>(stack) - <span class="number">1</span>] - <span class="number">1</span></span><br><span class="line">            &#125;</span><br><span class="line">            area := h * w</span><br><span class="line">            <span class="keyword">if</span> result &lt; area &#123;</span><br><span class="line">                result = area</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        stack = <span class="built_in">append</span>(stack, i)</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>]]></content>
    
    
      
      
    <summary type="html">&lt;p&gt;Monotonic Stack is the best time complexity solution for many “range queries in an array” problems. Because every element in the array co</summary>
      
    
    
    
    <category term="CS" scheme="http://blog.beendless.com/categories/CS/"/>
    
    
    <category term="Golang" scheme="http://blog.beendless.com/tags/Golang/"/>
    
    <category term="Algorithms" scheme="http://blog.beendless.com/tags/Algorithms/"/>
    
    <category term="Leetcode" scheme="http://blog.beendless.com/tags/Leetcode/"/>
    
    <category term="Dynamic Programming" scheme="http://blog.beendless.com/tags/Dynamic-Programming/"/>
    
    <category term="Two Pointers" scheme="http://blog.beendless.com/tags/Two-Pointers/"/>
    
    <category term="Monotonic Stack" scheme="http://blog.beendless.com/tags/Monotonic-Stack/"/>
    
  </entry>
  
  <entry>
    <title>Indoor bluetooth location</title>
    <link href="http://blog.beendless.com/2021/10/15/Indoor%20bluetooth%20location/"/>
    <id>http://blog.beendless.com/2021/10/15/Indoor%20bluetooth%20location/</id>
    <published>2021-10-15T20:54:33.000Z</published>
    <updated>2023-04-03T05:45:42.331Z</updated>
    
    <content type="html"><![CDATA[<p>Indoor positioning technology is more and more widely used in daily life, such as indoor navigation, smart home, shopping mall advertisement, etc. This article will detail the principles of this technique and its advantages in practical applications.</p><h3 id="principle"><a href="#principle" class="headerlink" title="principle"></a>principle</h3><p>The basic principle is to obtain the distance between the device and the beacon in the indoor environment by deploying several Bluetooth beacons, and then combine the current location information of the device collected by the built-in sensors (such as accelerometers, gyroscopes, etc.) of the mobile phone, and input these data into It is processed in the Kalman filter algorithm, and finally the optimized device location information is output to improve positioning accuracy and real-time performance.</p><h3 id="Deploy-Bluetooth-Beacons"><a href="#Deploy-Bluetooth-Beacons" class="headerlink" title="Deploy Bluetooth Beacons"></a>Deploy Bluetooth Beacons</h3><p>Deploy several Bluetooth beacons indoors, and record the location coordinates and signal strength values of each beacon. Because the signal penetration ability of Bluetooth is strong and can pass through obstacles, Bluetooth positioning is widely used in indoor environments.</p><h3 id="Data-collection-by-mobile-phone-hardware"><a href="#Data-collection-by-mobile-phone-hardware" class="headerlink" title="Data collection by mobile phone hardware"></a>Data collection by mobile phone hardware</h3><p>Use hardware devices such as built-in sensors (such as accelerometers, gyroscopes, etc.) in the mobile phone to collect the current location information of the device, such as direction, moving speed, angle, etc.</p><h3 id="Bluetooth-positioning-to-obtain-data"><a href="#Bluetooth-positioning-to-obtain-data" class="headerlink" title="Bluetooth positioning to obtain data"></a>Bluetooth positioning to obtain data</h3><p>Use the Bluetooth module of the mobile phone to scan the surrounding Bluetooth beacons and obtain their signal strength values. Based on the signal strength value, the distance between the device and the beacon is calculated, and then the location of the device is determined.</p><h3 id="Kalman-filter-algorithm-to-process-data"><a href="#Kalman-filter-algorithm-to-process-data" class="headerlink" title="Kalman filter algorithm to process data"></a>Kalman filter algorithm to process data</h3><p>The collected location information and signal strength values are input into the Kalman filter algorithm for processing, and the location information of the device is optimized by means of weighted average and sliding window to improve the positioning accuracy and real-time performance. The Kalman filter algorithm is a commonly used data prediction and processing algorithm, which can effectively deal with the noise and errors existing in sensor data.</p><h3 id="Data-Fusion"><a href="#Data-Fusion" class="headerlink" title="Data Fusion"></a>Data Fusion</h3><p>The position information output by the Kalman filter algorithm is fused with other positioning technologies (such as WiFi positioning) to further improve the positioning accuracy and accuracy. The fusion of multiple positioning technologies can eliminate the disadvantages of a single technology while making full use of their respective advantages.</p><p>The indoor positioning technology based on Bluetooth positioning, mobile phone sensors and Kalman filter has the characteristics of high positioning accuracy, good real-time performance and low cost. This technology has important application value in smart home, shopping mall advertising, indoor navigation and other fields. However, in the application process, there are also many challenges, such as the noise interference of sensor data and the uncertainty of position information, etc., which need to be further studied and solved.</p>]]></content>
    
    
      
      
    <summary type="html">&lt;p&gt;Indoor positioning technology is more and more widely used in daily life, such as indoor navigation, smart home, shopping mall advertisem</summary>
      
    
    
    
    <category term="CS" scheme="http://blog.beendless.com/categories/CS/"/>
    
    
    <category term="Bluetooth" scheme="http://blog.beendless.com/tags/Bluetooth/"/>
    
    <category term="GEO Location" scheme="http://blog.beendless.com/tags/GEO-Location/"/>
    
  </entry>
  
  <entry>
    <title>Dynamic Programming IV</title>
    <link href="http://blog.beendless.com/2021/10/14/Dynamic%20Programming%20IV/"/>
    <id>http://blog.beendless.com/2021/10/14/Dynamic%20Programming%20IV/</id>
    <published>2021-10-14T18:14:24.000Z</published>
    <updated>2023-03-08T05:05:31.142Z</updated>
    
    <content type="html"><![CDATA[<h2 id="115-Distinct-Subsequences"><a href="#115-Distinct-Subsequences" class="headerlink" title="115. Distinct Subsequences"></a><a href="https://leetcode.com/problems/distinct-subsequences/">115. Distinct Subsequences</a></h2><p>Let’s denote dp[i][j] as the amount of distinct subsequences in s[:i] which can construct t[:j]. So we can get the state transition function dp[i][j] &#x3D; s[i - 1] &#x3D;&#x3D; t[i - 1] ? (dp[i - 1][j - 1] + dp[i - 1][j] : dp[i-1][j]. Also for the initial value, <code>dp[i][0]</code> needs to be 0 (it means there’s one way we can construct empty string from s[:i]).</p><figure class="highlight golang"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><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="function"><span class="keyword">func</span> <span class="title">numDistinct</span><span class="params">(s <span class="type">string</span>, t <span class="type">string</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">    m := <span class="built_in">len</span>(s)</span><br><span class="line">    n := <span class="built_in">len</span>(t)</span><br><span class="line">    dp := <span class="built_in">make</span>([][]<span class="type">int</span>, m + <span class="number">1</span>)</span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">0</span>; i &lt;= m; i++ &#123;</span><br><span class="line">        dp[i] = <span class="built_in">make</span>([]<span class="type">int</span>, n + <span class="number">1</span>)</span><br><span class="line">        dp[i][<span class="number">0</span>] = <span class="number">1</span></span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">1</span>; i &lt;= m; i++ &#123;</span><br><span class="line">        <span class="keyword">for</span> j := <span class="number">1</span>; j &lt;= n; j++ &#123;</span><br><span class="line">            <span class="keyword">if</span> s[i - <span class="number">1</span>] == t[j - <span class="number">1</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">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><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></pre></td></tr></table></figure><h2 id="583-Delete-Operation-for-Two-Strings"><a href="#583-Delete-Operation-for-Two-Strings" class="headerlink" title="583. Delete Operation for Two Strings"></a><a href="https://leetcode.com/problems/delete-operation-for-two-strings/submissions/">583. Delete Operation for Two Strings</a></h2><p>a. LCS solution.</p><p>Delete characters to make two strings match, in another word, it means we need to find the longest common sequence.</p><figure class="highlight golang"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><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="function"><span class="keyword">func</span> <span class="title">minDistance</span><span class="params">(word1 <span class="type">string</span>, word2 <span class="type">string</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">    m := <span class="built_in">len</span>(word1)</span><br><span class="line">    n := <span class="built_in">len</span>(word2)</span><br><span class="line">    dp := <span class="built_in">make</span>([][]<span class="type">int</span>, m + <span class="number">1</span>)</span><br><span class="line">    lcs := <span class="number">0</span></span><br><span class="line">    max := <span class="function"><span class="keyword">func</span><span class="params">(a, b <span class="type">int</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> a &gt; b &#123;</span><br><span class="line">            <span class="keyword">return</span> a</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> b</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">0</span>; i &lt;= m; i++ &#123;</span><br><span class="line">        dp[i] = <span class="built_in">make</span>([]<span class="type">int</span>, n + <span class="number">1</span>)</span><br><span class="line">        <span class="keyword">for</span> j := <span class="number">0</span>; j &lt;= n; j++ &#123;</span><br><span class="line">            <span class="keyword">if</span> i == <span class="number">0</span> || j == <span class="number">0</span> &#123;</span><br><span class="line">                <span class="keyword">continue</span></span><br><span class="line">            &#125; <span class="keyword">else</span> <span class="keyword">if</span> word1[i - <span class="number">1</span>] == word2[j - <span class="number">1</span>] &#123;</span><br><span class="line">                dp[i][j] = <span class="number">1</span> + 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] = 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">            lcs = max(lcs, dp[i][j])</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> m + n - <span class="number">2</span> * lcs</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>b. Intuitive dynamic programming solution.</p><p>Let’s denote dp[i][j] as the minimum delete operation to match word1[:i] and word2[:j]. So the state transition function is dp[i][j] &#x3D; word1[i-1] &#x3D;&#x3D; word2[j-1] ? dp[i-1][j-1] : max(dp[i - 1][j] + 1, dp[i][j-1] + 1, dp[i-1][j-1] + 2).</p><figure class="highlight golang"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><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="function"><span class="keyword">func</span> <span class="title">minDistance</span><span class="params">(word1 <span class="type">string</span>, word2 <span class="type">string</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">    m := <span class="built_in">len</span>(word1)</span><br><span class="line">    n := <span class="built_in">len</span>(word2)</span><br><span class="line">    dp := <span class="built_in">make</span>([][]<span class="type">int</span>, m + <span class="number">1</span>)</span><br><span class="line">    min := <span class="function"><span class="keyword">func</span><span class="params">(a, b <span class="type">int</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> a &gt; b &#123;</span><br><span class="line">            <span class="keyword">return</span> a</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> b</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">0</span>; i &lt;= m; i++ &#123;</span><br><span class="line">        dp[i] = <span class="built_in">make</span>([]<span class="type">int</span>, n + <span class="number">1</span>)</span><br><span class="line">        <span class="keyword">for</span> j := <span class="number">0</span>; j &lt;= n; j++ &#123;</span><br><span class="line">            <span class="keyword">if</span> i == <span class="number">0</span> &#123;</span><br><span class="line">                dp[i][j] = j</span><br><span class="line">            &#125; <span class="keyword">else</span> <span class="keyword">if</span> j == <span class="number">0</span> &#123;</span><br><span class="line">                dp[i][j] = i</span><br><span class="line">            &#125; <span class="keyword">else</span> <span class="keyword">if</span> word1[i - <span class="number">1</span>] == word2[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] = min(dp[i][j - <span class="number">1</span>] + <span class="number">1</span>, min(dp[i - <span class="number">1</span>][j] + <span class="number">1</span>, dp[i - <span class="number">1</span>][j - <span class="number">1</span>] + <span class="number">2</span>))</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> dp[m][n]</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>We can also reduce the space complexity to O(n)</p><figure class="highlight golang"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><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="function"><span class="keyword">func</span> <span class="title">minDistance</span><span class="params">(word1 <span class="type">string</span>, word2 <span class="type">string</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">    m := <span class="built_in">len</span>(word1)</span><br><span class="line">    n := <span class="built_in">len</span>(word2)</span><br><span class="line">    min := <span class="function"><span class="keyword">func</span><span class="params">(a, b <span class="type">int</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> a &gt; b &#123;</span><br><span class="line">            <span class="keyword">return</span> b</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> a</span><br><span class="line">    &#125;</span><br><span class="line">    dp := <span class="built_in">make</span>([]<span class="type">int</span>, n + <span class="number">1</span>)</span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">0</span>; i &lt;= m; i++ &#123;</span><br><span class="line">        temp := <span class="built_in">make</span>([]<span class="type">int</span>, n + <span class="number">1</span>)</span><br><span class="line">        <span class="keyword">for</span> j := <span class="number">0</span>; j &lt;= n; j++ &#123;</span><br><span class="line">            <span class="keyword">if</span> i == <span class="number">0</span> &#123;</span><br><span class="line">                temp[j] = j</span><br><span class="line">            &#125; <span class="keyword">else</span> <span class="keyword">if</span> j == <span class="number">0</span> &#123;</span><br><span class="line">                temp[j] = i</span><br><span class="line">            &#125; <span class="keyword">else</span> <span class="keyword">if</span> word1[i - <span class="number">1</span>] == word2[j - <span class="number">1</span>] &#123;</span><br><span class="line">                temp[j] = dp[j - <span class="number">1</span>]</span><br><span class="line">            &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                <span class="comment">//temp[j] = min(temp[j - 1] + 1, min(dp[j] + 1, temp[j - 1] + 2))</span></span><br><span class="line">                temp[j] = <span class="number">1</span> + min(temp[j - <span class="number">1</span>], dp[j])</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        dp = temp</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><h2 id="72-Edit-Distance"><a href="#72-Edit-Distance" class="headerlink" title="72. Edit Distance"></a><a href="https://leetcode.com/problems/edit-distance/">72. Edit Distance</a></h2><p>This one is similar as the above one. Let’s denote dp[i][j] as the edit distance between word1[:i] and word2[:j]. So if word1[i] &#x3D;&#x3D; word2[j], we get dp[i][j] &#x3D; dp[i - 1][j-1]. Otherwise, there will be three cases:</p><ol><li>add&#x2F;delete one from word1, so dp[i-1][j] + 1 or dp[i][j-1] + 1</li><li>add&#x2F;delete one from word2, so dp[i-1][j] + 1 or dp[i][j-1] + 1</li><li>replace one from either word1 or word2, so dp[i-1][j-1] + 1</li></ol><p>So dp[i][j] &#x3D; 1 + min(dp[i-1][j], dp[i][j-1], dp[i-1][j-1])</p><figure class="highlight golang"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><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="function"><span class="keyword">func</span> <span class="title">minDistance</span><span class="params">(word1 <span class="type">string</span>, word2 <span class="type">string</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">    m := <span class="built_in">len</span>(word1)</span><br><span class="line">    n := <span class="built_in">len</span>(word2)</span><br><span class="line">    dp := <span class="built_in">make</span>([][]<span class="type">int</span>, m + <span class="number">1</span>)</span><br><span class="line">    min := <span class="function"><span class="keyword">func</span><span class="params">(a, b <span class="type">int</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> a &gt; b &#123;</span><br><span class="line">            <span class="keyword">return</span> b</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> a</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">0</span>; i &lt;= m; i++ &#123;</span><br><span class="line">        dp[i] = <span class="built_in">make</span>([]<span class="type">int</span>, n + <span class="number">1</span>)</span><br><span class="line">        <span class="keyword">for</span> j := <span class="number">0</span>; j &lt;= n; j++ &#123;</span><br><span class="line">            <span class="keyword">if</span> i == <span class="number">0</span> &#123;</span><br><span class="line">                dp[i][j] = j</span><br><span class="line">            &#125; <span class="keyword">else</span> <span class="keyword">if</span> j == <span class="number">0</span> &#123;</span><br><span class="line">                dp[i][j] = i</span><br><span class="line">            &#125; <span class="keyword">else</span> <span class="keyword">if</span> word1[i - <span class="number">1</span>] == word2[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] = <span class="number">1</span> + min(dp[i - <span class="number">1</span>][j - <span class="number">1</span>], min(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></pre></td></tr></table></figure><p>we can also reduce the space complexity to O(n)</p><figure class="highlight golang"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><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="function"><span class="keyword">func</span> <span class="title">minDistance</span><span class="params">(word1 <span class="type">string</span>, word2 <span class="type">string</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">    m := <span class="built_in">len</span>(word1)</span><br><span class="line">    n := <span class="built_in">len</span>(word2)</span><br><span class="line">    dp := <span class="built_in">make</span>([]<span class="type">int</span>, n + <span class="number">1</span>)</span><br><span class="line">    min := <span class="function"><span class="keyword">func</span><span class="params">(a, b <span class="type">int</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> a &gt; b &#123;</span><br><span class="line">            <span class="keyword">return</span> b</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> a</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">0</span>; i &lt;= m; i++ &#123;</span><br><span class="line">        temp := <span class="built_in">make</span>([]<span class="type">int</span>, n + <span class="number">1</span>)</span><br><span class="line">        <span class="keyword">for</span> j := <span class="number">0</span>; j &lt;= n; j++ &#123;</span><br><span class="line">            <span class="keyword">if</span> i == <span class="number">0</span> || j == <span class="number">0</span> &#123;</span><br><span class="line">                temp[j] = i + j</span><br><span class="line">            &#125; <span class="keyword">else</span> <span class="keyword">if</span> word1[i - <span class="number">1</span>] == word2[j - <span class="number">1</span>] &#123;</span><br><span class="line">                temp[j] = dp[j - <span class="number">1</span>]</span><br><span class="line">            &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                temp[j] = <span class="number">1</span> + min(dp[j - <span class="number">1</span>], min(dp[j], temp[j - <span class="number">1</span>]))</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        dp = temp</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><h2 id="647-Palindromic-Substrings"><a href="#647-Palindromic-Substrings" class="headerlink" title="647. Palindromic Substrings"></a><a href="https://leetcode.com/problems/palindromic-substrings/">647. Palindromic Substrings</a></h2><p>a. Dynamic Programming</p><p>Let’s denote dp[i][j] as a boolean value to identify if substring s[j:i] is a parlindrom or not. So if s[j] !&#x3D; s[i], then dp[i][j] is false. Otherwise, there are three cases:</p><ol><li>i - j &lt;&#x3D; 1, so dp[i][j] &#x3D; true</li><li>i - j &gt; 1, so dp[i][j] &#x3D; dp[i - 1][j + 1]</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><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><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">func countSubstrings(s string) int &#123;</span><br><span class="line">    n := len(s)</span><br><span class="line">    dp := make([][]bool, n + 1)</span><br><span class="line">    result := 0</span><br><span class="line">    for i := 0; i &lt;= n; i++ &#123;</span><br><span class="line">        dp[i] = make([]bool, n + 1)</span><br><span class="line">        for j := 0; j &lt;= i; j++ &#123;</span><br><span class="line">            if i == 0 || j == 0 &#123;</span><br><span class="line">                continue</span><br><span class="line">            &#125; else if s[j - 1] == s[i - 1] &#123;</span><br><span class="line">                if i - j &lt;= 1 || dp[i - 1][j + 1] &#123;</span><br><span class="line">                    dp[i][j] = true</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><span class="line">    &#125;</span><br><span class="line">    return result</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>b. Two pointers expand from center solution</p><p>All parlindrom related problems, we can try to use two pointers solution, we selecte the middle point (it could be only one pointer or two pointers), then we expand to left and right.</p><figure class="highlight golang"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><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="function"><span class="keyword">func</span> <span class="title">countSubstrings</span><span class="params">(s <span class="type">string</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">    n := <span class="built_in">len</span>(s)</span><br><span class="line">    expanding := <span class="function"><span class="keyword">func</span><span class="params">(l, r <span class="type">int</span>)</span></span> <span class="type">int</span> &#123; <span class="comment">// return the numbers of parlindrom substrings the given string contains</span></span><br><span class="line">        result := <span class="number">0</span></span><br><span class="line">        <span class="keyword">for</span> l &gt;= <span class="number">0</span> &amp;&amp; r &lt; n &amp;&amp; s[l] == s[r] &#123;</span><br><span class="line">            result++</span><br><span class="line">            l--</span><br><span class="line">            r++</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> result</span><br><span class="line">    &#125;</span><br><span class="line">    result := <span class="number">0</span></span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">0</span>; i &lt; n; i++ &#123;</span><br><span class="line">        result += expanding(i, i)</span><br><span class="line">        result += expanding(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></pre></td></tr></table></figure><h2 id="516-Longest-Palindromic-Subsequence"><a href="#516-Longest-Palindromic-Subsequence" class="headerlink" title="516. Longest Palindromic Subsequence"></a><a href="https://leetcode.com/problems/longest-palindromic-subsequence">516. Longest Palindromic Subsequence</a></h2><p>Denote dp[i][j] as the longest palindromic sequence in s[i:j], so if s[i] &#x3D;&#x3D; s[j], dp[i][j] &#x3D; 2 + dp[i + 1][j - 1]. Otherwise dp[i][j] &#x3D; max(dp[i][j - 1], dp[i + 1][j]). Since dp[i][j] depends on dp[i+1][?] value, we should reverse the for loop</p><figure class="highlight golang"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><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="function"><span class="keyword">func</span> <span class="title">longestPalindromeSubseq</span><span class="params">(s <span class="type">string</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">    n := <span class="built_in">len</span>(s)</span><br><span class="line">    dp := <span class="built_in">make</span>([][]<span class="type">int</span>, n)</span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">0</span>; i &lt; n; i++ &#123;</span><br><span class="line">        dp[i] = <span class="built_in">make</span>([]<span class="type">int</span>, n)</span><br><span class="line">        dp[i][i] = <span class="number">1</span></span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">for</span> i := n - <span class="number">1</span>; i &gt;= <span class="number">0</span>; i-- &#123;</span><br><span class="line">        <span class="keyword">for</span> j = i + <span class="number">1</span>; j &lt; n; j++ &#123;</span><br><span class="line">            <span class="keyword">if</span> s[i] == s[j] &#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">2</span></span><br><span class="line">            &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                dp[i][j] = 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[<span class="number">0</span>][n - <span class="number">1</span>]</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="5-Longest-Palindromic-Substring"><a href="#5-Longest-Palindromic-Substring" class="headerlink" title="5. Longest Palindromic Substring"></a><a href="https://leetcode.com/problems/longest-palindromic-substring">5. Longest Palindromic Substring</a></h2><p>a. Dynamic Programming</p><p>Same as above, let’s denote dp[i][j] to flag if s[i:j] is a parlindrom. So we know if s[i] &#x3D;&#x3D; s[j], dp[i][j] &#x3D; dp[i + 1][j - 1].  and dp[i][i] &#x3D; true.</p><figure class="highlight golang"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><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="function"><span class="keyword">func</span> <span class="title">longestPalindrome</span><span class="params">(s <span class="type">string</span>)</span></span> <span class="type">string</span> &#123;</span><br><span class="line">    n := <span class="built_in">len</span>(s)</span><br><span class="line">    dp := <span class="built_in">make</span>([][]<span class="type">bool</span>, n)</span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">0</span>; i &lt; n; i++ &#123;</span><br><span class="line">        dp[i] = <span class="built_in">make</span>([]<span class="type">bool</span>, n)</span><br><span class="line">        dp[i][i] = <span class="literal">true</span></span><br><span class="line">    &#125;</span><br><span class="line">    max := <span class="number">1</span></span><br><span class="line">    result = <span class="type">string</span>(s[<span class="number">0</span>])</span><br><span class="line">    <span class="keyword">for</span> i := n - <span class="number">1</span>; i &gt;= <span class="number">0</span>; i-- &#123;</span><br><span class="line">        <span class="keyword">for</span> j := i + <span class="number">1</span>; j &lt; n; j++ &#123;</span><br><span class="line">            <span class="keyword">if</span> s[i] == s[j] &#123;</span><br><span class="line">                <span class="keyword">if</span> j - i &lt;= <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 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>]</span><br><span class="line">                &#125;</span><br><span class="line">                <span class="keyword">if</span> dp[i][j] &amp;&amp; max &lt; j - i + <span class="number">1</span> &#123;</span><br><span class="line">                    max = j - i + <span class="number">1</span></span><br><span class="line">                    result = s[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">    &#125;</span><br><span class="line">    <span class="keyword">return</span> result</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>b. Two pointers expand from center solution</p><figure class="highlight golang"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><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="function"><span class="keyword">func</span> <span class="title">longestPalindrome</span><span class="params">(s <span class="type">string</span>)</span></span> <span class="type">string</span> &#123;</span><br><span class="line">    n := <span class="built_in">len</span>(s)</span><br><span class="line">    expanding := <span class="function"><span class="keyword">func</span><span class="params">(l, r <span class="type">int</span>)</span></span> <span class="type">int</span> &#123; <span class="comment">// return the longest length of the parlindrom in the given substring</span></span><br><span class="line">        <span class="keyword">for</span> l &gt;= <span class="number">0</span> &amp;&amp; r &lt; n &amp;&amp; s[l] == s[r] &#123;</span><br><span class="line">            l--</span><br><span class="line">            r++</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> r - l - <span class="number">1</span></span><br><span class="line">    &#125;</span><br><span class="line">    max := <span class="number">0</span></span><br><span class="line">    start := <span class="number">0</span></span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">0</span>; i &lt; n; i++ &#123;</span><br><span class="line">        p1 := expanding(i, i)</span><br><span class="line">        p2 := expanding(i, i + <span class="number">1</span>)</span><br><span class="line">        <span class="keyword">if</span> p1 &gt; p2 &amp;&amp; max &lt; p1 &#123;</span><br><span class="line">            start = i - (p1 - <span class="number">1</span>) / <span class="number">2</span></span><br><span class="line">            max = p1</span><br><span class="line">        &#125; <span class="keyword">else</span> <span class="keyword">if</span> max &lt; p2 &amp;&amp; p1 &lt; p2 &#123;</span><br><span class="line">            start = i -  (p2 - <span class="number">2</span>) / <span class="number">2</span></span><br><span class="line">            max = p2</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> s[start:start + max]</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>]]></content>
    
    
      
      
    <summary type="html">&lt;h2 id=&quot;115-Distinct-Subsequences&quot;&gt;&lt;a href=&quot;#115-Distinct-Subsequences&quot; class=&quot;headerlink&quot; title=&quot;115. Distinct Subsequences&quot;&gt;&lt;/a&gt;&lt;a href=&quot;h</summary>
      
    
    
    
    <category term="CS" scheme="http://blog.beendless.com/categories/CS/"/>
    
    
    <category term="Golang" scheme="http://blog.beendless.com/tags/Golang/"/>
    
    <category term="Algorithms" scheme="http://blog.beendless.com/tags/Algorithms/"/>
    
    <category term="Leetcode" scheme="http://blog.beendless.com/tags/Leetcode/"/>
    
    <category term="Dynamic Programming" scheme="http://blog.beendless.com/tags/Dynamic-Programming/"/>
    
    <category term="Two Pointers" scheme="http://blog.beendless.com/tags/Two-Pointers/"/>
    
  </entry>
  
  <entry>
    <title>Dynamic Programming III</title>
    <link href="http://blog.beendless.com/2021/10/13/Dynamic%20Programming%20III/"/>
    <id>http://blog.beendless.com/2021/10/13/Dynamic%20Programming%20III/</id>
    <published>2021-10-13T18:08:24.000Z</published>
    <updated>2023-03-08T05:05:31.142Z</updated>
    
    <content type="html"><![CDATA[<h2 id="300-Longest-Increasing-Subsequence"><a href="#300-Longest-Increasing-Subsequence" class="headerlink" title="300. Longest Increasing Subsequence"></a><a href="https://leetcode.com/problems/longest-increasing-subsequence">300. Longest Increasing Subsequence</a></h2><p>If we define dp[i] as the longest increasing subsequence of [0, i]. Then dp[i] &gt;&#x3D; 1. And the state transition function is <code>dp[i] = max(dp[i], dp[j] + 1)</code> here j ∈ [0, i).</p><figure class="highlight golang"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="function"><span class="keyword">func</span> <span class="title">lengthOfLIS</span><span class="params">(nums []<span class="type">int</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">    n := <span class="built_in">len</span>(nums)</span><br><span class="line">    dp := <span class="built_in">make</span>([]<span class="type">int</span>, n)</span><br><span class="line">    dp[<span class="number">0</span>] = <span class="number">1</span></span><br><span class="line">    result = <span class="number">1</span></span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">1</span>; i &lt; n; i++ &#123;</span><br><span class="line">        dp[i] = <span class="number">1</span></span><br><span class="line">        <span class="keyword">for</span> j := <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] = 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">        result = 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></pre></td></tr></table></figure><h2 id="674-Longest-Continuous-Increasing-Subsequence"><a href="#674-Longest-Continuous-Increasing-Subsequence" class="headerlink" title="674. Longest Continuous Increasing Subsequence"></a><a href="https://leetcode.com/problems/longest-continuous-increasing-subsequence/">674. Longest Continuous Increasing Subsequence</a></h2><figure class="highlight golang"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><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="function"><span class="keyword">func</span> <span class="title">findLengthOfLCIS</span><span class="params">(nums []<span class="type">int</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">    n := <span class="built_in">len</span>(nums)</span><br><span class="line">    dp := <span class="built_in">make</span>([]<span class="type">int</span>, n)</span><br><span class="line">    dp[<span class="number">0</span>] = <span class="number">1</span></span><br><span class="line">    result := <span class="number">1</span></span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">1</span>; i &lt; n; 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">            dp[i] = dp[i - <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] = <span class="number">1</span></span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span> result &lt; dp[i] &#123;</span><br><span class="line">            result = dp[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></pre></td></tr></table></figure><p>We can reduce the space complexity to O(1)</p><figure class="highlight golang"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="function"><span class="keyword">func</span> <span class="title">findLengthOfLCIS</span><span class="params">(nums []<span class="type">int</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">    n := <span class="built_in">len</span>(nums)</span><br><span class="line">    count := <span class="number">1</span></span><br><span class="line">    result := <span class="number">1</span></span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">1</span>; i &lt; n; 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">            count++</span><br><span class="line">        &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">            count = <span class="number">1</span></span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span> count &gt; result &#123;</span><br><span class="line">            result = count</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> result</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="718-Maximum-Length-of-Repeated-Subarray"><a href="#718-Maximum-Length-of-Repeated-Subarray" class="headerlink" title="718. Maximum Length of Repeated Subarray"></a><a href="https://leetcode.com/problems/maximum-length-of-repeated-subarray/">718. Maximum Length of Repeated Subarray</a></h2><p>Let’s denote dp[i][j] as the maximum length of repeated subarray which <code>ends with i and j</code>. So we know that <code>dp[i][j] = nums1[i] == nums[j] ? (dp[i-1][j-1] + 1) : 0</code></p><figure class="highlight golang"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><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="function"><span class="keyword">func</span> <span class="title">findLength</span><span class="params">(nums1 []<span class="type">int</span>, nums2 []<span class="type">int</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">    m := <span class="built_in">len</span>(nums1)</span><br><span class="line">    n := <span class="built_in">len</span>(nums2)</span><br><span class="line">    dp := <span class="built_in">make</span>([][]<span class="type">int</span>, m + <span class="number">1</span>)</span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">0</span>; i &lt;= m; i++ &#123;</span><br><span class="line">        dp[i] = <span class="built_in">make</span>([]<span class="type">int</span>, n + <span class="number">1</span>)</span><br><span class="line">    &#125;</span><br><span class="line">    result := <span class="number">0</span></span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">1</span>; i &lt;= m; i++ &#123;</span><br><span class="line">        <span class="keyword">for</span> j := <span class="number">1</span>; j &lt;= n; j++ &#123;</span><br><span class="line">            <span class="keyword">if</span> nums[i - <span class="number">1</span>] == nums2[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><br><span class="line">            <span class="keyword">if</span> dp[i][j] &gt; result &#123;</span><br><span class="line">                result = dp[i][j]</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> result</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="1143-Longest-Common-Subsequence"><a href="#1143-Longest-Common-Subsequence" class="headerlink" title="1143. Longest Common Subsequence"></a><a href="https://leetcode.com/problems/longest-common-subsequence/">1143. Longest Common Subsequence</a></h2><p>Similar like above, if we denote dp[i][j] as the maximum number commen sequence which <code>ends with i and j</code>. So we know <code>dp[i][j] == text1[i] == text2[j] ? dp[i-1][j-1] + 1 : max(dp[i-1][j], dp[i][j-1])</code>.</p><figure class="highlight golang"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><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="function"><span class="keyword">func</span> <span class="title">longestCommonSubsequence</span><span class="params">(text1 <span class="type">string</span>, text2 <span class="type">string</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">    m := <span class="built_in">len</span>(text1)</span><br><span class="line">    n := <span class="built_in">len</span>(text2)</span><br><span class="line">    dp := <span class="built_in">make</span>([][]<span class="type">int</span>, m + <span class="number">1</span>)</span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">0</span>; i &lt;= m; i++ &#123;</span><br><span class="line">        dp[i] = <span class="built_in">make</span>([]<span class="type">int</span>, n + <span class="number">1</span>)</span><br><span class="line">    &#125;</span><br><span class="line">    max := <span class="function"><span class="keyword">func</span><span class="params">(a, b <span class="type">int</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> a &gt; b &#123;</span><br><span class="line">            <span class="keyword">return</span> a</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> b</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">1</span>; i &lt;= m; i++ &#123;</span><br><span class="line">        <span class="keyword">for</span> j := <span class="number">1</span>; j &lt;= n; j++ &#123;</span><br><span class="line">            <span class="keyword">if</span> text[i - <span class="number">1</span>] == text2[j - <span class="number">1</span>] &#123;</span><br><span class="line">                dp[i][j] = <span class="number">1</span> + 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] = max(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[m][n]</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="1035-Uncrossed-Lines"><a href="#1035-Uncrossed-Lines" class="headerlink" title="1035. Uncrossed Lines"></a><a href="https://leetcode.com/problems/uncrossed-lines/">1035. Uncrossed Lines</a></h2><p>If you compare this one wtih LCS problem above, actually they are exactly the same. The connection lines doesn’t have intersections means the we just need to get the LCS.</p><figure class="highlight golang"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><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="function"><span class="keyword">func</span> <span class="title">maxUncrossedLines</span><span class="params">(nums1 []<span class="type">int</span>, nums2 []<span class="type">int</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">    m := <span class="built_in">len</span>(nums1)</span><br><span class="line">    n := <span class="built_in">len</span>(nums2)</span><br><span class="line">    dp := <span class="built_in">make</span>([][]<span class="type">int</span>, m + <span class="number">1</span>)</span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">0</span>; i &lt;= m; i++ &#123;</span><br><span class="line">        dp[i] = <span class="built_in">make</span>([]<span class="type">int</span>, n + <span class="number">1</span>)</span><br><span class="line">    &#125;</span><br><span class="line">    max := <span class="function"><span class="keyword">func</span><span class="params">(a, b <span class="type">int</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> a &gt; b &#123;</span><br><span class="line">            <span class="keyword">return</span> a</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> b</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">1</span>; i &lt;= m; i++ &#123;</span><br><span class="line">        <span class="keyword">for</span> j := <span class="number">1</span>; j &lt;= n; j++ &#123;</span><br><span class="line">            <span class="keyword">if</span> nums1[i - <span class="number">1</span>] == nums2[j - <span class="number">1</span>] &#123;</span><br><span class="line">                dp[i][j] = <span class="number">1</span> + 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] = 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[m][n]</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="392-Is-Subsequence"><a href="#392-Is-Subsequence" class="headerlink" title="392. Is Subsequence"></a><a href="https://leetcode.com/problems/is-subsequence/">392. Is Subsequence</a></h2><p>a. Naive two pointers</p><figure class="highlight golang"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><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="function"><span class="keyword">func</span> <span class="title">isSubsequence</span><span class="params">(s <span class="type">string</span>, t <span class="type">string</span>)</span></span> <span class="type">bool</span> &#123;</span><br><span class="line">    <span class="keyword">if</span> <span class="built_in">len</span>(s) &gt; <span class="built_in">len</span>(t) &#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">    i := <span class="number">0</span></span><br><span class="line">    <span class="keyword">for</span> j := <span class="number">0</span>; i &lt; <span class="built_in">len</span>(s) &amp;&amp; j &lt; <span class="built_in">len</span>(t); j++ &#123;</span><br><span class="line">        <span class="keyword">if</span> s[i] == t[j] &#123;</span><br><span class="line">            i++</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> i == <span class="built_in">len</span>(s)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>b. Dynamic Programming</p><p>Let’s use dp[i][j] to denote the subsequence length <code>ends with i and j</code>. So the state transition function is <code>dp[i][j] = s[i] == s[j] ? dp[i - 1][j - 1] + 1 : dp[i-1][j - 1]</code></p><figure class="highlight golang"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><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="function"><span class="keyword">func</span> <span class="title">isSubsequence</span><span class="params">(s <span class="type">string</span>, t <span class="type">string</span>)</span></span> <span class="type">bool</span> &#123;</span><br><span class="line">    m := <span class="built_in">len</span>(s)</span><br><span class="line">    n := <span class="built_in">len</span>(t)</span><br><span class="line">    <span class="keyword">if</span> m &gt; n &#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">    dp := <span class="built_in">make</span>([][]<span class="type">int</span>, m + <span class="number">1</span>)</span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">0</span>; i &lt;= m; i++ &#123;</span><br><span class="line">        dp[i] = <span class="built_in">make</span>([]<span class="type">int</span>, n + <span class="number">1</span>)</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">1</span>; i &lt;= m; i++ &#123;</span><br><span class="line">        <span class="keyword">for</span> j := <span class="number">1</span>; j &lt;= n; j++ &#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">            <span class="keyword">if</span> s[i - <span class="number">1</span>] == t[j - <span class="number">1</span>] &#123;</span><br><span class="line">                dp[i][j]++</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> dp[m][n] == m</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>]]></content>
    
    
      
      
    <summary type="html">&lt;h2 id=&quot;300-Longest-Increasing-Subsequence&quot;&gt;&lt;a href=&quot;#300-Longest-Increasing-Subsequence&quot; class=&quot;headerlink&quot; title=&quot;300. Longest Increasing </summary>
      
    
    
    
    <category term="CS" scheme="http://blog.beendless.com/categories/CS/"/>
    
    
    <category term="Golang" scheme="http://blog.beendless.com/tags/Golang/"/>
    
    <category term="Algorithms" scheme="http://blog.beendless.com/tags/Algorithms/"/>
    
    <category term="Leetcode" scheme="http://blog.beendless.com/tags/Leetcode/"/>
    
    <category term="Dynamic Programming" scheme="http://blog.beendless.com/tags/Dynamic-Programming/"/>
    
    <category term="Two Pointers" scheme="http://blog.beendless.com/tags/Two-Pointers/"/>
    
  </entry>
  
  <entry>
    <title>Stock Exchange Problems</title>
    <link href="http://blog.beendless.com/2021/10/12/Stock%20Exchange%20Problems/"/>
    <id>http://blog.beendless.com/2021/10/12/Stock%20Exchange%20Problems/</id>
    <published>2021-10-13T01:30:24.000Z</published>
    <updated>2023-03-08T05:05:31.153Z</updated>
    
    <content type="html"><![CDATA[<h2 id="121-Best-Time-to-Buy-and-Sell-Stock"><a href="#121-Best-Time-to-Buy-and-Sell-Stock" class="headerlink" title="121. Best Time to Buy and Sell Stock"></a><a href="https://leetcode.com/problems/best-time-to-buy-and-sell-stock/">121. Best Time to Buy and Sell Stock</a></h2><p>a. Two pointers greedy solution.</p><p>Since the profit is defined by the current price and the minimum price before today. So we can have one pointer holds the minimum price so far, and another pointer holds the max price so far, with the lowerest peak from the left and highest peak from the right, we can get the maximum profit.</p><figure class="highlight golang"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><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="function"><span class="keyword">func</span> <span class="title">maxProfit</span><span class="params">(prices []<span class="type">int</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">    profit := <span class="number">0</span></span><br><span class="line">    <span class="keyword">for</span> min, i := <span class="number">100001</span>, <span class="number">0</span>; i &lt; <span class="built_in">len</span>(prices); i++ &#123;</span><br><span class="line">        <span class="keyword">if</span> min &gt; prices[i] &#123;</span><br><span class="line">            min = prices[i]</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span> prices[i] - min &gt; profit &#123;</span><br><span class="line">            profit = prices[i] - min</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> profit</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>b. Dynamic programming</p><p>Let’s denote dp[i] as the profit we have so far, it can be two cases:</p><ol><li>dp[i][0] We have stock so the profit we have for the first day if we buy stock is dp[0][0] &#x3D; -prices[0]</li><li>dp[i][1] We don’t have stock</li></ol><p>so the state transition function will be :</p><p><code>dp[i][0] = max(dp[i - 1][0], -prices[i])</code> the maximum value if we bought the stock in the previous day of we buy the stock on day i<br><code>dp[i][1] = max(dp[i - 1][0] + prices[i], dp[i-1][1])</code> the maximum value if we bought the stock before and sell it today, or we don’t have stock before and won’t buy today</p><figure class="highlight golang"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><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="function"><span class="keyword">func</span> <span class="title">maxProfit</span><span class="params">(prices []<span class="type">int</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">    n := <span class="built_in">len</span>(prices)</span><br><span class="line">    dp := <span class="built_in">make</span>([][<span class="number">2</span>]<span class="type">int</span>, n)</span><br><span class="line">    dp[<span class="number">0</span>][<span class="number">0</span>] = -prices[<span class="number">0</span>]</span><br><span class="line">    dp[<span class="number">0</span>][<span class="number">1</span>] = <span class="number">0</span></span><br><span class="line">    max := <span class="function"><span class="keyword">func</span><span class="params">(a, b <span class="type">int</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> a &gt; b &#123;</span><br><span class="line">            <span class="keyword">return</span> a</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> b</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">1</span>; i &lt; n; i++ &#123;</span><br><span class="line">        dp[i][<span class="number">0</span>] = max(dp[i - <span class="number">1</span>][<span class="number">0</span>], -prices[i])</span><br><span class="line">        dp[i][<span class="number">1</span>] = max(dp[i - <span class="number">1</span>][<span class="number">0</span>] + prices[i], dp[i - <span class="number">1</span>][<span class="number">1</span>])</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> dp[n - <span class="number">1</span>][<span class="number">1</span>]</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="122-Best-Time-to-Buy-and-Sell-Stock-II"><a href="#122-Best-Time-to-Buy-and-Sell-Stock-II" class="headerlink" title="122. Best Time to Buy and Sell Stock II"></a><a href="https://leetcode.com/problems/best-time-to-buy-and-sell-stock-ii/">122. Best Time to Buy and Sell Stock II</a></h2><p>a. Greedy solution</p><p>To gian the maximum amount of profit, we just need to accumulate the position profits if we buy it on the previous day and sell it on the next day.</p><figure class="highlight golang"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><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="function"><span class="keyword">func</span> <span class="title">maxProfit</span><span class="params">(prices []<span class="type">int</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">    result := <span class="number">0</span></span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">1</span>; i &lt; <span class="built_in">len</span>(prices); i++ &#123;</span><br><span class="line">        profit := prices[i] - prices[i - <span class="number">1</span>]</span><br><span class="line">        <span class="keyword">if</span> profit &gt; <span class="number">0</span> &#123;</span><br><span class="line">            result += profit</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> result</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>b. Peak &amp; Valley solution</p><p>A naive approach is find the local lowest price (valley price) and sell it at the next local highest price (peak price). Then we accumulate all of those local profits.</p><figure class="highlight golang"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><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="function"><span class="keyword">func</span> <span class="title">maxProfit</span><span class="params">(prices []<span class="type">int</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">    result := <span class="number">0</span></span><br><span class="line">    peak := prices[<span class="number">0</span>]</span><br><span class="line">    valley := prices[<span class="number">0</span>]</span><br><span class="line">    length := <span class="built_in">len</span>(prices)</span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">0</span>; i &lt; length - <span class="number">1</span>; &#123;</span><br><span class="line">        <span class="keyword">for</span> i &lt; length - <span class="number">1</span> &amp;&amp; prices[i] &gt;= prices[i + <span class="number">1</span>] &#123;</span><br><span class="line">            i++</span><br><span class="line">        &#125;</span><br><span class="line">        valley = prices[i]</span><br><span class="line">        <span class="keyword">for</span> i &lt; length - <span class="number">1</span> &amp;&amp; prices[i] &lt;= prices[i + <span class="number">1</span>] &#123;</span><br><span class="line">            i++</span><br><span class="line">        &#125;</span><br><span class="line">        peak = prices[i]</span><br><span class="line">        result += peak - valley</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> result</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>c. Dynamic programming</p><figure class="highlight golang"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><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="function"><span class="keyword">func</span> <span class="title">maxProfit</span><span class="params">(prices []<span class="type">int</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">    length := <span class="built_in">len</span>(prices)</span><br><span class="line">    dp := <span class="built_in">make</span>([][<span class="number">2</span>]<span class="type">int</span>, length)</span><br><span class="line">    <span class="comment">// dp[i][0] on day i we are holding stock</span></span><br><span class="line">    <span class="comment">// dp[i][1] on day i we don&#x27;t have stock</span></span><br><span class="line">    dp[<span class="number">0</span>] = [<span class="number">2</span>]<span class="type">int</span>&#123;-prices[<span class="number">0</span>], <span class="number">0</span>&#125;</span><br><span class="line">    max := <span class="function"><span class="keyword">func</span><span class="params">(a, b <span class="type">int</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> a &gt; b &#123;</span><br><span class="line">            <span class="keyword">return</span> a</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> b</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">1</span>; i &lt; length; i++ &#123;</span><br><span class="line">        <span class="comment">// stock we got from day i - 1, or stock we are going to buy on day i</span></span><br><span class="line">        dp[i][<span class="number">0</span>] = max(dp[i - <span class="number">1</span>][<span class="number">0</span>], dp[i - <span class="number">1</span>][<span class="number">1</span>] - prices[i])</span><br><span class="line">        <span class="comment">// we don&#x27;t have stock from day i - 1, or we are going to sell stock we got from day i - 1</span></span><br><span class="line">        dp[i][<span class="number">1</span>] = max(dp[i - <span class="number">1</span>][<span class="number">1</span>], dp[i - <span class="number">1</span>][<span class="number">0</span>] + prices[i])</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> max(dp[length - <span class="number">1</span>][<span class="number">0</span>], dp[length - <span class="number">1</span>][<span class="number">1</span>])</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="123-Best-Time-to-Buy-and-Sell-Stock-III"><a href="#123-Best-Time-to-Buy-and-Sell-Stock-III" class="headerlink" title="123. Best Time to Buy and Sell Stock III"></a><a href="https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iii/">123. Best Time to Buy and Sell Stock III</a></h2><p>Since we can make two transactions at most, so there will be 5 status for a given day dp[i]</p><ol><li>dp[i][0] We have made 0 transaction so far</li><li>dp[i][1] We bought the stock once so far</li><li>dp[i][2] We have made 1 full transaction once (bought&#x2F;sold the stock once so far)</li><li>dp[i][3] We bought the stock twice and sold once so far</li><li>dp[i][4] We have made 2 full transaction once (bought&#x2F;sold the stock twice so far)</li></ol><figure class="highlight golang"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><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="function"><span class="keyword">func</span> <span class="title">maxProfit</span><span class="params">(prices []<span class="type">int</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">    n := <span class="built_in">len</span>(prices)</span><br><span class="line">    dp := <span class="built_in">make</span>([][<span class="number">5</span>]<span class="type">int</span>, n)</span><br><span class="line">    dp[<span class="number">0</span>] = [<span class="number">5</span>]<span class="type">int</span>&#123;<span class="number">0</span>, -prices[<span class="number">0</span>], <span class="number">0</span>, -prices[<span class="number">0</span>], <span class="number">0</span>&#125;  <span class="comment">// dp[0][1] = dp[0][0] - prices[0], dp[0][2] = dp[0][1] + prices[0], dp[0][3] = dp[0][2] - prices[0], dp[0][4] = dp[0][3] + prices[0], </span></span><br><span class="line">    max := <span class="function"><span class="keyword">func</span><span class="params">(a, b <span class="type">int</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> a &gt; b &#123;</span><br><span class="line">            <span class="keyword">return</span> a</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> b</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">1</span>; i &lt; n; i++ &#123;</span><br><span class="line">        dp[i][<span class="number">0</span>] = dp[i - <span class="number">1</span>][<span class="number">0</span>]</span><br><span class="line">        dp[i][<span class="number">1</span>] = max(dp[i - <span class="number">1</span>][<span class="number">0</span>] - prices[i], dp[i - <span class="number">1</span>][<span class="number">1</span>])</span><br><span class="line">        dp[i][<span class="number">2</span>] = max(dp[i - <span class="number">1</span>][<span class="number">1</span>] + prices[i], dp[i - <span class="number">1</span>][<span class="number">2</span>])</span><br><span class="line">        dp[i][<span class="number">3</span>] = max(dp[i - <span class="number">1</span>][<span class="number">2</span>] - prices[i], dp[i - <span class="number">1</span>][<span class="number">3</span>])</span><br><span class="line">        dp[i][<span class="number">4</span>] = max(dp[i - <span class="number">1</span>][<span class="number">3</span>] + prices[i], dp[i - <span class="number">1</span>][<span class="number">4</span>])</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> dp[n<span class="number">-1</span>][<span class="number">4</span>]</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>We can also optimize the space complexity.</p><figure class="highlight golang"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><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="function"><span class="keyword">func</span> <span class="title">maxProfit</span><span class="params">(prices []<span class="type">int</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">    n := <span class="built_in">len</span>(prices)</span><br><span class="line">    dp := [<span class="number">5</span>]<span class="type">int</span>&#123;<span class="number">0</span>, -prices[<span class="number">0</span>], <span class="number">0</span>, -prices[<span class="number">0</span>], <span class="number">0</span>&#125; </span><br><span class="line">    max := <span class="function"><span class="keyword">func</span><span class="params">(a, b <span class="type">int</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> a &gt; b &#123;</span><br><span class="line">            <span class="keyword">return</span> a</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> b</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">1</span>; i &lt; n; i++ &#123;</span><br><span class="line">        dp[<span class="number">1</span>] = max(dp[<span class="number">0</span>] - prices[i], dp[<span class="number">1</span>])</span><br><span class="line">        dp[<span class="number">2</span>] = max(dp[<span class="number">1</span>] + prices[i], dp[<span class="number">2</span>])</span><br><span class="line">        dp[<span class="number">3</span>] = max(dp[<span class="number">2</span>] - prices[i], dp[<span class="number">3</span>])</span><br><span class="line">        dp[<span class="number">4</span>] = max(dp[<span class="number">3</span>] + prices[i], dp[<span class="number">4</span>])</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> dp[<span class="number">4</span>]</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="188-Best-Time-to-Buy-and-Sell-Stock-IV"><a href="#188-Best-Time-to-Buy-and-Sell-Stock-IV" class="headerlink" title="188. Best Time to Buy and Sell Stock IV"></a><a href="https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iv/">188. Best Time to Buy and Sell Stock IV</a></h2><p>Same as the above solution, here each day will won <code>2 * k + 1</code> states.</p><figure class="highlight golang"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><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="function"><span class="keyword">func</span> <span class="title">maxProfit</span><span class="params">(k <span class="type">int</span>, prices []<span class="type">int</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">    n := <span class="built_in">len</span>(prices)</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">    dp := <span class="built_in">make</span>([][]<span class="type">int</span>, n)</span><br><span class="line">    max := <span class="function"><span class="keyword">func</span><span class="params">(a, b <span class="type">int</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> a &gt; b &#123;</span><br><span class="line">            <span class="keyword">return</span> a</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> b</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">0</span>; i &lt; n; i++ &#123;</span><br><span class="line">        dp[i] = <span class="built_in">make</span>([]<span class="type">int</span>, <span class="number">2</span> * k + <span class="number">1</span>)</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">1</span>; i &lt; <span class="number">2</span> * k + <span class="number">1</span>; i+=<span class="number">2</span> &#123;</span><br><span class="line">        dp[<span class="number">0</span>][i] = -prices[<span class="number">0</span>]</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">1</span>; i &lt; n; i++ &#123;</span><br><span class="line">        <span class="keyword">for</span> j := <span class="number">1</span>; j &lt; <span class="number">2</span> * k + <span class="number">1</span>; j++ &#123;</span><br><span class="line">            <span class="keyword">if</span> j % <span class="number">2</span> == <span class="number">1</span> &#123;</span><br><span class="line">                dp[i][j] = max(dp[i - <span class="number">1</span>][j], dp[i - <span class="number">1</span>][j - <span class="number">1</span>] - prices[i])   </span><br><span class="line">            &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                dp[i][j] = max(dp[i - <span class="number">1</span>][j], dp[i - <span class="number">1</span>][j - <span class="number">1</span>] + prices[i])   </span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> dp[n - <span class="number">1</span>][<span class="number">2</span> * k]</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>We can reduce the space complexity to O(n)</p><figure class="highlight golang"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><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="function"><span class="keyword">func</span> <span class="title">maxProfit</span><span class="params">(k <span class="type">int</span>, prices []<span class="type">int</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">    n := <span class="built_in">len</span>(prices)</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">    dp := <span class="built_in">make</span>([]<span class="type">int</span>, <span class="number">2</span> * k + <span class="number">1</span>)</span><br><span class="line">    max := <span class="function"><span class="keyword">func</span><span class="params">(a, b <span class="type">int</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> a &gt; b &#123;</span><br><span class="line">            <span class="keyword">return</span> a</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> b</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">1</span>; i &lt; <span class="number">2</span> * k + <span class="number">1</span>; i+=<span class="number">2</span> &#123;</span><br><span class="line">        dp[i] = -prices[<span class="number">0</span>]</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">1</span>; i &lt; n; i++ &#123;</span><br><span class="line">        <span class="keyword">for</span> j := <span class="number">1</span>; j &lt; <span class="number">2</span> * k + <span class="number">1</span>; j++ &#123;</span><br><span class="line">            <span class="keyword">if</span> j % <span class="number">2</span> == <span class="number">1</span> &#123;</span><br><span class="line">                dp[j] = max(dp[j], dp[j - <span class="number">1</span>] - prices[i])   </span><br><span class="line">            &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                dp[j] = max(dp[j], dp[j - <span class="number">1</span>] + prices[i])   </span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> dp[<span class="number">2</span> * k]</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="309-Best-Time-to-Buy-and-Sell-Stock-with-Cooldown"><a href="#309-Best-Time-to-Buy-and-Sell-Stock-with-Cooldown" class="headerlink" title="309. Best Time to Buy and Sell Stock with Cooldown"></a><a href="https://leetcode.com/problems/best-time-to-buy-and-sell-stock-with-cooldown/">309. Best Time to Buy and Sell Stock with Cooldown</a></h2><p>Similar like the above problems, we need to define the states of i<sup>th</sup> day based on the state machine diagram.</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><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line">               -----</span><br><span class="line">               |   |</span><br><span class="line">               ⌄   |</span><br><span class="line">          ------------</span><br><span class="line">          | Cooldown | </span><br><span class="line">          ------------</span><br><span class="line">            /        ^</span><br><span class="line">   __      /          \</span><br><span class="line">   | |    /            \</span><br><span class="line">   ⌄ |   ⌄              \                              </span><br><span class="line">------------         ------------</span><br><span class="line">| Buy      |------- &gt;| Sold     | </span><br><span class="line">------------         ------------</span><br><span class="line"></span><br></pre></td></tr></table></figure><ol><li>dp[i][0] we are holding the stock, so <code>dp[i][0] = max(dp[i-1][0], dp[i-1][2] - prices[i])</code></li><li>dp[i][1] we are selling the stock, so <code>dp[i][1] = dp[i - 1][0] + prices[i]</code></li><li>dp[i][2] we are in the cooldown period, so <code>dp[i][2] = max(dp[i-1][2], dp[i-1][1])</code></li></ol><figure class="highlight golang"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><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="function"><span class="keyword">func</span> <span class="title">maxProfit</span><span class="params">(prices []<span class="type">int</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">    n := <span class="built_in">len</span>(prices)</span><br><span class="line">    dp := <span class="built_in">make</span>([][<span class="number">3</span>]<span class="type">int</span>, n)</span><br><span class="line">    max := <span class="function"><span class="keyword">func</span><span class="params">(a, b <span class="type">int</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> a &gt; b &#123;</span><br><span class="line">            <span class="keyword">return</span> a</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> b</span><br><span class="line">    &#125;</span><br><span class="line">    dp[<span class="number">0</span>] = [<span class="number">3</span>]<span class="type">int</span>&#123;-prices[<span class="number">0</span>], <span class="number">0</span>, <span class="number">0</span>&#125;</span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">1</span>; i &lt; n; i++ &#123;</span><br><span class="line">        dp[i][<span class="number">0</span>] = max(dp[i<span class="number">-1</span>][<span class="number">0</span>], dp[i<span class="number">-1</span>][<span class="number">2</span>] - prices[i])</span><br><span class="line">        dp[i][<span class="number">1</span>] = dp[i<span class="number">-1</span>][<span class="number">0</span>] + prices[i]</span><br><span class="line">        dp[i][<span class="number">2</span>] = max(dp[i<span class="number">-1</span>][<span class="number">2</span>], dp[i<span class="number">-1</span>][<span class="number">1</span>])</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> max(dp[n<span class="number">-1</span>][<span class="number">1</span>], dp[n<span class="number">-1</span>][<span class="number">2</span>])</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>We can also reduce the space complexity to O(n)</p><figure class="highlight golang"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><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="function"><span class="keyword">func</span> <span class="title">maxProfit</span><span class="params">(prices []<span class="type">int</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">    n := <span class="built_in">len</span>(prices)</span><br><span class="line">    max := <span class="function"><span class="keyword">func</span><span class="params">(a, b <span class="type">int</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> a &gt; b &#123;</span><br><span class="line">            <span class="keyword">return</span> a</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> b</span><br><span class="line">    &#125;</span><br><span class="line">    hold := -prices[<span class="number">0</span>]</span><br><span class="line">    cooldown := <span class="number">0</span></span><br><span class="line">    sold := <span class="number">0</span></span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">1</span>; i &lt; n; i++ &#123;</span><br><span class="line">        previousSold := sold</span><br><span class="line">        sold = hold + prices[i]</span><br><span class="line">        hold = max(hold, cooldown - prices[i])</span><br><span class="line">        cooldown = max(cooldown, previousSold)</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> max(cooldown, sold)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="714-Best-Time-to-Buy-and-Sell-Stock-with-Transaction-Fee"><a href="#714-Best-Time-to-Buy-and-Sell-Stock-with-Transaction-Fee" class="headerlink" title="714. Best Time to Buy and Sell Stock with Transaction Fee"></a><a href="https://leetcode.com/problems/best-time-to-buy-and-sell-stock-with-transaction-fee/">714. Best Time to Buy and Sell Stock with Transaction Fee</a></h2><p>Same like #122, we just need to process the transaction fee when buying a new stock</p><figure class="highlight golang"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="function"><span class="keyword">func</span> <span class="title">maxProfit</span><span class="params">(prices []<span class="type">int</span>, fee <span class="type">int</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">    n := <span class="built_in">len</span>(prices)</span><br><span class="line">    dp := <span class="built_in">make</span>([][<span class="number">2</span>]<span class="type">int</span>, n)</span><br><span class="line">    dp[<span class="number">0</span>] = [<span class="number">2</span>]<span class="type">int</span>&#123;-prices[<span class="number">0</span>]-fee, <span class="number">0</span>&#125;</span><br><span class="line">    max := <span class="function"><span class="keyword">func</span><span class="params">(a, b <span class="type">int</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> a &gt; b &#123;</span><br><span class="line">            <span class="keyword">return</span> a</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> b</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">1</span>; i &lt; n; i++ &#123;</span><br><span class="line">        dp[i][<span class="number">0</span>] = max(dp[i<span class="number">-1</span>][<span class="number">0</span>], dp[i<span class="number">-1</span>][<span class="number">1</span>] - prices[i] - fee)</span><br><span class="line">        dp[i][<span class="number">1</span>] = max(dp[i<span class="number">-1</span>][<span class="number">1</span>], dp[i<span class="number">-1</span>][<span class="number">0</span>] + prices[i])</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> dp[n<span class="number">-1</span>][<span class="number">1</span>]</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>]]></content>
    
    
      
      
    <summary type="html">&lt;h2 id=&quot;121-Best-Time-to-Buy-and-Sell-Stock&quot;&gt;&lt;a href=&quot;#121-Best-Time-to-Buy-and-Sell-Stock&quot; class=&quot;headerlink&quot; title=&quot;121. Best Time to Buy </summary>
      
    
    
    
    <category term="CS" scheme="http://blog.beendless.com/categories/CS/"/>
    
    
    <category term="Golang" scheme="http://blog.beendless.com/tags/Golang/"/>
    
    <category term="Algorithms" scheme="http://blog.beendless.com/tags/Algorithms/"/>
    
    <category term="Leetcode" scheme="http://blog.beendless.com/tags/Leetcode/"/>
    
    <category term="Dynamic Programming" scheme="http://blog.beendless.com/tags/Dynamic-Programming/"/>
    
    <category term="Greedy" scheme="http://blog.beendless.com/tags/Greedy/"/>
    
    <category term="Stock Exchange" scheme="http://blog.beendless.com/tags/Stock-Exchange/"/>
    
  </entry>
  
  <entry>
    <title>Bluetooth navigation code analysis</title>
    <link href="http://blog.beendless.com/2021/10/10/Bluetooth%20navigation%20code%20analysis/"/>
    <id>http://blog.beendless.com/2021/10/10/Bluetooth%20navigation%20code%20analysis/</id>
    <published>2021-10-10T20:54:33.000Z</published>
    <updated>2023-04-04T05:06:16.882Z</updated>
    
    <content type="html"><![CDATA[<p>Recently, I found a <a href="/js/se.js">source code</a> about Bluetooth positioning and navigation. Through its analysis and research, I have a deep understanding of the positioning and navigation process of the entire Bluetooth algorithm. Learn about Bluetooth signal acquisition, distance estimation, positioning calculation, Kalman model and other aspects.</p><span id="more"></span><h3 id="structure"><a href="#structure" class="headerlink" title="structure"></a>structure</h3><p>LocationEngine core modules include: model manager, Bluetooth locator, geo-locator, motion detector, area monitor and other modules.</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">i.modelManager = new T.ModelManager(t), </span><br><span class="line">i.roadNetData = new d.RoadNetData(t),  </span><br><span class="line">i.navProcessor = new g.NavigationProcessor(t), </span><br><span class="line">i.bluetoothLocator = new l.BluetoothLocator(t), </span><br><span class="line">i.geoLocator = new c.GeoLocator(t), </span><br><span class="line">i.motionDetector = new u.MotionDetector(t), </span><br><span class="line">i.areaChecker = new f.AreaChecker(t), </span><br></pre></td></tr></table></figure><ul><li>ModelManager: Model manager.</li><li>RoadNetData: configuration-based road network data.</li><li>NavigationProcessor: Navigation processor.</li><li>BluetoothLocator: Bluetooth locator.</li><li>MotionDetector: Motion detector.</li></ul><h3 id="Bluetooth-Locator"><a href="#Bluetooth-Locator" class="headerlink" title="Bluetooth Locator"></a>Bluetooth Locator</h3><p>Locator initialization, default parameter settings and Bluetooth configuration information settings.</p><ul><li>set default parameters.</li></ul><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">value: function(t) &#123;</span><br><span class="line">    t || (t = &#123;&#125;),</span><br><span class="line">    this.REC_INTERVAL = t.RecInterval ? t.RecInterval : 5e3,</span><br><span class="line">    this.QUERY_INTERVAL = t.QueryInterval ? t.QueryInterval : 2e3,</span><br><span class="line">    this.Z_CHECK_INTERVAL = t.ZCheckInterval ? t.ZCheckInterval : 3e3,</span><br><span class="line">    this.ZInitTimeout = t.ZInitTimeout ? t.ZInitTimeout : 3e3,</span><br><span class="line">    this.deviceType = void 0 !== t.deviceType ? t.deviceType : s.CONSTANTS.DEVICE.ANDROID</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><ul><li>Configure Bluetooth beacons.</li></ul><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">key: &quot;addAps&quot;,</span><br><span class="line">value: function(t) &#123;</span><br><span class="line">    t &amp;&amp; (t.forEach(function(t) &#123;</span><br><span class="line">        void 0 === t.z &amp;&amp; (t.z = t.re),</span><br><span class="line">        t.rssiList = []</span><br><span class="line">    &#125;),</span><br><span class="line">    this._aps = this._aps.concat(t))</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><ul><li>By obtaining the Bluetooth signal data, LocationEngine calls the bluetoothLocator.updateBeacons() method to calculate the location.</li></ul><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">var n = this.bluetoothLocator.updateBeacons(i, t.value, this.posMode, this.isIndoor, this.kfPos)</span><br></pre></td></tr></table></figure><ul><li><p>Filter non-Bluetooth configuration beacons and invalid rssi signals, and update the Bluetooth beacon signal queue.</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><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">key: &quot;updateApsByReceivedBeacons&quot;,</span><br><span class="line"> value: function(t, e) &#123;</span><br><span class="line">     var i = this;</span><br><span class="line">     e.forEach(function(e) &#123;</span><br><span class="line">         var n = i._matchAp(e.major, e.minor); </span><br><span class="line">         if (n &amp;&amp; &quot;-100&quot; !== e.rssi &amp;&amp; &quot;0&quot; !== e.rssi &amp;&amp; 0 !== e.rssi &amp;&amp; -100 !== e.rssi) &#123;</span><br><span class="line">             var r = n.rssiList.push(&#123;</span><br><span class="line">                 timestamp: t, </span><br><span class="line">                 rssi: parseInt(e.rssi)</span><br><span class="line">             &#125;);</span><br><span class="line">             n.status = 1,</span><br><span class="line">             r &gt; 15 &amp;&amp; n.rssiList.shift()</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>Get the current Bluetooth beacon, sort according to the signal strength, and set the Bluetooth beacon information strength.</p></li></ul><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><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">for (var d, v = l.rssiList[Symbol.iterator](); !(c = (d = v.next()).done); c = !0) &#123; </span><br><span class="line">           var p = d.value;</span><br><span class="line">           i - p.timestamp &lt; this.REC_INTERVAL &amp;&amp; n.push(&#123;</span><br><span class="line">               major: l.ma,</span><br><span class="line">               minor: l.mi,</span><br><span class="line">               x: l.x,</span><br><span class="line">               y: l.y,</span><br><span class="line">               region: l.re,</span><br><span class="line">               timestamp: p.timestamp,</span><br><span class="line">               rssi: p.rssi,</span><br><span class="line">               z: l.z</span><br><span class="line">           &#125;)  </span><br><span class="line"> &#125;</span><br></pre></td></tr></table></figure><ul><li>Filter the beacons whose distance between the beacon position and the last beacon position is greater than 100, and the time is greater than 2s.</li></ul><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">h = (a = a.filter(function(t) &#123;</span><br><span class="line">               return !s || r.LocationUtils.distance(s, t) &lt;= 100 </span><br><span class="line">           &#125;)).filter(function(e) &#123;</span><br><span class="line">               return t - e.timestamp &lt; o.QUERY_INTERVAL</span><br><span class="line">           &#125;)</span><br></pre></td></tr></table></figure><ul><li>The filtered Bluetooth signals are sorted, and the first 5 are selected for weight and calculation, and the x and y position information is calculated according to the weight of the Bluetooth beacon.</li></ul><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><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><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">key: &quot;calBtPos&quot;,  </span><br><span class="line">            value: function(e, i, n, r, s) &#123;</span><br><span class="line">                if (0 === e.length) </span><br><span class="line">                    return null;</span><br><span class="line">                e.sort(function(t, e) &#123; </span><br><span class="line">                    return e.rssi - t.rssi</span><br><span class="line">                &#125;);</span><br><span class="line">                var o = e[0].rssi  </span><br><span class="line">                  , a = e.slice(0, 5); </span><br><span class="line">                t.calGradientWeight(a, o);  </span><br><span class="line">                var h = a.reduce(function(t, e) &#123;</span><br><span class="line">                    return t + e.weight</span><br><span class="line">                &#125;, 0) </span><br><span class="line">                  , l = t.calConfidence(a) </span><br><span class="line">                  , c = t.calNearAPCount(a, o, r, s</span><br><span class="line">                  , u = t.checkBoundaryState(a, n) </span><br><span class="line">                  , f = a.reduce(function(t, e) &#123;   </span><br><span class="line">                    return t + e.rssi</span><br><span class="line">                &#125;, 0) / a.length;</span><br><span class="line">                return &#123;</span><br><span class="line">                    x: a.reduce(function(t, e) &#123;  </span><br><span class="line">                        return t + e.x * e.weight</span><br><span class="line">                    &#125;, 0) / h,</span><br><span class="line">                    y: a.reduce(function(t, e) &#123; </span><br><span class="line">                        return t + e.y * e.weight</span><br><span class="line">                    &#125;, 0) / h,</span><br><span class="line">                    z: parseFloat(i), //</span><br><span class="line">                    c: l, </span><br><span class="line">                    p: c, </span><br><span class="line">                    s: u, </span><br><span class="line">                    m: f </span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br></pre></td></tr></table></figure><h3 id="Motion-Detector"><a href="#Motion-Detector" class="headerlink" title="Motion Detector"></a>Motion Detector</h3><ul><li>LocationEngine update accelerometer mode.</li></ul><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">key: &quot;updateAccSensorMode&quot;, </span><br><span class="line">value: function() &#123;</span><br><span class="line">    this.motionDetector ? this.accSensorStatus = this.motionDetector.getAccSensorStatus() : this.accSensorStatus = P.CONSTANTS.ACC_SENSOR_STATUS.EMPTY</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><ul><li>Set accelerometer mode according to accelerometer frequency.</li></ul><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">key: &quot;checkAccSensorMode&quot;, </span><br><span class="line">value: function(t) &#123;</span><br><span class="line">    t - this.startTime &lt; this.gravityTimeLen || (this.gravityList &amp;&amp; 0 === this.gravityList.length &amp;&amp; (this.accSensorStatus = o.CONSTANTS.ACC_SENSOR_STATUS.EMPTY),</span><br><span class="line">    this.accCompBuffer.reduce(function(t, e) &#123;</span><br><span class="line">        return t + e</span><br><span class="line">    &#125;, 0) / this.accCompBufferLen &gt; 9 &amp;&amp; (this.accFreq = 1e3 * this.gravityList.length / this.gravityTimeLen,</span><br><span class="line">    this.accFreq &lt; 13 ? this.accSensorStatus = o.CONSTANTS.ACC_SENSOR_STATUS.LOW_FREQ : this.accFreq &gt;= 22 &amp;&amp; (this.accSensorStatus = o.CONSTANTS.ACC_SENSOR_STATUS.NORMAL)))</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><ul><li>By obtaining the compass data, LocationEngine calls the motionDetector.updateHeading() method and passes in the angle value of the current device.</li></ul><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">key: &quot;updateHeading&quot;, </span><br><span class="line">             value: function(t) &#123;</span><br><span class="line">                 this.headingChange = this.headingFlag ? t.value.heading - this.headingDeg : 0,</span><br><span class="line">                 this.headingDeg = t.value.heading, </span><br><span class="line">                 this.motionDetector.updateHeading(t.timestamp, t.value.heading),</span><br><span class="line">                 this.headingFlag = !0</span><br><span class="line">             &#125;</span><br></pre></td></tr></table></figure><ul><li>LocationEngine calls the motionDetector.detectMotion() method to process the acceleration data.</li></ul><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">key: &quot;updateAcc&quot;, </span><br><span class="line">   var n = this.motionDetector.detectMotion(t, e, i);  </span><br></pre></td></tr></table></figure><ul><li>By analyzing and processing the motion state of the device, the number of steps, step length, mobile phone posture, motion state, etc. are obtained.</li></ul><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">this.motionResult = Object.assign(&#123;</span><br><span class="line">                       t: t,  </span><br><span class="line">                       stepDetected: a, </span><br><span class="line">                       step: h,</span><br><span class="line">                       phonePlacement: this.phonePlacement,</span><br><span class="line">                       motionState: this.motionState </span><br><span class="line">                   &#125;, l  )</span><br></pre></td></tr></table></figure><ul><li>step counting<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><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><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">key: &quot;detectStep&quot;, </span><br><span class="line">              value: function(t, e, i) &#123;</span><br><span class="line">                  var n = !1; </span><br><span class="line">                  return 0 !== this.peakTime   </span><br><span class="line">                              &amp;&amp; this.peakValleyPair.pvDiff &gt; this.PeakValleyTh </span><br><span class="line">                              &amp;&amp; t - this.peakTime &gt; this.MinPeakInterval </span><br><span class="line">                              &amp;&amp; this.peakTime - this.stepTime &gt; this.MinStepInterval </span><br><span class="line">                              &amp;&amp; (this.stepTime = this.peakTime,</span><br><span class="line">                                     this.stepCount += 1,</span><br><span class="line">                                     this.saver &amp;&amp; </span><br><span class="line">                                     this.saver.saveStepResult(this.stepTime, this.peakValleyPair.peak, this.peakValleyPair.valley, this.PeakValleyTh),</span><br><span class="line">                                     n = !0),</span><br><span class="line">                              e &lt; this.valleyValue </span><br><span class="line">                              &amp;&amp; (this.valleyValue = e,this.valleyTime = t),</span><br><span class="line">                             this.validValleyValue = t - this.lastValleyVTime &lt; 2 * this.MinStepInterval </span><br><span class="line">                                  &amp;&amp; this.lastValleyVTime &gt; this.stepTime </span><br><span class="line">                                  &amp;&amp; this.lastValleyValue &lt; this.valleyValue ? this.lastValleyValue : this.valleyValue,</span><br><span class="line">                             0 !== i &amp;&amp; 1 === this.detectPeak(t, e, i)  </span><br><span class="line">                                   &amp;&amp; i - this.validValleyValue &gt; 1.3 </span><br><span class="line">                                   &amp;&amp; (this.saver &amp;&amp; this.saver.savePeakResult(t, i, this.validValleyValue, i - this.validValleyValue), //</span><br><span class="line">                             t - this.peakTime &gt; this.MinPeakInterval &amp;&amp; (this.PeakValleyTh = this.peakValleyThresholdUpdate(i - this.validValleyValue),</span><br><span class="line">                            this.lastValleyValue = this.valleyValue,</span><br><span class="line">                            this.lastValleyVTime = this.valleyTime,</span><br><span class="line">                            this.valleyValue = 100,</span><br><span class="line">                            this.peakTime = t,</span><br><span class="line">                            this.peakValleyPair = &#123;</span><br><span class="line">                                   peak: i,</span><br><span class="line">                                   valley: this.validValleyValue,</span><br><span class="line">                                  pvDiff: i - this.validValleyValue</span><br><span class="line">                                  &#125;),</span><br><span class="line">                            t - this.peakTime &lt;= this.MinPeakInterval </span><br><span class="line">                               &amp;&amp; i &gt; this.peakValleyPair.peak &amp;&amp; (this.peakTime = t,</span><br><span class="line">                                      this.validValleyValue = this.validValleyValue &lt; this.peakValleyPair.valley ? this.validValleyValue : this.peakValleyPair.valley,</span><br><span class="line">                                      this.peakValleyPair = &#123;</span><br><span class="line">                                           peak: i,</span><br><span class="line">                                           valley: this.validValleyValue,</span><br><span class="line">                                           pvDiff: i - this.validValleyValue</span><br><span class="line">                              &#125;)),</span><br><span class="line">                           n</span><br><span class="line">              &#125;</span><br></pre></td></tr></table></figure></li></ul><h3 id="Model-Manager"><a href="#Model-Manager" class="headerlink" title="Model Manager"></a>Model Manager</h3><ul><li><p>Kalman filter model setting parameters。</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">i.pdrKf = new o.KalmanFilterPDR(i.t,a.KF_TYPE.PDR_WLK,t.deviceType,t.params),</span><br><span class="line">i.diffKf = new s.KalmanFilterDiffHeading(i.t,a.KF_TYPE.DIFF_WLK,t.deviceType,t.params),</span><br><span class="line">i.baseKf = new s.KalmanFilterDiffHeading(i.t,a.KF_TYPE.DIFF_BASE,t.deviceType,t.params),</span><br><span class="line">i.drvKf = new s.KalmanFilterDiffHeading(i.t,a.KF_TYPE.DIFF_DRV,t.deviceType,t.params),</span><br></pre></td></tr></table></figure></li><li><p>When the location engine gets new location information, it will pass this information to the model manager for processing and analysis. The model manager updates the Kalman filter model based on the current location state and historical data.</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><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><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">key: &quot;updateFusionModels&quot;, </span><br><span class="line">value: function(t, e, i, n, r, s, o, a, l, u) &#123;</span><br><span class="line">    if (this.started || this.checkInitSignal(t, n, r) &amp;&amp; (this.t = t,</span><br><span class="line">    this.started = !0,</span><br><span class="line">    this.z = e,</span><br><span class="line">    this.isARLast(this.arLastPos, n, r)),</span><br><span class="line">    this.started) &#123; </span><br><span class="line">        e !== this.z &amp;&amp; (this.z = e,</span><br><span class="line">        h.LocationUtils.distance(i, n) &lt; h.LocationUtils.distance(i, r) &amp;&amp; h.LocationUtils.distance(i, n) &lt; 10 ? this.reStartModels(n, null) : this.reStartModels(n, r));</span><br><span class="line">        this.t;</span><br><span class="line">        this.t = t,</span><br><span class="line">        this.pdrKf.update(t, n, r, s, o, a, l, u),</span><br><span class="line">        this.diffKf.update(t, n, r, s, l, u),</span><br><span class="line">        this.baseKf.update(t, n, r, void 0, u),</span><br><span class="line">        this.drvKf.update(t, n, r, s, !1, u),</span><br><span class="line">        this.drvOutKF.update(t, n, r, s, l),</span><br><span class="line">        this.updateBaseKfInfos(c.Numerical.rad2deg(s))  </span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></li><li><p>Kafman filter direction angle。</p></li></ul><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">key: &quot;getHeadingDeg&quot;,</span><br><span class="line">value: function() &#123;</span><br><span class="line">    if (this.kalmanModel)</span><br><span class="line">        return h.Numerical.rad2deg(Math.atan2(this.kalmanModel.x_k.elements[1], this.kalmanModel.x_k.elements[3]))</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><ul><li>Get Kalman filter position.</li></ul> <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">key: &quot;getPosition&quot;,</span><br><span class="line">value: function() &#123;</span><br><span class="line">    if (this.kalmanModel)</span><br><span class="line">        return &#123;</span><br><span class="line">            x: this.kalmanModel.x_k.elements[0],</span><br><span class="line">            y: this.kalmanModel.x_k.elements[2]</span><br><span class="line">        &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><ul><li>Get the Kalman filter speed.</li></ul>  <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">key: &quot;getVelocity&quot;,</span><br><span class="line">value: function() &#123;</span><br><span class="line">    if (this.kalmanModel)</span><br><span class="line">        return &#123;</span><br><span class="line">            x: this.kalmanModel.x_k.elements[1],</span><br><span class="line">            y: this.kalmanModel.x_k.elements[3]</span><br><span class="line">        &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>]]></content>
    
    
    <summary type="html">&lt;p&gt;Recently, I found a &lt;a href=&quot;/js/se.js&quot;&gt;source code&lt;/a&gt; about Bluetooth positioning and navigation. Through its analysis and research, I have a deep understanding of the positioning and navigation process of the entire Bluetooth algorithm. Learn about Bluetooth signal acquisition, distance estimation, positioning calculation, Kalman model and other aspects.&lt;/p&gt;</summary>
    
    
    
    <category term="CS" scheme="http://blog.beendless.com/categories/CS/"/>
    
    
    <category term="Bluetooth" scheme="http://blog.beendless.com/tags/Bluetooth/"/>
    
    <category term="GEO Location" scheme="http://blog.beendless.com/tags/GEO-Location/"/>
    
  </entry>
  
  <entry>
    <title>Knapsack Problems II</title>
    <link href="http://blog.beendless.com/2021/10/09/Knapsack%20Problem%20II/"/>
    <id>http://blog.beendless.com/2021/10/09/Knapsack%20Problem%20II/</id>
    <published>2021-10-10T05:14:24.000Z</published>
    <updated>2023-03-08T05:05:31.146Z</updated>
    
    <content type="html"><![CDATA[<h2 id="377-Combination-Sum-IV"><a href="#377-Combination-Sum-IV" class="headerlink" title="377. Combination Sum IV"></a><a href="https://leetcode.com/problems/combination-sum-iv">377. Combination Sum IV</a></h2><p>This is also a full knapsack problem. It looks similar to the <a href="/2021/10/07/Knapsack%20Problem%20I/">coins change ii</a>, but the difference here is that we need to get the permutation of the solutions instead of combination. So in this case we need to iterate the knapsack space first, then iterate the items.</p><figure class="highlight golang"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><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="function"><span class="keyword">func</span> <span class="title">combinationSum4</span><span class="params">(nums []<span class="type">int</span>, target <span class="type">int</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">    dp := <span class="built_in">make</span>([]<span class="type">int</span>, target + <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> i := <span class="number">1</span>; i &lt;= target; i++ &#123;</span><br><span class="line">        <span class="keyword">for</span> j := <span class="number">0</span>; j &lt; <span class="built_in">len</span>(nums); j++ &#123;</span><br><span class="line">            <span class="keyword">if</span> i &gt;= nums[j] &#123;</span><br><span class="line">                dp[i] += dp[i - nums[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[target]</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="279-Perfect-Squares"><a href="#279-Perfect-Squares" class="headerlink" title="279. Perfect Squares"></a><a href="https://leetcode.com/problems/perfect-squares/">279. Perfect Squares</a></h2><p>This is also a full knapsack problem. We can consider all squares not greater than the given n as items, n as the knapsack total capacity,  and we can reuse all items to fill the knapsack. To get the minimal items, the state transition function is <code>dp[i] = min(dp[i], dp[i - j] + 1</code></p><figure class="highlight golang"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><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="function"><span class="keyword">func</span> <span class="title">numSquares</span><span class="params">(n <span class="type">int</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">    squares := []<span class="type">int</span>&#123;&#125;</span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">1</span>; i * i &lt;= n; i++ &#123;</span><br><span class="line">        squares = <span class="built_in">append</span>(squares, i * i)</span><br><span class="line">    &#125;</span><br><span class="line">    dp := <span class="built_in">make</span>([]<span class="type">int</span>, n + <span class="number">1</span>)</span><br><span class="line">    dp[<span class="number">1</span>] = <span class="number">1</span></span><br><span class="line">    min := <span class="function"><span class="keyword">func</span><span class="params">(a, b <span class="type">int</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> a &lt; b &#123;</span><br><span class="line">            <span class="keyword">return</span> a</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> b</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">2</span>; i &lt;= n; i++ &#123;</span><br><span class="line">        <span class="keyword">for</span> j := <span class="number">0</span>; j &lt; <span class="built_in">len</span>(squares); j++ &#123;</span><br><span class="line">            <span class="keyword">if</span> i &gt;= squares[j] &#123;</span><br><span class="line">                dp[i] = min(dp[i], dp[i - squares[j]] + <span class="number">1</span>) <span class="comment">// here we are counting the number, so we increase the items count.</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[n]</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>We can also try to use backtracking to resolve this problem.</p><figure class="highlight golang"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><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="function"><span class="keyword">func</span> <span class="title">numSquares</span><span class="params">(n <span class="type">int</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">    squares := []<span class="type">int</span>&#123;&#125;</span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">1</span>; i * i &lt;= n; i++ &#123;</span><br><span class="line">        squares = <span class="built_in">append</span>(squares, i * i)</span><br><span class="line">    &#125;</span><br><span class="line">    hash := <span class="built_in">make</span>(<span class="keyword">map</span>[<span class="type">int</span>]<span class="type">int</span>)</span><br><span class="line">    min := <span class="function"><span class="keyword">func</span><span class="params">(a, b <span class="type">int</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> a &lt; b &#123;</span><br><span class="line">            <span class="keyword">return</span> a</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> b</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">var</span> backtracking <span class="function"><span class="keyword">func</span><span class="params">(<span class="type">int</span>)</span></span> <span class="type">int</span></span><br><span class="line">    backtracking = <span class="function"><span class="keyword">func</span><span class="params">(index <span class="type">int</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> v, ok := hash[index]; ok &#123;</span><br><span class="line">            <span class="keyword">return</span> v</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span> index == <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">        count := n + <span class="number">1</span></span><br><span class="line">        <span class="keyword">for</span> j := <span class="number">0</span>; j &lt; <span class="built_in">len</span>(squares); j++ &#123;</span><br><span class="line">            <span class="keyword">if</span> index &gt;= squares[j] &#123;</span><br><span class="line">                count = min(count, backtracking(index - squares[j]) + <span class="number">1</span>)   </span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        hash[index] = count</span><br><span class="line">        <span class="keyword">return</span> count</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> backtracking(n)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="139-Word-Break"><a href="#139-Word-Break" class="headerlink" title="139. Word Break"></a><a href="https://leetcode.com/problems/word-break/">139. Word Break</a></h2><p>Obviously, an empty string can be part of any string. So if we denote dp[i] as s[:i] which can be constructed by the worddict, dp[0] is true. And the state transition function can be <code>dp[i] = dp[i - len(words[j]] &amp;&amp; words[j] == s[i - len(words[j]):i]</code>. We can consider this as a full knapsack problem. Words can be consider as items, and the s can be considered as a special knapsack.</p><figure class="highlight golang"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><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="function"><span class="keyword">func</span> <span class="title">wordBreak</span><span class="params">(s <span class="type">string</span>, wordDict []<span class="type">string</span>)</span></span> <span class="type">bool</span> &#123;</span><br><span class="line">    dp := <span class="built_in">make</span>([]<span class="type">bool</span>, <span class="built_in">len</span>(s) + <span class="number">1</span>)</span><br><span class="line">    dp[<span class="number">0</span>] = <span class="literal">true</span></span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">1</span>; i &lt;= <span class="built_in">len</span>(s); i++ &#123;</span><br><span class="line">        <span class="keyword">for</span> j := <span class="number">0</span>; j &lt; <span class="built_in">len</span>(wordDict); j++ &#123;</span><br><span class="line">            <span class="keyword">if</span> i &gt;= wordDict[j] &#123;</span><br><span class="line">                dp[i] = dp[i] || (dp[i - <span class="built_in">len</span>(wordDict[j])] &amp;&amp; wordDict[j] == s[i - <span class="built_in">len</span>(wordDict[j]):i])</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> dp[<span class="built_in">len</span>(s)]</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>We can also optimize it with a hashmap to store all words</p><figure class="highlight golang"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><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="function"><span class="keyword">func</span> <span class="title">wordBreak</span><span class="params">(s <span class="type">string</span>, wordDict []<span class="type">string</span>)</span></span> <span class="type">bool</span> &#123;</span><br><span class="line">    dp := <span class="built_in">make</span>([]<span class="type">bool</span>, <span class="built_in">len</span>(s) + <span class="number">1</span>)</span><br><span class="line">    hash := <span class="built_in">make</span>(<span class="keyword">map</span>[<span class="type">string</span>]<span class="type">bool</span>)</span><br><span class="line">    <span class="keyword">for</span> _, word := <span class="keyword">range</span> wordDict &#123;</span><br><span class="line">        hash[word] = <span class="literal">true</span></span><br><span class="line">    &#125;</span><br><span class="line">    dp[<span class="number">0</span>] = <span class="literal">true</span></span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">1</span>; i &lt;= <span class="built_in">len</span>(s); i++ &#123;</span><br><span class="line">        <span class="keyword">for</span> j := <span class="number">0</span>; j &lt; i; j++ &#123;</span><br><span class="line">            dp[i] = dp[i] || (dp[j] &amp;&amp; hash[s[j:i]])</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> dp[<span class="built_in">len</span>(s)]</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>]]></content>
    
    
      
      
    <summary type="html">&lt;h2 id=&quot;377-Combination-Sum-IV&quot;&gt;&lt;a href=&quot;#377-Combination-Sum-IV&quot; class=&quot;headerlink&quot; title=&quot;377. Combination Sum IV&quot;&gt;&lt;/a&gt;&lt;a href=&quot;https://le</summary>
      
    
    
    
    <category term="CS" scheme="http://blog.beendless.com/categories/CS/"/>
    
    
    <category term="Golang" scheme="http://blog.beendless.com/tags/Golang/"/>
    
    <category term="Algorithms" scheme="http://blog.beendless.com/tags/Algorithms/"/>
    
    <category term="Leetcode" scheme="http://blog.beendless.com/tags/Leetcode/"/>
    
    <category term="Dynamic Programming" scheme="http://blog.beendless.com/tags/Dynamic-Programming/"/>
    
    <category term="Knapsack" scheme="http://blog.beendless.com/tags/Knapsack/"/>
    
  </entry>
  
  <entry>
    <title>Dynamic Programming II</title>
    <link href="http://blog.beendless.com/2021/10/08/Dynamic%20Programming%20II/"/>
    <id>http://blog.beendless.com/2021/10/08/Dynamic%20Programming%20II/</id>
    <published>2021-10-08T18:04:24.000Z</published>
    <updated>2023-03-08T05:05:31.142Z</updated>
    
    <content type="html"><![CDATA[<h2 id="494-Target-Sum"><a href="#494-Target-Sum" class="headerlink" title="494. Target Sum"></a><a href="https://leetcode.com/problems/target-sum/">494. Target Sum</a></h2><p>a. Brute-force DFS recursive solution</p><figure class="highlight golang"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="function"><span class="keyword">func</span> <span class="title">findTargetSumWays</span><span class="params">(nums []<span class="type">int</span>, target <span class="type">int</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">    count := <span class="number">0</span></span><br><span class="line">    <span class="keyword">var</span> dfs <span class="function"><span class="keyword">func</span><span class="params">(<span class="type">int</span> ,<span class="type">int</span>)</span></span></span><br><span class="line">    dfs = <span class="function"><span class="keyword">func</span><span class="params">(index, left <span class="type">int</span>)</span></span> &#123;</span><br><span class="line">        <span class="keyword">if</span> index == <span class="built_in">len</span>(nums) &#123;</span><br><span class="line">            <span class="keyword">if</span> left == <span class="number">0</span> &#123;</span><br><span class="line">                count++</span><br><span class="line">            &#125;</span><br><span class="line">        &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">            dfs(index + <span class="number">1</span>, left + nums[index])</span><br><span class="line">            dfs(index + <span class="number">1</span>, left - nums[index])</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    dfs(<span class="number">0</span>, target)</span><br><span class="line">    <span class="keyword">return</span> count</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>b. Dynamic Programming</p><p><code>dp[i][j]</code> refers to the number of assignments which can lead to a sum of j up to the ith items in the Array. We can get the state transition function: <code>dp[i][j] = dp[i - 1][j + nums[i]] + dp[i - 1][j - nums[i]]</code></p><figure class="highlight golang"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><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="function"><span class="keyword">func</span> <span class="title">findTargetSumWays</span><span class="params">(nums []<span class="type">int</span>, target <span class="type">int</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">    sum := <span class="number">0</span></span><br><span class="line">    <span class="keyword">for</span> _, num := <span class="keyword">range</span> 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; target || -sum &gt; target || (sum + target) % <span class="number">2</span> != <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">    n := <span class="built_in">len</span>(nums)</span><br><span class="line">    dp := <span class="built_in">make</span>([][]<span class="type">int</span>, n)</span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">0</span>; i &lt; n; i++ &#123;</span><br><span class="line">        dp[i] = <span class="built_in">make</span>([]<span class="type">int</span>, <span class="number">2</span> * sum + <span class="number">1</span>)</span><br><span class="line">    &#125;</span><br><span class="line">    dp[<span class="number">0</span>][sum + nums[<span class="number">0</span>]] = <span class="number">1</span></span><br><span class="line">    dp[<span class="number">0</span>][sum - nums[<span class="number">0</span>]] += <span class="number">1</span></span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">1</span>; i &lt; n; i++ &#123;</span><br><span class="line">        <span class="keyword">for</span> j := -sum; j &lt;= sum; j++ &#123;</span><br><span class="line">            <span class="keyword">if</span> j + nums[i] &lt; sum + <span class="number">1</span> &#123;</span><br><span class="line">                dp[i][j + sum + nums[i]] += dp[i - <span class="number">1</span>][j + sum]</span><br><span class="line">            &#125;   </span><br><span class="line">            <span class="keyword">if</span> j + sum - nums[i] &gt;= <span class="number">0</span> &#123;</span><br><span class="line">                dp[i][j + sum - nums[i]] += dp[i - <span class="number">1</span>][j + sum]   </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 - <span class="number">1</span>][sum + target]</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>c. Knapsack solution (subset sum)</p><p>Based on the problem description, we will have two subsets. One with positive symbol (s1) and another one with negative symbol (s2).  So <code>s1 + s2 = sum</code>  and <code>s1 - s2 = target</code>. We can convert this problem to a 0-1 knapsack problem — find a subset which subtotal is <code>s1 = (sum + target) / 2</code>.</p><figure class="highlight golang"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><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="function"><span class="keyword">func</span> <span class="title">findTargetSumWays</span><span class="params">(nums []<span class="type">int</span>, target <span class="type">int</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">    sum := <span class="number">0</span></span><br><span class="line">    zero := <span class="number">0</span></span><br><span class="line">    sort.Ints(nums)  <span class="comment">// to make sure we can handle cases contains 0</span></span><br><span class="line">    <span class="keyword">for</span> _, num := <span class="keyword">range</span> nums &#123;</span><br><span class="line">        <span class="keyword">if</span> num == <span class="number">0</span> &#123;</span><br><span class="line">            zero++</span><br><span class="line">        &#125;</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; target || -sum &gt; target || (sum + target) % <span class="number">2</span> != <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">    n := <span class="built_in">len</span>(nums)</span><br><span class="line">    target = (sum + target) / <span class="number">2</span></span><br><span class="line">    dp := <span class="built_in">make</span>([][]<span class="type">int</span>, n + <span class="number">1</span>)</span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">0</span>; i &lt;= n; i++ &#123;</span><br><span class="line">        dp[i] = <span class="built_in">make</span>([]<span class="type">int</span>, target + <span class="number">1</span>)</span><br><span class="line">        dp[i][<span class="number">0</span>] = <span class="number">1</span></span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">1</span>; i &lt;= n; i++ &#123;</span><br><span class="line">        <span class="keyword">for</span> j := <span class="number">1</span>; j &lt;= target; j++ &#123;</span><br><span class="line">            dp[i][j] = dp[i<span class="number">-1</span>][j]</span><br><span class="line">            <span class="keyword">if</span> j &gt;= nums[i - <span class="number">1</span>] &#123;</span><br><span class="line">                dp[i][j] += dp[i<span class="number">-1</span>][j - nums[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">    <span class="keyword">return</span> dp[n][target] * <span class="type">int</span>(math.Pow(<span class="type">float64</span>(<span class="number">2</span>), <span class="type">float64</span>(zero)))</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>We can use 1D rolling array to reduce the space complexity.</p><figure class="highlight golang"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><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="function"><span class="keyword">func</span> <span class="title">findTargetSumWays</span><span class="params">(nums []<span class="type">int</span>, target <span class="type">int</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">    sum := <span class="number">0</span></span><br><span class="line">    zeros := <span class="number">0</span></span><br><span class="line">    sort.Ints(nums)</span><br><span class="line">    <span class="keyword">for</span> _, num := <span class="keyword">range</span> nums &#123;</span><br><span class="line">        sum += num</span><br><span class="line">        <span class="keyword">if</span> num == <span class="number">0</span> &#123;</span><br><span class="line">            zeros++</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span> sum &lt; target || -sum &gt; target || (sum + target) % <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">    n := <span class="built_in">len</span>(nums)</span><br><span class="line">    target = (sum + target) / <span class="number">2</span></span><br><span class="line">    dp := <span class="built_in">make</span>([]<span class="type">int</span>, target + <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> i := <span class="number">0</span>; i &lt; n; i++ &#123;</span><br><span class="line">        <span class="keyword">for</span> j := target; j &gt;= nums[i]; j-- &#123;</span><br><span class="line">            dp[j] += dp[j - nums[i]]</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> dp[target] * <span class="type">int</span>(math.Pow(<span class="type">float64</span>(<span class="number">2</span>), <span class="type">float64</span>(zeros)))</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="198-House-Robber"><a href="#198-House-Robber" class="headerlink" title="198. House Robber"></a><a href="https://leetcode.com/problems/house-robber/">198. House Robber</a></h2><p>State transition function: <code>dp[i] = max(dp[i - 1], dp[i - 2] + value[i]</code></p><figure class="highlight golang"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">rob</span><span class="params">(nums []<span class="type">int</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">    n := <span class="built_in">len</span>(nums)</span><br><span class="line">    dp := <span class="built_in">make</span>([]<span class="type">int</span>, n + <span class="number">1</span>)</span><br><span class="line">    dp[<span class="number">1</span>] = nums[<span class="number">0</span>]</span><br><span class="line">    max := <span class="function"><span class="keyword">func</span><span class="params">(a, b <span class="type">int</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> a &gt; b &#123;</span><br><span class="line">            <span class="keyword">return</span> a</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> b</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">2</span>; i &lt;= n; i++ &#123;</span><br><span class="line">        dp[i] = max(dp[i - <span class="number">1</span>], dp[i - <span class="number">2</span>] + nums[i - <span class="number">1</span>])</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><h2 id="213-House-Robber-II"><a href="#213-House-Robber-II" class="headerlink" title="213. House Robber II"></a><a href="https://leetcode.com/problems/house-robber-ii">213. House Robber II</a></h2><p>Since we only need to compare [0, n-1] and [1, n] cases, and those two can be resolved with the solution we have above.</p><figure class="highlight golang"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><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="function"><span class="keyword">func</span> <span class="title">rob</span><span class="params">(nums []<span class="type">int</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">    max := <span class="function"><span class="keyword">func</span><span class="params">(a, b <span class="type">int</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> a &gt; b &#123;</span><br><span class="line">            <span class="keyword">return</span> a</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> b</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span> <span class="built_in">len</span>(nums) == <span class="number">1</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> nums[<span class="number">0</span>]</span><br><span class="line">    &#125;</span><br><span class="line">    basicRobber := <span class="function"><span class="keyword">func</span><span class="params">(nums []<span class="type">int</span>)</span></span> <span class="type">int</span>&#123;</span><br><span class="line">        n := <span class="built_in">len</span>(nums)</span><br><span class="line">        dp := <span class="built_in">make</span>([]<span class="type">int</span>, n + <span class="number">1</span>)</span><br><span class="line">        dp[<span class="number">1</span>] = nums[<span class="number">0</span>]</span><br><span class="line">        <span class="keyword">for</span> i := <span class="number">2</span>; i &lt;= n; i++ &#123;</span><br><span class="line">            dp[i] = max(dp[i - <span class="number">1</span>], dp[i - <span class="number">2</span>] + nums[i - <span class="number">1</span>])</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><span class="line">    <span class="keyword">return</span> max(basicRobber(nums[:<span class="built_in">len</span>(nums) - <span class="number">1</span>]), basicRobber(nums[<span class="number">1</span>:<span class="built_in">len</span>(nums)]))</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="337-House-Robber-III"><a href="#337-House-Robber-III" class="headerlink" title="337. House Robber III"></a><a href="https://leetcode.com/problems/house-robber-iii">337. House Robber III</a></h2><p>a. DFS + memorized result</p><figure class="highlight golang"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Definition for a binary tree node.</span></span><br><span class="line"><span class="comment"> * type TreeNode struct &#123;</span></span><br><span class="line"><span class="comment"> *     Val int</span></span><br><span class="line"><span class="comment"> *     Left *TreeNode</span></span><br><span class="line"><span class="comment"> *     Right *TreeNode</span></span><br><span class="line"><span class="comment"> * &#125;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">rob</span><span class="params">(root *TreeNode)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">    cache := <span class="built_in">make</span>(<span class="keyword">map</span>[*TreeNode]<span class="type">int</span>)</span><br><span class="line">    <span class="keyword">var</span> dfs <span class="function"><span class="keyword">func</span><span class="params">(*TreeNode)</span></span> <span class="type">int</span></span><br><span class="line">    dfs = <span class="function"><span class="keyword">func</span><span class="params">(root *TreeNode)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> root == <span class="literal">nil</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> value, ok := cache[root]; ok &#123;</span><br><span class="line">            <span class="keyword">return</span> value</span><br><span class="line">        &#125;</span><br><span class="line">        rootValue := root.Val</span><br><span class="line">        <span class="keyword">if</span> root.Left != <span class="literal">nil</span> &#123;</span><br><span class="line">            rootValue += dfs(root.Left.Left) + dfs(root.Left.Right)</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span> root.Right != <span class="literal">nil</span> &#123;</span><br><span class="line">            rootValue += dfs(root.Right.Left) + dfs(root.Right.Right)</span><br><span class="line">        &#125;</span><br><span class="line">        childValue := dfs(root.Left) + dfs(root.Right)</span><br><span class="line">        maxValue := childValue</span><br><span class="line">        <span class="keyword">if</span> rootValue &gt; childValue &#123;</span><br><span class="line">            maxValue = rootValue</span><br><span class="line">        &#125;</span><br><span class="line">        cache[root] = maxValue</span><br><span class="line">        <span class="keyword">return</span> maxValue</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> dfs(root)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>b. Dynamic Programming to cache more calculation results.</p><p>Since each node has two values, with or without its own value. The above one only caches the maxValue, if we cache both of those in an array, it will speed up the calculating.</p><figure class="highlight golang"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><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="function"><span class="keyword">func</span> <span class="title">rob</span><span class="params">(root *TreeNode)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">    cache := <span class="built_in">make</span>(<span class="keyword">map</span>[*TreeNode][<span class="number">2</span>]<span class="type">int</span>)</span><br><span class="line">    <span class="keyword">var</span> dfs <span class="function"><span class="keyword">func</span><span class="params">(*TreeNode)</span></span> [<span class="number">2</span>]<span class="type">int</span></span><br><span class="line">    max := <span class="function"><span class="keyword">func</span><span class="params">(a, b <span class="type">int</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> a &gt; b &#123;</span><br><span class="line">            <span class="keyword">return</span> a</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> b</span><br><span class="line">    &#125;</span><br><span class="line">    dfs = <span class="function"><span class="keyword">func</span><span class="params">(root *TreeNode)</span></span> [<span class="number">2</span>]<span class="type">int</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> root == <span class="literal">nil</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> [<span class="number">2</span>]<span class="type">int</span>&#123;<span class="number">0</span>, <span class="number">0</span>&#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span> value, ok := cache[root]; ok &#123;</span><br><span class="line">            <span class="keyword">return</span> value</span><br><span class="line">        &#125;</span><br><span class="line">        rootValue := root.Val</span><br><span class="line">        leftValue := dfs(root.Left)</span><br><span class="line">        rightValue := dfs(root.Right)</span><br><span class="line">        childValue := max(leftValue[<span class="number">0</span>], leftValue[<span class="number">1</span>]) + max(rightValue[<span class="number">0</span>], rightValue[<span class="number">1</span>])</span><br><span class="line">        cache[root] = [<span class="number">2</span>]<span class="type">int</span>&#123;rootValue + leftValue[<span class="number">1</span>] + rightValue[<span class="number">1</span>], childValue&#125;</span><br><span class="line">        <span class="keyword">return</span> cache[root]</span><br><span class="line">    &#125;</span><br><span class="line">    value := dfs(root)</span><br><span class="line">    <span class="keyword">return</span> max(value[<span class="number">0</span>], value[<span class="number">1</span>])</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>]]></content>
    
    
      
      
    <summary type="html">&lt;h2 id=&quot;494-Target-Sum&quot;&gt;&lt;a href=&quot;#494-Target-Sum&quot; class=&quot;headerlink&quot; title=&quot;494. Target Sum&quot;&gt;&lt;/a&gt;&lt;a href=&quot;https://leetcode.com/problems/targ</summary>
      
    
    
    
    <category term="CS" scheme="http://blog.beendless.com/categories/CS/"/>
    
    
    <category term="Golang" scheme="http://blog.beendless.com/tags/Golang/"/>
    
    <category term="Algorithms" scheme="http://blog.beendless.com/tags/Algorithms/"/>
    
    <category term="Leetcode" scheme="http://blog.beendless.com/tags/Leetcode/"/>
    
    <category term="Dynamic Programming" scheme="http://blog.beendless.com/tags/Dynamic-Programming/"/>
    
    <category term="DFS" scheme="http://blog.beendless.com/tags/DFS/"/>
    
    <category term="Knapsack" scheme="http://blog.beendless.com/tags/Knapsack/"/>
    
  </entry>
  
  <entry>
    <title>Knapsack Problems I</title>
    <link href="http://blog.beendless.com/2021/10/07/Knapsack%20Problem%20I/"/>
    <id>http://blog.beendless.com/2021/10/07/Knapsack%20Problem%20I/</id>
    <published>2021-10-08T05:12:24.000Z</published>
    <updated>2023-03-08T05:05:31.146Z</updated>
    
    <content type="html"><![CDATA[<p>The knapsack problem is a problem in combinatorial optimization: Given a set of items, each with a weight and a value, determine the number of each item to include in a collection so that the total weight is less than or equal to a given limit and the total value is as large as possible.</p><h2 id="416-Partition-Equal-Subset-Sum"><a href="#416-Partition-Equal-Subset-Sum" class="headerlink" title="416. Partition Equal Subset Sum"></a><a href="https://leetcode.com/problems/partition-equal-subset-sum/">416. Partition Equal Subset Sum</a></h2><p>We can quickly get the result if the sum is an odd number. If the sum is an even number <code>s</code>, it means we need to find some items in the slice which can get a sum to <code>s / 2</code>. Now the problem becomes a classical 0-1 knapsack problem.</p><p>a. Classical 0-1 knapsack solution</p><p>Denote dp[i][j] as if we can construct a sum <code>j</code> from the first <code>i</code> items. So the state transition function is <code>dp[i][j] = dp[i - 1][j] || dp[i - 1][j - nums[i]]</code>.  The value is determined by:</p><ol><li>If we don’t use the current item, we need to check if we can construct the target <code>j</code> by the first <code>i - 1</code> items: <code>dp[i-1][j]</code></li><li>If we use the current item, we need to check if we can construct the target <code>j - nums[i]</code> by the first <code>i - 1</code> items: <code>dp[i - 1][j - nums[i]]</code></li></ol><figure class="highlight golang"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><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="function"><span class="keyword">func</span> <span class="title">canPartition</span><span class="params">(nums []<span class="type">int</span>)</span></span> <span class="type">bool</span> &#123;</span><br><span class="line">    sum := <span class="number">0</span></span><br><span class="line">    <span class="keyword">for</span> _, num := <span class="keyword">range</span> 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 % <span class="number">2</span> == <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">    target := sum / <span class="number">2</span></span><br><span class="line">    n := <span class="built_in">len</span>(nums)</span><br><span class="line">    dp := <span class="built_in">make</span>([][]<span class="type">bool</span>, n + <span class="number">1</span>)</span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">0</span>; i &lt;= n; i++ &#123;</span><br><span class="line">        dp[i] = <span class="built_in">make</span>([]<span class="type">bool</span>, target + <span class="number">1</span>)</span><br><span class="line">        dp[i][<span class="number">0</span>] = <span class="literal">true</span></span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">1</span>; i &lt;= n; i++ &#123;</span><br><span class="line">        <span class="keyword">for</span> j := <span class="number">1</span>; j &lt;= target; j++ &#123;</span><br><span class="line">            <span class="keyword">if</span> j &gt;= nums[i - <span class="number">1</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 - nums[i - <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><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][target]</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>b. Rolling array solution</p><p>Based on the state transition function above, we can simplifiy it by using a 1D array. <code>dp[i] = dp[i] || dp[i - nums[i]]</code>. Note since this time in the 1D array, the left part has side effect to the right side, so we need to iterate the array from right to left.</p><figure class="highlight golang"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><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="function"><span class="keyword">func</span> <span class="title">canPartition</span><span class="params">(nums []<span class="type">int</span>)</span></span> <span class="type">bool</span> &#123;</span><br><span class="line">    sum := <span class="number">0</span></span><br><span class="line">    <span class="keyword">for</span> _, num := <span class="keyword">range</span> 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 % <span class="number">2</span> == <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">    target := sum / <span class="number">2</span></span><br><span class="line">    n := <span class="built_in">len</span>(nums)</span><br><span class="line">    dp := <span class="built_in">make</span>([]<span class="type">bool</span>, target + <span class="number">1</span>)</span><br><span class="line">    dp[<span class="number">0</span>] = <span class="literal">true</span></span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">0</span>; i &lt; n; i++ &#123;</span><br><span class="line">        <span class="keyword">for</span> j := target; j &gt;= nums[i]; j-- &#123;</span><br><span class="line">            dp[j] = dp[j] || dp[j - nums[i]]</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> dp[target]</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>Note: the two solutions above are using <code>bool</code> value as dp array value type, we can also use <code>int</code> to store the sum we can get. So the state transition function will be <code>dp[j] = max(dp[j], dp[j - nums[i]] + nums[i])</code>. At the end, we just need to veryfy <code>dp[target] == target</code>.</p><h2 id="1049-Last-Stone-Weight-II"><a href="#1049-Last-Stone-Weight-II" class="headerlink" title="1049. Last Stone Weight II"></a><a href="https://leetcode.com/problems/last-stone-weight-ii/">1049. Last Stone Weight II</a></h2><p>a. Dynamic programming</p><p>To get the minimum result, we need to try our best to split the stones into two similar weight subsets. Let’s denote the <code>sum</code> as the total weight of all stones, so we need to find <code>target = sum/2</code> to get the minimum <code>sum - 2 * target</code></p><figure class="highlight golang"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><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="function"><span class="keyword">func</span> <span class="title">lastStoneWeightII</span><span class="params">(stones []<span class="type">int</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">    sum := <span class="number">0</span></span><br><span class="line">    <span class="keyword">for</span> _, stone := <span class="keyword">range</span> stones &#123;</span><br><span class="line">        sum += stone</span><br><span class="line">    &#125;</span><br><span class="line">    target := sum / <span class="number">2</span></span><br><span class="line">    n := <span class="built_in">len</span>(stones)</span><br><span class="line">    dp := <span class="built_in">make</span>([][]<span class="type">int</span>, n + <span class="number">1</span>)</span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">0</span>; i &lt;= n; i++ &#123;</span><br><span class="line">        dp[i] = <span class="built_in">make</span>([]<span class="type">int</span>, target + <span class="number">1</span>)</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">1</span>; i &lt;= n; i++ &#123;</span><br><span class="line">        <span class="keyword">for</span> j := <span class="number">0</span>; j &lt;= target; j++ &#123;</span><br><span class="line">            <span class="keyword">if</span> j &gt;= stones[i - <span class="number">1</span>] &amp;&amp; dp[i - <span class="number">1</span>][j] &lt; dp[i - <span class="number">1</span>][j - stones[i - <span class="number">1</span>]] + stones[i - <span class="number">1</span>] &#123;</span><br><span class="line">                dp[i][j] = dp[i - <span class="number">1</span>][j - stones[i - <span class="number">1</span>]] + stones[i - <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><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> sum - <span class="number">2</span> * dp[n][target]</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>We can use 1D rolling array</p><figure class="highlight golang"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><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="function"><span class="keyword">func</span> <span class="title">lastStoneWeightII</span><span class="params">(stones []<span class="type">int</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">    sum := <span class="number">0</span></span><br><span class="line">    <span class="keyword">for</span> _, stone := <span class="keyword">range</span> stones &#123;</span><br><span class="line">        sum += stone</span><br><span class="line">    &#125;</span><br><span class="line">    target := sum / <span class="number">2</span></span><br><span class="line">    n := <span class="built_in">len</span>(stones)</span><br><span class="line">    dp := <span class="built_in">make</span>([]<span class="type">int</span>, target + <span class="number">1</span>)</span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">0</span>; i &lt; n; i++ &#123;</span><br><span class="line">        <span class="keyword">for</span> j := target; j &gt;= stones[i]; j-- &#123;</span><br><span class="line">            <span class="keyword">if</span> dp[j] &lt; dp[j - stones[i]] + stones[i] &#123;</span><br><span class="line">                dp[j] = dp[j - stones[i]] + stones[i]</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> sum - <span class="number">2</span> * dp[target]</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>b. Brute-force Set </p><p>We can get all possible combinations of the sum and find the minimum absolute value.</p><figure class="highlight golang"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><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="function"><span class="keyword">func</span> <span class="title">lastStoneWeightII</span><span class="params">(stones []<span class="type">int</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">    sum := stones[<span class="number">0</span>]</span><br><span class="line">    hash := <span class="built_in">make</span>(<span class="keyword">map</span>[<span class="type">int</span>]<span class="type">bool</span>)</span><br><span class="line">    hash[stones[<span class="number">0</span>]] = <span class="literal">true</span></span><br><span class="line">    hash[-stones[<span class="number">0</span>]] = <span class="literal">true</span></span><br><span class="line">    n := <span class="built_in">len</span>(stones)</span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">1</span>; i &lt; n; i++ &#123;</span><br><span class="line">        sum += stones[i]</span><br><span class="line">        temp := <span class="built_in">make</span>(<span class="keyword">map</span>[<span class="type">int</span>]<span class="type">bool</span>)</span><br><span class="line">        <span class="keyword">for</span> key, _ := <span class="keyword">range</span> hash &#123;</span><br><span class="line">            temp[key + stones[i]] = <span class="literal">true</span></span><br><span class="line">            temp[key - stones[i]] = <span class="literal">true</span></span><br><span class="line">        &#125;</span><br><span class="line">        hash = temp</span><br><span class="line">    &#125;</span><br><span class="line">    result := sum + <span class="number">1</span></span><br><span class="line">    <span class="keyword">for</span> key, _ := <span class="keyword">range</span> hash &#123;</span><br><span class="line">        <span class="keyword">if</span> key &gt;= <span class="number">0</span> &amp;&amp; key &lt; result&#123;</span><br><span class="line">            result = key</span><br><span class="line">        &#125; <span class="keyword">else</span> <span class="keyword">if</span> key &lt; <span class="number">0</span> &amp;&amp; -key &lt; result &#123;</span><br><span class="line">            result = -key</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> result</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="474-Ones-and-Zeroes"><a href="#474-Ones-and-Zeroes" class="headerlink" title="474. Ones and Zeroes"></a><a href="https://leetcode.com/problems/ones-and-zeroes/">474. Ones and Zeroes</a></h2><p>Each items have two properties (1 amount and 0 amount) and we need to get the maximum sum of a subset based on the two dememsion restrictions (total 1 amount n and total 0 amount m). It can be considered as a classical two dememsion 0-1 knapsack problem. So the state transition function is <code>dp[i][j] = max(dp[i][j], dp[i - zeros][j - ones] + 1)</code> (Note, ideally we need 3D array to solve this problem, but based on the state transition function, we can reduce to a 2D rolling array with reverse for-loop).</p><figure class="highlight golang"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><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="function"><span class="keyword">func</span> <span class="title">findMaxForm</span><span class="params">(strs []<span class="type">string</span>, m <span class="type">int</span>, n <span class="type">int</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">    dp := <span class="built_in">make</span>([][]<span class="type">int</span>, m + <span class="number">1</span>)</span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">0</span>; i &lt;= m; i++ &#123;</span><br><span class="line">        dp[i] = <span class="built_in">make</span>([]<span class="type">int</span>, n + <span class="number">1</span>)</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">for</span> _, str := <span class="keyword">range</span> strs &#123;</span><br><span class="line">        ones := strings.Count(<span class="string">&quot;1&quot;</span>)</span><br><span class="line">        zeros := strings.Count(<span class="string">&quot;0&quot;</span>)</span><br><span class="line">        <span class="keyword">for</span> i := m; i &gt;= zeros; i-- &#123;</span><br><span class="line">            <span class="keyword">for</span> j := n; j &gt;= ones; j-- &#123;</span><br><span class="line">                pickme := dp[i - zeros][j - ones] + <span class="number">1</span></span><br><span class="line">                <span class="keyword">if</span> dp[i][j] &lt; pickme &#123;</span><br><span class="line">                    dp[i][j] = pickme</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][j]</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="322-Coin-Change"><a href="#322-Coin-Change" class="headerlink" title="322. Coin Change"></a><a href="https://leetcode.com/problems/coin-change/">322. Coin Change</a></h2><p>This is a classical full knapsack problem. The state transition function is <code>dp[i] = min(dp[i], dp[i - coins[i]] + 1)</code>. Since we need to get the minimal number, so the initial value needs to be an integer which is out of the scope (except dp[0] which is 0). We can either use <code>math.MaxInt32</code> or <code>amount + 1</code></p><p>a. Traverse knapsack volume first.</p><figure class="highlight golang"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><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="function"><span class="keyword">func</span> <span class="title">coinChange</span><span class="params">(coins []<span class="type">int</span>, amount <span class="type">int</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">    dp := <span class="built_in">make</span>([]<span class="type">int</span>, 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> i := <span class="number">0</span>; i &lt;= amount; i++ &#123;</span><br><span class="line">        dp[i] = math.MaxInt32</span><br><span class="line">    &#125;</span><br><span class="line">    min := <span class="function"><span class="keyword">func</span><span class="params">(a, b <span class="type">int</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> a &lt; b &#123;</span><br><span class="line">            <span class="keyword">return</span> a</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> b</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">1</span>; i &lt;= amount; i++ &#123;</span><br><span class="line">        <span class="keyword">for</span> j := <span class="number">0</span>; j &lt; <span class="built_in">len</span>(coins); j++ &#123;</span><br><span class="line">            <span class="keyword">if</span> i &gt;= coins[j] &amp;&amp; dp[i - coins[j]] != math.MaxInt32 &#123; <span class="comment">// If we pick one current coin and there&#x27;s some calculated solution to the state dp[i - coins[j]] which is not the initial value, then we have a valid solution</span></span><br><span class="line">                dp[i] = min(dp[i], dp[i - coins[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">if</span> dp[amount] == math.MaxInt32 &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="number">-1</span></span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> dp[amount]</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>b. Traverse items first.</p><figure class="highlight golang"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><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="function"><span class="keyword">func</span> <span class="title">coinChange</span><span class="params">(coins []<span class="type">int</span>, amount <span class="type">int</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">    dp := <span class="built_in">make</span>([]<span class="type">int</span>, 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> i := <span class="number">1</span>; i &lt;= amount; i++ &#123;</span><br><span class="line">        dp[i] = math.MaxInt32</span><br><span class="line">    &#125;</span><br><span class="line">    min := <span class="function"><span class="keyword">func</span><span class="params">(a, b <span class="type">int</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> a &lt; b &#123;</span><br><span class="line">            <span class="keyword">return</span> a</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> b</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">0</span>; i &lt; <span class="built_in">len</span>(coins); i++ &#123;</span><br><span class="line">        <span class="keyword">for</span> j := coins[i]; j &lt;= amount; j++ &#123;</span><br><span class="line">            <span class="keyword">if</span> dp[j - coins[i]] != math.MaxInt32 &#123;</span><br><span class="line">                dp[j] = min(dp[j], dp[j - 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">    <span class="keyword">if</span> dp[amount] == math.MaxInt32 &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="number">-1</span></span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> dp[amount]</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="518-Coin-Change-2"><a href="#518-Coin-Change-2" class="headerlink" title="518. Coin Change 2"></a><a href="https://leetcode.com/problems/coin-change-2/">518. Coin Change 2</a></h2><p>This is is also a full knapsack problem. The difference between this and the above is that we need to get the amount of combinations. So the state transition function is <code>dp[i] += dp[i - coins[j]]</code>. Since here each coin change solution is a combination problem instead of permutation problem, we can only iterate the coins first. If we iterate the knapsack space first, we will get the duplicated result like [[coins[0], coins[1]], [coins[1], coins[0]]]. </p><figure class="highlight golang"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><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="function"><span class="keyword">func</span> <span class="title">change</span><span class="params">(amount <span class="type">int</span>, coins []<span class="type">int</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">    dp := <span class="built_in">make</span>([]<span class="type">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> i := <span class="number">0</span>; i &lt; <span class="built_in">len</span>(coins); i++ &#123;</span><br><span class="line">        <span class="keyword">for</span> j := coins[i]; j &lt;= amount; j++ &#123;</span><br><span class="line">            dp[j] += dp[j - coins[i]]</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></pre></td></tr></table></figure><p>Based on the problems above, we can get a knapsack problem solution template</p><p><strong>0-1 knapsack template</strong></p><figure class="highlight golang"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><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">dp := <span class="built_in">make</span>([]<span class="type">int</span>, amount + <span class="number">1</span>)</span><br><span class="line">dp[<span class="number">0</span>] = <span class="comment">// Initial value based on the problem</span></span><br><span class="line"><span class="keyword">for</span> i := <span class="number">0</span>; i &lt;= <span class="built_in">len</span>(nums); i++ &#123;</span><br><span class="line">    <span class="keyword">for</span> j := amount; j &gt;= nums[i]; j-- &#123;</span><br><span class="line">        <span class="comment">// state transition function</span></span><br><span class="line">        <span class="comment">// dp[j] = dp[j] || dp[j - nums[i]]</span></span><br><span class="line">        <span class="comment">// dp[j] = max(dp[j], dp[j - nums[i]] + nums[i])</span></span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p><strong>full knapsack template to get the combination of items</strong></p><figure class="highlight golang"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><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">dp := <span class="built_in">make</span>([]<span class="type">int</span>, amount + <span class="number">1</span>)</span><br><span class="line">dp[<span class="number">0</span>] = <span class="comment">// Initial value based on the problem</span></span><br><span class="line"><span class="comment">// dp[i] = // Initial value based on the problem, could be 0 for total solutions counting or min/max value to get the maximum/minimum expectation</span></span><br><span class="line"><span class="keyword">for</span> i := <span class="number">0</span>; i &lt; <span class="built_in">len</span>(nums); i++ &#123;</span><br><span class="line">    <span class="keyword">for</span> j := nums[i]; j &lt;= amount; j++ &#123;</span><br><span class="line">        <span class="comment">// state transition function</span></span><br><span class="line">        <span class="comment">// dp[j] += dp[j - nums[i]]</span></span><br><span class="line">        <span class="comment">// dp[j] = min(dp[j], dp[j - nums[i]] + nums[i])</span></span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p><strong>full knapsack template to get the permutation of items</strong></p><figure class="highlight golang"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><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">dp := <span class="built_in">make</span>([]<span class="type">int</span>, amount + <span class="number">1</span>)</span><br><span class="line">dp[<span class="number">0</span>] = <span class="comment">// Initial value based on the problem</span></span><br><span class="line"><span class="comment">// dp[i] = // Initial value based on the problem, could be 0 for total solutions counting or min/max value to get the maximum/minimum expectation</span></span><br><span class="line"><span class="keyword">for</span> j := <span class="number">0</span>; j &lt;= amount; j++ &#123;</span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">0</span>; i &lt; <span class="built_in">len</span>(nums); i++ &#123;</span><br><span class="line">        <span class="comment">// state transition function</span></span><br><span class="line">        <span class="comment">// dp[j] += dp[j - nums[i]]</span></span><br><span class="line">        <span class="comment">// dp[j] = min(dp[j], dp[j - nums[i]] + nums[i])</span></span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>]]></content>
    
    
      
      
    <summary type="html">&lt;p&gt;The knapsack problem is a problem in combinatorial optimization: Given a set of items, each with a weight and a value, determine the numb</summary>
      
    
    
    
    <category term="CS" scheme="http://blog.beendless.com/categories/CS/"/>
    
    
    <category term="Golang" scheme="http://blog.beendless.com/tags/Golang/"/>
    
    <category term="Algorithms" scheme="http://blog.beendless.com/tags/Algorithms/"/>
    
    <category term="Leetcode" scheme="http://blog.beendless.com/tags/Leetcode/"/>
    
    <category term="Dynamic Programming" scheme="http://blog.beendless.com/tags/Dynamic-Programming/"/>
    
    <category term="Knapsack" scheme="http://blog.beendless.com/tags/Knapsack/"/>
    
  </entry>
  
  <entry>
    <title>Dynamic Programming I</title>
    <link href="http://blog.beendless.com/2021/10/06/Dynamic%20Programming%20I/"/>
    <id>http://blog.beendless.com/2021/10/06/Dynamic%20Programming%20I/</id>
    <published>2021-10-07T05:00:25.000Z</published>
    <updated>2023-03-08T05:05:31.141Z</updated>
    
    <content type="html"><![CDATA[<p>Dynamic Programming (commonly referred to as DP) is an algorithmic technique for solving a problem by recursively breaking it down into simpler subproblems and using the fact that the optimal solution to the overall problem depends upon the optimal solution to it’s individual subproblems. Here is an interesting Quora question <a href="https://www.quora.com/How-should-I-explain-dynamic-programming-to-a-4-year-old">How should I explain dynamic programming to a 4-year-old?</a>.</p><h2 id="509-Fibonacci-Number"><a href="#509-Fibonacci-Number" class="headerlink" title="509. Fibonacci Number"></a><a href="https://leetcode.com/problems/fibonacci-number/">509. Fibonacci Number</a></h2><p>a. Recursive solution</p><figure class="highlight golang"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">fib</span><span class="params">(n <span class="type">int</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">    <span class="keyword">if</span> n &lt; <span class="number">2</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> n</span><br><span class="line">    &#125;</span><br><span class="line">    fib0 := fib(n - <span class="number">2</span>)</span><br><span class="line">    fib1 := fib(n - <span class="number">1</span>)</span><br><span class="line">    <span class="keyword">return</span> fib0 + fib1</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>b. Dynamic Programming</p><p>State transition function: <code>dp[i] = dp[i - 1] + dp[i - 2]</code></p><figure class="highlight golang"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><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="function"><span class="keyword">func</span> <span class="title">fib</span><span class="params">(n <span class="type">int</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">    <span class="keyword">if</span> n &lt; <span class="number">2</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> n</span><br><span class="line">    &#125;</span><br><span class="line">    dp := <span class="built_in">make</span>([]<span class="type">int</span>, n + <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">    dp[<span class="number">1</span>] = <span class="number">1</span></span><br><span class="line">    <span class="keyword">for</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[n]</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="70-Climbing-Stairs"><a href="#70-Climbing-Stairs" class="headerlink" title="70. Climbing Stairs"></a><a href="https://leetcode.com/problems/climbing-stairs/">70. Climbing Stairs</a></h2><p>State transition function: <code>dp[i] = dp[i - 1] + dp[i - 2]</code></p><figure class="highlight golang"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><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="function"><span class="keyword">func</span> <span class="title">climbStairs</span><span class="params">(n <span class="type">int</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">    <span class="keyword">if</span> n &lt; <span class="number">3</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> n</span><br><span class="line">    &#125;</span><br><span class="line">    dp := <span class="built_in">make</span>([]<span class="type">int</span>, n + <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">    dp[<span class="number">1</span>] = <span class="number">1</span></span><br><span class="line">    dp[<span class="number">2</span>] = <span class="number">2</span></span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">3</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[n]</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>If given we can climb the stairs from 1 ~ m steps each time, how to solve this problem? It becomes a full knapsack problem now. And the state transition function is <code>dp[i] += dp[i - j]</code>, here 2 is the special case.</p><figure class="highlight golang"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><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="function"><span class="keyword">func</span> <span class="title">climbStairs</span><span class="params">(n <span class="type">int</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">    steps := []<span class="type">int</span>&#123;<span class="number">1</span>, <span class="number">2</span>&#125;</span><br><span class="line">    dp := <span class="built_in">make</span>([]<span class="type">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">for</span> i := <span class="number">1</span>; i &lt;= n; i++ &#123;</span><br><span class="line">        <span class="keyword">for</span> j := <span class="number">0</span>; j &lt; <span class="built_in">len</span>(steps); j++ &#123;</span><br><span class="line">            <span class="keyword">if</span> i &gt;= steps[j] &#123;</span><br><span class="line">                dp[i] += dp[i - steps[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]</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="746-Min-Cost-Climbing-Stairs"><a href="#746-Min-Cost-Climbing-Stairs" class="headerlink" title="746. Min Cost Climbing Stairs"></a><a href="https://leetcode.com/problems/min-cost-climbing-stairs/">746. Min Cost Climbing Stairs</a></h2><p>Denote dp[i] to the cost we want to step away from stair ith,  so the state transition function: <code>min(dp[i - 1], dp[i - 2]) + cost[i]</code>. </p><figure class="highlight golang"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="function"><span class="keyword">func</span> <span class="title">minCostClimbingStairs</span><span class="params">(cost []<span class="type">int</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">    n := <span class="built_in">len</span>(cost)</span><br><span class="line">    dp := <span class="built_in">make</span>([]<span class="type">int</span>, n)</span><br><span class="line">    min := <span class="function"><span class="keyword">func</span><span class="params">(a, b <span class="type">int</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> a &lt; b &#123;</span><br><span class="line">            <span class="keyword">return</span> a</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> b</span><br><span class="line">    &#125;</span><br><span class="line">    dp[<span class="number">0</span>] = cost[<span class="number">0</span>]</span><br><span class="line">    dp[<span class="number">1</span>] = cost[<span class="number">1</span>]</span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">2</span>; i &lt; n; i++ &#123;</span><br><span class="line">        dp[i] = min(dp[i - <span class="number">1</span>], dp[i - <span class="number">2</span>]) + cost[i]</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> min(dp[n - <span class="number">1</span>], dp[n - <span class="number">2</span>]) <span class="comment">// To reach to stair n, we can step away from n - 1 or n - 2</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>Another way to think about it. If we denote dp[i] as the cost to reach to ith stair, the state transition function is <code>dp[n] = min(dp[i - 1] + cost[i - 1], dp[i - 2] + cost[i - 2])</code></p><figure class="highlight golang"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><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="function"><span class="keyword">func</span> <span class="title">minCostClimbingStairs</span><span class="params">(cost []<span class="type">int</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">    n := <span class="built_in">len</span>(cost)</span><br><span class="line">    dp := <span class="built_in">make</span>([]<span class="type">int</span>, n + <span class="number">1</span>)</span><br><span class="line">    min := <span class="function"><span class="keyword">func</span><span class="params">(a, b <span class="type">int</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> a &lt; b &#123;</span><br><span class="line">            <span class="keyword">return</span> a</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> b</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">2</span>; i &lt;= n; i++ &#123;</span><br><span class="line">        dp[i] = min(dp[i - <span class="number">1</span>] + cost[i - <span class="number">1</span>], dp[i - <span class="number">2</span>] + cost[i - <span class="number">2</span>])</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><h2 id="62-Unique-Paths"><a href="#62-Unique-Paths" class="headerlink" title="62. Unique Paths"></a><a href="https://leetcode.com/problems/unique-paths/">62. Unique Paths</a></h2><p>It’s easy to get the state transition function <code>dp[i][j] = dp[i - 1][j] + dp[i][j - 1]</code> . Note for the special case first line and first row, the value is 1.</p><figure class="highlight golang"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="function"><span class="keyword">func</span> <span class="title">uniquePaths</span><span class="params">(m <span class="type">int</span>, n <span class="type">int</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">    dp := <span class="built_in">make</span>([][]<span class="type">int</span>, m)</span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">0</span>; i &lt; m; i++ &#123;</span><br><span class="line">        dp[i] = <span class="built_in">make</span>([]<span class="type">int</span>, n)</span><br><span class="line">        dp[i][<span class="number">0</span>] = <span class="number">1</span></span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">0</span>; i &lt; n; i++ &#123;</span><br><span class="line">        dp[<span class="number">0</span>][i] = <span class="number">1</span></span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">1</span>; i &lt; m; i++ &#123;</span><br><span class="line">        <span class="keyword">for</span> j := <span class="number">1</span>; j &lt; n; j++ &#123;</span><br><span class="line">            dp[i][j] = dp[i - <span class="number">1</span>][j] + dp[i][j - <span class="number">1</span>]</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> dp[m - <span class="number">1</span>][n - <span class="number">1</span>]</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>Based on the state transition function, dp[i][j] is defined only by two values, so we can optimize the space complexity from O(m * n) to O(n) by using a new state transition function <code>dp[j] = dp[j] + dp[j - 1]</code></p><figure class="highlight golang"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><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="function"><span class="keyword">func</span> <span class="title">uniquePaths</span><span class="params">(m <span class="type">int</span>, n <span class="type">int</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">    dp := <span class="built_in">make</span>([]<span class="type">int</span>, n)</span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">0</span>; i &lt; n; i++ &#123;</span><br><span class="line">        dp[i] = <span class="number">1</span></span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">1</span>; i &lt; m; i++ &#123;</span><br><span class="line">        <span class="keyword">for</span> j := <span class="number">1</span>; j &lt; n; j++ &#123;</span><br><span class="line">            dp[j] += 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="keyword">return</span> dp[n - <span class="number">1</span>]</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="63-Unique-Paths-II"><a href="#63-Unique-Paths-II" class="headerlink" title="63. Unique Paths II"></a><a href="https://leetcode.com/problems/unique-paths-ii/">63. Unique Paths II</a></h2><p>This is a similar problem to #62. The only difference is that we need to reset the path sum to 0 if there’s an obstacle at the coordinate.</p><figure class="highlight golang"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><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="function"><span class="keyword">func</span> <span class="title">uniquePathsWithObstacles</span><span class="params">(obstacleGrid [][]<span class="type">int</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">    m := <span class="built_in">len</span>(obstacleGrid)</span><br><span class="line">    n := <span class="built_in">len</span>(obstacleGrid[<span class="number">0</span>])</span><br><span class="line">    dp := <span class="built_in">make</span>([]<span class="type">int</span>, n)</span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">0</span>; i &lt; n; i++ &#123;</span><br><span class="line">        <span class="keyword">if</span> obstacleGrid[<span class="number">0</span>][i] = <span class="number">1</span> &#123;</span><br><span class="line">            dp[i] = <span class="number">0</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] = <span class="number">1</span></span><br><span class="line">        &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">            dp[i] = dp[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> i := <span class="number">1</span>; i &lt; m; i++ &#123;</span><br><span class="line">        <span class="keyword">for</span> j := <span class="number">0</span>; j &lt; n; j++ &#123;</span><br><span class="line">            <span class="keyword">if</span> obstacleGrid[i][j] == <span class="number">1</span>&#123;</span><br><span class="line">                dp[i] = <span class="number">0</span></span><br><span class="line">            &#125; <span class="keyword">else</span> <span class="keyword">if</span> j &gt; <span class="number">0</span> &#123;</span><br><span class="line">                dp[i] += dp[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">    <span class="keyword">return</span> dp[n - <span class="number">1</span>]</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="343-Integer-Break"><a href="#343-Integer-Break" class="headerlink" title="343. Integer Break"></a><a href="https://leetcode.com/problems/integer-break/">343. Integer Break</a></h2><p>The key point of solving this problem is to get the state transition function. There are two cases:</p><ol><li>we can split the number i into two i - j and j</li><li>we can split the number into more than two, this case we can reuse the cached value from dp array.  dp[i - j] * j</li></ol><p>So the state transition function <code>dp[i] = max(dp[i], dp[i - j] * j, (i - j) * j)</code></p><figure class="highlight golang"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><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="function"><span class="keyword">func</span> <span class="title">integerBreak</span><span class="params">(n <span class="type">int</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">    dp := <span class="built_in">make</span>([]<span class="type">int</span>, n + <span class="number">1</span>)</span><br><span class="line">    dp[<span class="number">1</span>] = <span class="number">1</span></span><br><span class="line">    dp[<span class="number">2</span>] = <span class="number">1</span></span><br><span class="line">    max := <span class="function"><span class="keyword">func</span><span class="params">(a, b <span class="type">int</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> a &gt; b &#123;</span><br><span class="line">            <span class="keyword">return</span> a</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> b</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">3</span>; i &lt;= n; i++ &#123;</span><br><span class="line">        <span class="keyword">for</span> j := <span class="number">1</span>; j &lt; i; j++ &#123;</span><br><span class="line">            two := j * (i - j)</span><br><span class="line">            twoMore := j * dp[i - j]</span><br><span class="line">            dp[i] = max(dp[i], max(two, twoMore))</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><h2 id="96-Unique-Binary-Search-Trees"><a href="#96-Unique-Binary-Search-Trees" class="headerlink" title="96. Unique Binary Search Trees"></a><a href="https://leetcode.com/problems/unique-binary-search-trees/">96. Unique Binary Search Trees</a></h2><p>Based on the BST specs, we can get the state transition function <code>dp[i] = dp[j] * dp[i - j - 1]</code>, here dp[i] denotes when i is set to the root node, we have j nodes on left child and i - j - 1 on right child. Note here the base case is 1. If there’s 0 nodes on left tree, it means we can construct the left tree in one uniq way.</p><figure class="highlight golang"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">numTrees</span><span class="params">(n <span class="type">int</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">    <span class="keyword">if</span> n &lt; <span class="number">3</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> n</span><br><span class="line">    &#125;</span><br><span class="line">    dp := <span class="built_in">make</span>([]<span class="type">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">    dp[<span class="number">1</span>] = <span class="number">1</span></span><br><span class="line">    dp[<span class="number">2</span>] = <span class="number">2</span></span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">3</span>; i &lt;= n; i++ &#123;</span><br><span class="line">        <span class="keyword">for</span> j := <span class="number">0</span>; j &lt; i; j++ &#123;</span><br><span class="line">            dp[i] += dp[j] &amp; dp[i - j - <span class="number">1</span>]</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> dp[n]</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>]]></content>
    
    
      
      
    <summary type="html">&lt;p&gt;Dynamic Programming (commonly referred to as DP) is an algorithmic technique for solving a problem by recursively breaking it down into s</summary>
      
    
    
    
    <category term="CS" scheme="http://blog.beendless.com/categories/CS/"/>
    
    
    <category term="Golang" scheme="http://blog.beendless.com/tags/Golang/"/>
    
    <category term="Algorithms" scheme="http://blog.beendless.com/tags/Algorithms/"/>
    
    <category term="Leetcode" scheme="http://blog.beendless.com/tags/Leetcode/"/>
    
    <category term="Dynamic Programming" scheme="http://blog.beendless.com/tags/Dynamic-Programming/"/>
    
    <category term="Knapsack" scheme="http://blog.beendless.com/tags/Knapsack/"/>
    
  </entry>
  
  <entry>
    <title>Greedy Problems - III</title>
    <link href="http://blog.beendless.com/2021/10/06/Greedy%20%20Problems%20III/"/>
    <id>http://blog.beendless.com/2021/10/06/Greedy%20%20Problems%20III/</id>
    <published>2021-10-07T04:55:24.000Z</published>
    <updated>2023-03-08T05:05:31.143Z</updated>
    
    <content type="html"><![CDATA[<h2 id="56-Merge-Intervals"><a href="#56-Merge-Intervals" class="headerlink" title="56. Merge Intervals"></a><a href="https://leetcode.com/problems/merge-intervals/">56. Merge Intervals</a></h2><p>Similar to other sgement related problems. The first thing we need to do is to sort the slice. Once we have a sorted segment slice, we can iterate over all items and merge them. Note there is one edge case we need to cover after the iteration, either we merged all segments into one or the last one can’t be merged into the previous segment. </p><figure class="highlight golang"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><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="function"><span class="keyword">func</span> <span class="title">merge</span><span class="params">(intervals [][]<span class="type">int</span>)</span></span> [][]<span class="type">int</span> &#123;</span><br><span class="line">    sort.Slice(intervals, <span class="function"><span class="keyword">func</span><span class="params">(a, b <span class="type">int</span>)</span></span> <span class="type">bool</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> intervals[a][<span class="number">0</span>] &lt; intervals[b][<span class="number">0</span>]</span><br><span class="line">    &#125;)</span><br><span class="line">    result := []<span class="type">int</span>&#123;&#125;</span><br><span class="line">    start := intervals[<span class="number">0</span>][<span class="number">0</span>]</span><br><span class="line">    end := intervals[<span class="number">0</span>][<span class="number">1</span>]</span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">0</span>; i &lt; <span class="built_in">len</span>(intervals); i++ &#123;</span><br><span class="line">        <span class="keyword">if</span> end &lt; intervals[i][<span class="number">0</span>] &#123;</span><br><span class="line">            result = <span class="built_in">append</span>(result, []<span class="type">int</span>&#123;start, end&#125;)</span><br><span class="line">            start = intervals[i][<span class="number">0</span>]</span><br><span class="line">            end = intervals[i][<span class="number">1</span>]</span><br><span class="line">        &#125; <span class="keyword">else</span> <span class="keyword">if</span> end &lt; intervals[i][<span class="number">1</span>] &#123;</span><br><span class="line">            end = intervals[i][<span class="number">1</span>]</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    result = <span class="built_in">append</span>(result, []<span class="type">int</span>&#123;start, end&#125;)</span><br><span class="line">    <span class="keyword">return</span> result</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="763-Partition-Labels"><a href="#763-Partition-Labels" class="headerlink" title="763. Partition Labels"></a><a href="https://leetcode.com/problems/partition-labels/">763. Partition Labels</a></h2><h2 id="738-Monotone-Increasing-Digits"><a href="#738-Monotone-Increasing-Digits" class="headerlink" title="738. Monotone Increasing Digits"></a><a href="https://leetcode.com/problems/monotone-increasing-digits/">738. Monotone Increasing Digits</a></h2><h2 id="968-Binary-Tree-Cameras"><a href="#968-Binary-Tree-Cameras" class="headerlink" title="968. Binary Tree Cameras"></a><a href="https://leetcode.com/problems/binary-tree-cameras/">968. Binary Tree Cameras</a></h2>]]></content>
    
    
      
      
    <summary type="html">&lt;h2 id=&quot;56-Merge-Intervals&quot;&gt;&lt;a href=&quot;#56-Merge-Intervals&quot; class=&quot;headerlink&quot; title=&quot;56. Merge Intervals&quot;&gt;&lt;/a&gt;&lt;a href=&quot;https://leetcode.com/p</summary>
      
    
    
    
    <category term="CS" scheme="http://blog.beendless.com/categories/CS/"/>
    
    
    <category term="Golang" scheme="http://blog.beendless.com/tags/Golang/"/>
    
    <category term="Algorithms" scheme="http://blog.beendless.com/tags/Algorithms/"/>
    
    <category term="Leetcode" scheme="http://blog.beendless.com/tags/Leetcode/"/>
    
    <category term="Greedy" scheme="http://blog.beendless.com/tags/Greedy/"/>
    
  </entry>
  
  <entry>
    <title>Greedy Problems - II</title>
    <link href="http://blog.beendless.com/2021/10/05/Greedy%20%20Problems%20II/"/>
    <id>http://blog.beendless.com/2021/10/05/Greedy%20%20Problems%20II/</id>
    <published>2021-10-05T17:25:24.000Z</published>
    <updated>2023-03-08T05:05:31.143Z</updated>
    
    <content type="html"><![CDATA[<h2 id="1005-Maximize-Sum-Of-Array-After-K-Negations"><a href="#1005-Maximize-Sum-Of-Array-After-K-Negations" class="headerlink" title="1005. Maximize Sum Of Array After K Negations"></a><a href="https://leetcode.com/problems/maximize-sum-of-array-after-k-negations/">1005. Maximize Sum Of Array After K Negations</a></h2><p>To get a maximum sum, we need to convert as many negative numbers to positive ones. If there is still an odd times of converting number left, we just need to convert the smallest positive number to a negative one</p><figure class="highlight golang"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><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="function"><span class="keyword">func</span> <span class="title">largestSumAfterKNegations</span><span class="params">(nums []<span class="type">int</span>, k <span class="type">int</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">    sort.Ints(nums)</span><br><span class="line">    i := <span class="number">0</span></span><br><span class="line">    <span class="keyword">for</span> i &lt; k &amp;&amp; i &lt; <span class="built_in">len</span>(nums) &#123;</span><br><span class="line">        <span class="keyword">if</span> nums[i] &lt; <span class="number">0</span> &#123;</span><br><span class="line">            nums[i] = -nums[i]</span><br><span class="line">            i++</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">    <span class="keyword">if</span> i &lt; k &amp;&amp; (k - i) % <span class="number">2</span> == <span class="number">1</span> &#123;</span><br><span class="line">        sort.Ints(nums)</span><br><span class="line">        nums[<span class="number">0</span>] = -nums[<span class="number">0</span>]</span><br><span class="line">    &#125;</span><br><span class="line">    result := <span class="number">0</span></span><br><span class="line">    <span class="keyword">for</span> _, num := <span class="keyword">range</span> 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></pre></td></tr></table></figure><h2 id="134-Gas-Station"><a href="#134-Gas-Station" class="headerlink" title="134. Gas Station"></a><a href="https://leetcode.com/problems/gas-station/">134. Gas Station</a></h2><p>Several cases:<br>    1) If the total amount of gas is less than the total amount of the cost, we can’t make a round trip<br>    2) Given an arbitrary start point i, and at i we have gas[i] in the tank. Let’s start at this point and accumulate the gas we left in the tank. If at point i + k the acculation is negative, it means we can’t reach from any point in beteeen [i, i + k - 1) to point k. So we can quickly start from i + k + 1 instead of i + 1.</p><p>So the local optimal solution for a given start point is from this starting point, we are making a round trip, the debet won’t be negative. If it’s negative, we need to start after the negative point. This can lead to a global optimal solution.</p><figure class="highlight golang"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><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="function"><span class="keyword">func</span> <span class="title">canCompleteCircuit</span><span class="params">(gas []<span class="type">int</span>, cost []<span class="type">int</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">    result := <span class="number">0</span></span><br><span class="line">    sum := <span class="number">0</span></span><br><span class="line">    debet := <span class="number">0</span></span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">0</span>; i &lt; <span class="built_in">len</span>(gas); i++ &#123;</span><br><span class="line">        sum += gas[i] - cost[i]</span><br><span class="line">        debet += gas[i] - cost[i]</span><br><span class="line">        <span class="keyword">if</span> debet &lt; <span class="number">0</span> &#123;</span><br><span class="line">            debet = <span class="number">0</span></span><br><span class="line">            result = 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">if</span> sum &lt; <span class="number">0</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="number">-1</span></span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> result</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="135-Candy"><a href="#135-Candy" class="headerlink" title="135. Candy"></a><a href="https://leetcode.com/problems/candy/">135. Candy</a></h2><p>Since the rating only have effect to neighbour candy distribution. We can start from one end to distribution the candy once, to make sure all children are happy when looking to their right. Then we make another round from the other end.</p><figure class="highlight golang"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><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="function"><span class="keyword">func</span> <span class="title">candy</span><span class="params">(ratings []<span class="type">int</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">    length := <span class="built_in">len</span>(ratings)</span><br><span class="line">    candies := <span class="built_in">make</span>([]<span class="type">int</span>, length)</span><br><span class="line">    candies[<span class="number">0</span>] = <span class="number">1</span></span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">1</span>; i &lt; 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">            candies[i] = candies[i - <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">            candies[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> i := 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; candies[i] &lt; candies[i + <span class="number">1</span>] + <span class="number">1</span> &#123;</span><br><span class="line">            candies[i] = candies[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">    result := <span class="number">0</span></span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">0</span>; i &lt; length; i++ &#123;</span><br><span class="line">        result += candies[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></pre></td></tr></table></figure><h2 id="860-Lemonade-Change"><a href="#860-Lemonade-Change" class="headerlink" title="860. Lemonade Change"></a><a href="https://leetcode.com/problems/lemonade-change/">860. Lemonade Change</a></h2><p>A greedy solution will be if we have <sup>10, we provide </sup>10 to customers who pay with $20.</p><figure class="highlight golang"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><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="function"><span class="keyword">func</span> <span class="title">lemonadeChange</span><span class="params">(bills []<span class="type">int</span>)</span></span> <span class="type">bool</span> &#123;</span><br><span class="line">    five := <span class="number">0</span></span><br><span class="line">    ten := <span class="number">0</span></span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">0</span>; i &lt; <span class="built_in">len</span>(bills); i++ &#123;</span><br><span class="line">        <span class="keyword">switch</span> bills[i] &#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">case</span> <span class="number">10</span>:</span><br><span class="line">            ten++</span><br><span class="line">            <span class="keyword">if</span> five &gt;= <span class="number">1</span> &#123;</span><br><span class="line">                five --</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> ten == <span class="number">0</span> &#123;</span><br><span class="line">                <span class="keyword">if</span> five &lt; <span class="number">3</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">                five -= <span class="number">3</span></span><br><span class="line">            &#125; <span class="keyword">else</span> <span class="keyword">if</span> ten &gt; <span class="number">0</span> &#123;</span><br><span class="line">                ten--</span><br><span class="line">                <span class="keyword">if</span> five == <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">                five--</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">true</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="406-Queue-Reconstruction-by-Height"><a href="#406-Queue-Reconstruction-by-Height" class="headerlink" title="406. Queue Reconstruction by Height"></a><a href="https://leetcode.com/problems/queue-reconstruction-by-height/">406. Queue Reconstruction by Height</a></h2><p>Since there are to demensions, and the demension k depends on h, the idea is we sort the given slice by h as the primary order, k as the secondary order. After that, we use the insert sorting algorithm to insert all slice items one by one based on the k value to a new slice.</p><figure class="highlight golang"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">reconstructQueue</span><span class="params">(people [][]<span class="type">int</span>)</span></span> [][]<span class="type">int</span> &#123;</span><br><span class="line">    result := [][]<span class="type">int</span>&#123;&#125;</span><br><span class="line">    sort.Slice(people, <span class="function"><span class="keyword">func</span><span class="params">(a, b <span class="type">int</span>)</span></span> <span class="type">bool</span> &#123; <span class="comment">// order by h desc, order by k asc</span></span><br><span class="line">        <span class="keyword">if</span> people[a][<span class="number">0</span>] == people[b][<span class="number">0</span>] &#123;</span><br><span class="line">            <span class="keyword">return</span> people[a][<span class="number">1</span>] &lt; people[b][<span class="number">1</span>]</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> people[a][<span class="number">0</span>] &gt; people[b][<span class="number">0</span>]</span><br><span class="line">    &#125;)</span><br><span class="line">    <span class="keyword">for</span> _, p := <span class="keyword">range</span> people &#123;</span><br><span class="line">        result = <span class="built_in">append</span>(result, p)</span><br><span class="line">        <span class="built_in">copy</span>(result[p[<span class="number">1</span>] + <span class="number">1</span>:], result[p[<span class="number">1</span>]:])</span><br><span class="line">        result[p[<span class="number">1</span>]] = p</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> result</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="452-Minimum-Number-of-Arrows-to-Burst-Balloons"><a href="#452-Minimum-Number-of-Arrows-to-Burst-Balloons" class="headerlink" title="452. Minimum Number of Arrows to Burst Balloons"></a><a href="https://leetcode.com/problems/minimum-number-of-arrows-to-burst-balloons/">452. Minimum Number of Arrows to Burst Balloons</a></h2><p>A greedy solution is we choose the shoot point which is the most line segments overlaped as a local optimal, it also leads to a global optimal solution. For example, we have four segments as below. If we sort them by the start point, we can easily get a first point should be between e ~ b. It means we iterate all segments, if the current segment’s start point is no great than the previous one’s end point, we can merge those two by reseting the current one’s end point to the minimum number between itself and the previous one’s end point.</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">|--------------|</span><br><span class="line">a              b</span><br><span class="line">    |-----------------|</span><br><span class="line">    c                 d</span><br><span class="line">       |---------|</span><br><span class="line">       e         f</span><br><span class="line">                   |---------|</span><br><span class="line">                   g         h</span><br></pre></td></tr></table></figure><figure class="highlight golang"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">findMinArrowShots</span><span class="params">(points [][]<span class="type">int</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">    sort.Slice(points, <span class="function"><span class="keyword">func</span><span class="params">(a, b <span class="type">int</span>)</span></span> <span class="type">bool</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> points[a][<span class="number">0</span>] &lt; points[b][<span class="number">0</span>]</span><br><span class="line">    &#125;)</span><br><span class="line">    result := <span class="number">1</span></span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">1</span>; i &lt; <span class="built_in">len</span>(points); i++ &#123;</span><br><span class="line">        <span class="keyword">if</span> points[i][<span class="number">0</span>] &gt; points[i - <span class="number">1</span>][<span class="number">1</span>] &#123;</span><br><span class="line">            result++</span><br><span class="line">        &#125; <span class="keyword">else</span> <span class="keyword">if</span> points[i][<span class="number">1</span>] &gt; points[i - <span class="number">1</span>][<span class="number">1</span>] &#123;</span><br><span class="line">            points[i][<span class="number">1</span>] = points[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">return</span> result</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="435-Non-overlapping-Intervals"><a href="#435-Non-overlapping-Intervals" class="headerlink" title="435. Non-overlapping Intervals"></a><a href="https://leetcode.com/problems/non-overlapping-intervals/">435. Non-overlapping Intervals</a></h2><p>This one is a similar problem as #452. An intuition to solve this kind of problem is sort if first. Since all line segments have two points, we have two choices to sort it. The local optimal to find the interval is the end of current segment should have a distance between the next one’s start point. With this in mind, we can quickly get the total of intervals. So if we sort by the end point, we can iterate from left to right. Otherwise, we need to reverse the iteration order.</p><figure class="highlight golang"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><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="function"><span class="keyword">func</span> <span class="title">eraseOverlapIntervals</span><span class="params">(intervals [][]<span class="type">int</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">    sort.Slice(intervals, <span class="function"><span class="keyword">func</span><span class="params">(a, b <span class="type">int</span>)</span></span> <span class="type">bool</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> intervals[a][<span class="number">1</span>] &lt; intervals[b][<span class="number">1</span>]</span><br><span class="line">    &#125;)</span><br><span class="line">    end := intervals[<span class="number">0</span>][<span class="number">1</span>]</span><br><span class="line">    count := <span class="number">1</span></span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">1</span>; i &lt; <span class="built_in">len</span>(intervals); i++ &#123;</span><br><span class="line">        <span class="keyword">if</span> end &lt;= intervals[i][<span class="number">0</span>] &#123;</span><br><span class="line">            count++</span><br><span class="line">            end = intervals[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> <span class="built_in">len</span>(intervals) - count</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>]]></content>
    
    
      
      
    <summary type="html">&lt;h2 id=&quot;1005-Maximize-Sum-Of-Array-After-K-Negations&quot;&gt;&lt;a href=&quot;#1005-Maximize-Sum-Of-Array-After-K-Negations&quot; class=&quot;headerlink&quot; title=&quot;1005</summary>
      
    
    
    
    <category term="CS" scheme="http://blog.beendless.com/categories/CS/"/>
    
    
    <category term="Golang" scheme="http://blog.beendless.com/tags/Golang/"/>
    
    <category term="Algorithms" scheme="http://blog.beendless.com/tags/Algorithms/"/>
    
    <category term="Leetcode" scheme="http://blog.beendless.com/tags/Leetcode/"/>
    
    <category term="Greedy" scheme="http://blog.beendless.com/tags/Greedy/"/>
    
  </entry>
  
  <entry>
    <title>JumpGame  Problems</title>
    <link href="http://blog.beendless.com/2021/10/03/JumpGame%20%20Problems/"/>
    <id>http://blog.beendless.com/2021/10/03/JumpGame%20%20Problems/</id>
    <published>2021-10-04T05:05:24.000Z</published>
    <updated>2023-03-08T05:05:31.145Z</updated>
    
    <content type="html"><![CDATA[<h2 id="55-Jump-Game"><a href="#55-Jump-Game" class="headerlink" title="55. Jump Game"></a><a href="https://leetcode.com/problems/jump-game/">55. Jump Game</a></h2><p>a. Greedy solutions</p><p>At each step, a greedy jump can give us the local optimal furthest solution. Our global solution can be found in if we always take the greedy jump.</p><figure class="highlight golang"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><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="function"><span class="keyword">func</span> <span class="title">canJump</span><span class="params">(nums []<span class="type">int</span>)</span></span> <span class="type">bool</span> &#123;</span><br><span class="line">    distance := <span class="number">0</span></span><br><span class="line">    length := <span class="built_in">len</span>(nums)</span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">0</span>; i &lt;= distance; i++ &#123; <span class="comment">// Note: here we use distance to control which items we can check</span></span><br><span class="line">        <span class="keyword">if</span> distance &lt; i + nums[i] &#123;</span><br><span class="line">            distance = i + nums[i]</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span> distance &gt;= length - <span class="number">1</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> <span class="literal">true</span></span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="literal">false</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>b. Dynamic programming</p><figure class="highlight golang"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><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="function"><span class="keyword">func</span> <span class="title">canJump</span><span class="params">(nums []<span class="type">int</span>)</span></span> <span class="type">bool</span> &#123;</span><br><span class="line">    length := <span class="built_in">len</span>(nums)</span><br><span class="line">    dp := <span class="built_in">make</span>([]<span class="type">int</span>, length)</span><br><span class="line">    dp[<span class="number">0</span>] = <span class="literal">true</span></span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">0</span>; i &lt; length; i++ &#123;</span><br><span class="line">        <span class="keyword">if</span> dp[i] &#123;</span><br><span class="line">            <span class="keyword">for</span> j := <span class="number">1</span>; j &lt;= nums[i] &amp;&amp; i + j &lt; length; j++ &#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">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> dp[length - <span class="number">1</span>]</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="45-Jump-Game-II"><a href="#45-Jump-Game-II" class="headerlink" title="45. Jump Game II"></a><a href="https://leetcode.com/problems/jump-game-ii/">45. Jump Game II</a></h2><p>a. Greedy solution</p><p>Each time, we will jump to a position which can make us future jumping even further. And each jump will resolve to a coverage range as below, so the total jump steps will be the sum of times we reach to the edge of the coverge range.</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">| 2 | 3 | 1 | 1 | 4 | 5 | 1 | 2 |</span><br><span class="line"></span><br><span class="line">|----------&gt;|</span><br><span class="line">    |--------------&gt;|</span><br><span class="line"></span><br><span class="line">                |--------------&gt;|</span><br></pre></td></tr></table></figure><figure class="highlight golang"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="function"><span class="keyword">func</span> <span class="title">jump</span><span class="params">(nums []<span class="type">int</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">    result := <span class="number">0</span></span><br><span class="line">    length := <span class="built_in">len</span>(nums)</span><br><span class="line">    end := <span class="number">0</span></span><br><span class="line">    max := <span class="number">0</span></span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">0</span>; i &lt; length - <span class="number">1</span>; i++&#123;</span><br><span class="line">        <span class="keyword">if</span> max &lt; nums[i] + i &#123;  <span class="comment">// Get the next coverage edge</span></span><br><span class="line">            max = nums[i] + i</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span> i == end &#123;           <span class="comment">// Switch to the next range with a jump</span></span><br><span class="line">            end = max</span><br><span class="line">            result++</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> result</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>b. Dynamic programming</p><figure class="highlight golang"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><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="function"><span class="keyword">func</span> <span class="title">jump</span><span class="params">(nums []<span class="type">int</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">    dp := <span class="built_in">make</span>([]<span class="type">int</span>, <span class="built_in">len</span>(nums))</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> i := <span class="number">1</span>; i &lt; <span class="built_in">len</span>(nums); i++ &#123;</span><br><span class="line">        dp[i] = <span class="number">-1</span></span><br><span class="line">    &#125; </span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">0</span>; i &lt; <span class="built_in">len</span>(nums); i ++ &#123;</span><br><span class="line">        <span class="keyword">for</span> j := <span class="number">1</span>; j &lt;= nums[i] &amp;&amp; i + j &lt; <span class="built_in">len</span>(nums); j++ &#123;</span><br><span class="line">            <span class="keyword">if</span> dp[i + j] == <span class="number">-1</span> &#123;</span><br><span class="line">                dp[i + j] = dp[i] + <span class="number">1</span>   </span><br><span class="line">            &#125; <span class="keyword">else</span> <span class="keyword">if</span> dp[i + j] &gt; dp[i] + <span class="number">1</span> &#123;</span><br><span class="line">                dp[i + j] = dp[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">    <span class="keyword">return</span> dp[<span class="built_in">len</span>(nums) - <span class="number">1</span>]</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="1306-Jump-Game-III"><a href="#1306-Jump-Game-III" class="headerlink" title="1306. Jump Game III"></a><a href="https://leetcode.com/problems/jump-game-iii/">1306. Jump Game III</a></h2><p>The keypoint here is during the traversal of the recursive, we don’t get lost in a infinite loop. So we need to remember all of the visted nodes in a hash.</p><p>a. Recursive solution</p><figure class="highlight golang"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><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="function"><span class="keyword">func</span> <span class="title">canReach</span><span class="params">(arr []<span class="type">int</span>, start <span class="type">int</span>)</span></span> <span class="type">bool</span> &#123;</span><br><span class="line">    result := <span class="literal">false</span></span><br><span class="line">    reachedNodes := <span class="built_in">make</span>(<span class="keyword">map</span>[<span class="type">int</span>]<span class="type">bool</span>)</span><br><span class="line">    <span class="keyword">var</span> jump <span class="function"><span class="keyword">func</span><span class="params">(<span class="type">int</span>)</span></span></span><br><span class="line">    jump = <span class="function"><span class="keyword">func</span><span class="params">(index <span class="type">int</span>)</span></span> &#123;</span><br><span class="line">        <span class="keyword">if</span> arr[index] == <span class="number">0</span> &#123;</span><br><span class="line">            result = <span class="literal">true</span></span><br><span class="line">            <span class="keyword">return</span></span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span> reachedNodes[index] &#123;</span><br><span class="line">            <span class="keyword">return</span></span><br><span class="line">        &#125;</span><br><span class="line">        reachedNodes[index] = <span class="literal">true</span></span><br><span class="line">        <span class="keyword">if</span> index - arr[index] &gt;= <span class="number">0</span> &#123;</span><br><span class="line">            jump(index - arr[index])</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span> index + arr[index] &lt; <span class="built_in">len</span>(arr) &#123;</span><br><span class="line">            jump(index + arr[index])</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    jump(start)</span><br><span class="line">    <span class="keyword">return</span> result</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>b. Queue traversal solution.</p><figure class="highlight golang"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><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="function"><span class="keyword">func</span> <span class="title">canReach</span><span class="params">(arr []<span class="type">int</span>, start <span class="type">int</span>)</span></span> <span class="type">bool</span> &#123;</span><br><span class="line">    reachedNodes := <span class="built_in">make</span>(<span class="keyword">map</span>[<span class="type">int</span>]<span class="type">bool</span>)</span><br><span class="line">    queue := []<span class="type">int</span>&#123;start&#125;</span><br><span class="line">    length := <span class="built_in">len</span>(arr)</span><br><span class="line">    <span class="keyword">for</span> <span class="built_in">len</span>(queue) &gt; <span class="number">0</span> &#123;</span><br><span class="line">        index := queue[<span class="number">0</span>]</span><br><span class="line">        <span class="keyword">if</span> arr[index] == <span class="number">0</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">        reachedNodes[index] = <span class="literal">true</span></span><br><span class="line">        queue = queue[<span class="number">1</span>:]</span><br><span class="line">        <span class="keyword">if</span> index + arr[index] &lt; length &amp;&amp; !reachedNodes[index + arr[index]] &#123;</span><br><span class="line">            queue = <span class="built_in">append</span>(queue, index + arr[index])</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span> index - arr[index] &lt; length &amp;&amp; !reachedNodes[index - arr[index]] &#123;</span><br><span class="line">            queue = <span class="built_in">append</span>(queue, index - arr[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="literal">false</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="1345-Jump-Game-IV"><a href="#1345-Jump-Game-IV" class="headerlink" title="1345. Jump Game IV"></a><a href="https://leetcode.com/problems/jump-game-iv/">1345. Jump Game IV</a></h2><p>This is a classical tree traversal with BFS problem. From each array index we can jump to multiple elements simoteniously, those nextstep elements can be consiered as the tree node’s child nodes. So we jump to all nodes’s children nodes at once which can be considered as one jump (BFS). Since the same value of the nodes can jump to each other, we have to mark the nodes values which have been pushed to the queue to make sure we don’t push the same nodes back to the queue (even we have a visited flag, we can easily run out of memory without another same number flag under this edge case if we have 1000 same value nodes in the slice). </p><figure class="highlight golang"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">minJumps</span><span class="params">(arr []<span class="type">int</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">    length := <span class="built_in">len</span>(arr)</span><br><span class="line">    <span class="keyword">if</span> length &lt; <span class="number">3</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> length - <span class="number">1</span></span><br><span class="line">    &#125;</span><br><span class="line">    jumpIndexes := <span class="built_in">make</span>(<span class="keyword">map</span>[<span class="type">int</span>][]<span class="type">int</span>)</span><br><span class="line">    <span class="keyword">for</span> i, v := <span class="keyword">range</span> arr &#123;</span><br><span class="line">        jumpIndexes[v] = <span class="built_in">append</span>(jumpIndexes[v], i)</span><br><span class="line">    &#125;</span><br><span class="line">    queue := <span class="built_in">make</span>([]<span class="type">int</span>, <span class="number">1</span>)</span><br><span class="line">    queue[<span class="number">0</span>] = <span class="number">0</span></span><br><span class="line">    result := <span class="number">0</span></span><br><span class="line">    visited := <span class="built_in">make</span>([]<span class="type">bool</span>, length)</span><br><span class="line">    sameNumberVisited := <span class="built_in">make</span>(<span class="keyword">map</span>[<span class="type">int</span>]<span class="type">bool</span>) <span class="comment">// Have a flag is one thing, another solution is to remove the sameNumber key from the jumpIndexes hashmap.</span></span><br><span class="line">    n := <span class="built_in">len</span>(queue)</span><br><span class="line">    <span class="keyword">for</span> n &gt; <span class="number">0</span> &#123;</span><br><span class="line">        <span class="keyword">for</span> i := <span class="number">0</span>; i &lt; n; i++ &#123;</span><br><span class="line">            index := queue[i]</span><br><span class="line">            <span class="keyword">if</span> index == length - <span class="number">1</span> &#123;</span><br><span class="line">                <span class="keyword">return</span> result</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">if</span> !visited[index] &#123;</span><br><span class="line">                visited[index] = <span class="literal">true</span></span><br><span class="line">                <span class="keyword">if</span> index - <span class="number">1</span> &gt;= <span class="number">0</span> &amp;&amp; !visited[index - <span class="number">1</span>]&#123;</span><br><span class="line">                    queue = <span class="built_in">append</span>(queue, index - <span class="number">1</span>)</span><br><span class="line">                &#125;</span><br><span class="line">                <span class="keyword">if</span> index + <span class="number">1</span> &lt; length &amp;&amp; !visited[index + <span class="number">1</span>] &#123;</span><br><span class="line">                    queue = <span class="built_in">append</span>(queue, index + <span class="number">1</span>)</span><br><span class="line">                &#125;</span><br><span class="line">                <span class="keyword">if</span> !sameNumberVisited[arr[index]] &#123;</span><br><span class="line">                    sameNumberVisited[arr[index]] = <span class="literal">true</span></span><br><span class="line">                    <span class="keyword">for</span> _, v := <span class="keyword">range</span> jumpIndexes[arr[index]] &#123;</span><br><span class="line">                        <span class="keyword">if</span> !visited[v] &#123;</span><br><span class="line">                            queue = <span class="built_in">append</span>(queue, v)</span><br><span class="line">                        &#125;</span><br><span class="line">                    &#125;</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        queue = queue[n:]</span><br><span class="line">        n = <span class="built_in">len</span>(queue)</span><br><span class="line">        result++</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> result</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="1340-Jump-Game-V"><a href="#1340-Jump-Game-V" class="headerlink" title="1340. Jump Game V"></a><a href="https://leetcode.com/problems/jump-game-v/">1340. Jump Game V</a></h2><p>To resolve this problem, we need to understand <code> you can only jump from index i to index j if arr[i] &gt; arr[j] and arr[i] &gt; arr[k] for all indices k between i and j (More formally min(i, j) &lt; k &lt; max(i, j)).</code>. Let’s say we stand at index i, and jumping from i - 1, i + 1 until i - d, i + d inside of for loops. We need to break the loop if we find a k between [i-d, i) or (i, i + d] which makes arr[k] &gt;&#x3D; arr[i].</p><figure class="highlight golang"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><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="function"><span class="keyword">func</span> <span class="title">maxJumps</span><span class="params">(arr []<span class="type">int</span>, d <span class="type">int</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">    result := <span class="number">0</span></span><br><span class="line">    length := <span class="built_in">len</span>(arr)</span><br><span class="line">    dp := <span class="built_in">make</span>([]<span class="type">int</span>, length)</span><br><span class="line">    max := <span class="function"><span class="keyword">func</span><span class="params">(a, b <span class="type">int</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> a &gt; b &#123;</span><br><span class="line">            <span class="keyword">return</span> a</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> b</span><br><span class="line">    &#125;</span><br><span class="line">    min := <span class="function"><span class="keyword">func</span><span class="params">(a, b <span class="type">int</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> a &gt; b &#123;</span><br><span class="line">            <span class="keyword">return</span> b</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> a</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">var</span> jump <span class="function"><span class="keyword">func</span><span class="params">(<span class="type">int</span>)</span></span> <span class="type">int</span></span><br><span class="line">    jump = <span class="function"><span class="keyword">func</span><span class="params">(index <span class="type">int</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> dp[index] == <span class="number">0</span> &#123;</span><br><span class="line">            dp[index] = <span class="number">1</span></span><br><span class="line">            <span class="keyword">for</span> i := index - <span class="number">1</span>; i &gt;= max(<span class="number">0</span>, index - d) &amp;&amp; arr[i] &lt; arr[index]; i-- &#123;</span><br><span class="line">                dp[index] = max(dp[index], jump(i) + <span class="number">1</span>)</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">for</span> i := index + <span class="number">1</span>; i &lt;= min(length - <span class="number">1</span>, index + d) &amp;&amp; arr[i] &lt; arr[index]; i++ &#123;</span><br><span class="line">                dp[index] = max(dp[index], jump(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> dp[index]</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">0</span>; i &lt; length; i++ &#123;</span><br><span class="line">        dp[i] = jump(i)</span><br><span class="line">        result = max(dp[i], result)</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> result</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="1696-Jump-Game-VI"><a href="#1696-Jump-Game-VI" class="headerlink" title="1696. Jump Game VI"></a><a href="https://leetcode.com/problems/jump-game-vi/">1696. Jump Game VI</a></h2><p>A naive idea is to iterate over all nodes, so the worse time complexity could be O(n * k) [K &#x3D; maxJump - minJump] which most likely will cause a TLE issue. This one can be considered as a classic <a href="/tags/Sliding-Window/">sliding window</a> maximum problem. Since dp[i] &#x3D; nums[i] + max(dp[i - k], … , dp[i - 1]). We just need to maintain the maximum dp value in the sliding window during the iteration.</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">01010101010101011111</span><br><span class="line"></span><br><span class="line">|---------(i)------|</span><br><span class="line">    |-----&gt;|</span><br><span class="line">    i-k    i-1</span><br><span class="line">|----------(i + 1)------|</span><br><span class="line">     |-----&gt;|</span><br><span class="line">     i-k+1  i</span><br></pre></td></tr></table></figure><figure class="highlight golang"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><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="function"><span class="keyword">func</span> <span class="title">maxResult</span><span class="params">(nums []<span class="type">int</span>, k <span class="type">int</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">    length := <span class="built_in">len</span>(nums)</span><br><span class="line">    queue := []<span class="type">int</span>&#123;<span class="number">0</span>&#125;      <span class="comment">// stores the dp indexes of the sliding window items</span></span><br><span class="line">    dp := <span class="built_in">make</span>([]<span class="type">int</span>, length)</span><br><span class="line">    dp[<span class="number">0</span>] = nums[<span class="number">0</span>]</span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">1</span>; i &lt; length; i++ &#123;</span><br><span class="line">        maxSumIndex := queue[<span class="number">0</span>]</span><br><span class="line">        dp[i] = nums[i] + dp[maxSumIndex]</span><br><span class="line">        <span class="keyword">for</span> <span class="built_in">len</span>(queue) &gt; <span class="number">0</span> &amp;&amp; dp[queue[<span class="built_in">len</span>(queue) - <span class="number">1</span>]] &lt;= dp[i] &#123; <span class="comment">// sliding window queue contains all values in a desending order</span></span><br><span class="line">            queue = queue[:<span class="built_in">len</span>(queue) - <span class="number">1</span>]</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">for</span> <span class="built_in">len</span>(queue) &gt; <span class="number">0</span> &amp;&amp; i - queue[<span class="number">0</span>] &gt;= k &#123;  <span class="comment">// remove the index which is going to out of the window</span></span><br><span class="line">            queue = queue[<span class="number">1</span>:]</span><br><span class="line">        &#125;</span><br><span class="line">        queue = <span class="built_in">append</span>(queue, dp[i])</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> dp[length - <span class="number">1</span>]</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="1871-Jump-Game-VII"><a href="#1871-Jump-Game-VII" class="headerlink" title="1871. Jump Game VII"></a><a href="https://leetcode.com/problems/jump-game-vii/">1871. Jump Game VII</a></h2><p>Same as the above one, a naive dp will get a TLE. A keypoint to solve this problem is we need to avoid the duplicated node visiting. One way is we can use a hashmap to note all visited elements. Another method is that we can bypass the overlap like below:</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">01010101010101011111</span><br><span class="line">  |---------&gt;|</span><br><span class="line">  1          2</span><br><span class="line">    |---------&gt;|</span><br><span class="line">    3          4</span><br></pre></td></tr></table></figure><p>The first jump range is 1 ~ 2, the second is 3 ~ 4, here the range 3 ~ 2 doesn’t need to be visited again. With this in mind, we can use tree-like traversal solution with queue or two pointers sliding window to fix this issue.</p><p>a. Queue with traversal solution</p><figure class="highlight golang"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><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="function"><span class="keyword">func</span> <span class="title">canReach</span><span class="params">(s <span class="type">string</span>, minJump <span class="type">int</span>, maxJump <span class="type">int</span>)</span></span> <span class="type">bool</span> &#123;</span><br><span class="line">    queue := []<span class="type">int</span>&#123;<span class="number">0</span>&#125;</span><br><span class="line">    length := <span class="built_in">len</span>(s)</span><br><span class="line">    visited := <span class="built_in">make</span>(<span class="keyword">map</span>[<span class="type">int</span>]<span class="type">bool</span>)</span><br><span class="line">    visited[<span class="number">0</span>] = <span class="literal">true</span></span><br><span class="line">    edge := <span class="number">0</span></span><br><span class="line">    min := <span class="function"><span class="keyword">func</span><span class="params">(a, b <span class="type">int</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> a &gt; b &#123;</span><br><span class="line">            <span class="keyword">return</span> b</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> a</span><br><span class="line">    &#125;</span><br><span class="line">    max := <span class="function"><span class="keyword">func</span><span class="params">(a, b <span class="type">int</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> a &gt; b &#123;</span><br><span class="line">            <span class="keyword">return</span> a</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> b</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">for</span> <span class="built_in">len</span>(queue) &gt; <span class="number">0</span> &#123;</span><br><span class="line">        index := queue[<span class="number">0</span>]</span><br><span class="line">        <span class="keyword">if</span> index == length - <span class="number">1</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> <span class="literal">true</span></span><br><span class="line">        &#125;</span><br><span class="line">        queue = queue[<span class="number">1</span>:]</span><br><span class="line">        left := index + minJump</span><br><span class="line">        right := min(length - <span class="number">1</span>, index + maxJump)</span><br><span class="line">        <span class="keyword">for</span> i := max(edge + <span class="number">1</span>, left); i &lt;= right; i++ &#123;</span><br><span class="line">            <span class="keyword">if</span> s[i] == <span class="string">&#x27;0&#x27;</span> &amp;&amp; !visited[i]&#123;</span><br><span class="line">                visited[i] = <span class="literal">true</span></span><br><span class="line">                queue = <span class="built_in">append</span>(queue, i)</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        edge = right</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="literal">false</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>b. Two pointers</p><figure class="highlight golang"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><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="function"><span class="keyword">func</span> <span class="title">canReach</span><span class="params">(s <span class="type">string</span>, minJump <span class="type">int</span>, maxJump <span class="type">int</span>)</span></span> <span class="type">bool</span> &#123;</span><br><span class="line">    length := <span class="built_in">len</span>(s)</span><br><span class="line">    <span class="keyword">if</span> s[length - <span class="number">1</span>] == <span class="string">&#x27;0&#x27;</span> &#123;</span><br><span class="line">        min := <span class="function"><span class="keyword">func</span><span class="params">(a, b <span class="type">int</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">            <span class="keyword">if</span> a &gt; b &#123;</span><br><span class="line">                <span class="keyword">return</span> b</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">return</span> a</span><br><span class="line">        &#125;</span><br><span class="line">        max := <span class="function"><span class="keyword">func</span><span class="params">(a, b <span class="type">int</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">            <span class="keyword">if</span> a &gt; b &#123;</span><br><span class="line">                <span class="keyword">return</span> a</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">return</span> b</span><br><span class="line">        &#125;</span><br><span class="line">        canVisit := <span class="built_in">make</span>(<span class="keyword">map</span>[<span class="type">int</span>]<span class="type">bool</span>)</span><br><span class="line">        canVisit[<span class="number">0</span>] = <span class="literal">true</span></span><br><span class="line">        edge := <span class="number">0</span></span><br><span class="line">        <span class="keyword">for</span> i := <span class="number">0</span>; i &lt;= edge &amp;&amp; i &lt; length; i++ &#123;</span><br><span class="line">            <span class="keyword">if</span> canVisit[i] &#123;</span><br><span class="line">                left := i + minJump</span><br><span class="line">                right := min(length - <span class="number">1</span>, i + maxJump)</span><br><span class="line">                <span class="keyword">for</span> j := max(left, edge + <span class="number">1</span>); j &lt;= right; j++ &#123;</span><br><span class="line">                    <span class="keyword">if</span> s[j] == <span class="string">&#x27;0&#x27;</span> &#123;</span><br><span class="line">                        canVisit[j] = <span class="literal">true</span></span><br><span class="line">                        <span class="keyword">if</span> j == length - <span class="number">1</span> &#123;</span><br><span class="line">                            <span class="keyword">return</span> <span class="literal">true</span></span><br><span class="line">                        &#125;</span><br><span class="line">                    &#125;</span><br><span class="line">                &#125;</span><br><span class="line">                edge = 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> <span class="literal">false</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>]]></content>
    
    
      
      
    <summary type="html">&lt;h2 id=&quot;55-Jump-Game&quot;&gt;&lt;a href=&quot;#55-Jump-Game&quot; class=&quot;headerlink&quot; title=&quot;55. Jump Game&quot;&gt;&lt;/a&gt;&lt;a href=&quot;https://leetcode.com/problems/jump-game/</summary>
      
    
    
    
    <category term="CS" scheme="http://blog.beendless.com/categories/CS/"/>
    
    
    <category term="Golang" scheme="http://blog.beendless.com/tags/Golang/"/>
    
    <category term="Algorithms" scheme="http://blog.beendless.com/tags/Algorithms/"/>
    
    <category term="Leetcode" scheme="http://blog.beendless.com/tags/Leetcode/"/>
    
    <category term="Binary Tree" scheme="http://blog.beendless.com/tags/Binary-Tree/"/>
    
    <category term="Dynamic Programming" scheme="http://blog.beendless.com/tags/Dynamic-Programming/"/>
    
    <category term="DFS" scheme="http://blog.beendless.com/tags/DFS/"/>
    
    <category term="Two Pointers" scheme="http://blog.beendless.com/tags/Two-Pointers/"/>
    
    <category term="Greedy" scheme="http://blog.beendless.com/tags/Greedy/"/>
    
    <category term="JumpGame" scheme="http://blog.beendless.com/tags/JumpGame/"/>
    
    <category term="BFS" scheme="http://blog.beendless.com/tags/BFS/"/>
    
    <category term="Sliding Window" scheme="http://blog.beendless.com/tags/Sliding-Window/"/>
    
  </entry>
  
</feed>
