[{"content":"1996. The Number of Weak Characters in the Game 蠻有趣的題目，跟 354.russian-doll-envelopes 大概有87%像，這種二維排序找大小的問題似乎也是固定套路，兩個方向升、降冪相反就是了，端看題目要求的是甚麼，以 354 這題來說，需求是小信封裝進大信封，所以 x 軸先按升冪排序， y 軸按降冪排序，之後按照 $y_{i+1} \u0026gt; y_{i}$ 的邏輯搜尋即可，因為對 x 已經確定 $x_{i+1} \u0026gt; x_{i}$ 了\n本題則剛好相反，需求是要找 weak character ，所以先對 x 軸按降冪排序， y 軸按升幂排序，然後對 y 軸找小於某個特定值的元素個數即可\n這裡先弄個簡單的類別，方便閱讀\n1 2 3 4 5 6 7 8 9 10 11 12 struct attrib { int atk; int def; attrib(vector\u0026lt;int\u0026gt;\u0026amp; v) : atk(v[0]), def(v[1]) {}; bool operator \u0026lt;(const attrib\u0026amp; rhs) const { if (this-\u0026gt;atk == rhs.atk) return this-\u0026gt;def \u0026lt; rhs.def; return this-\u0026gt;atk \u0026gt; rhs.atk; } string to_string() { return \u0026#34;(\u0026#34; + ::to_string(this-\u0026gt;atk) + \u0026#34;, \u0026#34; + ::to_string(this-\u0026gt;def) + \u0026#34;)\u0026#34;; } }; 對於排序好的 props 只需要找出 $def_{i} \u0026lt; max(def)$ 的個數即可，因為已知 $atk_{i} \u0026gt; atk_{i+1}$，如果是 $atk_{i} == atk_{i+1}$ 的情況， 則 $def_{i} \u0026lt; def_{i+1}$ ，所以 $max(def)$ 需要隨時更新\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 int numberOfWeakCharacters(vector\u0026lt;vector\u0026lt;int\u0026gt;\u0026gt;\u0026amp; properties) { vector\u0026lt;attrib\u0026gt; props(properties.begin(), properties.end()); sort(props.begin(), props.end()); dump(props); int count = 0, max_def = INT_MIN; for (auto\u0026amp; p : props) { if (p.def \u0026lt; max_def) { cout \u0026lt;\u0026lt; p.to_string() \u0026lt;\u0026lt; endl; count++; } else max_def = p.def; } return count; } void dump(vector\u0026lt;attrib\u0026gt;\u0026amp; vp) { for (auto\u0026amp; p : vp) cout \u0026lt;\u0026lt; p.to_string() \u0026lt;\u0026lt; endl; cout \u0026lt;\u0026lt; \u0026#34;----------------\u0026#34; \u0026lt;\u0026lt; endl; } 以測資 $[[7,7],[1,2],[9,7],[7,3],[3,10],[9,8],[8,10],[4,3],[1,5],[1,5]]$ 來舉例吧，執行後的輸出如下\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 (9, 7) (9, 8) (8, 10) (7, 3) (7, 7) (4, 3) (3, 10) (1, 2) (1, 5) (1, 5) ---------------- (7, 3) (7, 7) (4, 3) (1, 2) (1, 5) (1, 5) 因為 $atk$ 屬性是降冪排序，所以我們只需要關心 $def$ 屬性即可，按照程式邏輯， $max(def)$ 會依序被更新為 7, 8, 10 ，所以之後只要小於 10 的屬性都會被算進 count 裡，也就是題目要求的解答了\n以時間複雜度來說，STL的排序演算法 大約是 $O(nlog_2 n)$ ，之後的 for-loop 是 $O(n)$ ，如果直接對輸入的陣列進行操作而不拷貝至新陣列，空間複雜度是 $O(1)$\n","date":"2022-09-09T00:00:00Z","permalink":"https://lr-ch.netlify.app/p/leetcode-daily-challenge-2022/09/09/","title":"LeetCode daily challenge (2022/09/09)"},{"content":"417. Pacific Atlantic Water Flow 連續五天都是 matrix 相關的問題啊\u0026hellip;\n這題一開始就決定用深度優先搜尋配合遞迴的解法，使用正向搜尋的邏輯，也就是題目所說的：假如 heights(x, y) \u0026gt;= heights(x + 1, y) ，河流就可以往 x + 1 的方向流動，結果發現處理重複尋訪的問題實在很煩人，空間複雜度平白多了 O(m*n) 不說，程式邏輯也是奇醜無比，後來靈光一閃，其實可以用反向搜尋，也就是從岸邊開始往內陸尋找上游，這樣就可以完全無視重複尋訪的問題，有點 DP 的感覺\u0026hellip;\n1 2 3 4 5 6 7 8 9 10 11 void flow(vector\u0026lt;vector\u0026lt;int\u0026gt;\u0026gt;\u0026amp; h, vector\u0026lt;vector\u0026lt;bool\u0026gt;\u0026gt;\u0026amp; t, int row, int col) { if(row \u0026lt; 0 || row \u0026gt; m - 1 || col \u0026lt; 0 || col \u0026gt; n - 1) return; if (!t[row][col]) { t[row][col] = true; if (row - 1 \u0026gt;= 0 \u0026amp;\u0026amp; h[row][col] \u0026lt;= h[row - 1][col]) flow(h, t, row - 1, col); if (col - 1 \u0026gt;= 0 \u0026amp;\u0026amp; h[row][col] \u0026lt;= h[row][col - 1]) flow(h, t, row, col - 1); if (row + 1 \u0026lt; m \u0026amp;\u0026amp; h[row][col] \u0026lt;= h[row + 1][col]) flow(h, t, row + 1, col); if (col + 1 \u0026lt; n \u0026amp;\u0026amp; h[row][col] \u0026lt;= h[row][col + 1]) flow(h, t, row, col + 1); } } 可以看到規則變成 heights(x, y) \u0026lt;= heights(x + 1, y) 才繼續往 x + 1 的方向走，反正就是一路往上，如果已經是 true 就直接離開，否則先標記成 true 再繼續溯源。這裡的參數 h 就是原始題目輸入的 heights ， t 則是表示座標 (x, y) 可否流至 Pacific Ocean 或是 Atlantic Ocean 的布林陣列，遞迴的起點就是從岸邊開始\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 static int m, n; vector\u0026lt;vector\u0026lt;int\u0026gt;\u0026gt; pacificAtlantic(vector\u0026lt;vector\u0026lt;int\u0026gt;\u0026gt;\u0026amp; heights) { m = heights.size(), n = heights[0].size(); vector\u0026lt;vector\u0026lt;bool\u0026gt;\u0026gt; toPac(m, vector\u0026lt;bool\u0026gt;(n, false)); vector\u0026lt;vector\u0026lt;bool\u0026gt;\u0026gt; toAtl(m, vector\u0026lt;bool\u0026gt;(n, false)); vector\u0026lt;vector\u0026lt;int\u0026gt;\u0026gt; ans; for (int p = 0; p \u0026lt; m; p++) for (int q = 0; q \u0026lt; n; q++) { if (p == m - 1 || q == n - 1) flow(heights, toAtl, p, q); if (p == 0 || q == 0) flow(heights, toPac, p, q); } for (int x = 0; x \u0026lt; m; x++) for (int y = 0; y \u0026lt; n; y++) if (toPac[x][y] \u0026amp;\u0026amp; toAtl[x][y]) ans.push_back({ x, y }); return ans; } 因為 Pacific Ocean 是在西北方，所以岸邊座標就是 row = 0 和 column = 0 ，而 Atlantic Ocean 是在東南方，所以從 row = m - 1 和 column = n - 1 的位置開始遞迴，最後找出兩個矩陣的交集就是答案了\n","date":"2022-08-31T00:00:00Z","permalink":"https://lr-ch.netlify.app/p/leetcode-daily-challenge-2022/08/31/","title":"LeetCode daily challenge (2022/08/31)"},{"content":"363. Max Sum of Rectangle No Larger Than K 乍看是一題複雜度很高的題目，實際上也真的很高，第一次遇到 judge 時間超過1000ms將近2000ms竟然沒有TLE還AC的題目。但也有可能是我做的題目不夠多，少見多怪罷了\n題目給定一個 m 列 (row) 和 n 行 (column) 的矩陣 matrix，和一個 k 值，要求返回一個子矩陣內的值相加最接近或等於 k 的值但不大於 k，已知測資矩陣內的每個值皆不大於 k\n這種求和的問題第一個直覺都是想到用prefix sum來解決，只不過平常都是用在一維陣列，這題很巧妙地考驗操作 2-d 陣列的技巧，只要稍微在紙上演練一下就可以想出來了\n舉個簡單的例子\nC0 C1 C2 R0 1 2 3 R1 4 5 6 R2 7 8 9 可以依列對每一行的值累加，然後得到這樣的prefix sum table\nC0 C1 C2 R0 0 0 0 R1 1 2 3 R2 5 7 9 R3 12 15 18 如果子矩陣取 (R1, C0)~(R2, C1) (4 + 5 + 7 + 8)，只要計算 prefix sum table 中的 (R3, C0) - (R1, C0) + (R3, C1) - (R1, C1) 即可，也就是 (12 - 1) + (15 - 2)\n找出規則後就可以開工了，首先建立 prefix sum table\n1 2 3 4 5 6 int m = matrix.size(), n = matrix[0].size(); vector\u0026lt;vector\u0026lt;int\u0026gt;\u0026gt; preSum(m + 1, vector\u0026lt;int\u0026gt;(n, 0)); for (int i = 0; i \u0026lt; m; i++) for (int j = 0; j \u0026lt; n; j++) preSum[i + 1][j] = preSum[i][j] + matrix[i][j]; 這裡要注意的是因為對每一行進行累加，所以 table 的列數要比原本的列數多一\n然後用 4 個迴圈按照 (r1, c1), (r2, c2) 的順序找出答案\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 int ans = INT_MIN; for (int r1 = 0; r1 \u0026lt; m; r1++) for (int r2 = r1 + 1; r2 \u0026lt;= m; r2++) for (int c1 = 0; c1 \u0026lt; n; c1++) { int val = 0; for (int c2 = c1; c2 \u0026lt; n; c2++) { val += preSum[r2][c2] - preSum[r1][c2]; if (val \u0026lt; k) { ans = max(ans, val); } else if (val == k) { return k; } } } 因為 table 比原本的 matrix 多了一列，所以 r2 的上界是 \u0026lt;= m ，這應該沒甚麼問題，另外這也將子矩陣取單一個數的情況也考慮到了，例如當 k 為 8 的情況，子矩陣應該為 matrix 的 (R2, C1) ，在迴圈裡就是 preSum[3][1] - preSum[2][1]\n題目的 hint 有提到 ordered set 和 binary search ，不過我看了一下 discussion 看不出個所以然就放棄了\u0026hellip; 改天有空再研究研究\n這題的難度大概 90% 來自繁瑣的迴圈過程，沒有紙筆輔助大概很難光靠空想推導出來，當然我是說我自己啦\n","date":"2022-08-27T00:00:00Z","permalink":"https://lr-ch.netlify.app/p/leetcode-daily-challenge-2022/08/27/","title":"LeetCode daily challenge (2022/08/27)"},{"content":"869. Reordered Power of 2 好不容易總算等到一題不會複雜到懶得寫，又不會簡單到不屑寫的題目了。不知道為什麼難度被歸在medium，好吧我承認一開始有誤會題意導致第一個submit被WA，下次看到簡單的題目真的不要腦衝，把題意看清楚再動手，戒之慎之\n題目要求輸入任意數n，n的每一位數可以任意排列(除了把0放在首位)，如果n可以成為2的指數返回true，否則返回false\n很直覺的想法就是把所有可能範圍內的2的指數和輸入的n拆解成array存到set裡，然後比對一下就行了\n拆解的方法就是把數字除以10取餘數，除到商數為零即可，因為最後要放到set裡，如果vector裡的數字順序不一樣可能會被視為不同的key，所以先對vector的內容進行排序\n1 2 3 4 5 6 7 vector\u0026lt;int\u0026gt; disect(int i) { vector\u0026lt;int\u0026gt; res; for (int j = i; j \u0026gt; 0; j /= 10) res.push_back(j % 10); sort(res.begin(), res.end()); return res; } 因為題目限制輸入的n值範圍為 \\( 1 \u0026lt;= n \u0026lt;= 10^9 \\)，所以對範圍內所有2的指數建立set，i \u0026lt;\u0026lt;= 1 其實就是 i *= 2 的意思，老梗。最後用 std::set 的 find() 尋找相同位數的vector，找得到就 true，反之 false，收工\n1 2 3 4 5 6 7 set\u0026lt;vector\u0026lt;int\u0026gt;\u0026gt; pool; bool reorderedPowerOf2(int n) { for (int i = 1; i \u0026lt; 1e9; i \u0026lt;\u0026lt;= 1) pool.insert(disect(i)); return pool.find(disect(n)) != pool.end(); } 這code如果直接submit，測完時間大概在10ms上下，直覺應該是disect()直接返回vector\u0026lt;int\u0026gt;的緣故，如果修改為\n1 2 3 4 5 void disect(int i, vector\u0026lt;int\u0026gt;\u0026amp; v) { for (int j = i; j \u0026gt; 0; j /= 10) v.push_back(j % 10); sort(v.begin(), v.end()); } 則一舉降為3ms，物件拷貝真的是代價不斐，翻了一下Discuss發現好多宣稱0ms，結果作法大同小異，leetcode的judge真的很謎啊\n","date":"2022-08-26T00:00:00Z","permalink":"https://lr-ch.netlify.app/p/leetcode-daily-challenge-2022/08/26/","title":"LeetCode daily challenge (2022/08/26)"},{"content":"使用KaTeX 行內、區塊 When \\(a \\ne 0\\), there are two solutions to \\(ax^2 + bx + c = 0\\) and they are\n$$ x = {-b \\pm \\sqrt{b^2-4ac} \\over 2a} $$\n羅倫茲方程 $$ \\begin{aligned} \\dot{x} \u0026amp; = \\sigma(y-x) \\\\ \\dot{y} \u0026amp; = \\rho x - y - xz \\\\ \\dot{z} \u0026amp; = -\\beta z + xy \\end{aligned} $$\n柯西－史瓦茲不等式 $$ \\left( \\sum_{k=1}^n a_k b_k \\right)^2 \\leq \\left( \\sum_{k=1}^n a_k^2 \\right) \\left( \\sum_{k=1}^n b_k^2 \\right) $$\n向量外積 $$ \\mathbf{V}_1 \\times \\mathbf{V}_2 = \\left| \\begin{matrix} \\mathbf{i} \u0026amp; \\mathbf{j} \u0026amp; \\mathbf{k} \\\\[0.3em] \\frac{\\partial X}{\\partial u} \u0026amp; \\frac{\\partial Y}{\\partial u} \u0026amp; 0 \\\\[0.5em] \\frac{\\partial X}{\\partial v} \u0026amp; \\frac{\\partial Y}{\\partial v} \u0026amp; 0 \\end{matrix} \\right| $$\n投擲 n 個硬幣得到 k 個人頭的機率 $$ P(E) = {n \\choose k} p^k (1-p)^{ n-k} $$\nAn Identity of Ramanujan $$ \\frac{1}{\\Bigl(\\sqrt{\\phi \\sqrt{5}}-\\phi\\Bigr) e^{\\frac25 \\pi}} = 1+\\frac{e^{-2\\pi}} {1+\\frac{e^{-4\\pi}} {1+\\frac{e^{-6\\pi}} {1+\\frac{e^{-8\\pi}} {1+\\ldots} } } } $$\nA Rogers-Ramanujan Identity $$ 1 + \\frac{q^2}{(1-q)}+\\frac{q^6}{(1-q)(1-q^2)}+\\cdots = \\prod_{j=0}^{\\infty}\\frac{1}{(1-q^{5j+2})(1-q^{5j+3})}, \\quad\\quad \\text{for $|q|\u0026lt;1$}. $$\n馬克士威方程 $$ \\begin{aligned} \\nabla \\times \\vec{\\mathbf{B}} -\\ \\frac1c\\ \\frac{\\partial\\vec{\\mathbf{E}}}{\\partial t} \u0026amp; = \\frac{4\\pi}{c}\\vec{\\mathbf{j}} \\\\[1.0em] \\nabla \\cdot \\vec{\\mathbf{E}} \u0026amp; = 4 \\pi \\rho \\\\[0.5em] \\nabla \\times \\vec{\\mathbf{E}}\\ +\\ \\frac1c\\ \\frac{\\partial\\vec{\\mathbf{B}}}{\\partial t} \u0026amp; = \\vec{\\mathbf{0}} \\\\[1.0em] \\nabla \\cdot \\vec{\\mathbf{B}} \u0026amp; = 0 \\end{aligned} $$\nInline math: \\(\\varphi = \\dfrac{1+\\sqrt5}{2}= 1.6180339887…\\)\nBlock math: $$ \\varphi = 1+\\frac{1} {1+\\frac{1} {1+\\frac{1} {1+\\cdots} } } $$\n","date":"2022-08-12T09:00:00Z","permalink":"https://lr-ch.netlify.app/p/%E4%BD%BF%E7%94%A8%E6%95%B8%E5%AD%B8%E7%AC%A6%E8%99%9F/","title":"使用數學符號"},{"content":"測試貼文 這是一篇測試文章\nTables Are Cool col 1 Hello $1600 col 2 Hello $12 col 3 Hello $1 ","date":"2022-08-11T01:00:00Z","permalink":"https://lr-ch.netlify.app/p/%E6%B8%AC%E8%A9%A6/","title":"測試"}]