<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>prefix-sum on SAN == 0 ?</title><link>https://lr-ch.netlify.app/tags/prefix-sum/</link><description>Recent content in prefix-sum on SAN == 0 ?</description><generator>Hugo -- gohugo.io</generator><language>zh-tw</language><lastBuildDate>Sat, 27 Aug 2022 00:00:00 +0000</lastBuildDate><atom:link href="https://lr-ch.netlify.app/tags/prefix-sum/index.xml" rel="self" type="application/rss+xml"/><item><title>LeetCode daily challenge (2022/08/27)</title><link>https://lr-ch.netlify.app/p/leetcode-daily-challenge-2022/08/27/</link><pubDate>Sat, 27 Aug 2022 00:00:00 +0000</pubDate><guid>https://lr-ch.netlify.app/p/leetcode-daily-challenge-2022/08/27/</guid><description>&lt;h2 id="363-max-sum-of-rectangle-no-larger-than-k">363. Max Sum of Rectangle No Larger Than K&lt;/h2>
&lt;p>乍看是一題複雜度很高的題目，實際上也真的很高，第一次遇到 judge 時間超過1000ms將近2000ms竟然沒有TLE還AC的題目。但也有可能是我做的題目不夠多，少見多怪罷了&lt;/p>
&lt;p>題目給定一個 m 列 (row) 和 n 行 (column) 的矩陣 matrix，和一個 k 值，要求返回一個子矩陣內的值相加最接近或等於 k 的值但不大於 k，已知測資矩陣內的每個值皆不大於 k&lt;/p>
&lt;p>這種求和的問題第一個直覺都是想到用&lt;code>prefix sum&lt;/code>來解決，只不過平常都是用在一維陣列，這題很巧妙地考驗操作 2-d 陣列的技巧，只要稍微在紙上演練一下就可以想出來了&lt;/p>
&lt;p>舉個簡單的例子&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th style="text-align:center">&lt;/th>
&lt;th style="text-align:center">C0&lt;/th>
&lt;th style="text-align:center">C1&lt;/th>
&lt;th style="text-align:center">C2&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td style="text-align:center">R0&lt;/td>
&lt;td style="text-align:center">1&lt;/td>
&lt;td style="text-align:center">2&lt;/td>
&lt;td style="text-align:center">3&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td style="text-align:center">R1&lt;/td>
&lt;td style="text-align:center">4&lt;/td>
&lt;td style="text-align:center">5&lt;/td>
&lt;td style="text-align:center">6&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td style="text-align:center">R2&lt;/td>
&lt;td style="text-align:center">7&lt;/td>
&lt;td style="text-align:center">8&lt;/td>
&lt;td style="text-align:center">9&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>可以依列對每一行的值累加，然後得到這樣的&lt;code>prefix sum table&lt;/code>&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th style="text-align:center">&lt;/th>
&lt;th style="text-align:center">C0&lt;/th>
&lt;th style="text-align:center">C1&lt;/th>
&lt;th style="text-align:center">C2&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td style="text-align:center">R0&lt;/td>
&lt;td style="text-align:center">0&lt;/td>
&lt;td style="text-align:center">0&lt;/td>
&lt;td style="text-align:center">0&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td style="text-align:center">R1&lt;/td>
&lt;td style="text-align:center">1&lt;/td>
&lt;td style="text-align:center">2&lt;/td>
&lt;td style="text-align:center">3&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td style="text-align:center">R2&lt;/td>
&lt;td style="text-align:center">5&lt;/td>
&lt;td style="text-align:center">7&lt;/td>
&lt;td style="text-align:center">9&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td style="text-align:center">R3&lt;/td>
&lt;td style="text-align:center">12&lt;/td>
&lt;td style="text-align:center">15&lt;/td>
&lt;td style="text-align:center">18&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>如果子矩陣取 (R1, C0)~(R2, C1) &lt;code>(4 + 5 + 7 + 8)&lt;/code>，只要計算 prefix sum table 中的 (R3, C0) - (R1, C0) + (R3, C1) - (R1, C1) 即可，也就是 &lt;code>(12 - 1) + (15 - 2)&lt;/code>&lt;/p>
&lt;p>找出規則後就可以開工了，首先建立 &lt;code>prefix sum table&lt;/code>&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;span class="lnt">6
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-c++" data-lang="c++">&lt;span class="line">&lt;span class="cl">&lt;span class="kt">int&lt;/span> &lt;span class="n">m&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">matrix&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">size&lt;/span>&lt;span class="p">(),&lt;/span> &lt;span class="n">n&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">matrix&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">].&lt;/span>&lt;span class="n">size&lt;/span>&lt;span class="p">();&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">vector&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="n">vector&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="kt">int&lt;/span>&lt;span class="o">&amp;gt;&amp;gt;&lt;/span> &lt;span class="n">preSum&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">m&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">vector&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="kt">int&lt;/span>&lt;span class="o">&amp;gt;&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">n&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">));&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">for&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="kt">int&lt;/span> &lt;span class="n">i&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="n">i&lt;/span> &lt;span class="o">&amp;lt;&lt;/span> &lt;span class="n">m&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="n">i&lt;/span>&lt;span class="o">++&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">for&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="kt">int&lt;/span> &lt;span class="n">j&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="n">j&lt;/span> &lt;span class="o">&amp;lt;&lt;/span> &lt;span class="n">n&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="n">j&lt;/span>&lt;span class="o">++&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">preSum&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">i&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">][&lt;/span>&lt;span class="n">j&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">preSum&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">i&lt;/span>&lt;span class="p">][&lt;/span>&lt;span class="n">j&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="n">matrix&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">i&lt;/span>&lt;span class="p">][&lt;/span>&lt;span class="n">j&lt;/span>&lt;span class="p">];&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>這裡要注意的是因為對每一行進行累加，所以 table 的列數要比原本的列數多一&lt;/p>
&lt;p>然後用 4 個迴圈按照 &lt;code>(r1, c1), (r2, c2)&lt;/code> 的順序找出答案&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-c++" data-lang="c++">&lt;span class="line">&lt;span class="cl">&lt;span class="kt">int&lt;/span> &lt;span class="n">ans&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">INT_MIN&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">for&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="kt">int&lt;/span> &lt;span class="n">r1&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="n">r1&lt;/span> &lt;span class="o">&amp;lt;&lt;/span> &lt;span class="n">m&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="n">r1&lt;/span>&lt;span class="o">++&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">for&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="kt">int&lt;/span> &lt;span class="n">r2&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">r1&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="n">r2&lt;/span> &lt;span class="o">&amp;lt;=&lt;/span> &lt;span class="n">m&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="n">r2&lt;/span>&lt;span class="o">++&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">for&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="kt">int&lt;/span> &lt;span class="n">c1&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="n">c1&lt;/span> &lt;span class="o">&amp;lt;&lt;/span> &lt;span class="n">n&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="n">c1&lt;/span>&lt;span class="o">++&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kt">int&lt;/span> &lt;span class="n">val&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">for&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="kt">int&lt;/span> &lt;span class="n">c2&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">c1&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="n">c2&lt;/span> &lt;span class="o">&amp;lt;&lt;/span> &lt;span class="n">n&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="n">c2&lt;/span>&lt;span class="o">++&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">val&lt;/span> &lt;span class="o">+=&lt;/span> &lt;span class="n">preSum&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">r2&lt;/span>&lt;span class="p">][&lt;/span>&lt;span class="n">c2&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">-&lt;/span> &lt;span class="n">preSum&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">r1&lt;/span>&lt;span class="p">][&lt;/span>&lt;span class="n">c2&lt;/span>&lt;span class="p">];&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">val&lt;/span> &lt;span class="o">&amp;lt;&lt;/span> &lt;span class="n">k&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">ans&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">max&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">ans&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">val&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span> &lt;span class="k">else&lt;/span> &lt;span class="nf">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">val&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="n">k&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="n">k&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>因為 table 比原本的 matrix 多了一列，所以 r2 的上界是 &lt;code>&amp;lt;= m&lt;/code> ，這應該沒甚麼問題，另外這也將子矩陣取單一個數的情況也考慮到了，例如當 k 為 8 的情況，子矩陣應該為 matrix 的 &lt;code>(R2, C1)&lt;/code> ，在迴圈裡就是 &lt;code>preSum[3][1] - preSum[2][1]&lt;/code>&lt;/p>
&lt;p>題目的 hint 有提到 &lt;code>ordered set&lt;/code> 和 &lt;code>binary search&lt;/code> ，不過我看了一下 discussion 看不出個所以然就放棄了&amp;hellip; 改天有空再研究研究&lt;/p>
&lt;p>這題的難度大概 90% 來自繁瑣的迴圈過程，沒有紙筆輔助大概很難光靠空想推導出來，當然我是說我自己啦&lt;/p></description></item></channel></rss>