{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Notes" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Links\n", "\n", "* [Not All LeetCode Questions are Created Equal](https://www.reddit.com/r/cscareerquestions/comments/7rey82/how_to_avoid_wasting_time_on_weird_leetcode/)\n", " * These types of questions won't get asked: \n", " * problem statement are too long for interviewer to remember\n", " * too many corner cases to finish in interview\n", " * Look for: \n", " * questions that implement popular fundamental algorithms like trees, string manipulation, dfs/bfs, matrix\n", " * questions that have good real life application like regular expression\n", "* [算法模板 repo](https://github.com/greyireland/algorithm-pattern)\n", "* [BFS 模板](https://leetcode-cn.com/problems/ji-qi-ren-de-yun-dong-fan-wei-lcof/solution/bfsmo-ban-yi-ci-bei-hui-chu-chu-shi-yong-by-fuxuem/)\n", " * [同一作者寫的完整(?)模板](https://blog.csdn.net/fuxuemingzhu/article/details/101900729)\n", "* [OA difficulty](https://www.reddit.com/r/cscareerquestions/comments/ejyffw/difficultyexamples_of_hackerrank_questions_for/)\n", " * Akuna 比 Google 難,最簡單的一題是 upper medium,也有 hard leetcode 數學題\n", " * Citadel: 3 leetcode mediums in 60 minutes (hard but you don’t need to get all 3 perfectly).\n", " * Two Sigma\n", " * 1 leetcode easy, 2 medium in 60 minutes\n", " * Easier side of medium, on-site interviews are harder\n", " * 要練到 20 分鐘可以做完 most mediums,10 分鐘可以做完大部份 easies\n", " * 又有說 2 questions in 3 hours, be ready for DP/Graphs/DFS, all that stuff\n", " * 考過 friend circle leetcode question\n", " * Relatively easy/on par with tech companies\n", " * [2 sample questions](https://leetcode.com/discuss/interview-question/algorithms/1968209/two-sigma-hacker-rank-code-assessment)\n", "* Lists\n", " * [Teamblind's Curated List (75 題)](https://www.teamblind.com/post/New-Year-Gift---Curated-List-of-Top-75-LeetCode-Questions-to-Save-Your-Time-OaM1orEU)\n", " * [NeetCode 150](https://leetcode.com/problem-list/plakya4j/)\n", " * Superset of Blind 75\n", " * [LeetCode 75](https://leetcode.com/studyplan/leetcode-75/): Ace Coding Interview with 75 Qs\n", " * Minimal redundancy covering all core patterns \n", " * [Top Interview 150](https://leetcode.com/studyplan/top-interview-150/): Must-do List for Interview Prep\n", " * More variations of the same patterns,有點 complement to LC75" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## High Frequency\n", "\n", "* [LeetCode Questions CompanyWise](https://github.com/krishnadey30/LeetCode-Questions-CompanyWise/blob/master/citadel_alltime.csv)\n", "* 在下面這些題單裡出面過三次以上的題\n", " * ZXI(花花酱題目分類)\n", " * BL75(Blind 75 題單)\n", " * LC75(LeetCode 75 題單)\n", " * LC150(Top Interview 150 題單)\n", " * 有 16 題出現了四次,26 題出現三次\n", "\n", "" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "| 題目名稱 | 難度 | Freq | ZXI | BL75 | LC75 | LC150 |\n", "|----------|------|----------|-----|------|------|--------|\n", "| [1. Two Sum](https://leetcode.com/problems/two-sum/) | Easy | 4 | o | o | o | o |\n", "| [121. Best Time to Buy and Sell Stock](https://leetcode.com/problems/best-time-to-buy-and-sell-stock/) | Easy | 4 | o | o | o | o |\n", "| [20. Valid Parentheses](https://leetcode.com/problems/valid-parentheses/) | Easy | 4 | o | o | o | o |\n", "| [21. Merge Two Sorted Lists](https://leetcode.com/problems/merge-two-sorted-lists/) | Easy | 4 | o | o | o | o |\n", "| [242. Valid Anagram](https://leetcode.com/problems/valid-anagram/) | Easy | 4 | o | o | o | o |\n", "| [226. Invert Binary Tree](https://leetcode.com/problems/invert-binary-tree/) | Easy | 4 | o | o | o | o |\n", "| [141. Linked List Cycle](https://leetcode.com/problems/linked-list-cycle/) | Easy | 4 | o | o | o | o |\n", "| [206. Reverse Linked List](https://leetcode.com/problems/reverse-linked-list/) | Easy | 4 | o | o | o | o |\n", "| [53. Maximum Subarray](https://leetcode.com/problems/maximum-subarray/) | Medium | 4 | o | o | o | o |\n", "| [238. Product of Array Except Self](https://leetcode.com/problems/product-of-array-except-self/) | Medium | 4 | o | o | o | o |\n", "| [102. Binary Tree Level Order Traversal](https://leetcode.com/problems/binary-tree-level-order-traversal/) | Medium | 4 | o | o | o | o |\n", "| [56. Merge Intervals](https://leetcode.com/problems/merge-intervals/) | Medium | 4 | o | o | o | o |\n", "| [33. Search in Rotated Sorted Array](https://leetcode.com/problems/search-in-rotated-sorted-array/) | Medium | 4 | o | o | o | o |\n", "| [3. Longest Substring Without Repeating Characters](https://leetcode.com/problems/longest-substring-without-repeating-characters/) | Medium | 4 | o | o | o | o |\n", "| [139. Word Break](https://leetcode.com/problems/word-break/) | Medium | 4 | o | o | o | o |\n", "| [207. Course Schedule](https://leetcode.com/problems/course-schedule/) | Medium | 4 | o | o | o | o |\n", "| [125. Valid Palindrome](https://leetcode.com/problems/valid-palindrome/) | Easy | 3 | o | o | _ | o |\n", "| [217. Contains Duplicate](https://leetcode.com/problems/contains-duplicate/) | Easy | 3 | o | o | _ | o |\n", "| [70. Climbing Stairs](https://leetcode.com/problems/climbing-stairs/) | Easy | 3 | o | o | o | _ |\n", "| [252. Meeting Rooms](https://leetcode.com/problems/meeting-rooms/) | Easy | 3 | o | o | o | _ |\n", "| [253. Meeting Rooms II](https://leetcode.com/problems/meeting-rooms-ii/) | Medium | 3 | o | o | o | _ |\n", "| [49. Group Anagrams](https://leetcode.com/problems/group-anagrams/) | Medium | 3 | o | o | _ | o |\n", "| [5. Longest Palindromic Substring](https://leetcode.com/problems/longest-palindromic-substring/) | Medium | 3 | o | o | _ | o |\n", "| [647. Palindromic Substrings](https://leetcode.com/problems/palindromic-substrings/) | Medium | 3 | o | o | _ | o |\n", "| [271. Encode and Decode Strings](https://leetcode.com/problems/encode-and-decode-strings/) | Medium | 3 | _ | o | o | o |\n", "| [230. Kth Smallest Element in a BST](https://leetcode.com/problems/kth-smallest-element-in-a-bst/) | Medium | 3 | o | o | _ | o |\n", "| [235. Lowest Common Ancestor of BST](https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-search-tree/) | Medium | 3 | o | o | _ | o |\n", "| [208. Implement Trie](https://leetcode.com/problems/implement-trie-prefix-tree/) | Medium | 3 | o | o | _ | o |\n", "| [211. Add and Search Word](https://leetcode.com/problems/add-and-search-word-data-structure-design/) | Medium | 3 | o | o | _ | o |\n", "| [347. Top K Frequent Elements](https://leetcode.com/problems/top-k-frequent-elements/) | Medium | 3 | o | o | _ | o |\n", "| [322. Coin Change](https://leetcode.com/problems/coin-change/) | Medium | 3 | o | o | o | _ |\n", "| [198. House Robber](https://leetcode.com/problems/house-robber/) | Medium | 3 | o | o | o | _ |\n", "| [62. Unique Paths](https://leetcode.com/problems/unique-paths/) | Medium | 3 | o | o | o | _ |\n", "| [55. Jump Game](https://leetcode.com/problems/jump-game/) | Medium | 3 | o | o | o | _ |\n", "| [133. Clone Graph](https://leetcode.com/problems/clone-graph/) | Medium | 3 | o | o | o | _ |\n", "| [200. Number of Islands](https://leetcode.com/problems/number-of-islands/) | Medium | 3 | o | o | o | _ |\n", "| [261. Graph Valid Tree](https://leetcode.com/problems/graph-valid-tree/) | Medium | 3 | o | o | o | _ |\n", "| [57. Insert Interval](https://leetcode.com/problems/insert-interval/) | Medium | 3 | o | o | o | _ |\n", "| [435. Non-overlapping Intervals](https://leetcode.com/problems/non-overlapping-intervals/) | Medium | 3 | o | o | o | _ |\n", "| [212. Word Search II](https://leetcode.com/problems/word-search-ii/) | Hard | 3 | o | o | _ | o |\n", "| [295. Find Median from Data Stream](https://leetcode.com/problems/find-median-from-data-stream/) | Hard | 3 | o | o | _ | o |\n", "| [269. Alien Dictionary](https://leetcode.com/problems/alien-dictionary/) | Hard | 3 | o | o | o | _ |" ] }, { "cell_type": "markdown", "metadata": { "jp-MarkdownHeadingCollapsed": true }, "source": [ "## C \n", "\n", "* 常見題目(近一年)from AI's web search \n", "\n", "| 題目 | 難度 | Done | 題型分類 | 備註 | \n", "|------|------|------|-----------|------| \n", "| [146. LRU Cache](https://leetcode.com/problems/lru-cache) | Medium | | 設計題、Linked List + HashMap | 高頻設計題,需要自訂資料結構 | \n", "| [647. Palindromic Substrings](https://leetcode.com/problems/palindromic-substrings) | Medium | | 雙指標 | 可用中心擴展解法,C 出現過 | \n", "| [221. Maximal Square](https://leetcode.com/problems/maximal-square) | Medium | o | 動態規劃 | 經典 2D DP 題,C 題庫中 | \n", "| [200. Number of Islands](https://leetcode.com/problems/number-of-islands) | Medium | o | DFS / BFS | C 高頻,圖遍歷入門 | \n", "| [239. Sliding Window Maximum](https://leetcode.com/problems/sliding-window-maximum) | Hard | | 單調佇列 | 難度稍高但公司常問,可酌量準備 | \n", "| [295. Find Median from Data Stream](https://leetcode.com/problems/find-median-from-data-stream) | Hard | | Heap | 雙 heap 設計,C 常見進階設計題 | \n", "| [1048. Longest String Chain](https://leetcode.com/problems/longest-string-chain) | Medium | | 動態規劃 | 字串 + DP,C 題庫中頻率高 | \n", "| [740. Delete and Earn](https://leetcode.com/problems/delete-and-earn) | Medium | | 動態規劃 | 關聯到 House Robber 思維 | \n", "| [37. Sudoku Solver](https://leetcode.com/problems/sudoku-solver) | Hard | | 回溯 | 複雜回溯問題,不常出但代表性高 | \n", "| [150. Evaluate Reverse Polish Notation](https://leetcode.com/problems/evaluate-reverse-polish-notation) | Medium | | Stack | 經典堆疊運算題,C 出現紀錄 | \n", "\n", "\n", "\n", "### Sliding Window \n", "\n", "| 題目名稱 | 難度 | Done | 題型 | 備註 | \n", "|----------|------|------|------|------| \n", "| [3. Longest Substring Without Repeating Characters](https://leetcode.com/problems/longest-substring-without-repeating-characters) | Medium | | Sliding Window | 高頻且直覺 | \n", "| [121. Best Time to Buy and Sell Stock](重複) | Easy | o | Sliding Window / DP | 雙分類題型 | \n", "| [239. Sliding Window Maximum](https://leetcode.com/problems/sliding-window-maximum) | Hard | | Monotonic Queue | C 曾出現但可跳過 | \n", "| [438. Find All Anagrams in a String](https://leetcode.com/problems/find-all-anagrams-in-a-string) | Medium | | Sliding Window + Hash | 字串處理經典 | \n", "| [567. Permutation in String](https://leetcode.com/problems/permutation-in-string) | Medium | | Sliding Window | 與 438 類似但更簡潔 | \n", "\n", "\n", "\n", "### Tree / Graph Traversal \n", "\n", "| 題目名稱 | 難度 | Done | 題型 | 備註 | \n", "|----------|------|------|------|------| \n", "| [102. Binary Tree Level Order Traversal](https://leetcode.com/problems/binary-tree-level-order-traversal) | Medium | o | BFS | 你已經被問過 | \n", "| [200. Number of Islands](https://leetcode.com/problems/number-of-islands) | Medium | o | DFS / BFS | C 高頻 | \n", "| [199. Binary Tree Right Side View](https://leetcode.com/problems/binary-tree-right-side-view) | Medium | | BFS | C 題庫中 | \n", "| [104. Maximum Depth of Binary Tree](https://leetcode.com/problems/maximum-depth-of-binary-tree) | Easy | o | DFS | 快速上手 | \n", "| [112. Path Sum](https://leetcode.com/problems/path-sum) | Easy | o | DFS | 經典遞迴題型 | \n", "\n", "\n", "\n", "### String / Array Manipulation \n", "\n", "| 題目名稱 | 難度 | Done | 題型 | 備註 | \n", "|----------|------|------|------|------| \n", "| [151. Reverse Words in a String](https://leetcode.com/problems/reverse-words-in-a-string) | Medium | o | 字串處理 | C 題庫中 | \n", "| [28. Implement strStr()](https://leetcode.com/problems/implement-strstr) | Easy | o | 字串搜尋 | KMP 可選但不必要 | \n", "| [1. Two Sum](https://leetcode.com/problems/two-sum) | Easy | o | HashMap | 所有公司都愛問 | \n", "| [724. Find Pivot Index](https://leetcode.com/problems/find-pivot-index) | Easy | | Prefix Sum | C 題庫中 | \n", "| [647. Palindromic Substrings](https://leetcode.com/problems/palindromic-substrings) | Medium | | DP / Expand Center | C 高頻 | \n", "\n", "\n", "\n", "### Dynamic Programming(DP) \n", "\n", "| 題目 | 難度 | Done | 題型說明與考點 | \n", "|------|------|------|----------------| \n", "| [70. Climbing Stairs](https://leetcode.com/problems/climbing-stairs/) | Easy | o | 經典 DP 入門題,類似斐波那契數列,狀態轉移非常簡單 | \n", "| [53. Maximum Subarray](https://leetcode.com/problems/maximum-subarray/) | Easy | o | Kadane’s Algorithm,找最大連續子陣列和 | \n", "| [198. House Robber](https://leetcode.com/problems/house-robber/) | Easy | o | 線性 DP,相鄰不能同時選擇,是 DP 與貪婪策略的結合基礎 | \n", "| [121. Best Time to Buy and Sell Stock](https://leetcode.com/problems/best-time-to-buy-and-sell-stock/) | Easy | o | 雖非典型 DP,但常見於量化面試,考察最大利潤與滑動窗口 | \n", "| [5. Longest Palindromic Substring](https://leetcode.com/problems/longest-palindromic-substring/) | Medium | | 回文與 DP,考區間 DP 或中心擴展技巧 | \n", "| [139. Word Break](https://leetcode.com/problems/word-break/) | Medium | o | 字典查詢與 DP 結合,考察子字串切割與記憶化技巧 | \n", "| [221. Maximal Square](https://leetcode.com/problems/maximal-square/) | Medium | o | 二維 DP,找最大面積的正方形,你已經做得很好啦! | \n", "| [647. Palindromic Substrings](https://leetcode.com/problems/palindromic-substrings/) | Medium | | 計算所有回文子字串的數量,考察區間處理與效率 | \n", "| [322. Coin Change](https://leetcode.com/problems/coin-change/) | Medium | o | 類似背包問題,常用在金融類的動態選擇策略中 | \n", "| [62. Unique Paths](https://leetcode.com/problems/unique-paths/) | Medium | o | 二維 DP,經典路徑計算題,可用 combinatorics 或 DP | \n", "| [55. Jump Game](https://leetcode.com/problems/jump-game/) | Medium | | 一維 DP 或 greedy 解法,DP 是官方標準分類之一 | \n", "| [150. Evaluate Reverse Polish Notation](https://leetcode.com/problems/evaluate-reverse-polish-notation/) | Medium | | 字串與堆疊邏輯題,常見於 C 的邏輯考題中 | \n", "| [91. Decode Ways](https://leetcode.com/problems/decode-ways/) | Medium | | 字串與 DP 結合,考邊界條件與有效數字解析 | \n", "| [740. Delete and Earn](https://leetcode.com/problems/delete-and-earn/) | Medium | | 類似 House Robber 的變形題,考數字間的互斥處理 | \n", "| [718. Maximum Length of Repeated Subarray](https://leetcode.com/problems/maximum-length-of-repeated-subarray/) | Medium | | 二維 DP,類似 LCS(Longest Common Substring)題型 | \n", "| [71. Simplify Path](https://leetcode.com/problems/simplify-path/) | Medium | | 字串與堆疊處理,考目錄結構與邏輯解析,常見於 C 題庫中 | \n", "| [1143. Longest Common Subsequence](https://leetcode.com/problems/longest-common-subsequence/) | Medium || 經典 DP 題型,常見於字串比對與資料結構設計 |\n", "\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## DP" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 221. Maximal Square\n", "\n", "Medium\n", "\n", "* 用一個二維的表 `dp[i][j]` 記下以 `matrix[i][j]` 為左下角的最大方型邊長\n", "* 如果 `matrix[i][j]` 為 0 則 `dp[i][j]` 為 0,\n", "* 否則\n", "```py\n", "dp[i][j] = 1 + min(dp[i-1][j], dp[i][j-1], dp[i-1][j-1])\n", "```\n", "* 因為方型的大小受限於它的上面,左邊,和左上" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 198. House Robber\n", "\n", "Easy\n", "\n", "* 對於每間房子,robber 有兩個選擇:\n", " * 不搶這間:保留 $dp[j-1]$\n", " * 搶這間:加上 $dp[j-2] + n_j$" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 53. Maximum Subarray\n", "\n", "Easy\n", "\n", "Kadane's algorithm: Maximum subarray ending $n_i$ is either $[n_i]$, or the maximum subarray ending $n_{i-1}$, with $n_i$. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 44. Wildcard Matching\n", "\n", "Hard\n", "\n", "Use pattern as columns and string as index, both starting with an empty character (and $T_{0, 0}$ is True). \n", "\\begin{align*}\n", "T_{i, j} = \n", "\\begin{cases}\n", "T_{i-1, j-1} &\\mbox{ if } (s_i==p_j) ~||~ (p_j==\\text{'?'})\\\\\n", "T_{i-1, j} ~||~ T_{i, j-1} &\\mbox{ if } p_j==\\text{'*'}\\\\\n", "\\text{False}\n", "\\end{cases}.\n", "\\end{align*}\n", "First row is TTT... until the first non-asterisk character shows up, under which a sequence FFF... starts. First column is TFFFFF..." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 309. Best Time to Buy and Sell Stock with Cooldown\n", "\n", "Medium\n", " \n", "賣完之後不能隔天馬上買而是要等一天。\n", "\n", "\n", "[兩個狀態的 DP](https://youtu.be/Ggzbo9eVrLU?t=92)\n", ":h 和 u 分別為持有股票和空倉時,現金帳戶價值的最大值。把 prices 跑完時 u 的結尾即是答案。Transition function 的 max 裡第一項是第 n 天有改變狀態的情況,第二項是沒有改變狀態。\n", "\n", "\n", "Base case hold 狀態因為買入股票,現金帳戶變成負值。第二天的 hold 是前兩天股票選便宜的那天買:\n", "\n", "\n", "|p |8 |6 |4 |3 |3 |2 |3 |5 |8 |3 |8 |2 |6 |\n", "|--|--|--|--|--|--|--|--|--|--|--|--|--|--|\n", "|h|-8|-6|\n", "|u|0|\n", "\n", "\n", "Transition: \n", "\n", "\n", "$$\n", "\\begin{pmatrix}\n", "h_n\\\\\n", "u_n\n", "\\end{pmatrix}\n", "=\n", "\\begin{pmatrix}\n", "\\max(u_{n-2}-p_n, h_{n-1})\\\\\n", "\\max(h_{n-1}+p_n, u_{n-1})\n", "\\end{pmatrix}\n", "$$" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 714. Best Time to Buy and Sell Stock with Transaction Fee\n", "\n", "Medium\n", "\n", "用兩個狀態的 DP,同 309,但只需要一天的 Base case。Transition function 改成\n", "\n", "$$\n", "\\begin{pmatrix}\n", "h_n\\\\\n", "u_n\n", "\\end{pmatrix}\n", "=\n", "\\begin{pmatrix}\n", "\\max(u_{n-1}-p_n, h_{n-1})\\\\\n", "\\max(h_{n-1}+p_n- f, u_{n-1})\n", "\\end{pmatrix}\n", "$$\n", "\n", "交易成本一定要加在賣掉那邊(從 hold 轉成 unhold)因為這兩個變數記的是現金帳戶價值。\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 188. Best Time to Buy and Sell Stock IV\n", "\n", "Hard\n", "\n", "最多可以交易 $k$ 次,[這裡](https://www.youtube.com/watch?v=oDhu5uGq_ic)看來的解答。\n", "\n", "下面的答案是對的但在 LeetCode submit 不會過。如果遇到很長的 list 或 $k\\gg n$ 時間或空間會爆。\n", "\n", "| | 2| 5| 7| 1| 4| 3| 1| 3|\n", "|--|--|--|--|--|--|--|--|--|\n", "| 0| 0| 0| 0| 0| 0| 0| 0| 0|\n", "| 1| 0| 3| 5| 5| 5| 5| 5| 5|\n", "| 2| 0| 3| 5| 5| 8| 8| 8| 8|\n", "| 3| 0| 3| 5| 5| 8| 8| 8|10|\n", "\n", "\n", "$$\n", "T_{i, j} = \\max\n", "\\begin{cases}\n", "T_{i, j-1} \\\\\n", "(p_j - p_m) + T_{i-1, m}\\quad m=0, 1, \\ldots, j-1\n", "\\end{cases}, \n", "$$\n", "\n", "可再優化成\n", "\n", "\\begin{eqnarray*}\n", "T_{i, j} &=& \\max\n", "\\begin{cases}\n", "T_{i, j-1} \\\\\n", "p_j + \\text{maxDiff}_j\n", "\\end{cases}\\\\\\\\\n", "\\text{maxDiff}_{j} &=& \\max(\\text{maxDiff}_{j-1},~T_{i-1, j} - p_j), \n", "\\end{eqnarray*}\n", "\n", "每一列初始 $\\text{maxDiff}_0 = 0 - p_0$。\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Misc" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Implement eval()\n", "\n", "* '2 + 2' --> 4\n", "* '100-5+1' --> 96\n", "* Input 裡只會有加減號和整數,可能會有 space\n", "* 只能用 ? 查 doc\n", "* 檢查 input,raise error\n", "* 這個程式還有其它問題嗎? --> 連續兩個運算符就會爆" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import re\n", "\n", "def compute_expression(expression):\n", " if re.search(r'[+-]{2,}', expression):\n", " raise ValueError('illegal expression')\n", "\n", " return sum([int(n) for n in expression.replace(' ', '').replace('+', ',+').replace('-', ',-').split(',')])\n", "\n", "# compute_expression('1+-2') # ValueError\n", "\n", "all((compute_expression(expression) == eval(expression)) for expression in ['2 +2', '100-5+1'])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 829. Consecutive Numbers Sum\n", "\n", "Consider\n", "\\begin{align*}\n", "N &= m + (m+1) + (m+2) + \\cdots + n\\\\\n", "&= (n-m+1)(n+m)/2, \n", "\\end{align*}\n", "其中 $n-m+1$ 和 $n+m$ 一個是奇數,一個是偶數,而且已知 $n-m+1 > n+m$。所以所有 $N$ 的奇因數都確定了一組分解 $2N = (n-m+1)(n+m)$,從而確定了一組 $m$ 和 $n$ 的解。\n", "\n", "```floor(sqrt(N))``` 遇到很大的 $N$ 會 overflow。python 能處理任意大的整數,但 ```sqrt``` 會先轉成 float 然後就有可能出錯。一個安全判斷一個正整數是否為平方數的方法是[牛頓法](https://miscbeginnersc.readthedocs.io/en/latest/math/fun.html#Checking-if-an-Integer-Is-a-Perfect-Square)。" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 239. Sliding Window Maximum\n", "\n", "[Deque solution](https://youtu.be/TCHSXAu5pls?t=147)(video 裡存的是 index,這裡直接存數字):\n", "用一個 deque 存下 sliding window 裡的數字,並且要以 descending order。如果新進來的數不是最小的,就不斷 pop out 比它小的數直到它是最小的再 append。只要這個新進來的數存在,這些被 pop out 的數都不會是 sliding window maximum 所以可以直接 pop out。每次 slide 就檢查最左邊的數是不是應該被 pop out\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 123. Best Time to Buy and Sell Stock III\n", "\n", "最多可以交易兩次。\n", "\n", "Best Time to Buy and Sell Stock (121) 的解答有一個性質就是把 input 整個取負號再倒過來會得到一樣的結果,例如 maxProfit([5, 3, 6, 4]) 會等於 maxProfit([-4, -6, -3, -5])。\n", "\n", "可以交易兩次相當於把長度 n 的 array 拆成兩半分別求 121 的 maxProfit 再加起來。有 n 種拆法,例如 [7, 1, 5, 3, 6, 4] = [7, 1] + [5, 3, 6, 4] 是其中一種。隨著分拆點推進,第一個數列變長,第二個數列變短。第一個數列直接丟 121 的解答(但要記下 running max profit,不能用 O(1) space 的作法),第二個數列先倒過來取負號再丟,這樣新增的才是後面的數而不是前面的。\n", "\n", "下面 pass1 是在求 [7, 1, 5, 3, 6, 4] 的 121 解答,pass2 是求 [-4, -6, -3, -5, -1, -7] 的 121 解答。最後把其中一個 running max profit 倒過來和另一個相加,得到的數列就是用不同分拆點時得到的兩次交易 max profit。取 max 就是這題的答案。" ] }, { "attachments": { "500683be-31f9-484d-9813-f6a791dbdb68.png": { "image/png": "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HfnvduGz0ufzsM7vfve7fPGLX+SLX/wiTz/99B1x1jPn7fLZz3726Ot80/6Z881pvfU4Yafn4vtK0zRN05znWM/xAP/8z/+s/96k74cORxdKOc+VlQd48QXNupGuOGHn8/k3f/M3+ucWdnouOKELJfNY16EVJ7Tempyw03PxfaVpmqZpznOs53iAz33uc/pfZ98PHY4ulHKeKysP8Otf0K5cucLVq1eV8/jjj+sX3hUn7Hw+OzAchpXPykW4UDLvKyvT/ulxQuutyQk7PVfeV5qmaZrmPGfhHA9dKB3S2fn2sM4ulGRO2HmAX/+CdicWpGPx5S9/Wb/wrjhh5/PZgeEwrHxWLsKFknlfWaH90+OE1luTE3Z6rryvREREnCcL53joQumQzs63h3V2oSRzws4DvPKCtrCRrjhh5/PZgeEwrHxWulCK86D90+OE1luTE3Z6rryvREREnCcL53joQumQzs63h3V2oSRzws4DvPKCtrCRrjhh5/PZgeEwrHxWulCK86D90+OE1luTE3Z6rryvREREnCcL53joQumQzs63h3V2oSRzws4DvPKCtrCRrjhh5/PZgeEwrHxWulCK86D90+OE1luTE3Z6rryvREREnCcL53joQumQzs63h3V2oSRzws4DvPKCtrCRrjhh5/PZgeEwrHxWulCK86D90+OE1luTE3Z6rryvREREnCcL53joQumQzs63h3V2oSRzws4DvPKCtrCRrjhh5/PZgeEwrHxWulCK86D90+OE1luTE3Z6rryvREREnCcL53joQumQzs63h3V2oSRzws4DvPKCtrCRrjhh5/PZgeEwrHxWulCK86D90+OE1luTE3Z6rryvREREnCcL53joQumQzs63h3V2oSRzws4DvPKCtrCRrjhh5/PZgeEwrHxWulCK86D90+OE1luTE3Z6rryvREREnCcL53joQumQzs63h3V2oSRzws4DvPKCtrCRrjhh5/PZgeEwrHxWulCK86D90+OE1luTE3Z6rryvREREnCcL53joQumQzs63h3V2oSRzws4DvPKCtrCRrjhh5/PZgeEwrHxWulCK86D90+OE1luTE3Z6rryvREREnCcL53joQumQzs63h3V2oSRzws4DvPKCtrCRrjhh5/PZgeEwrHxWulCK86D90+OE1luTE3Z6rryvREREnCcL53joQumQzs63h3V2oSRzws4DvPKCtrCRrjhh5/PZgeEwrHxWulCK86D90+OE1luTE3Z6rryvREREnCcL53joQumQzs63h3V2oSRzws4DvPKCtrCRrjhh5/PZgeEwrHxWulCK86D90+OE1luTE3Z6rryvREREnCcL53joQumQzs63h3V2oSRzws4DvPKCtrCRrjhh5/PZgeEwrHxWulCK86D90+OE1luTE3Z6rryvREREnCcL53joQumQzs63h3V2oSRzws4DvPKCtrCRrjhh5/PZgeEwrHxWulCK86D90+OE1luTE3Z6rryvREREnCcL53joQumQzs63h3V2oSRzws4DvPKCtrCRrjhh5/PZgeEwrHxWulCK86D90+OE1luTE3Z6rryvREREnCcL53joQumQzs63h3V2oSRzws4DvPKCtrCRrjhh5/PZgeEwrHxWulCK86D90+OE1luTE3Z6rryvREREnCcL53joQumQzs63h3V2oSRzws4DvPKCtrCRrjhh5/PZgeEwrHxWulCK86D90+OE1luTE3Z6rryvREREnCcL53joQumQzs63h3V2oSRzws4DvPKCtrCRrjhh5/PZgeEwrHxWulCK86D90+OE1luTE3Z6rryvREREnCcL53joQumQzs63h3V2oSRzws4DvPKCtrCRrjhh5/PZgeEwrHxWulCK86D90+OE1luTE3Z6rryvREREnCcL53joQumQzs63h3V2oSRzws4DvPKCtrCRrjhh5/PZgeEwrHxWulCK86D90+OE1luTE3Z6rryvREREnCcL53joQumQzs63h3V2oSRzws4DvPKCtrCRrjhh5/PZgeEwrHxWulCK86D90+OE1luTE3Z6rryvREREnCcL53joQumQzs63h3V2oSRzws4DvPKCtrCRrjhh5/PZgeEwrHxWulCK86D90+OE1luTE3Z6rryvREREnCcL53joQumQzs63h3XecqH02l885ly7do3vfe97fO5zn+NDH/oQ73nPe24+dO95z3v40Ic+xOc//3m+//3vn/mf8dRTT938e5566imuX7/OCy+8wOc//3l+67d+i0uXLnFycsIv/dIv8Qd/8Ac888wzXLt27Wf+XD/60Y/4h3/4Bx5++GHe97733fzPf+CBB/iTP/kTnn76af7nf/7n6P/9Xb9+ndPT06P/DHdiVl7QXr+RfuITnzj6f+/N7c3K5/P1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" } }, "cell_type": "markdown", "metadata": {}, "source": [ "### 986. Interval List Intersections\n", "\n", "![image986.png](attachment:500683be-31f9-484d-9813-f6a791dbdb68.png)\n", "\n", "[用 two pointers 分別追蹤 A 和 B 的區間。](https://youtu.be/5xL_N2S3-QU?t=224)兩閉區間有重疊 iff $s \\leq e$。如果題目改開區間則是 $s < e$。" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 969. Pancake Sorting\n", "\n", "[最簡單的算法是 selection sort 變形:](https://zh.wikipedia.org/zh-tw/%E7%85%8E%E9%A4%85%E6%8E%92%E5%BA%8F)每次找出還沒排序的數之中最大的,先把它翻到最前面,再翻到還沒排序的部份的最後面。所以答案的偶數 subarray 會是 n, n-1, ...。看了 LeetCode 最快解法和一些 youtube,大家都只寫這種。\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 200. Number of Islands\n", "\n", "每次踩到 1 就 DFS 把同一個島都著色成 0,並且 count 累加一次。" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 560. Subarray Sum Equals K\n", "\n", "用一個 hash table 存下到目前為止,這個 cumsum 一共出現過幾次。" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 53. Maximum Subarray\n", "\n", "用一個變數 curMax 去 track 當前數字結尾的所有 subarray 中產生最大的 sum" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 47. Permutations II\n", "\n", "如果 input list 裡沒有重覆的數字,答案就是把每一個數字抓出來當開頭,剩下的拿去做 permutation(遞迴)。現在 input list 雖有重覆的數字,但重覆的數字只抓出來當開頭一次就會得到正確答案。例如 [1, 1, 1, 2, 2, 3, 3, 3, 3] 之中 1, 2, 3 各當開頭一次。第一個迴圈只是為了抓每個數字第一次出現時的 index。" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 15. 3Sum\n", "\n", "可以用 two sum (see the 2nd cell below) 但既然都要 $O(n^2)$ 不如[先排序然後用三個指標從左右往中間靠近。](https://www.youtube.com/watch?v=aSVI-DekuTk)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 121. Best Time to Buy and Sell Stock\n", "\n", "直接找出最大和最小再相減行不通,因為可能出現先賣再買。但一邊求 running max profit 一邊 update current min 就不會有這個問題了。" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.12.3" } }, "nbformat": 4, "nbformat_minor": 4 }