Check whether your feed is valid. For more information about JSON Feed, see the specification.
{ "version": "https://jsonfeed.org/version/1.1", "title": "Friedrich Ewald", "description": "Blog of a software engineer. Follow me along as I explore and write about Python, Ruby, and web development and random pieces of the internet. Happy to chat!", "language": "en", "home_page_url": "https://fewald.net", "feed_url": "https://fewald.net/feed.json", "items": [ { "id": "https://fewald.net/macos/2024/05/25/traveling-with-a-mac-book.html", "url": "https://fewald.net/macos/2024/05/25/traveling-with-a-mac-book.html", "title": "Traveling with a Mac Book", "content_html": "<p>I recently returned from a trip to Europe (GMT+2) to the West Coast (PT). Upon returning I noticed that none of my Two-factor (MFA) codes were accepted by either Cloudflare or AWS. I had not restarted my MacBook since leaving Europe. It seems to me that the internal clock which is used to calculate the current MFA code is not reset when switching time zones, thus producing invalid codes. A restart of the computer fixed this issue.</p><p><strong>Update:</strong> I also noticed that this happens sometimes when the laptop is closed (asleep) for some period of time. I found this little command that synchronizes the time.</p><figure class=\"highlight\"><pre><code class=\"language-zsh\" data-lang=\"zsh\"><span class=\"nb\">sudo </span>sntp <span class=\"nt\">-sS</span> time.apple.com</code></pre></figure>", "date_published": "2024-05-25T14:20:00+00:00" }, { "id": "https://fewald.net/leetcode/2024/04/28/leetcode-binary-search-matrix.html", "url": "https://fewald.net/leetcode/2024/04/28/leetcode-binary-search-matrix.html", "title": "Leetcode: Binary Search Matrix", "content_html": "<!--more--><p>The solution is a normal binary search as it would be done on a single array. The differenceis that it is a two-dimensional array. To solve for this, we treat the array as a one-dimensionalarray and check the middle element by calculating the row and column.</p><figure class=\"highlight\"><pre><code class=\"language-python\" data-lang=\"python\"><span class=\"k\">class</span> <span class=\"nc\">Solution</span><span class=\"p\">:</span> <span class=\"k\">def</span> <span class=\"nf\">searchMatrix</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">matrix</span><span class=\"p\">:</span> <span class=\"n\">List</span><span class=\"p\">[</span><span class=\"n\">List</span><span class=\"p\">[</span><span class=\"nb\">int</span><span class=\"p\">]],</span> <span class=\"n\">target</span><span class=\"p\">:</span> <span class=\"nb\">int</span><span class=\"p\">)</span> <span class=\"o\">-></span> <span class=\"nb\">bool</span><span class=\"p\">:</span> <span class=\"n\">left</span> <span class=\"o\">=</span> <span class=\"mi\">0</span> <span class=\"n\">right</span> <span class=\"o\">=</span> <span class=\"nf\">len</span><span class=\"p\">(</span><span class=\"n\">matrix</span><span class=\"p\">)</span> <span class=\"o\">*</span> <span class=\"nf\">len</span><span class=\"p\">(</span><span class=\"n\">matrix</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">])</span> <span class=\"k\">return</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"nf\">inner</span><span class=\"p\">(</span><span class=\"n\">matrix</span><span class=\"p\">,</span> <span class=\"n\">target</span><span class=\"p\">,</span> <span class=\"n\">left</span><span class=\"p\">,</span> <span class=\"n\">right</span><span class=\"p\">)</span> <span class=\"k\">def</span> <span class=\"nf\">inner</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">matrix</span><span class=\"p\">,</span> <span class=\"n\">target</span><span class=\"p\">,</span> <span class=\"n\">left</span><span class=\"p\">,</span> <span class=\"n\">right</span><span class=\"p\">)</span> <span class=\"o\">-></span> <span class=\"nb\">bool</span><span class=\"p\">:</span> <span class=\"n\">middle</span> <span class=\"o\">=</span> <span class=\"p\">(</span><span class=\"n\">left</span><span class=\"o\">+</span><span class=\"n\">right</span><span class=\"p\">)</span><span class=\"o\">//</span><span class=\"mi\">2</span> <span class=\"n\">row</span> <span class=\"o\">=</span> <span class=\"n\">middle</span><span class=\"o\">//</span><span class=\"nf\">len</span><span class=\"p\">(</span><span class=\"n\">matrix</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">])</span> <span class=\"n\">col</span> <span class=\"o\">=</span> <span class=\"n\">middle</span> <span class=\"o\">-</span> <span class=\"p\">(</span><span class=\"n\">row</span><span class=\"o\">*</span><span class=\"nf\">len</span><span class=\"p\">(</span><span class=\"n\">matrix</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]))</span> <span class=\"k\">if</span> <span class=\"n\">matrix</span><span class=\"p\">[</span><span class=\"n\">row</span><span class=\"p\">][</span><span class=\"n\">col</span><span class=\"p\">]</span> <span class=\"o\">==</span> <span class=\"n\">target</span><span class=\"p\">:</span> <span class=\"k\">return</span> <span class=\"bp\">True</span> <span class=\"k\">if</span> <span class=\"n\">right</span> <span class=\"o\">-</span> <span class=\"mi\">1</span> <span class=\"o\">></span> <span class=\"n\">left</span><span class=\"p\">:</span> <span class=\"k\">if</span> <span class=\"n\">matrix</span><span class=\"p\">[</span><span class=\"n\">row</span><span class=\"p\">][</span><span class=\"n\">col</span><span class=\"p\">]</span> <span class=\"o\"><</span> <span class=\"n\">target</span><span class=\"p\">:</span> <span class=\"k\">return</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"nf\">inner</span><span class=\"p\">(</span><span class=\"n\">matrix</span><span class=\"p\">,</span> <span class=\"n\">target</span><span class=\"p\">,</span> <span class=\"n\">middle</span><span class=\"p\">,</span> <span class=\"n\">right</span><span class=\"p\">)</span> <span class=\"k\">else</span><span class=\"p\">:</span> <span class=\"k\">return</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"nf\">inner</span><span class=\"p\">(</span><span class=\"n\">matrix</span><span class=\"p\">,</span> <span class=\"n\">target</span><span class=\"p\">,</span> <span class=\"n\">left</span><span class=\"p\">,</span> <span class=\"n\">middle</span><span class=\"p\">)</span> <span class=\"k\">else</span><span class=\"p\">:</span> <span class=\"k\">return</span> <span class=\"bp\">False</span></code></pre></figure>", "date_published": "2024-04-28T00:42:00+00:00" }, { "id": "https://fewald.net/leetcode/2024/04/27/leetcode-word-search.html", "url": "https://fewald.net/leetcode/2024/04/27/leetcode-word-search.html", "title": "Leetcode: Word Search", "content_html": "<p>Given a matrix of characters, return <code class=\"language-plaintext highlighter-rouge\">True</code> if the <code class=\"language-plaintext highlighter-rouge\">word</code> is contained within the matrix by visiting horizontally and vertically adjacent fields.</p><!--more--><p>The solution involves <strong>backtracking</strong> which means that we have to mark the character on the board as visited. In this case it is relatively simple as valid characters contain only <code class=\"language-plaintext highlighter-rouge\">[A-Z]</code> so that we can take a <code class=\"language-plaintext highlighter-rouge\">-</code> to mark a visited field and know that this will not appear in the word that we’re looking for.</p><p>Furthermore it helps to see the problem as a <strong>tree</strong> instead of a matrix. Once we find the first initial position (which there could be multiple of), select it as a <code class=\"language-plaintext highlighter-rouge\">root</code> node and move from there left, right, up and down in any order. Once we found the first viable solution, we return <code class=\"language-plaintext highlighter-rouge\">True</code>.</p><figure class=\"highlight\"><pre><code class=\"language-python\" data-lang=\"python\"><span class=\"k\">class</span> <span class=\"nc\">Solution</span><span class=\"p\">:</span> <span class=\"k\">def</span> <span class=\"nf\">exist</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">board</span><span class=\"p\">:</span> <span class=\"n\">List</span><span class=\"p\">[</span><span class=\"n\">List</span><span class=\"p\">[</span><span class=\"nb\">str</span><span class=\"p\">]],</span> <span class=\"n\">word</span><span class=\"p\">:</span> <span class=\"nb\">str</span><span class=\"p\">)</span> <span class=\"o\">-></span> <span class=\"nb\">bool</span><span class=\"p\">:</span> <span class=\"k\">if</span> <span class=\"n\">word</span> <span class=\"o\">==</span> <span class=\"sh\">''</span><span class=\"p\">:</span> <span class=\"k\">return</span> <span class=\"bp\">True</span> <span class=\"k\">for</span> <span class=\"n\">i</span> <span class=\"ow\">in</span> <span class=\"nf\">range</span><span class=\"p\">(</span><span class=\"nf\">len</span><span class=\"p\">(</span><span class=\"n\">board</span><span class=\"p\">)):</span> <span class=\"k\">for</span> <span class=\"n\">j</span> <span class=\"ow\">in</span> <span class=\"nf\">range</span><span class=\"p\">(</span><span class=\"nf\">len</span><span class=\"p\">(</span><span class=\"n\">board</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">])):</span> <span class=\"k\">if</span> <span class=\"n\">board</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">][</span><span class=\"n\">j</span><span class=\"p\">]</span> <span class=\"o\">==</span> <span class=\"n\">word</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]:</span> <span class=\"k\">if</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"nf\">inner</span><span class=\"p\">(</span><span class=\"n\">board</span><span class=\"p\">,</span> <span class=\"n\">word</span><span class=\"p\">,</span> <span class=\"n\">i</span><span class=\"p\">,</span> <span class=\"n\">j</span><span class=\"p\">):</span> <span class=\"k\">return</span> <span class=\"bp\">True</span> <span class=\"k\">return</span> <span class=\"bp\">False</span> <span class=\"k\">def</span> <span class=\"nf\">inner</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">board</span><span class=\"p\">,</span> <span class=\"n\">word</span><span class=\"p\">,</span> <span class=\"n\">i</span><span class=\"p\">,</span> <span class=\"n\">j</span><span class=\"p\">)</span> <span class=\"o\">-></span> <span class=\"nb\">bool</span><span class=\"p\">:</span> <span class=\"k\">if</span> <span class=\"n\">word</span> <span class=\"o\">==</span> <span class=\"n\">board</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">][</span><span class=\"n\">j</span><span class=\"p\">]:</span> <span class=\"k\">return</span> <span class=\"bp\">True</span> <span class=\"n\">char</span> <span class=\"o\">=</span> <span class=\"n\">word</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span> <span class=\"n\">res</span> <span class=\"o\">=</span> <span class=\"p\">[]</span> <span class=\"k\">if</span> <span class=\"n\">board</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">][</span><span class=\"n\">j</span><span class=\"p\">]</span> <span class=\"o\">==</span> <span class=\"n\">char</span><span class=\"p\">:</span> <span class=\"c1\"># Replace character so we don't visit twice</span> <span class=\"n\">board</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">][</span><span class=\"n\">j</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"sh\">'</span><span class=\"s\">-</span><span class=\"sh\">'</span> <span class=\"k\">if</span> <span class=\"n\">j</span> <span class=\"o\">></span> <span class=\"mi\">0</span><span class=\"p\">:</span> <span class=\"n\">res</span><span class=\"p\">.</span><span class=\"nf\">append</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">.</span><span class=\"nf\">inner</span><span class=\"p\">(</span><span class=\"n\">board</span><span class=\"p\">,</span> <span class=\"n\">word</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">:],</span> <span class=\"n\">i</span><span class=\"p\">,</span> <span class=\"n\">j</span> <span class=\"o\">-</span> <span class=\"mi\">1</span><span class=\"p\">))</span> <span class=\"k\">if</span> <span class=\"n\">i</span> <span class=\"o\">></span> <span class=\"mi\">0</span><span class=\"p\">:</span> <span class=\"n\">res</span><span class=\"p\">.</span><span class=\"nf\">append</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">.</span><span class=\"nf\">inner</span><span class=\"p\">(</span><span class=\"n\">board</span><span class=\"p\">,</span> <span class=\"n\">word</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">:],</span> <span class=\"n\">i</span> <span class=\"o\">-</span> <span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"n\">j</span><span class=\"p\">))</span> <span class=\"k\">if</span> <span class=\"n\">i</span> <span class=\"o\"><</span> <span class=\"nf\">len</span><span class=\"p\">(</span><span class=\"n\">board</span><span class=\"p\">)</span> <span class=\"o\">-</span> <span class=\"mi\">1</span><span class=\"p\">:</span> <span class=\"n\">res</span><span class=\"p\">.</span><span class=\"nf\">append</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">.</span><span class=\"nf\">inner</span><span class=\"p\">(</span><span class=\"n\">board</span><span class=\"p\">,</span> <span class=\"n\">word</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">:],</span> <span class=\"n\">i</span> <span class=\"o\">+</span> <span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"n\">j</span><span class=\"p\">))</span> <span class=\"k\">if</span> <span class=\"n\">j</span> <span class=\"o\"><</span> <span class=\"nf\">len</span><span class=\"p\">(</span><span class=\"n\">board</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">])</span> <span class=\"o\">-</span> <span class=\"mi\">1</span><span class=\"p\">:</span> <span class=\"n\">res</span><span class=\"p\">.</span><span class=\"nf\">append</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">.</span><span class=\"nf\">inner</span><span class=\"p\">(</span><span class=\"n\">board</span><span class=\"p\">,</span> <span class=\"n\">word</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">:],</span> <span class=\"n\">i</span><span class=\"p\">,</span> <span class=\"n\">j</span> <span class=\"o\">+</span> <span class=\"mi\">1</span><span class=\"p\">))</span> <span class=\"c1\"># Backtrack</span> <span class=\"n\">board</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">][</span><span class=\"n\">j</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">char</span> <span class=\"k\">return</span> <span class=\"nf\">any</span><span class=\"p\">(</span><span class=\"n\">res</span><span class=\"p\">)</span></code></pre></figure>", "date_published": "2024-04-27T21:00:00+00:00" }, { "id": "https://fewald.net/leetcode/2024/04/26/leetcode-combinations.html", "url": "https://fewald.net/leetcode/2024/04/26/leetcode-combinations.html", "title": "Leetcode: Combinations", "content_html": "<p>Given two integers <code class=\"language-plaintext highlighter-rouge\">n</code> and <code class=\"language-plaintext highlighter-rouge\">k</code>, create all possible solutions with all numbers from <code class=\"language-plaintext highlighter-rouge\">[1,n]</code> of <code class=\"language-plaintext highlighter-rouge\">k</code> length.</p><!--more--><p>This can be solved via recursion. An added complication is to remove duplicate paths (<code class=\"language-plaintext highlighter-rouge\">[1,2] == [2,1]</code>). To avoid this, we can start the next number always from the number higher than the last highest number.</p><figure class=\"highlight\"><pre><code class=\"language-python\" data-lang=\"python\"><span class=\"k\">class</span> <span class=\"nc\">Solution</span><span class=\"p\">:</span> <span class=\"k\">def</span> <span class=\"nf\">combine</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">n</span><span class=\"p\">:</span> <span class=\"nb\">int</span><span class=\"p\">,</span> <span class=\"n\">k</span><span class=\"p\">:</span> <span class=\"nb\">int</span><span class=\"p\">)</span> <span class=\"o\">-></span> <span class=\"n\">List</span><span class=\"p\">[</span><span class=\"n\">List</span><span class=\"p\">[</span><span class=\"nb\">int</span><span class=\"p\">]]:</span> <span class=\"n\">paths</span> <span class=\"o\">=</span> <span class=\"p\">[]</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"nf\">inner</span><span class=\"p\">(</span><span class=\"n\">n</span><span class=\"p\">,</span> <span class=\"n\">k</span><span class=\"p\">,</span> <span class=\"p\">[],</span> <span class=\"n\">paths</span><span class=\"p\">)</span> <span class=\"k\">return</span> <span class=\"n\">paths</span> <span class=\"k\">def</span> <span class=\"nf\">inner</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">n</span><span class=\"p\">:</span> <span class=\"nb\">int</span><span class=\"p\">,</span> <span class=\"n\">k</span><span class=\"p\">:</span> <span class=\"nb\">int</span><span class=\"p\">,</span> <span class=\"n\">path</span><span class=\"p\">:</span> <span class=\"n\">List</span><span class=\"p\">[</span><span class=\"nb\">int</span><span class=\"p\">],</span> <span class=\"n\">paths</span><span class=\"p\">:</span> <span class=\"n\">List</span><span class=\"p\">[</span><span class=\"n\">List</span><span class=\"p\">[</span><span class=\"nb\">int</span><span class=\"p\">]]):</span> <span class=\"k\">if</span> <span class=\"n\">k</span> <span class=\"o\">==</span> <span class=\"mi\">0</span><span class=\"p\">:</span> <span class=\"n\">paths</span><span class=\"p\">.</span><span class=\"nf\">append</span><span class=\"p\">(</span><span class=\"n\">path</span><span class=\"p\">)</span> <span class=\"k\">return</span> <span class=\"k\">if</span> <span class=\"nf\">len</span><span class=\"p\">(</span><span class=\"n\">path</span><span class=\"p\">)</span> <span class=\"o\">></span> <span class=\"mi\">0</span><span class=\"p\">:</span> <span class=\"n\">lower</span> <span class=\"o\">=</span> <span class=\"n\">path</span><span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">]</span> <span class=\"o\">+</span> <span class=\"mi\">1</span> <span class=\"k\">else</span><span class=\"p\">:</span> <span class=\"n\">lower</span> <span class=\"o\">=</span> <span class=\"mi\">1</span> <span class=\"k\">for</span> <span class=\"n\">i</span> <span class=\"ow\">in</span> <span class=\"nf\">range</span><span class=\"p\">(</span><span class=\"n\">lower</span><span class=\"p\">,</span> <span class=\"n\">n</span> <span class=\"o\">+</span> <span class=\"mi\">1</span><span class=\"p\">):</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"nf\">inner</span><span class=\"p\">(</span><span class=\"n\">n</span><span class=\"p\">,</span> <span class=\"n\">k</span> <span class=\"o\">-</span> <span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"n\">path</span> <span class=\"o\">+</span> <span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">],</span> <span class=\"n\">paths</span><span class=\"p\">)</span></code></pre></figure>", "date_published": "2024-04-26T21:56:00+00:00" }, { "id": "https://fewald.net/leetcode/2024/04/26/leetcode-letter-combinations-of-a-phone-number.html", "url": "https://fewald.net/leetcode/2024/04/26/leetcode-letter-combinations-of-a-phone-number.html", "title": "Leetcode: Letter Combinations of a Phone Number", "content_html": "<!--more--><figure class=\"highlight\"><pre><code class=\"language-python\" data-lang=\"python\"><span class=\"n\">letters</span> <span class=\"o\">=</span> <span class=\"p\">{</span> <span class=\"sh\">'</span><span class=\"s\">2</span><span class=\"sh\">'</span><span class=\"p\">:</span> <span class=\"p\">[</span><span class=\"sh\">'</span><span class=\"s\">a</span><span class=\"sh\">'</span><span class=\"p\">,</span> <span class=\"sh\">'</span><span class=\"s\">b</span><span class=\"sh\">'</span><span class=\"p\">,</span> <span class=\"sh\">'</span><span class=\"s\">c</span><span class=\"sh\">'</span><span class=\"p\">],</span> <span class=\"sh\">'</span><span class=\"s\">3</span><span class=\"sh\">'</span><span class=\"p\">:</span> <span class=\"p\">[</span><span class=\"sh\">'</span><span class=\"s\">d</span><span class=\"sh\">'</span><span class=\"p\">,</span> <span class=\"sh\">'</span><span class=\"s\">e</span><span class=\"sh\">'</span><span class=\"p\">,</span> <span class=\"sh\">'</span><span class=\"s\">f</span><span class=\"sh\">'</span><span class=\"p\">],</span> <span class=\"sh\">'</span><span class=\"s\">4</span><span class=\"sh\">'</span><span class=\"p\">:</span> <span class=\"p\">[</span><span class=\"sh\">'</span><span class=\"s\">g</span><span class=\"sh\">'</span><span class=\"p\">,</span><span class=\"sh\">'</span><span class=\"s\">h</span><span class=\"sh\">'</span><span class=\"p\">,</span><span class=\"sh\">'</span><span class=\"s\">i</span><span class=\"sh\">'</span><span class=\"p\">],</span> <span class=\"sh\">'</span><span class=\"s\">5</span><span class=\"sh\">'</span><span class=\"p\">:</span> <span class=\"p\">[</span><span class=\"sh\">'</span><span class=\"s\">j</span><span class=\"sh\">'</span><span class=\"p\">,</span><span class=\"sh\">'</span><span class=\"s\">k</span><span class=\"sh\">'</span><span class=\"p\">,</span><span class=\"sh\">'</span><span class=\"s\">l</span><span class=\"sh\">'</span><span class=\"p\">],</span> <span class=\"sh\">'</span><span class=\"s\">6</span><span class=\"sh\">'</span><span class=\"p\">:</span> <span class=\"p\">[</span><span class=\"sh\">'</span><span class=\"s\">m</span><span class=\"sh\">'</span><span class=\"p\">,</span><span class=\"sh\">'</span><span class=\"s\">n</span><span class=\"sh\">'</span><span class=\"p\">,</span><span class=\"sh\">'</span><span class=\"s\">o</span><span class=\"sh\">'</span><span class=\"p\">],</span> <span class=\"sh\">'</span><span class=\"s\">7</span><span class=\"sh\">'</span><span class=\"p\">:</span> <span class=\"p\">[</span><span class=\"sh\">'</span><span class=\"s\">p</span><span class=\"sh\">'</span><span class=\"p\">,</span><span class=\"sh\">'</span><span class=\"s\">q</span><span class=\"sh\">'</span><span class=\"p\">,</span><span class=\"sh\">'</span><span class=\"s\">r</span><span class=\"sh\">'</span><span class=\"p\">,</span><span class=\"sh\">'</span><span class=\"s\">s</span><span class=\"sh\">'</span><span class=\"p\">],</span> <span class=\"sh\">'</span><span class=\"s\">8</span><span class=\"sh\">'</span><span class=\"p\">:</span> <span class=\"p\">[</span><span class=\"sh\">'</span><span class=\"s\">t</span><span class=\"sh\">'</span><span class=\"p\">,</span><span class=\"sh\">'</span><span class=\"s\">u</span><span class=\"sh\">'</span><span class=\"p\">,</span><span class=\"sh\">'</span><span class=\"s\">v</span><span class=\"sh\">'</span><span class=\"p\">],</span> <span class=\"sh\">'</span><span class=\"s\">9</span><span class=\"sh\">'</span><span class=\"p\">:</span> <span class=\"p\">[</span><span class=\"sh\">'</span><span class=\"s\">w</span><span class=\"sh\">'</span><span class=\"p\">,</span><span class=\"sh\">'</span><span class=\"s\">x</span><span class=\"sh\">'</span><span class=\"p\">,</span><span class=\"sh\">'</span><span class=\"s\">y</span><span class=\"sh\">'</span><span class=\"p\">,</span><span class=\"sh\">'</span><span class=\"s\">z</span><span class=\"sh\">'</span><span class=\"p\">]</span><span class=\"p\">}</span><span class=\"k\">class</span> <span class=\"nc\">Solution</span><span class=\"p\">:</span> <span class=\"k\">def</span> <span class=\"nf\">letterCombinations</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">digits</span><span class=\"p\">:</span> <span class=\"nb\">str</span><span class=\"p\">)</span> <span class=\"o\">-></span> <span class=\"n\">List</span><span class=\"p\">[</span><span class=\"nb\">str</span><span class=\"p\">]:</span> <span class=\"n\">combinations</span> <span class=\"o\">=</span> <span class=\"p\">[]</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"nf\">inner</span><span class=\"p\">(</span><span class=\"n\">digits</span><span class=\"p\">,</span> <span class=\"sh\">''</span><span class=\"p\">,</span> <span class=\"n\">combinations</span><span class=\"p\">)</span> <span class=\"k\">return</span> <span class=\"n\">combinations</span> <span class=\"k\">def</span> <span class=\"nf\">inner</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">digits</span><span class=\"p\">:</span> <span class=\"nb\">str</span><span class=\"p\">,</span> <span class=\"n\">path</span><span class=\"p\">:</span> <span class=\"nb\">str</span><span class=\"p\">,</span> <span class=\"n\">combos</span><span class=\"p\">:</span> <span class=\"nb\">list</span><span class=\"p\">[</span><span class=\"nb\">str</span><span class=\"p\">]):</span> <span class=\"k\">if</span> <span class=\"n\">digits</span> <span class=\"o\">==</span> <span class=\"sh\">''</span><span class=\"p\">:</span> <span class=\"k\">if</span> <span class=\"n\">path</span> <span class=\"o\">!=</span> <span class=\"sh\">''</span><span class=\"p\">:</span> <span class=\"n\">combos</span><span class=\"p\">.</span><span class=\"nf\">append</span><span class=\"p\">(</span><span class=\"n\">path</span><span class=\"p\">)</span> <span class=\"k\">return</span> <span class=\"n\">first</span> <span class=\"o\">=</span> <span class=\"n\">digits</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span> <span class=\"k\">for</span> <span class=\"n\">d</span> <span class=\"ow\">in</span> <span class=\"n\">letters</span><span class=\"p\">[</span><span class=\"n\">first</span><span class=\"p\">]:</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"nf\">inner</span><span class=\"p\">(</span><span class=\"n\">digits</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">:],</span> <span class=\"n\">path</span> <span class=\"o\">+</span> <span class=\"n\">d</span><span class=\"p\">,</span> <span class=\"n\">combos</span><span class=\"p\">)</span></code></pre></figure>", "date_published": "2024-04-26T21:29:00+00:00" }, { "id": "https://fewald.net/leetcode/2024/04/26/leetcode-trie-prefix-tree.html", "url": "https://fewald.net/leetcode/2024/04/26/leetcode-trie-prefix-tree.html", "title": "Leetcode: Trie Prefix Tree", "content_html": "<p>Create an implementation of a <strong>Trie</strong> structure.</p><!--more--><figure class=\"highlight\"><pre><code class=\"language-python\" data-lang=\"python\"><span class=\"k\">class</span> <span class=\"nc\">Node</span><span class=\"p\">:</span> <span class=\"k\">def</span> <span class=\"nf\">__init__</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">val</span><span class=\"p\">:</span> <span class=\"nb\">str</span><span class=\"p\">,</span> <span class=\"n\">children</span><span class=\"p\">:</span> <span class=\"nb\">dict</span><span class=\"p\">[</span><span class=\"nb\">str</span><span class=\"p\">,</span> <span class=\"sh\">'</span><span class=\"s\">Node</span><span class=\"sh\">'</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"p\">{})</span> <span class=\"o\">-></span> <span class=\"bp\">None</span><span class=\"p\">:</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"sh\">'</span><span class=\"s\">init node</span><span class=\"sh\">'</span><span class=\"p\">,</span> <span class=\"n\">val</span><span class=\"p\">)</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">val</span> <span class=\"o\">=</span> <span class=\"n\">val</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">children</span> <span class=\"o\">=</span> <span class=\"n\">children</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">is_word</span> <span class=\"o\">=</span> <span class=\"bp\">False</span><span class=\"k\">class</span> <span class=\"nc\">Trie</span><span class=\"p\">:</span> <span class=\"k\">def</span> <span class=\"nf\">__init__</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">):</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">root</span> <span class=\"o\">=</span> <span class=\"nc\">Node</span><span class=\"p\">(</span><span class=\"sh\">''</span><span class=\"p\">,</span> <span class=\"p\">{})</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">root</span><span class=\"p\">.</span><span class=\"n\">children</span><span class=\"p\">)</span> <span class=\"k\">def</span> <span class=\"nf\">insert</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">word</span><span class=\"p\">:</span> <span class=\"nb\">str</span><span class=\"p\">)</span> <span class=\"o\">-></span> <span class=\"bp\">None</span><span class=\"p\">:</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"sh\">'</span><span class=\"s\">inserting</span><span class=\"sh\">'</span><span class=\"p\">,</span> <span class=\"n\">word</span><span class=\"p\">)</span> <span class=\"n\">root</span> <span class=\"o\">=</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">root</span> <span class=\"k\">while</span> <span class=\"n\">word</span> <span class=\"o\">!=</span> <span class=\"sh\">''</span><span class=\"p\">:</span> <span class=\"n\">char</span> <span class=\"o\">=</span> <span class=\"n\">word</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span> <span class=\"n\">word</span> <span class=\"o\">=</span> <span class=\"n\">word</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">:]</span> <span class=\"k\">if</span> <span class=\"n\">char</span> <span class=\"ow\">not</span> <span class=\"ow\">in</span> <span class=\"n\">root</span><span class=\"p\">.</span><span class=\"n\">children</span><span class=\"p\">:</span> <span class=\"n\">root</span><span class=\"p\">.</span><span class=\"n\">children</span><span class=\"p\">[</span><span class=\"n\">char</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"nc\">Node</span><span class=\"p\">(</span><span class=\"n\">char</span><span class=\"p\">,</span> <span class=\"p\">{})</span> <span class=\"n\">root</span> <span class=\"o\">=</span> <span class=\"n\">root</span><span class=\"p\">.</span><span class=\"n\">children</span><span class=\"p\">[</span><span class=\"n\">char</span><span class=\"p\">]</span> <span class=\"n\">root</span><span class=\"p\">.</span><span class=\"n\">is_word</span> <span class=\"o\">=</span> <span class=\"bp\">True</span> <span class=\"k\">def</span> <span class=\"nf\">search</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">word</span><span class=\"p\">:</span> <span class=\"nb\">str</span><span class=\"p\">)</span> <span class=\"o\">-></span> <span class=\"nb\">bool</span><span class=\"p\">:</span> <span class=\"n\">root</span> <span class=\"o\">=</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">root</span> <span class=\"k\">while</span> <span class=\"n\">word</span> <span class=\"o\">!=</span> <span class=\"sh\">''</span><span class=\"p\">:</span> <span class=\"n\">char</span> <span class=\"o\">=</span> <span class=\"n\">word</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span> <span class=\"n\">word</span> <span class=\"o\">=</span> <span class=\"n\">word</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">:]</span> <span class=\"k\">if</span> <span class=\"n\">char</span> <span class=\"ow\">not</span> <span class=\"ow\">in</span> <span class=\"n\">root</span><span class=\"p\">.</span><span class=\"n\">children</span><span class=\"p\">:</span> <span class=\"k\">return</span> <span class=\"bp\">False</span> <span class=\"n\">root</span> <span class=\"o\">=</span> <span class=\"n\">root</span><span class=\"p\">.</span><span class=\"n\">children</span><span class=\"p\">[</span><span class=\"n\">char</span><span class=\"p\">]</span> <span class=\"k\">return</span> <span class=\"n\">root</span><span class=\"p\">.</span><span class=\"n\">is_word</span> <span class=\"k\">def</span> <span class=\"nf\">startsWith</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">prefix</span><span class=\"p\">:</span> <span class=\"nb\">str</span><span class=\"p\">)</span> <span class=\"o\">-></span> <span class=\"nb\">bool</span><span class=\"p\">:</span> <span class=\"n\">root</span> <span class=\"o\">=</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">root</span> <span class=\"k\">while</span> <span class=\"n\">prefix</span> <span class=\"o\">!=</span> <span class=\"sh\">''</span><span class=\"p\">:</span> <span class=\"n\">char</span> <span class=\"o\">=</span> <span class=\"n\">prefix</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span> <span class=\"n\">prefix</span> <span class=\"o\">=</span> <span class=\"n\">prefix</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">:]</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"n\">char</span><span class=\"p\">,</span> <span class=\"n\">root</span><span class=\"p\">.</span><span class=\"n\">children</span><span class=\"p\">)</span> <span class=\"k\">if</span> <span class=\"n\">char</span> <span class=\"ow\">not</span> <span class=\"ow\">in</span> <span class=\"n\">root</span><span class=\"p\">.</span><span class=\"n\">children</span><span class=\"p\">:</span> <span class=\"k\">return</span> <span class=\"bp\">False</span> <span class=\"n\">root</span> <span class=\"o\">=</span> <span class=\"n\">root</span><span class=\"p\">.</span><span class=\"n\">children</span><span class=\"p\">[</span><span class=\"n\">char</span><span class=\"p\">]</span> <span class=\"k\">return</span> <span class=\"bp\">True</span></code></pre></figure><p>The same tree, but with allowing placeholders in the form of <code class=\"language-plaintext highlighter-rouge\">.</code> can be implemented as follows:</p><figure class=\"highlight\"><pre><code class=\"language-python\" data-lang=\"python\"><span class=\"k\">class</span> <span class=\"nc\">Node</span><span class=\"p\">:</span> <span class=\"k\">def</span> <span class=\"nf\">__init__</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">val</span><span class=\"p\">:</span> <span class=\"nb\">str</span><span class=\"p\">,</span> <span class=\"n\">children</span><span class=\"p\">:</span> <span class=\"nb\">dict</span><span class=\"p\">[</span><span class=\"nb\">str</span><span class=\"p\">,</span> <span class=\"sh\">'</span><span class=\"s\">Node</span><span class=\"sh\">'</span><span class=\"p\">]):</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">val</span> <span class=\"o\">=</span> <span class=\"n\">val</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">children</span> <span class=\"o\">=</span> <span class=\"n\">children</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">is_word</span> <span class=\"o\">=</span> <span class=\"bp\">False</span><span class=\"k\">class</span> <span class=\"nc\">WordDictionary</span><span class=\"p\">:</span> <span class=\"k\">def</span> <span class=\"nf\">__init__</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">):</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">root</span> <span class=\"o\">=</span> <span class=\"nc\">Node</span><span class=\"p\">(</span><span class=\"sh\">''</span><span class=\"p\">,</span> <span class=\"p\">{})</span> <span class=\"k\">def</span> <span class=\"nf\">addWord</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">word</span><span class=\"p\">:</span> <span class=\"nb\">str</span><span class=\"p\">)</span> <span class=\"o\">-></span> <span class=\"bp\">None</span><span class=\"p\">:</span> <span class=\"n\">root</span> <span class=\"o\">=</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">root</span> <span class=\"k\">while</span> <span class=\"n\">word</span> <span class=\"o\">!=</span> <span class=\"sh\">''</span><span class=\"p\">:</span> <span class=\"n\">char</span> <span class=\"o\">=</span> <span class=\"n\">word</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span> <span class=\"n\">word</span> <span class=\"o\">=</span> <span class=\"n\">word</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">:]</span> <span class=\"k\">if</span> <span class=\"n\">char</span> <span class=\"ow\">not</span> <span class=\"ow\">in</span> <span class=\"n\">root</span><span class=\"p\">.</span><span class=\"n\">children</span><span class=\"p\">:</span> <span class=\"n\">root</span><span class=\"p\">.</span><span class=\"n\">children</span><span class=\"p\">[</span><span class=\"n\">char</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"nc\">Node</span><span class=\"p\">(</span><span class=\"n\">char</span><span class=\"p\">,</span> <span class=\"p\">{})</span> <span class=\"n\">root</span> <span class=\"o\">=</span> <span class=\"n\">root</span><span class=\"p\">.</span><span class=\"n\">children</span><span class=\"p\">[</span><span class=\"n\">char</span><span class=\"p\">]</span> <span class=\"n\">root</span><span class=\"p\">.</span><span class=\"n\">is_word</span> <span class=\"o\">=</span> <span class=\"bp\">True</span> <span class=\"k\">def</span> <span class=\"nf\">search</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">word</span><span class=\"p\">:</span> <span class=\"nb\">str</span><span class=\"p\">)</span> <span class=\"o\">-></span> <span class=\"nb\">bool</span><span class=\"p\">:</span> <span class=\"n\">root</span> <span class=\"o\">=</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">root</span> <span class=\"k\">return</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"nf\">inner</span><span class=\"p\">(</span><span class=\"n\">root</span><span class=\"p\">,</span> <span class=\"n\">word</span><span class=\"p\">)</span> <span class=\"k\">def</span> <span class=\"nf\">inner</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">root</span><span class=\"p\">:</span> <span class=\"n\">Node</span><span class=\"p\">,</span> <span class=\"n\">word</span><span class=\"p\">:</span> <span class=\"nb\">str</span><span class=\"p\">)</span> <span class=\"o\">-></span> <span class=\"nb\">bool</span><span class=\"p\">:</span> <span class=\"k\">if</span> <span class=\"n\">root</span> <span class=\"ow\">is</span> <span class=\"bp\">None</span><span class=\"p\">:</span> <span class=\"k\">return</span> <span class=\"bp\">False</span> <span class=\"k\">if</span> <span class=\"n\">word</span> <span class=\"o\">==</span> <span class=\"sh\">''</span><span class=\"p\">:</span> <span class=\"k\">return</span> <span class=\"n\">root</span><span class=\"p\">.</span><span class=\"n\">is_word</span> <span class=\"n\">char</span> <span class=\"o\">=</span> <span class=\"n\">word</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span> <span class=\"k\">if</span> <span class=\"n\">char</span> <span class=\"o\">==</span> <span class=\"sh\">'</span><span class=\"s\">.</span><span class=\"sh\">'</span><span class=\"p\">:</span> <span class=\"n\">res</span> <span class=\"o\">=</span> <span class=\"nf\">any</span><span class=\"p\">([</span><span class=\"n\">self</span><span class=\"p\">.</span><span class=\"nf\">inner</span><span class=\"p\">(</span><span class=\"n\">child</span><span class=\"p\">,</span> <span class=\"n\">word</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">:])</span> <span class=\"k\">for</span> <span class=\"n\">child</span> <span class=\"ow\">in</span> <span class=\"n\">root</span><span class=\"p\">.</span><span class=\"n\">children</span><span class=\"p\">.</span><span class=\"nf\">values</span><span class=\"p\">()])</span> <span class=\"k\">return</span> <span class=\"n\">res</span> <span class=\"k\">else</span><span class=\"p\">:</span> <span class=\"k\">if</span> <span class=\"n\">char</span> <span class=\"ow\">in</span> <span class=\"n\">root</span><span class=\"p\">.</span><span class=\"n\">children</span><span class=\"p\">:</span> <span class=\"k\">return</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"nf\">inner</span><span class=\"p\">(</span><span class=\"n\">root</span><span class=\"p\">.</span><span class=\"n\">children</span><span class=\"p\">[</span><span class=\"n\">char</span><span class=\"p\">],</span> <span class=\"n\">word</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">:])</span> <span class=\"k\">else</span><span class=\"p\">:</span> <span class=\"k\">return</span> <span class=\"bp\">False</span></code></pre></figure>", "date_published": "2024-04-26T03:18:00+00:00" }, { "id": "https://fewald.net/leetcode/2024/04/25/leetcode-contains-duplicate-ii.html", "url": "https://fewald.net/leetcode/2024/04/25/leetcode-contains-duplicate-ii.html", "title": "Leetcode: Contains Duplicate II", "content_html": "<p>Given an array <code class=\"language-plaintext highlighter-rouge\">nums</code> and a number <code class=\"language-plaintext highlighter-rouge\">k</code>, return true if there are two distinct indices <code class=\"language-plaintext highlighter-rouge\">i</code> and <code class=\"language-plaintext highlighter-rouge\">j</code> in the array such that <code class=\"language-plaintext highlighter-rouge\">nums[i] == nums[j]</code> and <code class=\"language-plaintext highlighter-rouge\">abs(i - j) <= k</code>.</p><!--more--><p>The solution involves two pointers that are at most <code class=\"language-plaintext highlighter-rouge\">k</code> items apart. The items are stored in a set and if there’s a duplication, <code class=\"language-plaintext highlighter-rouge\">True</code> will be returned. Otherwise <code class=\"language-plaintext highlighter-rouge\">False</code>.</p><figure class=\"highlight\"><pre><code class=\"language-python\" data-lang=\"python\"><span class=\"k\">class</span> <span class=\"nc\">Solution</span><span class=\"p\">:</span> <span class=\"k\">def</span> <span class=\"nf\">containsNearbyDuplicate</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">nums</span><span class=\"p\">:</span> <span class=\"n\">List</span><span class=\"p\">[</span><span class=\"nb\">int</span><span class=\"p\">],</span> <span class=\"n\">k</span><span class=\"p\">:</span> <span class=\"nb\">int</span><span class=\"p\">)</span> <span class=\"o\">-></span> <span class=\"nb\">bool</span><span class=\"p\">:</span> <span class=\"n\">curr_nums</span> <span class=\"o\">=</span> <span class=\"nf\">set</span><span class=\"p\">()</span> <span class=\"n\">p1</span> <span class=\"o\">=</span> <span class=\"mi\">0</span> <span class=\"n\">p2</span> <span class=\"o\">=</span> <span class=\"mi\">0</span> <span class=\"k\">while</span> <span class=\"n\">p1</span> <span class=\"o\"><</span> <span class=\"nf\">len</span><span class=\"p\">(</span><span class=\"n\">nums</span><span class=\"p\">):</span> <span class=\"k\">if</span> <span class=\"n\">nums</span><span class=\"p\">[</span><span class=\"n\">p1</span><span class=\"p\">]</span> <span class=\"ow\">in</span> <span class=\"n\">curr_nums</span><span class=\"p\">:</span> <span class=\"k\">return</span> <span class=\"bp\">True</span> <span class=\"n\">curr_nums</span><span class=\"p\">.</span><span class=\"nf\">add</span><span class=\"p\">(</span><span class=\"n\">nums</span><span class=\"p\">[</span><span class=\"n\">p1</span><span class=\"p\">])</span> <span class=\"k\">if</span> <span class=\"n\">p1</span> <span class=\"o\">-</span> <span class=\"n\">p2</span> <span class=\"o\">>=</span> <span class=\"n\">k</span><span class=\"p\">:</span> <span class=\"n\">curr_nums</span><span class=\"p\">.</span><span class=\"nf\">remove</span><span class=\"p\">(</span><span class=\"n\">nums</span><span class=\"p\">[</span><span class=\"n\">p2</span><span class=\"p\">])</span> <span class=\"n\">p2</span> <span class=\"o\">+=</span> <span class=\"mi\">1</span> <span class=\"n\">p1</span> <span class=\"o\">+=</span> <span class=\"mi\">1</span> <span class=\"k\">return</span> <span class=\"bp\">False</span></code></pre></figure><p>Runtime is <code class=\"language-plaintext highlighter-rouge\">O(n)</code> and space complexity is <code class=\"language-plaintext highlighter-rouge\">O(k)</code>.</p>", "date_published": "2024-04-25T00:15:00+00:00" }, { "id": "https://fewald.net/leetcode/2024/04/24/leetcode-count-complete-tree-nodes.html", "url": "https://fewald.net/leetcode/2024/04/24/leetcode-count-complete-tree-nodes.html", "title": "Leetcode: Count Complete Tree Nodes", "content_html": "<p>Given a perfect binary tree, count the number of nodes with an algorithm that has less than <code class=\"language-plaintext highlighter-rouge\">O(n)</code> time complexity.</p><!--more--><figure class=\"highlight\"><pre><code class=\"language-python\" data-lang=\"python\"><span class=\"c1\"># Definition for a binary tree node.# class TreeNode:# def __init__(self, val=0, left=None, right=None):# self.val = val# self.left = left# self.right = right</span><span class=\"k\">class</span> <span class=\"nc\">Solution</span><span class=\"p\">:</span> <span class=\"k\">def</span> <span class=\"nf\">countNodes</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">root</span><span class=\"p\">:</span> <span class=\"n\">Optional</span><span class=\"p\">[</span><span class=\"n\">TreeNode</span><span class=\"p\">])</span> <span class=\"o\">-></span> <span class=\"nb\">int</span><span class=\"p\">:</span> <span class=\"k\">if</span> <span class=\"n\">root</span> <span class=\"ow\">is</span> <span class=\"bp\">None</span><span class=\"p\">:</span> <span class=\"k\">return</span> <span class=\"mi\">0</span> <span class=\"n\">l</span> <span class=\"o\">=</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"nf\">count_left</span><span class=\"p\">(</span><span class=\"n\">root</span><span class=\"p\">)</span> <span class=\"n\">r</span> <span class=\"o\">=</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"nf\">count_right</span><span class=\"p\">(</span><span class=\"n\">root</span><span class=\"p\">)</span> <span class=\"k\">if</span> <span class=\"n\">l</span> <span class=\"o\">==</span> <span class=\"n\">r</span><span class=\"p\">:</span> <span class=\"k\">return</span> <span class=\"nf\">pow</span><span class=\"p\">(</span><span class=\"mi\">2</span><span class=\"p\">,</span> <span class=\"n\">l</span><span class=\"p\">)</span> <span class=\"o\">-</span> <span class=\"mi\">1</span> <span class=\"k\">else</span><span class=\"p\">:</span> <span class=\"k\">return</span> <span class=\"mi\">1</span> <span class=\"o\">+</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"nf\">countNodes</span><span class=\"p\">(</span><span class=\"n\">root</span><span class=\"p\">.</span><span class=\"n\">left</span><span class=\"p\">)</span> <span class=\"o\">+</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"nf\">countNodes</span><span class=\"p\">(</span><span class=\"n\">root</span><span class=\"p\">.</span><span class=\"n\">right</span><span class=\"p\">)</span> <span class=\"k\">def</span> <span class=\"nf\">count_left</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">root</span><span class=\"p\">:</span> <span class=\"n\">Optional</span><span class=\"p\">[</span><span class=\"n\">TreeNode</span><span class=\"p\">])</span> <span class=\"o\">-></span> <span class=\"nb\">int</span><span class=\"p\">:</span> <span class=\"k\">if</span> <span class=\"n\">root</span> <span class=\"ow\">is</span> <span class=\"bp\">None</span><span class=\"p\">:</span> <span class=\"k\">return</span> <span class=\"mi\">0</span> <span class=\"k\">return</span> <span class=\"mi\">1</span> <span class=\"o\">+</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"nf\">count_left</span><span class=\"p\">(</span><span class=\"n\">root</span><span class=\"p\">.</span><span class=\"n\">left</span><span class=\"p\">)</span> <span class=\"k\">def</span> <span class=\"nf\">count_right</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">root</span><span class=\"p\">:</span> <span class=\"n\">Optional</span><span class=\"p\">[</span><span class=\"n\">TreeNode</span><span class=\"p\">])</span> <span class=\"o\">-></span> <span class=\"nb\">int</span><span class=\"p\">:</span> <span class=\"k\">if</span> <span class=\"n\">root</span> <span class=\"ow\">is</span> <span class=\"bp\">None</span><span class=\"p\">:</span> <span class=\"k\">return</span> <span class=\"mi\">0</span> <span class=\"k\">return</span> <span class=\"mi\">1</span> <span class=\"o\">+</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"nf\">count_right</span><span class=\"p\">(</span><span class=\"n\">root</span><span class=\"p\">.</span><span class=\"n\">right</span><span class=\"p\">)</span></code></pre></figure>", "date_published": "2024-04-24T20:20:00+00:00" }, { "id": "https://fewald.net/leetcode/2024/04/23/leetcode-binary-search-tree-iterator.html", "url": "https://fewald.net/leetcode/2024/04/23/leetcode-binary-search-tree-iterator.html", "title": "Leetcode: Binary Search Tree Iterator", "content_html": "<p>Given a binary tree, write an iterator that performs <strong>in-order</strong> iteration and returns <code class=\"language-plaintext highlighter-rouge\">next</code> as well as <code class=\"language-plaintext highlighter-rouge\">hasNext</code>. It is guaranteed that <code class=\"language-plaintext highlighter-rouge\">next</code> is never called on an empty tree.</p><!--more--><p>The naive approach looks as follows. Note that the space complexity here is <code class=\"language-plaintext highlighter-rouge\">O(n)</code>.</p><figure class=\"highlight\"><pre><code class=\"language-python\" data-lang=\"python\"><span class=\"c1\"># Definition for a binary tree node.# class TreeNode:# def __init__(self, val=0, left=None, right=None):# self.val = val# self.left = left# self.right = right</span><span class=\"k\">class</span> <span class=\"nc\">BSTIterator</span><span class=\"p\">:</span> <span class=\"k\">def</span> <span class=\"nf\">__init__</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">root</span><span class=\"p\">:</span> <span class=\"n\">Optional</span><span class=\"p\">[</span><span class=\"n\">TreeNode</span><span class=\"p\">]):</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">_list</span> <span class=\"o\">=</span> <span class=\"p\">[]</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"nf\">_buildTree</span><span class=\"p\">(</span><span class=\"n\">root</span><span class=\"p\">)</span> <span class=\"k\">def</span> <span class=\"nf\">_buildTree</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">root</span><span class=\"p\">:</span> <span class=\"n\">Optional</span><span class=\"p\">[</span><span class=\"n\">TreeNode</span><span class=\"p\">]):</span> <span class=\"k\">if</span> <span class=\"n\">root</span> <span class=\"ow\">is</span> <span class=\"bp\">None</span><span class=\"p\">:</span> <span class=\"k\">return</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"nf\">_buildTree</span><span class=\"p\">(</span><span class=\"n\">root</span><span class=\"p\">.</span><span class=\"n\">left</span><span class=\"p\">)</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">_list</span><span class=\"p\">.</span><span class=\"nf\">append</span><span class=\"p\">(</span><span class=\"n\">root</span><span class=\"p\">)</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"nf\">_buildTree</span><span class=\"p\">(</span><span class=\"n\">root</span><span class=\"p\">.</span><span class=\"n\">right</span><span class=\"p\">)</span> <span class=\"k\">def</span> <span class=\"nf\">next</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">)</span> <span class=\"o\">-></span> <span class=\"nb\">int</span><span class=\"p\">:</span> <span class=\"k\">return</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">_list</span><span class=\"p\">.</span><span class=\"nf\">pop</span><span class=\"p\">(</span><span class=\"mi\">0</span><span class=\"p\">).</span><span class=\"n\">val</span> <span class=\"k\">def</span> <span class=\"nf\">hasNext</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">)</span> <span class=\"o\">-></span> <span class=\"nb\">bool</span><span class=\"p\">:</span> <span class=\"k\">return</span> <span class=\"nf\">len</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">_list</span><span class=\"p\">)</span> <span class=\"o\">></span> <span class=\"mi\">0</span></code></pre></figure><p>To further improve this, we can store the current nodes in a stack so that we only need to pop from the stack with time complexity <code class=\"language-plaintext highlighter-rouge\">O(1)</code>. The approach here is that we only iterate over the tree until we find the first leaf node, which happens on average after the height <code class=\"language-plaintext highlighter-rouge\">h</code> of the tree. When popping the first element, we look for the next leaf node which can be found by going to the <code class=\"language-plaintext highlighter-rouge\">right</code> and subsequently to the <code class=\"language-plaintext highlighter-rouge\">left</code>. Repeat this process until the list is empty.</p><figure class=\"highlight\"><pre><code class=\"language-python\" data-lang=\"python\"><span class=\"c1\"># Definition for a binary tree node.# class TreeNode:# def __init__(self, val=0, left=None, right=None):# self.val = val# self.left = left# self.right = right</span><span class=\"k\">class</span> <span class=\"nc\">BSTIterator</span><span class=\"p\">:</span> <span class=\"k\">def</span> <span class=\"nf\">__init__</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">root</span><span class=\"p\">:</span> <span class=\"n\">Optional</span><span class=\"p\">[</span><span class=\"n\">TreeNode</span><span class=\"p\">]):</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">_list</span> <span class=\"o\">=</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"nf\">_buildTree</span><span class=\"p\">(</span><span class=\"n\">root</span><span class=\"p\">)</span> <span class=\"k\">def</span> <span class=\"nf\">_buildTree</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">root</span><span class=\"p\">:</span> <span class=\"n\">Optional</span><span class=\"p\">[</span><span class=\"n\">TreeNode</span><span class=\"p\">])</span> <span class=\"o\">-></span> <span class=\"n\">List</span><span class=\"p\">[</span><span class=\"n\">TreeNode</span><span class=\"p\">]:</span> <span class=\"k\">if</span> <span class=\"n\">root</span> <span class=\"ow\">is</span> <span class=\"bp\">None</span><span class=\"p\">:</span> <span class=\"k\">return</span> <span class=\"p\">[]</span> <span class=\"k\">return</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"nf\">_buildTree</span><span class=\"p\">(</span><span class=\"n\">root</span><span class=\"p\">.</span><span class=\"n\">left</span><span class=\"p\">)</span> <span class=\"o\">+</span> <span class=\"p\">[</span><span class=\"n\">root</span><span class=\"p\">]</span> <span class=\"k\">def</span> <span class=\"nf\">next</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">)</span> <span class=\"o\">-></span> <span class=\"nb\">int</span><span class=\"p\">:</span> <span class=\"n\">node</span> <span class=\"o\">=</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">_list</span><span class=\"p\">.</span><span class=\"nf\">pop</span><span class=\"p\">(</span><span class=\"mi\">0</span><span class=\"p\">)</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">_list</span> <span class=\"o\">=</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"nf\">_buildTree</span><span class=\"p\">(</span><span class=\"n\">node</span><span class=\"p\">.</span><span class=\"n\">right</span><span class=\"p\">)</span> <span class=\"o\">+</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">_list</span> <span class=\"k\">return</span> <span class=\"n\">node</span><span class=\"p\">.</span><span class=\"n\">val</span> <span class=\"k\">def</span> <span class=\"nf\">hasNext</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">)</span> <span class=\"o\">-></span> <span class=\"nb\">bool</span><span class=\"p\">:</span> <span class=\"k\">return</span> <span class=\"nf\">len</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">_list</span><span class=\"p\">)</span> <span class=\"o\">></span> <span class=\"mi\">0</span></code></pre></figure>", "date_published": "2024-04-23T04:14:00+00:00" }, { "id": "https://fewald.net/leetcode/2024/04/23/leetcode-sum-root-to-leaf-numbers.html", "url": "https://fewald.net/leetcode/2024/04/23/leetcode-sum-root-to-leaf-numbers.html", "title": "Leetcode: Sum Root to Leaf Numbers", "content_html": "<!--more--><p>Multiple things to note:</p><ul> <li>Make sure to visit only <code class=\"language-plaintext highlighter-rouge\">left</code> and <code class=\"language-plaintext highlighter-rouge\">right</code> if they exist respectively</li> <li>Sum up as <code class=\"language-plaintext highlighter-rouge\">str</code>, then finally convert to integer</li> <li>Consider nodes which have only a <code class=\"language-plaintext highlighter-rouge\">left</code> or only a <code class=\"language-plaintext highlighter-rouge\">right</code> child node, they’re not leaf nodes.</li></ul><figure class=\"highlight\"><pre><code class=\"language-python\" data-lang=\"python\"><span class=\"c1\"># Definition for a binary tree node.# class TreeNode:# def __init__(self, val=0, left=None, right=None):# self.val = val# self.left = left# self.right = right</span><span class=\"k\">class</span> <span class=\"nc\">Solution</span><span class=\"p\">:</span> <span class=\"k\">def</span> <span class=\"nf\">sumNumbers</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">root</span><span class=\"p\">:</span> <span class=\"n\">Optional</span><span class=\"p\">[</span><span class=\"n\">TreeNode</span><span class=\"p\">])</span> <span class=\"o\">-></span> <span class=\"nb\">int</span><span class=\"p\">:</span> <span class=\"k\">return</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"nf\">inner</span><span class=\"p\">(</span><span class=\"n\">root</span><span class=\"p\">,</span> <span class=\"sh\">''</span><span class=\"p\">)</span> <span class=\"k\">def</span> <span class=\"nf\">inner</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">root</span><span class=\"p\">:</span> <span class=\"n\">Optional</span><span class=\"p\">[</span><span class=\"n\">TreeNode</span><span class=\"p\">],</span> <span class=\"n\">path</span><span class=\"p\">:</span> <span class=\"nb\">str</span><span class=\"p\">)</span> <span class=\"o\">-></span> <span class=\"nb\">int</span><span class=\"p\">:</span> <span class=\"n\">v</span> <span class=\"o\">=</span> <span class=\"nf\">str</span><span class=\"p\">(</span><span class=\"n\">root</span><span class=\"p\">.</span><span class=\"n\">val</span><span class=\"p\">)</span> <span class=\"k\">if</span> <span class=\"n\">root</span><span class=\"p\">.</span><span class=\"n\">left</span> <span class=\"ow\">is</span> <span class=\"bp\">None</span> <span class=\"ow\">and</span> <span class=\"n\">root</span><span class=\"p\">.</span><span class=\"n\">right</span> <span class=\"ow\">is</span> <span class=\"bp\">None</span><span class=\"p\">:</span> <span class=\"k\">return</span> <span class=\"nf\">int</span><span class=\"p\">(</span><span class=\"n\">path</span> <span class=\"o\">+</span> <span class=\"n\">v</span><span class=\"p\">)</span> <span class=\"n\">s</span> <span class=\"o\">=</span> <span class=\"mi\">0</span> <span class=\"k\">if</span> <span class=\"n\">root</span><span class=\"p\">.</span><span class=\"n\">left</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"bp\">None</span><span class=\"p\">:</span> <span class=\"n\">s</span> <span class=\"o\">+=</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"nf\">inner</span><span class=\"p\">(</span><span class=\"n\">root</span><span class=\"p\">.</span><span class=\"n\">left</span><span class=\"p\">,</span> <span class=\"n\">path</span> <span class=\"o\">+</span> <span class=\"n\">v</span><span class=\"p\">)</span> <span class=\"k\">if</span> <span class=\"n\">root</span><span class=\"p\">.</span><span class=\"n\">right</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"bp\">None</span><span class=\"p\">:</span> <span class=\"n\">s</span> <span class=\"o\">+=</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"nf\">inner</span><span class=\"p\">(</span><span class=\"n\">root</span><span class=\"p\">.</span><span class=\"n\">right</span><span class=\"p\">,</span> <span class=\"n\">path</span> <span class=\"o\">+</span> <span class=\"n\">v</span><span class=\"p\">)</span> <span class=\"k\">return</span> <span class=\"n\">s</span></code></pre></figure>", "date_published": "2024-04-23T00:56:00+00:00" }, { "id": "https://fewald.net/leetcode/2024/04/22/leetcode-flatten-binary-tree-to-linked-list.html", "url": "https://fewald.net/leetcode/2024/04/22/leetcode-flatten-binary-tree-to-linked-list.html", "title": "Leetcode: Flatten Binary Tree to Linked List", "content_html": "<p>Given a binary tree, perform pre-order traversal and flatten it to a linked list such that <code class=\"language-plaintext highlighter-rouge\">right</code> for each node is the next node.</p><!--more--><p>In the naive solution <code class=\"language-plaintext highlighter-rouge\">O(n)</code> space complexity, we just perform a pre-order traversal (current node, left, right) through the tree and add every node as we visit them. Then in a final pass, set the <code class=\"language-plaintext highlighter-rouge\">left</code> to <code class=\"language-plaintext highlighter-rouge\">None</code> for each node and <code class=\"language-plaintext highlighter-rouge\">right</code> to the next node in the list - except for the last node where <code class=\"language-plaintext highlighter-rouge\">right</code> stays <code class=\"language-plaintext highlighter-rouge\">None</code>.</p><figure class=\"highlight\"><pre><code class=\"language-python\" data-lang=\"python\"><span class=\"c1\"># Definition for a binary tree node.# class TreeNode:# def __init__(self, val=0, left=None, right=None):# self.val = val# self.left = left# self.right = right</span><span class=\"k\">class</span> <span class=\"nc\">Solution</span><span class=\"p\">:</span> <span class=\"k\">def</span> <span class=\"nf\">flatten</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">root</span><span class=\"p\">:</span> <span class=\"n\">Optional</span><span class=\"p\">[</span><span class=\"n\">TreeNode</span><span class=\"p\">])</span> <span class=\"o\">-></span> <span class=\"bp\">None</span><span class=\"p\">:</span> <span class=\"sh\">\"\"\"</span><span class=\"s\"> Do not return anything, modify root in-place instead. </span><span class=\"sh\">\"\"\"</span> <span class=\"k\">if</span> <span class=\"n\">root</span> <span class=\"ow\">is</span> <span class=\"bp\">None</span><span class=\"p\">:</span> <span class=\"k\">return</span> <span class=\"n\">visited</span> <span class=\"o\">=</span> <span class=\"p\">[]</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"nf\">inner</span><span class=\"p\">(</span><span class=\"n\">root</span><span class=\"p\">,</span> <span class=\"n\">visited</span><span class=\"p\">)</span> <span class=\"k\">for</span> <span class=\"n\">idx</span> <span class=\"ow\">in</span> <span class=\"nf\">range</span><span class=\"p\">(</span><span class=\"nf\">len</span><span class=\"p\">(</span><span class=\"n\">visited</span><span class=\"p\">)):</span> <span class=\"n\">visited</span><span class=\"p\">[</span><span class=\"n\">idx</span><span class=\"p\">].</span><span class=\"n\">left</span> <span class=\"o\">=</span> <span class=\"bp\">None</span> <span class=\"k\">if</span> <span class=\"n\">idx</span> <span class=\"o\"><</span> <span class=\"nf\">len</span><span class=\"p\">(</span><span class=\"n\">visited</span><span class=\"p\">)</span> <span class=\"o\">-</span> <span class=\"mi\">1</span><span class=\"p\">:</span> <span class=\"n\">visited</span><span class=\"p\">[</span><span class=\"n\">idx</span><span class=\"p\">].</span><span class=\"n\">right</span> <span class=\"o\">=</span> <span class=\"n\">visited</span><span class=\"p\">[</span><span class=\"n\">idx</span> <span class=\"o\">+</span> <span class=\"mi\">1</span><span class=\"p\">]</span> <span class=\"k\">def</span> <span class=\"nf\">inner</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">root</span><span class=\"p\">:</span> <span class=\"n\">Optional</span><span class=\"p\">[</span><span class=\"n\">TreeNode</span><span class=\"p\">],</span> <span class=\"n\">visited</span><span class=\"p\">:</span> <span class=\"n\">List</span><span class=\"p\">[</span><span class=\"n\">TreeNode</span><span class=\"p\">])</span> <span class=\"o\">-></span> <span class=\"bp\">None</span><span class=\"p\">:</span> <span class=\"k\">if</span> <span class=\"n\">root</span> <span class=\"ow\">is</span> <span class=\"bp\">None</span><span class=\"p\">:</span> <span class=\"k\">return</span> <span class=\"n\">visited</span><span class=\"p\">.</span><span class=\"nf\">append</span><span class=\"p\">(</span><span class=\"n\">root</span><span class=\"p\">)</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"nf\">inner</span><span class=\"p\">(</span><span class=\"n\">root</span><span class=\"p\">.</span><span class=\"n\">left</span><span class=\"p\">,</span> <span class=\"n\">visited</span><span class=\"p\">)</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"nf\">inner</span><span class=\"p\">(</span><span class=\"n\">root</span><span class=\"p\">.</span><span class=\"n\">right</span><span class=\"p\">,</span> <span class=\"n\">visited</span><span class=\"p\">)</span></code></pre></figure><p>This can be simplified using Morris traversal:</p><figure class=\"highlight\"><pre><code class=\"language-python\" data-lang=\"python\"><span class=\"c1\"># Definition for a binary tree node.# class TreeNode:# def __init__(self, val=0, left=None, right=None):# self.val = val# self.left = left# self.right = right</span><span class=\"k\">class</span> <span class=\"nc\">Solution</span><span class=\"p\">:</span> <span class=\"k\">def</span> <span class=\"nf\">flatten</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">root</span><span class=\"p\">:</span> <span class=\"n\">Optional</span><span class=\"p\">[</span><span class=\"n\">TreeNode</span><span class=\"p\">])</span> <span class=\"o\">-></span> <span class=\"bp\">None</span><span class=\"p\">:</span> <span class=\"sh\">\"\"\"</span><span class=\"s\"> Do not return anything, modify root in-place instead. </span><span class=\"sh\">\"\"\"</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"nf\">inner</span><span class=\"p\">(</span><span class=\"n\">root</span><span class=\"p\">)</span> <span class=\"k\">def</span> <span class=\"nf\">inner</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">root</span><span class=\"p\">:</span> <span class=\"n\">Optional</span><span class=\"p\">[</span><span class=\"n\">TreeNode</span><span class=\"p\">])</span> <span class=\"o\">-></span> <span class=\"bp\">None</span><span class=\"p\">:</span> <span class=\"n\">curr</span> <span class=\"o\">=</span> <span class=\"n\">root</span> <span class=\"k\">while</span> <span class=\"n\">curr</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"bp\">None</span><span class=\"p\">:</span> <span class=\"k\">if</span> <span class=\"n\">curr</span><span class=\"p\">.</span><span class=\"n\">left</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"bp\">None</span><span class=\"p\">:</span> <span class=\"n\">prev</span> <span class=\"o\">=</span> <span class=\"n\">curr</span><span class=\"p\">.</span><span class=\"n\">left</span> <span class=\"k\">while</span> <span class=\"n\">prev</span><span class=\"p\">.</span><span class=\"n\">right</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"bp\">None</span><span class=\"p\">:</span> <span class=\"n\">prev</span> <span class=\"o\">=</span> <span class=\"n\">prev</span><span class=\"p\">.</span><span class=\"n\">right</span> <span class=\"n\">prev</span><span class=\"p\">.</span><span class=\"n\">right</span> <span class=\"o\">=</span> <span class=\"n\">curr</span><span class=\"p\">.</span><span class=\"n\">right</span> <span class=\"n\">curr</span><span class=\"p\">.</span><span class=\"n\">right</span> <span class=\"o\">=</span> <span class=\"n\">curr</span><span class=\"p\">.</span><span class=\"n\">left</span> <span class=\"n\">curr</span><span class=\"p\">.</span><span class=\"n\">left</span> <span class=\"o\">=</span> <span class=\"bp\">None</span> <span class=\"n\">curr</span> <span class=\"o\">=</span> <span class=\"n\">curr</span><span class=\"p\">.</span><span class=\"n\">right</span> </code></pre></figure>", "date_published": "2024-04-22T22:51:00+00:00" }, { "id": "https://fewald.net/leetcode/2024/04/22/leetcode-populating-next-right-pointers-in-each-node-ii.html", "url": "https://fewald.net/leetcode/2024/04/22/leetcode-populating-next-right-pointers-in-each-node-ii.html", "title": "Leetcode: Populating Next Right Pointers in each Node II", "content_html": "<p>Given a tree, compute <code class=\"language-plaintext highlighter-rouge\">next</code> for each node such that each node points to its nextneighbor to the right.</p><!--more--><p>The idea is to have two alternate lists, <code class=\"language-plaintext highlighter-rouge\">curr_level</code> and <code class=\"language-plaintext highlighter-rouge\">next_level</code>. While travseringthe current level, all sub nodes (<code class=\"language-plaintext highlighter-rouge\">left</code> and <code class=\"language-plaintext highlighter-rouge\">right</code>) are written to <code class=\"language-plaintext highlighter-rouge\">next_level</code>. Afterall nodes are popped from the <code class=\"language-plaintext highlighter-rouge\">curr_level</code>, set <code class=\"language-plaintext highlighter-rouge\">curr_level = next_level</code> and begin theprocess anew. This keeps track of the individual levels. Initially, set the <code class=\"language-plaintext highlighter-rouge\">curr_level</code>to <code class=\"language-plaintext highlighter-rouge\">[root]</code>.</p><figure class=\"highlight\"><pre><code class=\"language-python\" data-lang=\"python\"><span class=\"sh\">\"\"\"</span><span class=\"s\"># Definition for a Node.class Node: def __init__(self, val: int = 0, left: </span><span class=\"sh\">'</span><span class=\"s\">Node</span><span class=\"sh\">'</span><span class=\"s\"> = None, right: </span><span class=\"sh\">'</span><span class=\"s\">Node</span><span class=\"sh\">'</span><span class=\"s\"> = None, next: </span><span class=\"sh\">'</span><span class=\"s\">Node</span><span class=\"sh\">'</span><span class=\"s\"> = None): self.val = val self.left = left self.right = right self.next = next</span><span class=\"sh\">\"\"\"</span><span class=\"k\">class</span> <span class=\"nc\">Solution</span><span class=\"p\">:</span> <span class=\"k\">def</span> <span class=\"nf\">connect</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">root</span><span class=\"p\">:</span> <span class=\"sh\">'</span><span class=\"s\">Node</span><span class=\"sh\">'</span><span class=\"p\">)</span> <span class=\"o\">-></span> <span class=\"sh\">'</span><span class=\"s\">Node</span><span class=\"sh\">'</span><span class=\"p\">:</span> <span class=\"k\">if</span> <span class=\"n\">root</span> <span class=\"ow\">is</span> <span class=\"bp\">None</span><span class=\"p\">:</span> <span class=\"k\">return</span> <span class=\"n\">root</span> <span class=\"n\">curr_level</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"n\">root</span><span class=\"p\">]</span> <span class=\"k\">while</span> <span class=\"nf\">len</span><span class=\"p\">(</span><span class=\"n\">curr_level</span><span class=\"p\">)</span> <span class=\"o\">></span> <span class=\"mi\">0</span><span class=\"p\">:</span> <span class=\"n\">next_level</span> <span class=\"o\">=</span> <span class=\"p\">[]</span> <span class=\"k\">while</span> <span class=\"nf\">len</span><span class=\"p\">(</span><span class=\"n\">curr_level</span><span class=\"p\">)</span> <span class=\"o\">></span> <span class=\"mi\">0</span><span class=\"p\">:</span> <span class=\"n\">node</span> <span class=\"o\">=</span> <span class=\"n\">curr_level</span><span class=\"p\">.</span><span class=\"nf\">pop</span><span class=\"p\">(</span><span class=\"mi\">0</span><span class=\"p\">)</span> <span class=\"k\">if</span> <span class=\"nf\">len</span><span class=\"p\">(</span><span class=\"n\">curr_level</span><span class=\"p\">)</span> <span class=\"o\">></span> <span class=\"mi\">0</span><span class=\"p\">:</span> <span class=\"n\">node</span><span class=\"p\">.</span><span class=\"nb\">next</span> <span class=\"o\">=</span> <span class=\"n\">curr_level</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span> <span class=\"k\">if</span> <span class=\"n\">node</span><span class=\"p\">.</span><span class=\"n\">left</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"bp\">None</span><span class=\"p\">:</span> <span class=\"n\">next_level</span><span class=\"p\">.</span><span class=\"nf\">append</span><span class=\"p\">(</span><span class=\"n\">node</span><span class=\"p\">.</span><span class=\"n\">left</span><span class=\"p\">)</span> <span class=\"k\">if</span> <span class=\"n\">node</span><span class=\"p\">.</span><span class=\"n\">right</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"bp\">None</span><span class=\"p\">:</span> <span class=\"n\">next_level</span><span class=\"p\">.</span><span class=\"nf\">append</span><span class=\"p\">(</span><span class=\"n\">node</span><span class=\"p\">.</span><span class=\"n\">right</span><span class=\"p\">)</span> <span class=\"n\">curr_level</span> <span class=\"o\">=</span> <span class=\"n\">next_level</span> <span class=\"k\">return</span> <span class=\"n\">root</span></code></pre></figure>", "date_published": "2024-04-22T22:00:00+00:00" }, { "id": "https://fewald.net/leetcode/2024/04/22/leetcode-construct-binary-tree-from-inorder-and-postorder-traversal.html", "url": "https://fewald.net/leetcode/2024/04/22/leetcode-construct-binary-tree-from-inorder-and-postorder-traversal.html", "title": "Leetcode: Construct Binary Tree from Inorder and Postorder Traversal", "content_html": "<p>Construct a binary tree from <strong>in-order</strong> and <strong>post-order</strong> arrays.</p><!--more--><p>The requirement is to understand in-order and post-order traversal. In-Order visits all nodes to the left, then the current node and then all nodes to the right. Post-order visits all nodes to the left of the current node, all nodes to the right of the current node and finally the node itself.</p><p>This means, that the root node can immediately identified as the last element in the <code class=\"language-plaintext highlighter-rouge\">postorder</code> array. From there we can split the <code class=\"language-plaintext highlighter-rouge\">inorder</code> array by getting the index of the element and immediately know that all nodes to the left of the pivot element belong to the left of the item and vice versa. By simply counting the number of elements, we where we need to split the <code class=\"language-plaintext highlighter-rouge\">postorder</code> array.</p><p>Finally, apply this knowledge in a recursive method (<code class=\"language-plaintext highlighter-rouge\">inner</code>) and stop once <code class=\"language-plaintext highlighter-rouge\">postorder</code> (or <code class=\"language-plaintext highlighter-rouge\">inorder</code>) is empty. Then we know we are below a leaf node.</p><figure class=\"highlight\"><pre><code class=\"language-python\" data-lang=\"python\"><span class=\"c1\"># Definition for a binary tree node.# class TreeNode:# def __init__(self, val=0, left=None, right=None):# self.val = val# self.left = left# self.right = right</span><span class=\"k\">class</span> <span class=\"nc\">Solution</span><span class=\"p\">:</span> <span class=\"k\">def</span> <span class=\"nf\">buildTree</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">inorder</span><span class=\"p\">:</span> <span class=\"n\">List</span><span class=\"p\">[</span><span class=\"nb\">int</span><span class=\"p\">],</span> <span class=\"n\">postorder</span><span class=\"p\">:</span> <span class=\"n\">List</span><span class=\"p\">[</span><span class=\"nb\">int</span><span class=\"p\">])</span> <span class=\"o\">-></span> <span class=\"n\">Optional</span><span class=\"p\">[</span><span class=\"n\">TreeNode</span><span class=\"p\">]:</span> <span class=\"k\">return</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"nf\">inner</span><span class=\"p\">(</span><span class=\"n\">inorder</span><span class=\"p\">,</span> <span class=\"n\">postorder</span><span class=\"p\">)</span> <span class=\"k\">def</span> <span class=\"nf\">inner</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">inorder</span><span class=\"p\">:</span> <span class=\"n\">List</span><span class=\"p\">[</span><span class=\"nb\">int</span><span class=\"p\">],</span> <span class=\"n\">postorder</span><span class=\"p\">:</span> <span class=\"n\">List</span><span class=\"p\">[</span><span class=\"nb\">int</span><span class=\"p\">])</span> <span class=\"o\">-></span> <span class=\"n\">Optional</span><span class=\"p\">[</span><span class=\"n\">TreeNode</span><span class=\"p\">]:</span> <span class=\"k\">if</span> <span class=\"nf\">len</span><span class=\"p\">(</span><span class=\"n\">postorder</span><span class=\"p\">)</span> <span class=\"o\">==</span> <span class=\"mi\">0</span><span class=\"p\">:</span> <span class=\"k\">return</span> <span class=\"bp\">None</span> <span class=\"n\">val</span> <span class=\"o\">=</span> <span class=\"n\">postorder</span><span class=\"p\">.</span><span class=\"nf\">pop</span><span class=\"p\">()</span> <span class=\"n\">root</span> <span class=\"o\">=</span> <span class=\"nc\">TreeNode</span><span class=\"p\">(</span><span class=\"n\">val</span><span class=\"o\">=</span><span class=\"n\">val</span><span class=\"p\">)</span> <span class=\"n\">idx</span> <span class=\"o\">=</span> <span class=\"n\">inorder</span><span class=\"p\">.</span><span class=\"nf\">index</span><span class=\"p\">(</span><span class=\"n\">val</span><span class=\"p\">)</span> <span class=\"n\">root</span><span class=\"p\">.</span><span class=\"n\">left</span> <span class=\"o\">=</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"nf\">inner</span><span class=\"p\">(</span><span class=\"n\">inorder</span><span class=\"p\">[:</span><span class=\"n\">idx</span><span class=\"p\">],</span> <span class=\"n\">postorder</span><span class=\"p\">[:</span><span class=\"n\">idx</span><span class=\"p\">])</span> <span class=\"n\">root</span><span class=\"p\">.</span><span class=\"n\">right</span> <span class=\"o\">=</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"nf\">inner</span><span class=\"p\">(</span><span class=\"n\">inorder</span><span class=\"p\">[</span><span class=\"n\">idx</span><span class=\"o\">+</span><span class=\"mi\">1</span><span class=\"p\">:],</span> <span class=\"n\">postorder</span><span class=\"p\">[</span><span class=\"n\">idx</span><span class=\"p\">:])</span> <span class=\"k\">return</span> <span class=\"n\">root</span></code></pre></figure>", "date_published": "2024-04-22T04:01:00+00:00" }, { "id": "https://fewald.net/leetcode/2024/04/21/leetcode-path-sum.html", "url": "https://fewald.net/leetcode/2024/04/21/leetcode-path-sum.html", "title": "Leetcode: Path Sum", "content_html": "<p>Given a binary tree, check if there’s a path such that a <code class=\"language-plaintext highlighter-rouge\">targetSum</code> can be reached. A target sum is the sum of values of all visited nodes along the path.</p><!--more--><p>This again can be solved well via recursion. The “trick” is to adapt the <code class=\"language-plaintext highlighter-rouge\">targetSum</code> and check at each level. If the tree is empty or if we reach beyond a leaf node, the <code class=\"language-plaintext highlighter-rouge\">targetSum</code> cannot be reached.</p><figure class=\"highlight\"><pre><code class=\"language-python\" data-lang=\"python\"><span class=\"c1\"># Definition for a binary tree node.# class TreeNode:# def __init__(self, val=0, left=None, right=None):# self.val = val# self.left = left# self.right = right</span><span class=\"k\">class</span> <span class=\"nc\">Solution</span><span class=\"p\">:</span> <span class=\"k\">def</span> <span class=\"nf\">hasPathSum</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">root</span><span class=\"p\">:</span> <span class=\"n\">Optional</span><span class=\"p\">[</span><span class=\"n\">TreeNode</span><span class=\"p\">],</span> <span class=\"n\">targetSum</span><span class=\"p\">:</span> <span class=\"nb\">int</span><span class=\"p\">)</span> <span class=\"o\">-></span> <span class=\"nb\">bool</span><span class=\"p\">:</span> <span class=\"k\">if</span> <span class=\"n\">root</span> <span class=\"ow\">is</span> <span class=\"bp\">None</span><span class=\"p\">:</span> <span class=\"k\">return</span> <span class=\"bp\">False</span> <span class=\"n\">newVal</span> <span class=\"o\">=</span> <span class=\"n\">targetSum</span> <span class=\"o\">-</span> <span class=\"n\">root</span><span class=\"p\">.</span><span class=\"n\">val</span> <span class=\"k\">if</span> <span class=\"n\">root</span><span class=\"p\">.</span><span class=\"n\">left</span> <span class=\"ow\">is</span> <span class=\"bp\">None</span> <span class=\"ow\">and</span> <span class=\"n\">root</span><span class=\"p\">.</span><span class=\"n\">right</span> <span class=\"ow\">is</span> <span class=\"bp\">None</span> <span class=\"ow\">and</span> <span class=\"n\">newVal</span> <span class=\"o\">==</span> <span class=\"mi\">0</span><span class=\"p\">:</span> <span class=\"k\">return</span> <span class=\"bp\">True</span> <span class=\"k\">return</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"nf\">hasPathSum</span><span class=\"p\">(</span><span class=\"n\">root</span><span class=\"p\">.</span><span class=\"n\">left</span><span class=\"p\">,</span> <span class=\"n\">newVal</span><span class=\"p\">)</span> <span class=\"ow\">or</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"nf\">hasPathSum</span><span class=\"p\">(</span><span class=\"n\">root</span><span class=\"p\">.</span><span class=\"n\">right</span><span class=\"p\">,</span> <span class=\"n\">newVal</span><span class=\"p\">)</span></code></pre></figure>", "date_published": "2024-04-21T22:45:00+00:00" }, { "id": "https://fewald.net/leetcode/2024/04/21/leetcode-maximum-depth-of-binary-tree.html", "url": "https://fewald.net/leetcode/2024/04/21/leetcode-maximum-depth-of-binary-tree.html", "title": "Leetcode: Maximum Depth of Binary Tree", "content_html": "<p>Calculate the maximum depth of a binary tree.</p><!--more--><p>This is best/easiest solved with recursion.</p><figure class=\"highlight\"><pre><code class=\"language-python\" data-lang=\"python\"><span class=\"c1\"># Definition for a binary tree node.# class TreeNode:# def __init__(self, val=0, left=None, right=None):# self.val = val# self.left = left# self.right = right</span><span class=\"k\">class</span> <span class=\"nc\">Solution</span><span class=\"p\">:</span> <span class=\"k\">def</span> <span class=\"nf\">maxDepth</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">root</span><span class=\"p\">:</span> <span class=\"n\">Optional</span><span class=\"p\">[</span><span class=\"n\">TreeNode</span><span class=\"p\">])</span> <span class=\"o\">-></span> <span class=\"nb\">int</span><span class=\"p\">:</span> <span class=\"k\">if</span> <span class=\"n\">root</span> <span class=\"ow\">is</span> <span class=\"bp\">None</span><span class=\"p\">:</span> <span class=\"k\">return</span> <span class=\"mi\">0</span> <span class=\"k\">return</span> <span class=\"mi\">1</span> <span class=\"o\">+</span> <span class=\"nf\">max</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">.</span><span class=\"nf\">maxDepth</span><span class=\"p\">(</span><span class=\"n\">root</span><span class=\"p\">.</span><span class=\"n\">left</span><span class=\"p\">),</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"nf\">maxDepth</span><span class=\"p\">(</span><span class=\"n\">root</span><span class=\"p\">.</span><span class=\"n\">right</span><span class=\"p\">))</span></code></pre></figure>", "date_published": "2024-04-21T22:28:00+00:00" }, { "id": "https://fewald.net/leetcode/2024/04/21/leetcode-same-tree.html", "url": "https://fewald.net/leetcode/2024/04/21/leetcode-same-tree.html", "title": "Leetcode: Same Tree", "content_html": "<p>Given two binary trees, <code class=\"language-plaintext highlighter-rouge\">p</code> and <code class=\"language-plaintext highlighter-rouge\">q</code>, return <code class=\"language-plaintext highlighter-rouge\">True</code> if they are the same, that is, if all values are the same and <code class=\"language-plaintext highlighter-rouge\">False</code> otherwise.<!--more--></p><p>The easiest solution I could come up with is to use recursion. A few edge cases need to be handled.Left or right can be <code class=\"language-plaintext highlighter-rouge\">null</code> at any time. In this case it’s clear that the tree cannot be the same. If both nodes are null, the trees are the same.</p><figure class=\"highlight\"><pre><code class=\"language-python\" data-lang=\"python\"><span class=\"c1\"># Definition for a binary tree node.# class TreeNode:# def __init__(self, val=0, left=None, right=None):# self.val = val# self.left = left# self.right = right</span><span class=\"k\">class</span> <span class=\"nc\">Solution</span><span class=\"p\">:</span> <span class=\"k\">def</span> <span class=\"nf\">isSameTree</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">p</span><span class=\"p\">:</span> <span class=\"n\">Optional</span><span class=\"p\">[</span><span class=\"n\">TreeNode</span><span class=\"p\">],</span> <span class=\"n\">q</span><span class=\"p\">:</span> <span class=\"n\">Optional</span><span class=\"p\">[</span><span class=\"n\">TreeNode</span><span class=\"p\">])</span> <span class=\"o\">-></span> <span class=\"nb\">bool</span><span class=\"p\">:</span> <span class=\"k\">if</span> <span class=\"n\">p</span> <span class=\"ow\">is</span> <span class=\"bp\">None</span> <span class=\"ow\">and</span> <span class=\"n\">q</span> <span class=\"ow\">is</span> <span class=\"bp\">None</span><span class=\"p\">:</span> <span class=\"k\">return</span> <span class=\"bp\">True</span> <span class=\"k\">if</span> <span class=\"n\">p</span> <span class=\"ow\">is</span> <span class=\"bp\">None</span> <span class=\"ow\">and</span> <span class=\"n\">q</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"bp\">None</span><span class=\"p\">:</span> <span class=\"k\">return</span> <span class=\"bp\">False</span> <span class=\"k\">if</span> <span class=\"n\">q</span> <span class=\"ow\">is</span> <span class=\"bp\">None</span> <span class=\"ow\">and</span> <span class=\"n\">p</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"bp\">None</span><span class=\"p\">:</span> <span class=\"k\">return</span> <span class=\"bp\">False</span> <span class=\"k\">return</span> <span class=\"n\">p</span><span class=\"p\">.</span><span class=\"n\">val</span> <span class=\"o\">==</span> <span class=\"n\">q</span><span class=\"p\">.</span><span class=\"n\">val</span> <span class=\"ow\">and</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"nf\">isSameTree</span><span class=\"p\">(</span><span class=\"n\">p</span><span class=\"p\">.</span><span class=\"n\">left</span><span class=\"p\">,</span> <span class=\"n\">q</span><span class=\"p\">.</span><span class=\"n\">left</span><span class=\"p\">)</span> <span class=\"ow\">and</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"nf\">isSameTree</span><span class=\"p\">(</span><span class=\"n\">p</span><span class=\"p\">.</span><span class=\"n\">right</span><span class=\"p\">,</span> <span class=\"n\">q</span><span class=\"p\">.</span><span class=\"n\">right</span><span class=\"p\">)</span></code></pre></figure><blockquote> <p>Beats 87.04% of users with Python3. Beats 87.04% of users with Python3</p></blockquote>", "date_published": "2024-04-21T21:18:00+00:00" }, { "id": "https://fewald.net/leetcode/2024/04/21/leetcode-partition-list.html", "url": "https://fewald.net/leetcode/2024/04/21/leetcode-partition-list.html", "title": "Leetcode: Partition List", "content_html": "<p>Partition a linked list given a value <code class=\"language-plaintext highlighter-rouge\">x</code> as a pivot element so that all nodes that aresmaller than <code class=\"language-plaintext highlighter-rouge\">x</code> come before all nodes that are greater or equal than <code class=\"language-plaintext highlighter-rouge\">x</code>. The originalorder of the elements should be retained.</p><!--more--><p>This can be solved by creating two sub lists with empty nodes, called <code class=\"language-plaintext highlighter-rouge\">left</code> and <code class=\"language-plaintext highlighter-rouge\">right</code>and then concatenating those lists in the last step. The easiest way to achieve this isto create two new empty nodes and then, return <code class=\"language-plaintext highlighter-rouge\">left.next</code>. This avoids having to keeptrack of <code class=\"language-plaintext highlighter-rouge\">None</code> inside the loop and simpliefies the code.</p><figure class=\"highlight\"><pre><code class=\"language-python\" data-lang=\"python\"><span class=\"c1\"># Definition for singly-linked list.# class ListNode:# def __init__(self, val=0, next=None):# self.val = val# self.next = next</span><span class=\"k\">class</span> <span class=\"nc\">Solution</span><span class=\"p\">:</span> <span class=\"k\">def</span> <span class=\"nf\">partition</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">head</span><span class=\"p\">:</span> <span class=\"n\">Optional</span><span class=\"p\">[</span><span class=\"n\">ListNode</span><span class=\"p\">],</span> <span class=\"n\">x</span><span class=\"p\">:</span> <span class=\"nb\">int</span><span class=\"p\">)</span> <span class=\"o\">-></span> <span class=\"n\">Optional</span><span class=\"p\">[</span><span class=\"n\">ListNode</span><span class=\"p\">]:</span> <span class=\"k\">if</span> <span class=\"n\">head</span> <span class=\"ow\">is</span> <span class=\"bp\">None</span> <span class=\"ow\">or</span> <span class=\"n\">head</span><span class=\"p\">.</span><span class=\"nb\">next</span> <span class=\"ow\">is</span> <span class=\"bp\">None</span><span class=\"p\">:</span> <span class=\"k\">return</span> <span class=\"n\">head</span> <span class=\"n\">left_head</span> <span class=\"o\">=</span> <span class=\"nc\">ListNode</span><span class=\"p\">()</span> <span class=\"n\">right_head</span> <span class=\"o\">=</span> <span class=\"nc\">ListNode</span><span class=\"p\">()</span> <span class=\"n\">left_curr</span> <span class=\"o\">=</span> <span class=\"n\">left_head</span> <span class=\"n\">right_curr</span> <span class=\"o\">=</span> <span class=\"n\">right_head</span> <span class=\"n\">curr</span> <span class=\"o\">=</span> <span class=\"n\">head</span> <span class=\"k\">while</span> <span class=\"n\">curr</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"bp\">None</span><span class=\"p\">:</span> <span class=\"k\">if</span> <span class=\"n\">curr</span><span class=\"p\">.</span><span class=\"n\">val</span> <span class=\"o\"><</span> <span class=\"n\">x</span><span class=\"p\">:</span> <span class=\"n\">left_curr</span><span class=\"p\">.</span><span class=\"nb\">next</span> <span class=\"o\">=</span> <span class=\"n\">curr</span> <span class=\"n\">left_curr</span> <span class=\"o\">=</span> <span class=\"n\">left_curr</span><span class=\"p\">.</span><span class=\"nb\">next</span> <span class=\"k\">else</span><span class=\"p\">:</span> <span class=\"n\">right_curr</span><span class=\"p\">.</span><span class=\"nb\">next</span> <span class=\"o\">=</span> <span class=\"n\">curr</span> <span class=\"n\">right_curr</span> <span class=\"o\">=</span> <span class=\"n\">right_curr</span><span class=\"p\">.</span><span class=\"nb\">next</span> <span class=\"n\">curr</span> <span class=\"o\">=</span> <span class=\"n\">curr</span><span class=\"p\">.</span><span class=\"nb\">next</span> <span class=\"n\">left_curr</span><span class=\"p\">.</span><span class=\"nb\">next</span> <span class=\"o\">=</span> <span class=\"n\">right_head</span><span class=\"p\">.</span><span class=\"nb\">next</span> <span class=\"n\">right_curr</span><span class=\"p\">.</span><span class=\"nb\">next</span> <span class=\"o\">=</span> <span class=\"bp\">None</span> <span class=\"k\">return</span> <span class=\"n\">left_head</span><span class=\"p\">.</span><span class=\"nb\">next</span></code></pre></figure>", "date_published": "2024-04-21T19:23:00+00:00" }, { "id": "https://fewald.net/leetcode/2024/04/21/leetcode-rotate-list.html", "url": "https://fewald.net/leetcode/2024/04/21/leetcode-rotate-list.html", "title": "Leetcode: Rotate List", "content_html": "<p>Rotate a singly-linked list at <code class=\"language-plaintext highlighter-rouge\">k</code> elements from their end.</p><!--more--><p>The two tricks here are to use a slower running pointer and detect if <code class=\"language-plaintext highlighter-rouge\">i < k</code> when the end is reached.If that is the case, <code class=\"language-plaintext highlighter-rouge\">k</code> is greater than the list and we can take the modulo, then iterating once more over the list. This is more efficient than to iterate <code class=\"language-plaintext highlighter-rouge\">n</code> times over the large list in a circle.</p><figure class=\"highlight\"><pre><code class=\"language-python\" data-lang=\"python\"><span class=\"c1\"># Definition for singly-linked list.# class ListNode:# def __init__(self, val=0, next=None):# self.val = val# self.next = next</span><span class=\"k\">class</span> <span class=\"nc\">Solution</span><span class=\"p\">:</span> <span class=\"k\">def</span> <span class=\"nf\">rotateRight</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">head</span><span class=\"p\">:</span> <span class=\"n\">Optional</span><span class=\"p\">[</span><span class=\"n\">ListNode</span><span class=\"p\">],</span> <span class=\"n\">k</span><span class=\"p\">:</span> <span class=\"nb\">int</span><span class=\"p\">)</span> <span class=\"o\">-></span> <span class=\"n\">Optional</span><span class=\"p\">[</span><span class=\"n\">ListNode</span><span class=\"p\">]:</span> <span class=\"k\">if</span> <span class=\"n\">head</span> <span class=\"ow\">is</span> <span class=\"bp\">None</span> <span class=\"ow\">or</span> <span class=\"n\">head</span><span class=\"p\">.</span><span class=\"nb\">next</span> <span class=\"ow\">is</span> <span class=\"bp\">None</span><span class=\"p\">:</span> <span class=\"k\">return</span> <span class=\"n\">head</span> <span class=\"c1\"># find k-th element</span> <span class=\"c1\"># If list smaller than k, take modulo</span> <span class=\"c1\"># Else take k</span> <span class=\"c1\"># Find length of list</span> <span class=\"n\">curr</span> <span class=\"o\">=</span> <span class=\"n\">head</span> <span class=\"n\">new_head</span> <span class=\"o\">=</span> <span class=\"n\">head</span> <span class=\"n\">i</span> <span class=\"o\">=</span> <span class=\"mi\">0</span> <span class=\"k\">while</span> <span class=\"n\">curr</span><span class=\"p\">.</span><span class=\"nb\">next</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"bp\">None</span><span class=\"p\">:</span> <span class=\"n\">curr</span> <span class=\"o\">=</span> <span class=\"n\">curr</span><span class=\"p\">.</span><span class=\"nb\">next</span> <span class=\"k\">if</span> <span class=\"n\">i</span> <span class=\"o\">>=</span> <span class=\"n\">k</span><span class=\"p\">:</span> <span class=\"n\">new_head</span> <span class=\"o\">=</span> <span class=\"n\">new_head</span><span class=\"p\">.</span><span class=\"nb\">next</span> <span class=\"n\">i</span> <span class=\"o\">+=</span> <span class=\"mi\">1</span> <span class=\"k\">if</span> <span class=\"n\">i</span> <span class=\"o\">>=</span> <span class=\"n\">k</span><span class=\"p\">:</span> <span class=\"c1\"># k is less than length of list</span> <span class=\"k\">pass</span> <span class=\"k\">else</span><span class=\"p\">:</span> <span class=\"c1\"># k is greater than length of list</span> <span class=\"n\">new_k</span> <span class=\"o\">=</span> <span class=\"n\">k</span> <span class=\"o\">%</span> <span class=\"p\">(</span><span class=\"n\">i</span> <span class=\"o\">+</span> <span class=\"mi\">1</span><span class=\"p\">)</span> <span class=\"n\">curr</span> <span class=\"o\">=</span> <span class=\"n\">head</span> <span class=\"n\">new_head</span> <span class=\"o\">=</span> <span class=\"n\">head</span> <span class=\"n\">i</span> <span class=\"o\">=</span> <span class=\"mi\">0</span> <span class=\"k\">while</span> <span class=\"n\">curr</span><span class=\"p\">.</span><span class=\"nb\">next</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"bp\">None</span><span class=\"p\">:</span> <span class=\"n\">curr</span> <span class=\"o\">=</span> <span class=\"n\">curr</span><span class=\"p\">.</span><span class=\"nb\">next</span> <span class=\"k\">if</span> <span class=\"n\">i</span> <span class=\"o\">>=</span> <span class=\"n\">new_k</span><span class=\"p\">:</span> <span class=\"n\">new_head</span> <span class=\"o\">=</span> <span class=\"n\">new_head</span><span class=\"p\">.</span><span class=\"nb\">next</span> <span class=\"n\">i</span> <span class=\"o\">+=</span> <span class=\"mi\">1</span> <span class=\"n\">curr</span><span class=\"p\">.</span><span class=\"nb\">next</span> <span class=\"o\">=</span> <span class=\"n\">head</span> <span class=\"n\">head</span> <span class=\"o\">=</span> <span class=\"n\">new_head</span><span class=\"p\">.</span><span class=\"nb\">next</span> <span class=\"n\">new_head</span><span class=\"p\">.</span><span class=\"nb\">next</span> <span class=\"o\">=</span> <span class=\"bp\">None</span> <span class=\"k\">return</span> <span class=\"n\">head</span></code></pre></figure>", "date_published": "2024-04-21T19:11:00+00:00" }, { "id": "https://fewald.net/leetcode/2024/04/21/leetcode-remove-duplicates-from-sorted-list-ii.html", "url": "https://fewald.net/leetcode/2024/04/21/leetcode-remove-duplicates-from-sorted-list-ii.html", "title": "Leetcode: Remove duplicates from sorted list II", "content_html": "<p>Remove duplicate items from a linked list completely, including the original item.<!--more--></p><p>The trick is to use two pointers and keep a <code class=\"language-plaintext highlighter-rouge\">pre_slow</code> pointer which is initially set to <code class=\"language-plaintext highlighter-rouge\">None</code>.Upon discovering duplicates, move the fast pointer until either the end of the list or a non-duplicateis seen and then set <code class=\"language-plaintext highlighter-rouge\">pre_slow.next</code> to the next element. Then move every pointer to the next pointer.</p><p>The special case here is if the duplicates occur in the beginning. In this case, <code class=\"language-plaintext highlighter-rouge\">head</code> itself needs tobe moved to <code class=\"language-plaintext highlighter-rouge\">fast</code> and <code class=\"language-plaintext highlighter-rouge\">slow</code> stays at the new <code class=\"language-plaintext highlighter-rouge\">head</code>.</p><figure class=\"highlight\"><pre><code class=\"language-python\" data-lang=\"python\"><span class=\"c1\"># class ListNode:# def __init__(self, val=0, next=None):# self.val = val# self.next = next</span><span class=\"k\">class</span> <span class=\"nc\">Solution</span><span class=\"p\">:</span> <span class=\"k\">def</span> <span class=\"nf\">deleteDuplicates</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">head</span><span class=\"p\">:</span> <span class=\"n\">Optional</span><span class=\"p\">[</span><span class=\"n\">ListNode</span><span class=\"p\">])</span> <span class=\"o\">-></span> <span class=\"n\">Optional</span><span class=\"p\">[</span><span class=\"n\">ListNode</span><span class=\"p\">]:</span> <span class=\"k\">if</span> <span class=\"n\">head</span> <span class=\"ow\">is</span> <span class=\"bp\">None</span> <span class=\"ow\">or</span> <span class=\"n\">head</span><span class=\"p\">.</span><span class=\"nb\">next</span> <span class=\"ow\">is</span> <span class=\"bp\">None</span><span class=\"p\">:</span> <span class=\"k\">return</span> <span class=\"n\">head</span> <span class=\"n\">pre_slow</span> <span class=\"o\">=</span> <span class=\"bp\">None</span> <span class=\"n\">slow</span> <span class=\"o\">=</span> <span class=\"n\">head</span> <span class=\"n\">fast</span> <span class=\"o\">=</span> <span class=\"n\">head</span><span class=\"p\">.</span><span class=\"nb\">next</span> <span class=\"k\">while</span> <span class=\"n\">slow</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"bp\">None</span> <span class=\"ow\">and</span> <span class=\"n\">fast</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"bp\">None</span><span class=\"p\">:</span> <span class=\"k\">if</span> <span class=\"n\">slow</span><span class=\"p\">.</span><span class=\"n\">val</span> <span class=\"o\">!=</span> <span class=\"n\">fast</span><span class=\"p\">.</span><span class=\"n\">val</span><span class=\"p\">:</span> <span class=\"n\">pre_slow</span> <span class=\"o\">=</span> <span class=\"n\">slow</span> <span class=\"n\">slow</span> <span class=\"o\">=</span> <span class=\"n\">slow</span><span class=\"p\">.</span><span class=\"nb\">next</span> <span class=\"n\">fast</span> <span class=\"o\">=</span> <span class=\"n\">slow</span><span class=\"p\">.</span><span class=\"nb\">next</span> <span class=\"k\">elif</span> <span class=\"n\">slow</span><span class=\"p\">.</span><span class=\"n\">val</span> <span class=\"o\">==</span> <span class=\"n\">fast</span><span class=\"p\">.</span><span class=\"n\">val</span><span class=\"p\">:</span> <span class=\"k\">while</span> <span class=\"n\">fast</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"bp\">None</span> <span class=\"ow\">and</span> <span class=\"n\">slow</span><span class=\"p\">.</span><span class=\"n\">val</span> <span class=\"o\">==</span> <span class=\"n\">fast</span><span class=\"p\">.</span><span class=\"n\">val</span><span class=\"p\">:</span> <span class=\"n\">fast</span> <span class=\"o\">=</span> <span class=\"n\">fast</span><span class=\"p\">.</span><span class=\"nb\">next</span> <span class=\"k\">if</span> <span class=\"n\">pre_slow</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"bp\">None</span><span class=\"p\">:</span> <span class=\"n\">pre_slow</span><span class=\"p\">.</span><span class=\"nb\">next</span> <span class=\"o\">=</span> <span class=\"n\">fast</span> <span class=\"n\">slow</span> <span class=\"o\">=</span> <span class=\"n\">pre_slow</span><span class=\"p\">.</span><span class=\"nb\">next</span> <span class=\"k\">if</span> <span class=\"n\">slow</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"bp\">None</span><span class=\"p\">:</span> <span class=\"n\">fast</span> <span class=\"o\">=</span> <span class=\"n\">slow</span><span class=\"p\">.</span><span class=\"nb\">next</span> <span class=\"k\">else</span><span class=\"p\">:</span> <span class=\"c1\"># Special case: Move head to fast as all nodes were the same</span> <span class=\"n\">head</span> <span class=\"o\">=</span> <span class=\"n\">fast</span> <span class=\"n\">slow</span> <span class=\"o\">=</span> <span class=\"n\">head</span> <span class=\"k\">if</span> <span class=\"n\">slow</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"bp\">None</span><span class=\"p\">:</span> <span class=\"n\">fast</span> <span class=\"o\">=</span> <span class=\"n\">slow</span><span class=\"p\">.</span><span class=\"nb\">next</span> <span class=\"k\">return</span> <span class=\"n\">head</span></code></pre></figure><p>This solution is faster than 99.52% of all submitted solutions.</p>", "date_published": "2024-04-21T18:03:00+00:00" }, { "id": "https://fewald.net/2024/01/31/silicon-valley.html", "url": "https://fewald.net/2024/01/31/silicon-valley.html", "title": "Silicon Valley Photos", "content_html": "<p>Marcus Kazmierczak has great photos of the <a href=\"https://mkaz.com/silicon-valley/\">Silicon Valley</a> on his homepage. Definitely worth checking them out.</p>", "date_published": "2024-01-31T17:28:00+00:00" }, { "id": "https://fewald.net/2023/12/19/rain.html", "url": "https://fewald.net/2023/12/19/rain.html", "title": "2023 Rain", "content_html": "<p>Rain started in the Bay Area yesterday.</p>", "date_published": "2023-12-19T18:00:00+00:00" }, { "id": "https://fewald.net/ruby/rails/2023/08/13/ruby-testing-server-part-two.html", "url": "https://fewald.net/ruby/rails/2023/08/13/ruby-testing-server-part-two.html", "title": "Ruby Testing Server Part Two", "content_html": "<p>Following from my post from 2022 about testing Rails application with a static server, I wanted to mock an API during a test. The reason for this is that I like to keep the external dependencies to a minimum.</p><!--more--><p>Webrick supports <code class=\"language-plaintext highlighter-rouge\">mount_proc</code> which lets me create endpoints on the fly. Since my <code class=\"language-plaintext highlighter-rouge\">fixture_server</code> provides access to the <code class=\"language-plaintext highlighter-rouge\">server</code> object, it’s as simple as this:</p><figure class=\"highlight\"><pre><code class=\"language-ruby\" data-lang=\"ruby\"><span class=\"n\">fixture_server</span> <span class=\"k\">do</span> <span class=\"o\">|</span><span class=\"n\">server</span><span class=\"p\">,</span> <span class=\"n\">port</span><span class=\"o\">|</span> <span class=\"n\">server</span><span class=\"p\">.</span><span class=\"nf\">mount_proc</span> <span class=\"s1\">'/extract_author'</span> <span class=\"k\">do</span> <span class=\"o\">|</span><span class=\"n\">req</span><span class=\"p\">,</span> <span class=\"n\">res</span><span class=\"o\">|</span> <span class=\"n\">res</span><span class=\"p\">.</span><span class=\"nf\">body</span> <span class=\"o\">=</span> <span class=\"p\">{</span> <span class=\"ss\">authors: </span><span class=\"sx\">%w[Alice Bob]</span> <span class=\"p\">}.</span><span class=\"nf\">to_json</span> <span class=\"k\">end</span> <span class=\"n\">nlp</span> <span class=\"o\">=</span> <span class=\"no\">Nlp</span><span class=\"p\">.</span><span class=\"nf\">new</span><span class=\"p\">(</span><span class=\"s2\">\"http://localhost:</span><span class=\"si\">#{</span><span class=\"n\">port</span><span class=\"si\">}</span><span class=\"s2\">\"</span><span class=\"p\">)</span> <span class=\"n\">extracted_authors</span> <span class=\"o\">=</span> <span class=\"n\">nlp</span><span class=\"p\">.</span><span class=\"nf\">extract_author</span><span class=\"p\">(</span><span class=\"s2\">\"Alice, Bob\"</span><span class=\"p\">)</span> <span class=\"n\">assert_not_nil</span> <span class=\"n\">extracted_authors</span> <span class=\"n\">assert_equal</span> <span class=\"sx\">%w[Alice Bob]</span><span class=\"p\">,</span> <span class=\"n\">extracted_authors</span><span class=\"k\">end</span></code></pre></figure>", "date_published": "2023-08-13T17:44:00+00:00" }, { "id": "https://fewald.net/2023/07/04/july-4-2023.html", "url": "https://fewald.net/2023/07/04/july-4-2023.html", "title": "July 4 2023", "content_html": "<p><a href=\"/assets/images/golden-gate-bridge.jpeg\"><picture><source srcset=\"/generated/assets/images/golden-gate-bridge-200-3b912ce1e.avif 200w, /generated/assets/images/golden-gate-bridge-400-3b912ce1e.avif 400w, /generated/assets/images/golden-gate-bridge-800-3b912ce1e.avif 800w, /generated/assets/images/golden-gate-bridge-1200-3b912ce1e.avif 1200w\" type=\"image/avif\"><source srcset=\"/generated/assets/images/golden-gate-bridge-200-50cc4d734.webp 200w, /generated/assets/images/golden-gate-bridge-400-50cc4d734.webp 400w, /generated/assets/images/golden-gate-bridge-800-50cc4d734.webp 800w, /generated/assets/images/golden-gate-bridge-1200-50cc4d734.webp 1200w\" type=\"image/webp\"><source srcset=\"/generated/assets/images/golden-gate-bridge-200-c5bfe6f92.jpeg 200w, /generated/assets/images/golden-gate-bridge-400-c5bfe6f92.jpeg 400w, /generated/assets/images/golden-gate-bridge-800-c5bfe6f92.jpeg 800w, /generated/assets/images/golden-gate-bridge-1200-c5bfe6f92.jpeg 1200w\" type=\"image/jpeg\"><img src=\"/generated/assets/images/golden-gate-bridge-800-c5bfe6f92.jpeg\" alt=\"Golden Gate Bridge in San Francisco, CA on 4th of July weekend\" width=\"1280\" height=\"960\"></picture></a>Happy 4th of July from San Francisco!</p>", "date_published": "2023-07-04T14:17:00+00:00" }, { "id": "https://fewald.net/misc/2023/05/21/bread-recipe.html", "url": "https://fewald.net/misc/2023/05/21/bread-recipe.html", "title": "Bread recipe", "content_html": "<p>I made my first bread today from scratch. The recipe is very simple:</p><ol> <li>430 grams flour (King Arthurs bread flour)</li> <li>2 teaspoons coarse salt</li> <li>1 bag (6-7 grams) of instant yeast</li> <li>1 1/2 cups of water</li></ol><p>Mix everything gently together in a bowl until the dough becomes sticky. Then proof at 95 Fahrenheit for 1 hour until the dough doubles in size.</p><p>Preheat the oven to <strong>475 Fahrenheit</strong> and bake for <strong>20 minutes</strong>.</p><p><a href=\"/assets/images/bread-in-oven.jpeg\"><picture><source srcset=\"/generated/assets/images/bread-in-oven-200-dda192b67.avif 200w, /generated/assets/images/bread-in-oven-400-dda192b67.avif 400w, /generated/assets/images/bread-in-oven-800-dda192b67.avif 800w, /generated/assets/images/bread-in-oven-1200-dda192b67.avif 1200w\" type=\"image/avif\"><source srcset=\"/generated/assets/images/bread-in-oven-200-41d0cb29a.webp 200w, /generated/assets/images/bread-in-oven-400-41d0cb29a.webp 400w, /generated/assets/images/bread-in-oven-800-41d0cb29a.webp 800w, /generated/assets/images/bread-in-oven-1200-41d0cb29a.webp 1200w\" type=\"image/webp\"><source srcset=\"/generated/assets/images/bread-in-oven-200-8f01ee7aa.jpeg 200w, /generated/assets/images/bread-in-oven-400-8f01ee7aa.jpeg 400w, /generated/assets/images/bread-in-oven-800-8f01ee7aa.jpeg 800w, /generated/assets/images/bread-in-oven-1200-8f01ee7aa.jpeg 1200w\" type=\"image/jpeg\"><img src=\"/generated/assets/images/bread-in-oven-800-8f01ee7aa.jpeg\" alt=\"Bread in the oven\" width=\"1280\" height=\"854\"></picture></a></p><p>The results were good for a first attempt, but I will try to proof for 2 hours next to achieve fluffier results.</p><p><a href=\"/assets/images/bread-cut.jpeg\"><picture><source srcset=\"/generated/assets/images/bread-cut-200-e05407fce.avif 200w, /generated/assets/images/bread-cut-400-e05407fce.avif 400w, /generated/assets/images/bread-cut-800-e05407fce.avif 800w, /generated/assets/images/bread-cut-1200-e05407fce.avif 1200w\" type=\"image/avif\"><source srcset=\"/generated/assets/images/bread-cut-200-4e4a1f47e.webp 200w, /generated/assets/images/bread-cut-400-4e4a1f47e.webp 400w, /generated/assets/images/bread-cut-800-4e4a1f47e.webp 800w, /generated/assets/images/bread-cut-1200-4e4a1f47e.webp 1200w\" type=\"image/webp\"><source srcset=\"/generated/assets/images/bread-cut-200-6fbab8b36.jpeg 200w, /generated/assets/images/bread-cut-400-6fbab8b36.jpeg 400w, /generated/assets/images/bread-cut-800-6fbab8b36.jpeg 800w, /generated/assets/images/bread-cut-1200-6fbab8b36.jpeg 1200w\" type=\"image/jpeg\"><img src=\"/generated/assets/images/bread-cut-800-6fbab8b36.jpeg\" alt=\"Bread after cutting\" width=\"1280\" height=\"854\"></picture></a></p>", "date_published": "2023-05-21T01:30:00+00:00" }, { "id": "https://fewald.net/development/python/2023/04/18/memory-profiling-memray.html", "url": "https://fewald.net/development/python/2023/04/18/memory-profiling-memray.html", "title": "Memory profiling with Memray", "content_html": "<p>I am currently working on a small Python project with a relatively large memory footprint. I wanted toanalyze the usage in detail and realized that I wasn’t aware of any good Python memory profiler. Aftersome searching I found the builtin package <a href=\"https://docs.python.org/3/library/tracemalloc.html\">tracemalloc</a>(Trace memory allocation). Especially interesting to me is the capability to take snapshots at differentpoints in time and then compare the delta between those snaphots. The following snippet illustrates this.</p><figure class=\"highlight\"><pre><code class=\"language-python\" data-lang=\"python\"><span class=\"kn\">import</span> <span class=\"n\">numpy</span><span class=\"kn\">import</span> <span class=\"n\">tracemalloc</span><span class=\"n\">tracemalloc</span><span class=\"p\">.</span><span class=\"nf\">start</span><span class=\"p\">()</span><span class=\"n\">snapshot_before</span> <span class=\"o\">=</span> <span class=\"n\">tracemalloc</span><span class=\"p\">.</span><span class=\"nf\">take_snapshot</span><span class=\"p\">()</span><span class=\"n\">array</span> <span class=\"o\">=</span> <span class=\"n\">numpy</span><span class=\"p\">.</span><span class=\"nf\">zeros</span><span class=\"p\">((</span><span class=\"mi\">100</span><span class=\"p\">,</span> <span class=\"mi\">100</span><span class=\"p\">))</span><span class=\"n\">array2</span> <span class=\"o\">=</span> <span class=\"n\">numpy</span><span class=\"p\">.</span><span class=\"n\">random</span><span class=\"p\">.</span><span class=\"nf\">rand</span><span class=\"p\">(</span><span class=\"mi\">1_000_000</span><span class=\"p\">,</span> <span class=\"mi\">1_000</span><span class=\"p\">)</span><span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"n\">array2</span><span class=\"p\">.</span><span class=\"n\">dtype</span><span class=\"p\">)</span><span class=\"n\">array3</span> <span class=\"o\">=</span> <span class=\"n\">array2</span><span class=\"p\">.</span><span class=\"nf\">astype</span><span class=\"p\">(</span><span class=\"n\">numpy</span><span class=\"p\">.</span><span class=\"n\">float16</span><span class=\"p\">)</span><span class=\"n\">snapshot_after</span> <span class=\"o\">=</span> <span class=\"n\">tracemalloc</span><span class=\"p\">.</span><span class=\"nf\">take_snapshot</span><span class=\"p\">()</span><span class=\"n\">stats</span> <span class=\"o\">=</span> <span class=\"n\">snapshot_after</span><span class=\"p\">.</span><span class=\"nf\">compare_to</span><span class=\"p\">(</span><span class=\"n\">snapshot_before</span><span class=\"p\">,</span> <span class=\"sh\">'</span><span class=\"s\">lineno</span><span class=\"sh\">'</span><span class=\"p\">)</span><span class=\"k\">for</span> <span class=\"n\">s</span> <span class=\"ow\">in</span> <span class=\"n\">stats</span><span class=\"p\">[:</span><span class=\"mi\">10</span><span class=\"p\">]:</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"n\">s</span><span class=\"p\">)</span><span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"n\">tracemalloc</span><span class=\"p\">.</span><span class=\"nf\">get_traced_memory</span><span class=\"p\">())</span></code></pre></figure><p>This is fine for smaller code bases where I have full control over the source. It requires however alot of editing and manual filtering of frames and taking snapshots at the right time.</p><p>Another interesting solution is Bloombergs <a href=\"https://github.com/bloomberg/memray\">memray</a>. This allows to run a whole Python application and save the snapshots into a file. From there memray can either create a table or a flamegraph to see the memory consumption over time.</p><p>Memray can be used like this:</p><figure class=\"highlight\"><pre><code class=\"language-shell\" data-lang=\"shell\">pip3 <span class=\"nb\">install </span>memray<span class=\"c\"># Run application and save snapshots</span>memray run my_app.py<span class=\"c\"># Display snapshots</span>memray flamegraph memray-test.py.94623.bin</code></pre></figure><p>This generates a HTML file which can be opened in any browser.</p>", "date_published": "2023-04-18T17:00:00+00:00" }, { "id": "https://fewald.net/development/2023/01/25/updating-jekyll-to-ruby-3-2-0.html", "url": "https://fewald.net/development/2023/01/25/updating-jekyll-to-ruby-3-2-0.html", "title": "Updating Jekyll to Ruby 3.2.0", "content_html": "<p>I recently updated this blog to <a href=\"https://www.ruby-lang.org/en/news/2022/12/25/ruby-3-2-0-released/\">Ruby 3.2.0</a> which was released on Dec 25, 2022.</p><p>I expected this to be a minor update since I came from Ruby 3.1.2. However, I ran into some problems that I had to solve.</p><!--more--><h2 id=\"outdated-api\">Outdated API</h2><p>It turns out that there is one important change in the Ruby standard library. <code class=\"language-plaintext highlighter-rouge\">File.exists?</code> was renamed to <code class=\"language-plaintext highlighter-rouge\">File.exist?</code> with the same functionality. Some third-party plugins that I use have not yet included this change. I was able to extend the <code class=\"language-plaintext highlighter-rouge\">File</code> class like so:</p><figure class=\"highlight\"><pre><code class=\"language-ruby\" data-lang=\"ruby\"><span class=\"k\">class</span> <span class=\"nc\">File</span> <span class=\"k\">def</span> <span class=\"nc\">self</span><span class=\"o\">.</span><span class=\"nf\">exists?</span><span class=\"p\">(</span><span class=\"o\">*</span><span class=\"n\">args</span><span class=\"p\">)</span> <span class=\"n\">exist?</span><span class=\"p\">(</span><span class=\"o\">*</span><span class=\"n\">args</span><span class=\"p\">)</span> <span class=\"k\">end</span><span class=\"k\">end</span></code></pre></figure><p>I added this file as in the <code class=\"language-plaintext highlighter-rouge\">_plugins</code> folder so that Jekyll would import it automatically.</p><h1 id=\"updating-jekyll\">Updating Jekyll</h1><p>The version of Jekyll that I used was not compatible with Ruby 3.2.0. I had to update my <code class=\"language-plaintext highlighter-rouge\">Gemfile</code> to the following and then run <code class=\"language-plaintext highlighter-rouge\">bundle update</code>. This will apply updates to Jekyll automatically in the future.</p><figure class=\"highlight\"><pre><code class=\"language-gem\" data-lang=\"gem\"># ...ruby \"3.2.0\"# ...gem \"jekyll\", \"~> 4\"</code></pre></figure><h2 id=\"sass-compiler\">SASS Compiler</h2><p>With the Jekyll update came also an update to the SASS compiler.My <code class=\"language-plaintext highlighter-rouge\">css</code> folder contains one file: <code class=\"language-plaintext highlighter-rouge\">main.scss</code>. This file has just some import statements that it uses to assemble a larger CSS file. I got an error message that instead of the <code class=\"language-plaintext highlighter-rouge\">;</code> at the end of each line, curly braces are expected. I spent quite some time to try to figure out what is going on, until I saw the changelog on the Jekyll homepage. It turns out that the <code class=\"language-plaintext highlighter-rouge\">main.scss</code> cannot have the same name as the imported <code class=\"language-plaintext highlighter-rouge\">_main.scss</code>. After renaming it to <code class=\"language-plaintext highlighter-rouge\">_base.scss</code>, it worked. See the last line in the snippet below for an example.</p><figure class=\"highlight\"><pre><code class=\"language-sass\" data-lang=\"sass\"><span class=\"nt\">---</span><span class=\"nn\">#</span> <span class=\"nt\">Front</span> <span class=\"nt\">matter</span> <span class=\"nt\">is</span> <span class=\"nt\">needed</span> <span class=\"nt\">here</span><span class=\"nt\">---</span><span class=\"k\">@charset</span> <span class=\"s2\">\"utf-8\"</span><span class=\"o\">;</span><span class=\"k\">@use</span> <span class=\"s2\">\"syntax\"</span><span class=\"o\">;</span><span class=\"k\">@use</span> <span class=\"s2\">\"poole\"</span><span class=\"o\">;</span><span class=\"k\">@use</span> <span class=\"s2\">\"lanyon\"</span><span class=\"o\">;</span><span class=\"k\">@use</span> <span class=\"s2\">\"base\"</span><span class=\"o\">;</span></code></pre></figure><p>After those steps, everything worked again and this site is now generated with Ruby 3.2.0!</p>", "date_published": "2023-01-25T16:35:00+00:00" }, { "id": "https://fewald.net/home-improvement/2022/12/18/electric-closet.html", "url": "https://fewald.net/home-improvement/2022/12/18/electric-closet.html", "title": "Electric Closet", "content_html": "<p>I never liked having the router in full display in the living room. I routed the fiber connection into a closet in our hallway with the plan on making this a “tech closet”. I had to route electricity to the closet and install some shelves. The goal was to have a space for the router, my printer (that I only use ocassionally), some other hardware like a Raspberry Pi and to be able to charge a Dyson vacuum cleaner.</p><p><a href=\"/assets/images/electric-closet/full-closet.jpeg\"><picture><source srcset=\"/generated/assets/images/electric-closet/full-closet-200-5bf80a708.avif 200w, /generated/assets/images/electric-closet/full-closet-400-5bf80a708.avif 400w, /generated/assets/images/electric-closet/full-closet-800-5bf80a708.avif 800w, /generated/assets/images/electric-closet/full-closet-1200-5bf80a708.avif 1200w\" type=\"image/avif\"><source srcset=\"/generated/assets/images/electric-closet/full-closet-200-58d2892b7.webp 200w, /generated/assets/images/electric-closet/full-closet-400-58d2892b7.webp 400w, /generated/assets/images/electric-closet/full-closet-800-58d2892b7.webp 800w, /generated/assets/images/electric-closet/full-closet-1200-58d2892b7.webp 1200w\" type=\"image/webp\"><source srcset=\"/generated/assets/images/electric-closet/full-closet-200-f4fc86ca4.jpeg 200w, /generated/assets/images/electric-closet/full-closet-400-f4fc86ca4.jpeg 400w, /generated/assets/images/electric-closet/full-closet-800-f4fc86ca4.jpeg 800w, /generated/assets/images/electric-closet/full-closet-1200-f4fc86ca4.jpeg 1200w\" type=\"image/jpeg\"><img src=\"/generated/assets/images/electric-closet/full-closet-800-f4fc86ca4.jpeg\" width=\"2107\" height=\"3160\"></picture></a>The (almost) finished closet. The cover plate for the outlet was not available at the time.</p><p><a href=\"/assets/images/electric-closet/wago-wiring-outlets.jpeg\"><picture><source srcset=\"/generated/assets/images/electric-closet/wago-wiring-outlets-200-acfa365f5.avif 200w, /generated/assets/images/electric-closet/wago-wiring-outlets-400-acfa365f5.avif 400w, /generated/assets/images/electric-closet/wago-wiring-outlets-800-acfa365f5.avif 800w, /generated/assets/images/electric-closet/wago-wiring-outlets-1200-acfa365f5.avif 1200w\" type=\"image/avif\"><source srcset=\"/generated/assets/images/electric-closet/wago-wiring-outlets-200-9b9fab8e7.webp 200w, /generated/assets/images/electric-closet/wago-wiring-outlets-400-9b9fab8e7.webp 400w, /generated/assets/images/electric-closet/wago-wiring-outlets-800-9b9fab8e7.webp 800w, /generated/assets/images/electric-closet/wago-wiring-outlets-1200-9b9fab8e7.webp 1200w\" type=\"image/webp\"><source srcset=\"/generated/assets/images/electric-closet/wago-wiring-outlets-200-dc152eaf9.jpeg 200w, /generated/assets/images/electric-closet/wago-wiring-outlets-400-dc152eaf9.jpeg 400w, /generated/assets/images/electric-closet/wago-wiring-outlets-800-dc152eaf9.jpeg 800w, /generated/assets/images/electric-closet/wago-wiring-outlets-1200-dc152eaf9.jpeg 1200w\" type=\"image/jpeg\"><img src=\"/generated/assets/images/electric-closet/wago-wiring-outlets-800-dc152eaf9.jpeg\" width=\"2842\" height=\"1895\"></picture></a>I connected the outlets with Wago connectors before installing them. This avoided having to install the outlets in an awkward position and sped the whole process up significantly.</p><p><a href=\"/assets/images/electric-closet/detail-below.jpeg\"><picture><source srcset=\"/generated/assets/images/electric-closet/detail-below-200-d48f07cf8.avif 200w, /generated/assets/images/electric-closet/detail-below-400-d48f07cf8.avif 400w, /generated/assets/images/electric-closet/detail-below-800-d48f07cf8.avif 800w, /generated/assets/images/electric-closet/detail-below-1200-d48f07cf8.avif 1200w\" type=\"image/avif\"><source srcset=\"/generated/assets/images/electric-closet/detail-below-200-8964a8e72.webp 200w, /generated/assets/images/electric-closet/detail-below-400-8964a8e72.webp 400w, /generated/assets/images/electric-closet/detail-below-800-8964a8e72.webp 800w, /generated/assets/images/electric-closet/detail-below-1200-8964a8e72.webp 1200w\" type=\"image/webp\"><source srcset=\"/generated/assets/images/electric-closet/detail-below-200-60812ee93.jpeg 200w, /generated/assets/images/electric-closet/detail-below-400-60812ee93.jpeg 400w, /generated/assets/images/electric-closet/detail-below-800-60812ee93.jpeg 800w, /generated/assets/images/electric-closet/detail-below-1200-60812ee93.jpeg 1200w\" type=\"image/jpeg\"><img src=\"/generated/assets/images/electric-closet/detail-below-800-60812ee93.jpeg\" alt=\"View from below\" width=\"4032\" height=\"3024\"></picture></a>The view from below. I used normal wood screws to attach the boards to the wall. Time will tell if this is sufficient. In case this is not stable enough: Behind the drywall are some studs at exactly the same position.</p><p><a href=\"/assets/images/electric-closet/detail-left.jpeg\"><picture><source srcset=\"/generated/assets/images/electric-closet/detail-left-200-bd39f05db.avif 200w, /generated/assets/images/electric-closet/detail-left-400-bd39f05db.avif 400w, /generated/assets/images/electric-closet/detail-left-800-bd39f05db.avif 800w, /generated/assets/images/electric-closet/detail-left-1200-bd39f05db.avif 1200w\" type=\"image/avif\"><source srcset=\"/generated/assets/images/electric-closet/detail-left-200-10b0aec1a.webp 200w, /generated/assets/images/electric-closet/detail-left-400-10b0aec1a.webp 400w, /generated/assets/images/electric-closet/detail-left-800-10b0aec1a.webp 800w, /generated/assets/images/electric-closet/detail-left-1200-10b0aec1a.webp 1200w\" type=\"image/webp\"><source srcset=\"/generated/assets/images/electric-closet/detail-left-200-75c31f7c3.jpeg 200w, /generated/assets/images/electric-closet/detail-left-400-75c31f7c3.jpeg 400w, /generated/assets/images/electric-closet/detail-left-800-75c31f7c3.jpeg 800w, /generated/assets/images/electric-closet/detail-left-1200-75c31f7c3.jpeg 1200w\" type=\"image/jpeg\"><img src=\"/generated/assets/images/electric-closet/detail-left-800-75c31f7c3.jpeg\" alt=\"View in the left corner from below\" width=\"3755\" height=\"2816\"></picture></a></p><p><a href=\"/assets/images/electric-closet/detail-divided.jpeg\"><picture><source srcset=\"/generated/assets/images/electric-closet/detail-divided-200-a39645a84.avif 200w, /generated/assets/images/electric-closet/detail-divided-400-a39645a84.avif 400w, /generated/assets/images/electric-closet/detail-divided-800-a39645a84.avif 800w, /generated/assets/images/electric-closet/detail-divided-1200-a39645a84.avif 1200w\" type=\"image/avif\"><source srcset=\"/generated/assets/images/electric-closet/detail-divided-200-c801e5dc5.webp 200w, /generated/assets/images/electric-closet/detail-divided-400-c801e5dc5.webp 400w, /generated/assets/images/electric-closet/detail-divided-800-c801e5dc5.webp 800w, /generated/assets/images/electric-closet/detail-divided-1200-c801e5dc5.webp 1200w\" type=\"image/webp\"><source srcset=\"/generated/assets/images/electric-closet/detail-divided-200-850289c26.jpeg 200w, /generated/assets/images/electric-closet/detail-divided-400-850289c26.jpeg 400w, /generated/assets/images/electric-closet/detail-divided-800-850289c26.jpeg 800w, /generated/assets/images/electric-closet/detail-divided-1200-850289c26.jpeg 1200w\" type=\"image/jpeg\"><img src=\"/generated/assets/images/electric-closet/detail-divided-800-850289c26.jpeg\" alt=\"Smaller, divided boards\" width=\"4032\" height=\"3024\"></picture></a>I chose to have some board divided in the middle and not spanning the whole depth of the closet. This allows flexibility and also to store bigger items.</p>", "date_published": "2022-12-18T01:50:00+00:00" }, { "id": "https://fewald.net/machine-learning/2022/12/11/chatgpt.html", "url": "https://fewald.net/machine-learning/2022/12/11/chatgpt.html", "title": "ChatGPT", "content_html": "<p>Who are you?</p><blockquote> <p>I am Assistant, a large language model trained by OpenAI to assist with a variety of tasks. I am not a person, but rather a program that uses advanced machine learning algorithms to process and generate text. I am here to provide information and help answer your questions to the best of my ability. Do you have any questions I can help you with?</p></blockquote><p>Do you have any special skills?</p><blockquote> <p>As a language model, my primary skill is generating and understanding natural language text. I am trained to assist with a variety of tasks, including answering questions, providing information, and engaging in conversation. I am constantly learning and improving my abilities through machine learning, so my capabilities are always expanding. Is there something specific you would like to know or discuss? I would be happy to help with any question or topic you have in mind.</p></blockquote><p>When being asked about ChatGPT, it doesn’t know itself. Likely because it was trained on data ending in 2021 which is before <a href=\"https://chat.openai.com\">ChatGPT</a> was published. I recommend trying it out.</p><h3 id=\"update-jan-25-2023\">Update Jan 25 2023</h3><p>Since a few days, ChatGPT has a premium plan. Anecdotaelly, I just went there and I got a message “ChatGPT is at capacity right now”. It seems like the free days are over.</p>", "date_published": "2022-12-11T16:25:00+00:00" }, { "id": "https://fewald.net/development/2022/11/28/testing-email-sending.html", "url": "https://fewald.net/development/2022/11/28/testing-email-sending.html", "title": "Testing email sending", "content_html": "<p>I recently came across <a href=\"https://github.com/mailhog/MailHog\">MailHog</a>. I needed to test some email functionality locally. MailHog creates an SMTP that accepts any email to any address and shows this in web interface.</p>", "date_published": "2022-11-28T16:14:00+00:00" }, { "id": "https://fewald.net/2022/11/18/heroku-price-increase.html", "url": "https://fewald.net/2022/11/18/heroku-price-increase.html", "title": "Heroku Price increase", "content_html": "<p>Heroku will increase <a href=\"https://www.heroku.com/pricing\">prices</a> and remove many free tiers.</p>", "date_published": "2022-11-18T18:44:00+00:00" }, { "id": "https://fewald.net/development/2022/11/16/change-font-size-depending-on-post-length.html", "url": "https://fewald.net/development/2022/11/16/change-font-size-depending-on-post-length.html", "title": "Change font size depending on post length", "content_html": "<p>One of the things that I like about Twitter is that the font size changes depending on the length of the tweet. Yesterday, I tried to achieve the same thing for this Jekyll based blog and came up with the following solution.</p><p>First, I created a plugin (in the folder <code class=\"language-plaintext highlighter-rouge\">_plugins</code>) and registered it as <code class=\"language-plaintext highlighter-rouge\">Liquid</code> filter with the following code:</p><figure class=\"highlight\"><pre><code class=\"language-ruby\" data-lang=\"ruby\"><span class=\"k\">module</span> <span class=\"nn\">Jekyll</span> <span class=\"k\">module</span> <span class=\"nn\">PostFilter</span> <span class=\"k\">def</span> <span class=\"nf\">post_class</span><span class=\"p\">(</span><span class=\"n\">input</span><span class=\"p\">)</span> <span class=\"c1\"># Catch invalid posts</span> <span class=\"k\">return</span> <span class=\"s1\">'default'</span> <span class=\"k\">if</span> <span class=\"n\">input</span><span class=\"p\">.</span><span class=\"nf\">nil?</span> <span class=\"k\">if</span> <span class=\"n\">input</span><span class=\"p\">.</span><span class=\"nf\">size</span> <span class=\"o\"><</span> <span class=\"mi\">32</span> <span class=\"k\">return</span> <span class=\"s1\">'large'</span> <span class=\"k\">elsif</span> <span class=\"n\">input</span><span class=\"p\">.</span><span class=\"nf\">size</span> <span class=\"o\"><</span> <span class=\"mi\">64</span> <span class=\"k\">return</span> <span class=\"s1\">'medium'</span> <span class=\"k\">else</span> <span class=\"k\">return</span> <span class=\"s1\">'default'</span> <span class=\"k\">end</span> <span class=\"k\">end</span> <span class=\"k\">end</span><span class=\"k\">end</span><span class=\"no\">Liquid</span><span class=\"o\">::</span><span class=\"no\">Template</span><span class=\"p\">.</span><span class=\"nf\">register_filter</span><span class=\"p\">(</span><span class=\"no\">Jekyll</span><span class=\"o\">::</span><span class=\"no\">PostFilter</span><span class=\"p\">)</span></code></pre></figure><p>As a next step I changed the <code class=\"language-plaintext highlighter-rouge\">post.html</code> template to this:</p><figure class=\"highlight\"><pre><code class=\"language-html\" data-lang=\"html\"><span class=\"nt\"><p</span> <span class=\"na\">itemprop=</span><span class=\"s\">\"articleBody\"</span> <span class=\"na\">class=</span><span class=\"s\">\"{{content | post_class }}\"</span><span class=\"nt\">></span> {{ content | remove: \"<span class=\"nt\"><p></span>\" | remove: \"<span class=\"nt\"></p></span>\" }}<span class=\"nt\"></p></span></code></pre></figure><p>It is important to remove the <code class=\"language-plaintext highlighter-rouge\"><p></code> tags because they cannot be nested in valid HTML and Jekyll adds their own tags to post content.</p><p>Finally, I created some SCSS to change the <code class=\"language-plaintext highlighter-rouge\">font-size</code> based on the CSS class.</p><figure class=\"highlight\"><pre><code class=\"language-scss\" data-lang=\"scss\"><span class=\"cm\">/* Post pages */</span><span class=\"nt\">div</span><span class=\"nc\">.post</span> <span class=\"p\">{</span> <span class=\"nt\">p</span><span class=\"nc\">.default</span> <span class=\"p\">{</span> <span class=\"nl\">font-size</span><span class=\"p\">:</span> <span class=\"m\">1em</span><span class=\"p\">;</span> <span class=\"p\">}</span> <span class=\"nt\">p</span><span class=\"nc\">.medium</span> <span class=\"p\">{</span> <span class=\"nl\">font-size</span><span class=\"p\">:</span> <span class=\"m\">1</span><span class=\"mi\">.6em</span><span class=\"p\">;</span> <span class=\"p\">}</span> <span class=\"nt\">p</span><span class=\"nc\">.large</span> <span class=\"p\">{</span> <span class=\"nl\">font-size</span><span class=\"p\">:</span> <span class=\"m\">1</span><span class=\"mi\">.8em</span><span class=\"p\">;</span> <span class=\"p\">}</span><span class=\"p\">}</span></code></pre></figure>", "date_published": "2022-11-16T15:43:00+00:00" }, { "id": "https://fewald.net/leetcode/2022/11/09/leetcode-house-robber-ii.html", "url": "https://fewald.net/leetcode/2022/11/09/leetcode-house-robber-ii.html", "title": "Leetcode: House robber II", "content_html": "<p>Similar to “House Robber”, but now we have to assume that the houses are aligned in a circle and the last house is a neighbor of the first house.</p><!--more--><p>We can solve it similarly but remove the first and last element and take the maximum of the result.</p><figure class=\"highlight\"><pre><code class=\"language-python\" data-lang=\"python\"><span class=\"k\">class</span> <span class=\"nc\">Solution</span><span class=\"p\">:</span> <span class=\"k\">def</span> <span class=\"nf\">rob</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">nums</span><span class=\"p\">:</span> <span class=\"n\">List</span><span class=\"p\">[</span><span class=\"nb\">int</span><span class=\"p\">])</span> <span class=\"o\">-></span> <span class=\"nb\">int</span><span class=\"p\">:</span> <span class=\"k\">if</span> <span class=\"nf\">len</span><span class=\"p\">(</span><span class=\"n\">nums</span><span class=\"p\">)</span> <span class=\"o\"><</span> <span class=\"mi\">2</span><span class=\"p\">:</span> <span class=\"k\">return</span> <span class=\"n\">nums</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span> <span class=\"k\">return</span> <span class=\"nf\">max</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">.</span><span class=\"nf\">r</span><span class=\"p\">(</span><span class=\"n\">nums</span><span class=\"p\">[:</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">]),</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"nf\">r</span><span class=\"p\">(</span><span class=\"n\">nums</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">:]))</span> <span class=\"k\">def</span> <span class=\"nf\">r</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">nums</span><span class=\"p\">):</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"n\">nums</span><span class=\"p\">)</span> <span class=\"k\">if</span> <span class=\"nf\">len</span><span class=\"p\">(</span><span class=\"n\">nums</span><span class=\"p\">)</span> <span class=\"o\"><</span> <span class=\"mi\">2</span><span class=\"p\">:</span> <span class=\"k\">return</span> <span class=\"n\">nums</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span> <span class=\"k\">if</span> <span class=\"nf\">len</span><span class=\"p\">(</span><span class=\"n\">nums</span><span class=\"p\">)</span> <span class=\"o\"><</span> <span class=\"mi\">3</span><span class=\"p\">:</span> <span class=\"k\">return</span> <span class=\"nf\">max</span><span class=\"p\">(</span><span class=\"n\">nums</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">],</span> <span class=\"n\">nums</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">])</span> <span class=\"n\">m</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"mi\">0</span> <span class=\"k\">for</span> <span class=\"n\">_</span> <span class=\"ow\">in</span> <span class=\"n\">nums</span><span class=\"p\">]</span> <span class=\"n\">m</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">nums</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span> <span class=\"n\">m</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">nums</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">]</span> <span class=\"n\">m</span><span class=\"p\">[</span><span class=\"mi\">2</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"nf\">max</span><span class=\"p\">(</span><span class=\"n\">m</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span><span class=\"o\">+</span><span class=\"n\">nums</span><span class=\"p\">[</span><span class=\"mi\">2</span><span class=\"p\">],</span> <span class=\"n\">m</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">])</span> <span class=\"k\">for</span> <span class=\"n\">pos</span> <span class=\"ow\">in</span> <span class=\"nf\">range</span><span class=\"p\">(</span><span class=\"mi\">3</span><span class=\"p\">,</span> <span class=\"nf\">len</span><span class=\"p\">(</span><span class=\"n\">nums</span><span class=\"p\">)):</span> <span class=\"n\">m</span><span class=\"p\">[</span><span class=\"n\">pos</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"nf\">max</span><span class=\"p\">(</span><span class=\"n\">m</span><span class=\"p\">[</span><span class=\"n\">pos</span><span class=\"o\">-</span><span class=\"mi\">2</span><span class=\"p\">],</span> <span class=\"n\">m</span><span class=\"p\">[</span><span class=\"n\">pos</span><span class=\"o\">-</span><span class=\"mi\">3</span><span class=\"p\">])</span> <span class=\"o\">+</span> <span class=\"n\">nums</span><span class=\"p\">[</span><span class=\"n\">pos</span><span class=\"p\">]</span> <span class=\"k\">return</span> <span class=\"nf\">max</span><span class=\"p\">(</span><span class=\"n\">m</span><span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">],</span> <span class=\"n\">m</span><span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">2</span><span class=\"p\">])</span></code></pre></figure><blockquote> <p>Runtime: 63 ms, faster than 22.78% of Python3 online submissions for House Robber II. Memory Usage: 13.9 MB, less than 70.83% of Python3 online submissions for House Robber II.</p></blockquote>", "date_published": "2022-11-09T20:00:00+00:00" }, { "id": "https://fewald.net/leetcode/2022/11/08/leetcode-house-robber.html", "url": "https://fewald.net/leetcode/2022/11/08/leetcode-house-robber.html", "title": "Leetcode: House robber", "content_html": "<p>Given an array of <code class=\"language-plaintext highlighter-rouge\">nums</code> that represent the loot of a house robber, return the maximum amount of money a robber can steal. The only rule is that a robber can not steal from two neighboring houses.</p><p>When looking at this problem, we can see that we want to maximize the number of houses that we rob from. Consider the following array: <code class=\"language-plaintext highlighter-rouge\">[0,1,0,1]</code>. Our maximum profit is <code class=\"language-plaintext highlighter-rouge\">2</code>, because we can rob the house at index <code class=\"language-plaintext highlighter-rouge\">1</code> and index <code class=\"language-plaintext highlighter-rouge\">3</code>. If we were to rob at index <code class=\"language-plaintext highlighter-rouge\">0</code> and <code class=\"language-plaintext highlighter-rouge\">2</code>, we would only gain <code class=\"language-plaintext highlighter-rouge\">0</code> profit. We cannot however simply compare the even versus the odd indices because there could also be the following situation: <code class=\"language-plaintext highlighter-rouge\">[10,5,5,10]</code>. Here, it is advantageous to skip <code class=\"language-plaintext highlighter-rouge\">2</code> instead of just skipping <code class=\"language-plaintext highlighter-rouge\">1</code>. We need to look at every step if we want to visit the one after the next or the one after this. We don’t need to look if we want to visit the one after this, because then we could also simply have visited the one after the next.</p><!--more--><p>Generally speaking, we always need to look at the <code class=\"language-plaintext highlighter-rouge\">index+2</code> and at the <code class=\"language-plaintext highlighter-rouge\">index+3</code>. To solve this problem, we can look backwards at the array. At position <code class=\"language-plaintext highlighter-rouge\">0</code>, we can only rob <code class=\"language-plaintext highlighter-rouge\">0</code>. At position <code class=\"language-plaintext highlighter-rouge\">1</code> we can only rob <code class=\"language-plaintext highlighter-rouge\">1</code>. At position <code class=\"language-plaintext highlighter-rouge\">2</code> we can rob <code class=\"language-plaintext highlighter-rouge\">0</code> and <code class=\"language-plaintext highlighter-rouge\">2</code>. From there on, we can iterate over the array and calculate the maximum for each position and add the current loot. Finally, we can return the maximum of the two last positions of the array.</p><figure class=\"highlight\"><pre><code class=\"language-python\" data-lang=\"python\"><span class=\"kn\">from</span> <span class=\"n\">typing</span> <span class=\"kn\">import</span> <span class=\"n\">List</span><span class=\"k\">class</span> <span class=\"nc\">Solution</span><span class=\"p\">:</span> <span class=\"k\">def</span> <span class=\"nf\">rob</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">nums</span><span class=\"p\">:</span> <span class=\"n\">List</span><span class=\"p\">[</span><span class=\"nb\">int</span><span class=\"p\">])</span> <span class=\"o\">-></span> <span class=\"nb\">int</span><span class=\"p\">:</span> <span class=\"k\">if</span> <span class=\"nf\">len</span><span class=\"p\">(</span><span class=\"n\">nums</span><span class=\"p\">)</span> <span class=\"o\"><</span> <span class=\"mi\">2</span><span class=\"p\">:</span> <span class=\"k\">return</span> <span class=\"n\">nums</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span> <span class=\"k\">if</span> <span class=\"nf\">len</span><span class=\"p\">(</span><span class=\"n\">nums</span><span class=\"p\">)</span> <span class=\"o\"><</span> <span class=\"mi\">3</span><span class=\"p\">:</span> <span class=\"k\">return</span> <span class=\"nf\">max</span><span class=\"p\">(</span><span class=\"n\">nums</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">],</span> <span class=\"n\">nums</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">])</span> <span class=\"n\">m</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"mi\">0</span> <span class=\"k\">for</span> <span class=\"n\">_</span> <span class=\"ow\">in</span> <span class=\"n\">nums</span><span class=\"p\">]</span> <span class=\"n\">m</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">nums</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span> <span class=\"n\">m</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">nums</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">]</span> <span class=\"n\">m</span><span class=\"p\">[</span><span class=\"mi\">2</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">m</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span> <span class=\"o\">+</span> <span class=\"n\">nums</span><span class=\"p\">[</span><span class=\"mi\">2</span><span class=\"p\">]</span> <span class=\"k\">for</span> <span class=\"n\">pos</span> <span class=\"ow\">in</span> <span class=\"nf\">range</span><span class=\"p\">(</span><span class=\"mi\">3</span><span class=\"p\">,</span> <span class=\"nf\">len</span><span class=\"p\">(</span><span class=\"n\">nums</span><span class=\"p\">)):</span> <span class=\"n\">m</span><span class=\"p\">[</span><span class=\"n\">pos</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"nf\">max</span><span class=\"p\">(</span><span class=\"n\">m</span><span class=\"p\">[</span><span class=\"n\">pos</span><span class=\"o\">-</span><span class=\"mi\">2</span><span class=\"p\">],</span> <span class=\"n\">m</span><span class=\"p\">[</span><span class=\"n\">pos</span><span class=\"o\">-</span><span class=\"mi\">3</span><span class=\"p\">])</span> <span class=\"o\">+</span> <span class=\"n\">nums</span><span class=\"p\">[</span><span class=\"n\">pos</span><span class=\"p\">]</span> <span class=\"k\">return</span> <span class=\"nf\">max</span><span class=\"p\">(</span><span class=\"n\">m</span><span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">],</span> <span class=\"n\">m</span><span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">2</span><span class=\"p\">])</span> <span class=\"k\">if</span> <span class=\"n\">__name__</span> <span class=\"o\">==</span> <span class=\"sh\">'</span><span class=\"s\">__main__</span><span class=\"sh\">'</span><span class=\"p\">:</span> <span class=\"n\">s</span> <span class=\"o\">=</span> <span class=\"nc\">Solution</span><span class=\"p\">().</span><span class=\"n\">rob</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">([</span><span class=\"mi\">1</span><span class=\"p\">,</span><span class=\"mi\">2</span><span class=\"p\">,</span><span class=\"mi\">1</span><span class=\"p\">,</span><span class=\"mi\">1</span><span class=\"p\">]),</span> <span class=\"mi\">3</span><span class=\"p\">)</span></code></pre></figure><blockquote> <p>Runtime: 39 ms, faster than 80.95% of Python3 online submissions for House Robber. Memory Usage: 14 MB, less than 19.55% of Python3 online submissions for House Robber.</p></blockquote>", "date_published": "2022-11-08T20:00:00+00:00" }, { "id": "https://fewald.net/leetcode/2022/11/07/leetcode-palindrome-linked-list.html", "url": "https://fewald.net/leetcode/2022/11/07/leetcode-palindrome-linked-list.html", "title": "Leetcode: Palindrome linked list", "content_html": "<p>Given the <code class=\"language-plaintext highlighter-rouge\">head</code> of a linked list, determine if the linked list is a palindrome and return <code class=\"language-plaintext highlighter-rouge\">True</code> if it is, <code class=\"language-plaintext highlighter-rouge\">False</code> otherwise. For added difficulty, find an algorithm that runs in <code class=\"language-plaintext highlighter-rouge\">O(n)</code> and uses <code class=\"language-plaintext highlighter-rouge\">O(1)</code> space.</p><!--more--><p>The idea to solving this problem can be written as three distinct steps:</p><ol> <li>Find the middle of the list</li> <li>Reverse the second half of the list</li> <li>Iterate over both lists simulatenously, comparing the elements</li></ol><p>Finding the middle can be achieved via slow/fast pointer. Reversing should be done iteratively because each recursion step costs memory. Finally we can set two pointers and compare each element. At the final step we need to check if we arrived at the second half or somewhere else.</p><figure class=\"highlight\"><pre><code class=\"language-python\" data-lang=\"python\"><span class=\"c1\"># Definition for singly-linked list.# class ListNode:# def __init__(self, val=0, next=None):# self.val = val# self.next = next</span><span class=\"k\">class</span> <span class=\"nc\">Solution</span><span class=\"p\">:</span> <span class=\"k\">def</span> <span class=\"nf\">isPalindrome</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">head</span><span class=\"p\">:</span> <span class=\"n\">Optional</span><span class=\"p\">[</span><span class=\"n\">ListNode</span><span class=\"p\">])</span> <span class=\"o\">-></span> <span class=\"nb\">bool</span><span class=\"p\">:</span> <span class=\"n\">p1</span> <span class=\"o\">=</span> <span class=\"n\">head</span> <span class=\"n\">p2</span> <span class=\"o\">=</span> <span class=\"n\">head</span> <span class=\"k\">while</span> <span class=\"n\">p2</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"bp\">None</span> <span class=\"ow\">and</span> <span class=\"n\">p2</span><span class=\"p\">.</span><span class=\"nb\">next</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"bp\">None</span><span class=\"p\">:</span> <span class=\"n\">p1</span> <span class=\"o\">=</span> <span class=\"n\">p1</span><span class=\"p\">.</span><span class=\"nb\">next</span> <span class=\"n\">p2</span> <span class=\"o\">=</span> <span class=\"n\">p2</span><span class=\"p\">.</span><span class=\"nb\">next</span><span class=\"p\">.</span><span class=\"nb\">next</span> <span class=\"n\">rev</span> <span class=\"o\">=</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"nf\">reverse</span><span class=\"p\">(</span><span class=\"n\">p1</span><span class=\"p\">)</span> <span class=\"k\">while</span> <span class=\"n\">head</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"bp\">None</span> <span class=\"ow\">and</span> <span class=\"n\">rev</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"bp\">None</span><span class=\"p\">:</span> <span class=\"k\">if</span> <span class=\"n\">head</span><span class=\"p\">.</span><span class=\"n\">val</span> <span class=\"o\">!=</span> <span class=\"n\">rev</span><span class=\"p\">.</span><span class=\"n\">val</span><span class=\"p\">:</span> <span class=\"k\">return</span> <span class=\"bp\">False</span> <span class=\"n\">rev</span> <span class=\"o\">=</span> <span class=\"n\">rev</span><span class=\"p\">.</span><span class=\"nb\">next</span> <span class=\"n\">head</span> <span class=\"o\">=</span> <span class=\"n\">head</span><span class=\"p\">.</span><span class=\"nb\">next</span> <span class=\"k\">if</span> <span class=\"n\">head</span> <span class=\"o\">==</span> <span class=\"n\">p1</span><span class=\"p\">:</span> <span class=\"n\">head</span> <span class=\"o\">=</span> <span class=\"bp\">None</span> <span class=\"k\">return</span> <span class=\"n\">head</span> <span class=\"ow\">is</span> <span class=\"bp\">None</span> <span class=\"ow\">and</span> <span class=\"n\">rev</span> <span class=\"ow\">is</span> <span class=\"bp\">None</span> <span class=\"k\">def</span> <span class=\"nf\">reverse</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">head</span><span class=\"p\">):</span> <span class=\"n\">prev</span> <span class=\"o\">=</span> <span class=\"bp\">None</span> <span class=\"n\">curr</span> <span class=\"o\">=</span> <span class=\"n\">head</span> <span class=\"k\">while</span> <span class=\"n\">curr</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"bp\">None</span><span class=\"p\">:</span> <span class=\"n\">n</span> <span class=\"o\">=</span> <span class=\"n\">curr</span><span class=\"p\">.</span><span class=\"nb\">next</span> <span class=\"n\">curr</span><span class=\"p\">.</span><span class=\"nb\">next</span> <span class=\"o\">=</span> <span class=\"n\">prev</span> <span class=\"n\">prev</span> <span class=\"o\">=</span> <span class=\"n\">curr</span> <span class=\"n\">curr</span> <span class=\"o\">=</span> <span class=\"n\">n</span> <span class=\"k\">return</span> <span class=\"n\">prev</span></code></pre></figure><blockquote> <p>Runtime: 1729 ms, faster than 12.02% of Python3 online submissions for Palindrome Linked List. Memory Usage: 39.1 MB, less than 77.96% of Python3 online submissions for Palindrome Linked List.</p></blockquote>", "date_published": "2022-11-07T20:00:00+00:00" }, { "id": "https://fewald.net/leetcode/2022/11/06/leetcode-intersection-of-two-arrays-ii.html", "url": "https://fewald.net/leetcode/2022/11/06/leetcode-intersection-of-two-arrays-ii.html", "title": "Leetcode: Intersection of two arrays II", "content_html": "<p>Given two arrays, <code class=\"language-plaintext highlighter-rouge\">nums1</code> and <code class=\"language-plaintext highlighter-rouge\">nums2</code>, return the intersection of those arrays in any order.</p><p>The easiest way I was able to come up with was to sort the arrays first and then look at the beginning of the arrays. If both are equal, add the element to the output and pop the first element from each array. Otherwise, pop the smaller element of both arrays. Repeat this until one of the arrays is empty at which point there can be no more intersecting elements.</p><!--more--><figure class=\"highlight\"><pre><code class=\"language-python\" data-lang=\"python\"><span class=\"k\">class</span> <span class=\"nc\">Solution</span><span class=\"p\">:</span> <span class=\"k\">def</span> <span class=\"nf\">intersect</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">nums1</span><span class=\"p\">:</span> <span class=\"n\">List</span><span class=\"p\">[</span><span class=\"nb\">int</span><span class=\"p\">],</span> <span class=\"n\">nums2</span><span class=\"p\">:</span> <span class=\"n\">List</span><span class=\"p\">[</span><span class=\"nb\">int</span><span class=\"p\">])</span> <span class=\"o\">-></span> <span class=\"n\">List</span><span class=\"p\">[</span><span class=\"nb\">int</span><span class=\"p\">]:</span> <span class=\"n\">nums1</span><span class=\"p\">.</span><span class=\"nf\">sort</span><span class=\"p\">()</span> <span class=\"n\">nums2</span><span class=\"p\">.</span><span class=\"nf\">sort</span><span class=\"p\">()</span> <span class=\"n\">out</span> <span class=\"o\">=</span> <span class=\"p\">[]</span> <span class=\"k\">while</span> <span class=\"nf\">len</span><span class=\"p\">(</span><span class=\"n\">nums1</span><span class=\"p\">)</span> <span class=\"o\">></span> <span class=\"mi\">0</span> <span class=\"ow\">and</span> <span class=\"nf\">len</span><span class=\"p\">(</span><span class=\"n\">nums2</span><span class=\"p\">)</span> <span class=\"o\">></span> <span class=\"mi\">0</span><span class=\"p\">:</span> <span class=\"k\">if</span> <span class=\"n\">nums1</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span> <span class=\"o\">==</span> <span class=\"n\">nums2</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]:</span> <span class=\"n\">out</span><span class=\"p\">.</span><span class=\"nf\">append</span><span class=\"p\">(</span><span class=\"n\">nums1</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">])</span> <span class=\"n\">nums1</span> <span class=\"o\">=</span> <span class=\"n\">nums1</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">:]</span> <span class=\"n\">nums2</span> <span class=\"o\">=</span> <span class=\"n\">nums2</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">:]</span> <span class=\"k\">elif</span> <span class=\"n\">nums1</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span> <span class=\"o\"><</span> <span class=\"n\">nums2</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]:</span> <span class=\"n\">nums1</span> <span class=\"o\">=</span> <span class=\"n\">nums1</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">:]</span> <span class=\"k\">else</span><span class=\"p\">:</span> <span class=\"n\">nums2</span> <span class=\"o\">=</span> <span class=\"n\">nums2</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">:]</span> <span class=\"k\">return</span> <span class=\"n\">out</span></code></pre></figure><blockquote> <p>Runtime: 62 ms, faster than 80.36% of Python3 online submissions for Intersection of Two Arrays II. Memory Usage: 14.2 MB, less than 14.77% of Python3 online submissions for Intersection of Two Arrays II.</p></blockquote>", "date_published": "2022-11-06T20:00:00+00:00" }, { "id": "https://fewald.net/leetcode/2022/11/05/leetcode-power-of-three.html", "url": "https://fewald.net/leetcode/2022/11/05/leetcode-power-of-three.html", "title": "Leetcode: Power of three", "content_html": "<p>Given a number <code class=\"language-plaintext highlighter-rouge\">n</code>, check if this number is a power of three, that is that it can be represented by <code class=\"language-plaintext highlighter-rouge\">3^x</code>.</p><p>A straightforward solution looks as follows. Multiply by <code class=\"language-plaintext highlighter-rouge\">3</code> until we reach <code class=\"language-plaintext highlighter-rouge\">n</code>. If we’re greater than <code class=\"language-plaintext highlighter-rouge\">n</code>, return <code class=\"language-plaintext highlighter-rouge\">False</code>, and <code class=\"language-plaintext highlighter-rouge\">True</code> otherwise.</p><figure class=\"highlight\"><pre><code class=\"language-python\" data-lang=\"python\"><span class=\"k\">class</span> <span class=\"nc\">Solution</span><span class=\"p\">:</span> <span class=\"k\">def</span> <span class=\"nf\">isPowerOfThree</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">n</span><span class=\"p\">:</span> <span class=\"nb\">int</span><span class=\"p\">)</span> <span class=\"o\">-></span> <span class=\"nb\">bool</span><span class=\"p\">:</span> <span class=\"k\">if</span> <span class=\"n\">n</span> <span class=\"o\"><=</span> <span class=\"mi\">0</span><span class=\"p\">:</span> <span class=\"k\">return</span> <span class=\"bp\">False</span> <span class=\"n\">x</span> <span class=\"o\">=</span> <span class=\"mi\">1</span> <span class=\"k\">while</span> <span class=\"n\">x</span> <span class=\"o\"><</span> <span class=\"n\">n</span><span class=\"p\">:</span> <span class=\"n\">x</span> <span class=\"o\">*=</span> <span class=\"mi\">3</span> <span class=\"k\">return</span> <span class=\"n\">x</span> <span class=\"o\">==</span> <span class=\"n\">n</span></code></pre></figure><!--more--><p>A mathematical more elegant solution looks as follows. Create the largest number that is less than <code class=\"language-plaintext highlighter-rouge\">2^31</code>: <code class=\"language-plaintext highlighter-rouge\">3^19</code>. Then use the modulo operator to test if the number is divisible without a rest. If this is the case, <code class=\"language-plaintext highlighter-rouge\">x*n == 3^19</code>, therefore <code class=\"language-plaintext highlighter-rouge\">n</code> is a valid number.</p><figure class=\"highlight\"><pre><code class=\"language-python\" data-lang=\"python\"><span class=\"k\">class</span> <span class=\"nc\">Solution</span><span class=\"p\">:</span> <span class=\"k\">def</span> <span class=\"nf\">isPowerOfThree</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">n</span><span class=\"p\">:</span> <span class=\"nb\">int</span><span class=\"p\">)</span> <span class=\"o\">-></span> <span class=\"nb\">bool</span><span class=\"p\">:</span> <span class=\"k\">return</span> <span class=\"n\">n</span> <span class=\"o\">></span> <span class=\"mi\">0</span> <span class=\"ow\">and</span> <span class=\"nf\">pow</span><span class=\"p\">(</span><span class=\"mi\">3</span><span class=\"p\">,</span><span class=\"mi\">19</span><span class=\"p\">)</span> <span class=\"o\">%</span> <span class=\"n\">n</span> <span class=\"o\">==</span> <span class=\"mi\">0</span></code></pre></figure><blockquote> <p>Runtime: 80 ms, faster than 95.46% of Python3 online submissions for Power of Three. Memory Usage: 13.9 MB, less than 16.48% of Python3 online submissions for Power of Three.</p></blockquote>", "date_published": "2022-11-05T20:00:00+00:00" }, { "id": "https://fewald.net/leetcode/2022/11/04/leetcode-kth-smallest-element-in-matrix.html", "url": "https://fewald.net/leetcode/2022/11/04/leetcode-kth-smallest-element-in-matrix.html", "title": "Leetcode: Kth smallest element in matrix", "content_html": "<p>Given a <code class=\"language-plaintext highlighter-rouge\">n*n</code> matrix, find the <code class=\"language-plaintext highlighter-rouge\">kth</code> smallest element. Each row in the matrix is sorted in ascending order and independent of the other rows. Do not use <code class=\"language-plaintext highlighter-rouge\">O(n*n)</code> space when solving this. One example matrix looks like this:</p><figure class=\"highlight\"><pre><code class=\"language-plain\" data-lang=\"plain\"> 1 5 9 10 11 13 12 13 15For k = 8 return 13 because 13 is the 8th smallest element.</code></pre></figure><p>If we could use all the space we wanted, we could just perform an n-way merge sort on every row at once. This would work because the rows itself are sorted already. Afterwards, we would need to pick the kth element from the list and would be done.</p><!--more--><p>The solution I came up with uses <code class=\"language-plaintext highlighter-rouge\">O(n)</code> space. That is one space for a pointer to each row and column. Initially we set all rows to the first column. Then we iterate over all rows and find the smallest element in this particular position. We advance the pointer to this element by 1. Afterwards we check if we left the bounds of this array. If we did, we remove the row as a possible candidate. Finally, we take the remaining pointers and write them in a list which we sort. From that sorted list, we pick the smallest value and return it.</p><figure class=\"highlight\"><pre><code class=\"language-python\" data-lang=\"python\"><span class=\"k\">class</span> <span class=\"nc\">Solution</span><span class=\"p\">:</span> <span class=\"k\">def</span> <span class=\"nf\">kthSmallest</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">matrix</span><span class=\"p\">:</span> <span class=\"n\">List</span><span class=\"p\">[</span><span class=\"n\">List</span><span class=\"p\">[</span><span class=\"nb\">int</span><span class=\"p\">]],</span> <span class=\"n\">k</span><span class=\"p\">:</span> <span class=\"nb\">int</span><span class=\"p\">)</span> <span class=\"o\">-></span> <span class=\"nb\">int</span><span class=\"p\">:</span> <span class=\"c1\"># Initialize pointer</span> <span class=\"n\">ptr</span> <span class=\"o\">=</span> <span class=\"p\">[[</span><span class=\"n\">i</span><span class=\"p\">,</span><span class=\"mi\">0</span><span class=\"p\">]</span> <span class=\"k\">for</span> <span class=\"n\">i</span> <span class=\"ow\">in</span> <span class=\"nf\">range</span><span class=\"p\">(</span><span class=\"nf\">len</span><span class=\"p\">(</span><span class=\"n\">matrix</span><span class=\"p\">))]</span> <span class=\"n\">min_val</span> <span class=\"o\">=</span> <span class=\"nf\">float</span><span class=\"p\">(</span><span class=\"sh\">'</span><span class=\"s\">inf</span><span class=\"sh\">'</span><span class=\"p\">)</span> <span class=\"n\">min_row</span> <span class=\"o\">=</span> <span class=\"o\">-</span><span class=\"mi\">1</span> <span class=\"k\">while</span> <span class=\"n\">k</span> <span class=\"o\">></span> <span class=\"mi\">1</span><span class=\"p\">:</span> <span class=\"n\">min_val</span> <span class=\"o\">=</span> <span class=\"nf\">float</span><span class=\"p\">(</span><span class=\"sh\">'</span><span class=\"s\">inf</span><span class=\"sh\">'</span><span class=\"p\">)</span> <span class=\"n\">min_row</span> <span class=\"o\">=</span> <span class=\"o\">-</span><span class=\"mi\">1</span> <span class=\"c1\"># Find minimum row</span> <span class=\"k\">for</span> <span class=\"n\">i</span><span class=\"p\">,</span> <span class=\"n\">coords</span> <span class=\"ow\">in</span> <span class=\"nf\">enumerate</span><span class=\"p\">(</span><span class=\"n\">ptr</span><span class=\"p\">):</span> <span class=\"k\">if</span> <span class=\"n\">matrix</span><span class=\"p\">[</span><span class=\"n\">coords</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]][</span><span class=\"n\">coords</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">]]</span> <span class=\"o\"><</span> <span class=\"n\">min_val</span><span class=\"p\">:</span> <span class=\"n\">min_row</span> <span class=\"o\">=</span> <span class=\"n\">i</span> <span class=\"n\">min_val</span> <span class=\"o\">=</span> <span class=\"n\">matrix</span><span class=\"p\">[</span><span class=\"n\">coords</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]][</span><span class=\"n\">coords</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">]]</span> <span class=\"c1\"># Advance minimum row by 1</span> <span class=\"n\">ptr</span><span class=\"p\">[</span><span class=\"n\">min_row</span><span class=\"p\">][</span><span class=\"mi\">1</span><span class=\"p\">]</span> <span class=\"o\">+=</span> <span class=\"mi\">1</span> <span class=\"k\">if</span> <span class=\"n\">ptr</span><span class=\"p\">[</span><span class=\"n\">min_row</span><span class=\"p\">][</span><span class=\"mi\">1</span><span class=\"p\">]</span> <span class=\"o\">>=</span> <span class=\"nf\">len</span><span class=\"p\">(</span><span class=\"n\">matrix</span><span class=\"p\">):</span> <span class=\"k\">del</span> <span class=\"n\">ptr</span><span class=\"p\">[</span><span class=\"n\">min_row</span><span class=\"p\">]</span> <span class=\"n\">k</span> <span class=\"o\">-=</span> <span class=\"mi\">1</span> <span class=\"n\">vals</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"n\">matrix</span><span class=\"p\">[</span><span class=\"n\">row</span><span class=\"p\">][</span><span class=\"n\">col</span><span class=\"p\">]</span> <span class=\"k\">for</span> <span class=\"n\">row</span><span class=\"p\">,</span> <span class=\"n\">col</span> <span class=\"ow\">in</span> <span class=\"n\">ptr</span><span class=\"p\">]</span> <span class=\"n\">vals</span><span class=\"p\">.</span><span class=\"nf\">sort</span><span class=\"p\">()</span> <span class=\"k\">return</span> <span class=\"n\">vals</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span><span class=\"k\">if</span> <span class=\"n\">__name__</span> <span class=\"o\">==</span> <span class=\"sh\">'</span><span class=\"s\">__main__</span><span class=\"sh\">'</span><span class=\"p\">:</span> <span class=\"n\">s</span> <span class=\"o\">=</span> <span class=\"nc\">Solution</span><span class=\"p\">().</span><span class=\"n\">kthSmallest</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">([[</span><span class=\"mi\">1</span><span class=\"p\">,</span><span class=\"mi\">5</span><span class=\"p\">,</span><span class=\"mi\">9</span><span class=\"p\">],[</span><span class=\"mi\">10</span><span class=\"p\">,</span><span class=\"mi\">11</span><span class=\"p\">,</span><span class=\"mi\">13</span><span class=\"p\">],[</span><span class=\"mi\">12</span><span class=\"p\">,</span><span class=\"mi\">13</span><span class=\"p\">,</span><span class=\"mi\">15</span><span class=\"p\">]],</span> <span class=\"mi\">8</span><span class=\"p\">),</span> <span class=\"mi\">13</span><span class=\"p\">)</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">([[</span><span class=\"mi\">1</span><span class=\"p\">,</span><span class=\"mi\">5</span><span class=\"p\">,</span><span class=\"mi\">9</span><span class=\"p\">],[</span><span class=\"mi\">10</span><span class=\"p\">,</span><span class=\"mi\">11</span><span class=\"p\">,</span><span class=\"mi\">13</span><span class=\"p\">],[</span><span class=\"mi\">12</span><span class=\"p\">,</span><span class=\"mi\">13</span><span class=\"p\">,</span><span class=\"mi\">15</span><span class=\"p\">]],</span> <span class=\"mi\">1</span><span class=\"p\">),</span> <span class=\"mi\">1</span><span class=\"p\">)</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">([[</span><span class=\"o\">-</span><span class=\"mi\">5</span><span class=\"p\">]],</span> <span class=\"mi\">1</span><span class=\"p\">),</span> <span class=\"o\">-</span><span class=\"mi\">5</span><span class=\"p\">)</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">([[</span><span class=\"mi\">1</span><span class=\"p\">,</span><span class=\"mi\">2</span><span class=\"p\">],</span> <span class=\"p\">[</span><span class=\"mi\">3</span><span class=\"p\">,</span><span class=\"mi\">3</span><span class=\"p\">]],</span> <span class=\"mi\">2</span><span class=\"p\">),</span> <span class=\"mi\">2</span><span class=\"p\">)</span></code></pre></figure><blockquote> <p>Runtime: 4712 ms, faster than 5.02% of Python3 online submissions for Kth Smallest Element in a Sorted Matrix. Memory Usage: 18.6 MB, less than 80.92% of Python3 online submissions for Kth Smallest Element in a Sorted Matrix.</p></blockquote>", "date_published": "2022-11-04T20:00:00+00:00" }, { "id": "https://fewald.net/leetcode/2022/11/03/leetcode-copy-list-with-random-pointer.html", "url": "https://fewald.net/leetcode/2022/11/03/leetcode-copy-list-with-random-pointer.html", "title": "Leetcode: Copy list with random pointer", "content_html": "<p>Given a <code class=\"language-plaintext highlighter-rouge\">head</code> of a list with pointers to <code class=\"language-plaintext highlighter-rouge\">next</code> and a <code class=\"language-plaintext highlighter-rouge\">random</code> element, copy the list to a new list without any random pointers pointing to the old list.</p><figure class=\"highlight\"><pre><code class=\"language-python\" data-lang=\"python\"><span class=\"c1\"># Definition for a Node.</span><span class=\"k\">class</span> <span class=\"nc\">Node</span><span class=\"p\">:</span> <span class=\"k\">def</span> <span class=\"nf\">__init__</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">x</span><span class=\"p\">:</span> <span class=\"nb\">int</span><span class=\"p\">,</span> <span class=\"nb\">next</span><span class=\"p\">:</span> <span class=\"sh\">'</span><span class=\"s\">Node</span><span class=\"sh\">'</span> <span class=\"o\">=</span> <span class=\"bp\">None</span><span class=\"p\">,</span> <span class=\"n\">random</span><span class=\"p\">:</span> <span class=\"sh\">'</span><span class=\"s\">Node</span><span class=\"sh\">'</span> <span class=\"o\">=</span> <span class=\"bp\">None</span><span class=\"p\">):</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">val</span> <span class=\"o\">=</span> <span class=\"nf\">int</span><span class=\"p\">(</span><span class=\"n\">x</span><span class=\"p\">)</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"nb\">next</span> <span class=\"o\">=</span> <span class=\"nb\">next</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">random</span> <span class=\"o\">=</span> <span class=\"n\">random</span></code></pre></figure><!--more--><p>One way to solve this is to copy first all the nodes into a new list via the <code class=\"language-plaintext highlighter-rouge\">next</code> links. Next, we create two pointers, one pointing at the original list and the other one pointing at the new list. We then iterate over the original list (while moving the second pointer as well) and check at each step if we hit our current node in the original list via <code class=\"language-plaintext highlighter-rouge\">random</code>. If we do, we make a connection in the new list as well. One specialty is that two <code class=\"language-plaintext highlighter-rouge\">random</code> pointers can point at the same element. For this reason, we cannot simply stop once we found the first pointer but have to continue until the end.</p><p>This solution has to iterate multiple times over the same list as we start from the destination and not from the source. For a more efficient solution, see the altnerative solution below.</p><figure class=\"highlight\"><pre><code class=\"language-python\" data-lang=\"python\"><span class=\"kn\">from</span> <span class=\"n\">typing</span> <span class=\"kn\">import</span> <span class=\"n\">Optional</span><span class=\"c1\"># Definition for a Node.</span><span class=\"k\">class</span> <span class=\"nc\">Node</span><span class=\"p\">:</span> <span class=\"k\">def</span> <span class=\"nf\">__init__</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">x</span><span class=\"p\">:</span> <span class=\"nb\">int</span><span class=\"p\">,</span> <span class=\"nb\">next</span><span class=\"p\">:</span> <span class=\"sh\">'</span><span class=\"s\">Node</span><span class=\"sh\">'</span> <span class=\"o\">=</span> <span class=\"bp\">None</span><span class=\"p\">,</span> <span class=\"n\">random</span><span class=\"p\">:</span> <span class=\"sh\">'</span><span class=\"s\">Node</span><span class=\"sh\">'</span> <span class=\"o\">=</span> <span class=\"bp\">None</span><span class=\"p\">):</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">val</span> <span class=\"o\">=</span> <span class=\"nf\">int</span><span class=\"p\">(</span><span class=\"n\">x</span><span class=\"p\">)</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"nb\">next</span> <span class=\"o\">=</span> <span class=\"nb\">next</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">random</span> <span class=\"o\">=</span> <span class=\"n\">random</span> <span class=\"k\">def</span> <span class=\"nf\">__repr__</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">)</span> <span class=\"o\">-></span> <span class=\"nb\">str</span><span class=\"p\">:</span> <span class=\"sh\">\"\"\"</span><span class=\"s\">Convenience method for debugging</span><span class=\"sh\">\"\"\"</span> <span class=\"k\">return</span> <span class=\"nf\">str</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">val</span><span class=\"p\">)</span><span class=\"k\">class</span> <span class=\"nc\">Solution</span><span class=\"p\">:</span> <span class=\"k\">def</span> <span class=\"nf\">copyRandomList</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">head</span><span class=\"p\">:</span> <span class=\"sh\">'</span><span class=\"s\">Optional[Node]</span><span class=\"sh\">'</span><span class=\"p\">)</span> <span class=\"o\">-></span> <span class=\"sh\">'</span><span class=\"s\">Optional[Node]</span><span class=\"sh\">'</span><span class=\"p\">:</span> <span class=\"k\">if</span> <span class=\"n\">head</span> <span class=\"ow\">is</span> <span class=\"bp\">None</span><span class=\"p\">:</span> <span class=\"k\">return</span> <span class=\"bp\">None</span> <span class=\"n\">p1</span> <span class=\"o\">=</span> <span class=\"n\">head</span> <span class=\"c1\"># Copy first node manually</span> <span class=\"n\">new_head</span> <span class=\"o\">=</span> <span class=\"nc\">Node</span><span class=\"p\">(</span><span class=\"n\">head</span><span class=\"p\">.</span><span class=\"n\">val</span><span class=\"p\">)</span> <span class=\"n\">p2</span> <span class=\"o\">=</span> <span class=\"n\">new_head</span> <span class=\"c1\"># Create single linked list</span> <span class=\"k\">while</span> <span class=\"n\">p1</span><span class=\"p\">.</span><span class=\"nb\">next</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"bp\">None</span><span class=\"p\">:</span> <span class=\"n\">p2</span><span class=\"p\">.</span><span class=\"nb\">next</span> <span class=\"o\">=</span> <span class=\"nc\">Node</span><span class=\"p\">(</span><span class=\"n\">p1</span><span class=\"p\">.</span><span class=\"nb\">next</span><span class=\"p\">.</span><span class=\"n\">val</span><span class=\"p\">)</span> <span class=\"n\">p2</span> <span class=\"o\">=</span> <span class=\"n\">p2</span><span class=\"p\">.</span><span class=\"nb\">next</span> <span class=\"n\">p1</span> <span class=\"o\">=</span> <span class=\"n\">p1</span><span class=\"p\">.</span><span class=\"nb\">next</span> <span class=\"c1\"># Reset pointers</span> <span class=\"n\">t1</span> <span class=\"o\">=</span> <span class=\"n\">head</span> <span class=\"n\">t2</span> <span class=\"o\">=</span> <span class=\"n\">new_head</span> <span class=\"k\">while</span> <span class=\"n\">t1</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"bp\">None</span><span class=\"p\">:</span> <span class=\"n\">p1</span> <span class=\"o\">=</span> <span class=\"n\">head</span> <span class=\"n\">p2</span> <span class=\"o\">=</span> <span class=\"n\">new_head</span> <span class=\"k\">while</span> <span class=\"n\">p1</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"bp\">None</span><span class=\"p\">:</span> <span class=\"k\">if</span> <span class=\"n\">p1</span><span class=\"p\">.</span><span class=\"n\">random</span> <span class=\"o\">==</span> <span class=\"n\">t1</span><span class=\"p\">:</span> <span class=\"n\">p2</span><span class=\"p\">.</span><span class=\"n\">random</span> <span class=\"o\">=</span> <span class=\"n\">t2</span> <span class=\"n\">p1</span> <span class=\"o\">=</span> <span class=\"n\">p1</span><span class=\"p\">.</span><span class=\"nb\">next</span> <span class=\"n\">p2</span> <span class=\"o\">=</span> <span class=\"n\">p2</span><span class=\"p\">.</span><span class=\"nb\">next</span> <span class=\"n\">t1</span> <span class=\"o\">=</span> <span class=\"n\">t1</span><span class=\"p\">.</span><span class=\"nb\">next</span> <span class=\"n\">t2</span> <span class=\"o\">=</span> <span class=\"n\">t2</span><span class=\"p\">.</span><span class=\"nb\">next</span> <span class=\"k\">return</span> <span class=\"n\">new_head</span><span class=\"k\">if</span> <span class=\"n\">__name__</span> <span class=\"o\">==</span> <span class=\"sh\">'</span><span class=\"s\">__main__</span><span class=\"sh\">'</span><span class=\"p\">:</span> <span class=\"n\">s</span> <span class=\"o\">=</span> <span class=\"nc\">Solution</span><span class=\"p\">().</span><span class=\"n\">copyRandomList</span> <span class=\"n\">n</span> <span class=\"o\">=</span> <span class=\"nc\">Node</span><span class=\"p\">(</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"nc\">Node</span><span class=\"p\">(</span><span class=\"mi\">2</span><span class=\"p\">,</span> <span class=\"nc\">Node</span><span class=\"p\">(</span><span class=\"mi\">3</span><span class=\"p\">,</span> <span class=\"nc\">Node</span><span class=\"p\">(</span><span class=\"mi\">4</span><span class=\"p\">))))</span> <span class=\"n\">n</span><span class=\"p\">.</span><span class=\"n\">random</span> <span class=\"o\">=</span> <span class=\"n\">n</span><span class=\"p\">.</span><span class=\"nb\">next</span><span class=\"p\">.</span><span class=\"nb\">next</span> <span class=\"n\">n</span><span class=\"p\">.</span><span class=\"n\">random</span><span class=\"p\">.</span><span class=\"n\">random</span> <span class=\"o\">=</span> <span class=\"n\">n</span><span class=\"p\">.</span><span class=\"nb\">next</span><span class=\"p\">.</span><span class=\"nb\">next</span><span class=\"p\">.</span><span class=\"nb\">next</span> <span class=\"n\">n</span><span class=\"p\">.</span><span class=\"n\">random</span><span class=\"p\">.</span><span class=\"n\">random</span><span class=\"p\">.</span><span class=\"n\">random</span> <span class=\"o\">=</span> <span class=\"n\">n</span><span class=\"p\">.</span><span class=\"nb\">next</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">(</span><span class=\"n\">n</span><span class=\"p\">))</span> <span class=\"n\">n</span> <span class=\"o\">=</span> <span class=\"nc\">Node</span><span class=\"p\">(</span><span class=\"mi\">7</span><span class=\"p\">,</span> <span class=\"nc\">Node</span><span class=\"p\">(</span><span class=\"mi\">13</span><span class=\"p\">,</span> <span class=\"nc\">Node</span><span class=\"p\">(</span><span class=\"mi\">11</span><span class=\"p\">,</span> <span class=\"nc\">Node</span><span class=\"p\">(</span><span class=\"mi\">10</span><span class=\"p\">,</span> <span class=\"nc\">Node</span><span class=\"p\">(</span><span class=\"mi\">1</span><span class=\"p\">)))))</span> <span class=\"n\">n</span><span class=\"p\">.</span><span class=\"nb\">next</span><span class=\"p\">.</span><span class=\"n\">random</span> <span class=\"o\">=</span> <span class=\"n\">n</span> <span class=\"n\">n</span><span class=\"p\">.</span><span class=\"nb\">next</span><span class=\"p\">.</span><span class=\"nb\">next</span><span class=\"p\">.</span><span class=\"n\">random</span> <span class=\"o\">=</span> <span class=\"n\">n</span><span class=\"p\">.</span><span class=\"nb\">next</span><span class=\"p\">.</span><span class=\"nb\">next</span><span class=\"p\">.</span><span class=\"nb\">next</span><span class=\"p\">.</span><span class=\"nb\">next</span> <span class=\"n\">n</span><span class=\"p\">.</span><span class=\"nb\">next</span><span class=\"p\">.</span><span class=\"nb\">next</span><span class=\"p\">.</span><span class=\"nb\">next</span><span class=\"p\">.</span><span class=\"n\">random</span> <span class=\"o\">=</span> <span class=\"n\">n</span><span class=\"p\">.</span><span class=\"nb\">next</span><span class=\"p\">.</span><span class=\"nb\">next</span> <span class=\"n\">n</span><span class=\"p\">.</span><span class=\"nb\">next</span><span class=\"p\">.</span><span class=\"nb\">next</span><span class=\"p\">.</span><span class=\"nb\">next</span><span class=\"p\">.</span><span class=\"nb\">next</span><span class=\"p\">.</span><span class=\"n\">random</span> <span class=\"o\">=</span> <span class=\"n\">n</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">(</span><span class=\"n\">n</span><span class=\"p\">))</span> </code></pre></figure><blockquote> <p>Runtime: 106 ms, faster than 5.23% of Python3 online submissions for Copy List with Random Pointer. Memory Usage: 15 MB, less than 46.50% of Python3 online submissions for Copy List with Random Pointer.</p></blockquote><h2 id=\"alternate-solution\">Alternate Solution</h2><p>Another solution is to first interweave the new nodes with the old nodes such that after each original node, there’s a copy of the original node, pointing to the next node, and so on. When following for every node the <code class=\"language-plaintext highlighter-rouge\">random</code> path, we just can set the <code class=\"language-plaintext highlighter-rouge\">next.random</code> to <code class=\"language-plaintext highlighter-rouge\">random.next</code> as the copy of the node comes always after the original node. This allows for a time complexity of <code class=\"language-plaintext highlighter-rouge\">O(3n)</code>.</p><figure class=\"highlight\"><pre><code class=\"language-python\" data-lang=\"python\"><span class=\"sh\">\"\"\"</span><span class=\"s\"># Definition for a Node.class Node: def __init__(self, x: int, next: </span><span class=\"sh\">'</span><span class=\"s\">Node</span><span class=\"sh\">'</span><span class=\"s\"> = None, random: </span><span class=\"sh\">'</span><span class=\"s\">Node</span><span class=\"sh\">'</span><span class=\"s\"> = None): self.val = int(x) self.next = next self.random = random</span><span class=\"sh\">\"\"\"</span><span class=\"k\">class</span> <span class=\"nc\">Solution</span><span class=\"p\">:</span> <span class=\"k\">def</span> <span class=\"nf\">copyRandomList</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">head</span><span class=\"p\">:</span> <span class=\"sh\">'</span><span class=\"s\">Optional[Node]</span><span class=\"sh\">'</span><span class=\"p\">)</span> <span class=\"o\">-></span> <span class=\"sh\">'</span><span class=\"s\">Optional[Node]</span><span class=\"sh\">'</span><span class=\"p\">:</span> <span class=\"k\">if</span> <span class=\"n\">head</span> <span class=\"ow\">is</span> <span class=\"bp\">None</span><span class=\"p\">:</span> <span class=\"k\">return</span> <span class=\"n\">head</span> <span class=\"c1\"># Step 1: Interweave new nodes in old list</span> <span class=\"n\">curr</span> <span class=\"o\">=</span> <span class=\"n\">head</span> <span class=\"k\">while</span> <span class=\"n\">curr</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"bp\">None</span><span class=\"p\">:</span> <span class=\"n\">n</span> <span class=\"o\">=</span> <span class=\"nc\">Node</span><span class=\"p\">(</span><span class=\"n\">x</span><span class=\"o\">=</span><span class=\"n\">curr</span><span class=\"p\">.</span><span class=\"n\">val</span><span class=\"p\">,</span> <span class=\"nb\">next</span><span class=\"o\">=</span><span class=\"n\">curr</span><span class=\"p\">.</span><span class=\"nb\">next</span><span class=\"p\">)</span> <span class=\"n\">curr</span><span class=\"p\">.</span><span class=\"nb\">next</span> <span class=\"o\">=</span> <span class=\"n\">n</span> <span class=\"n\">curr</span> <span class=\"o\">=</span> <span class=\"n\">curr</span><span class=\"p\">.</span><span class=\"nb\">next</span><span class=\"p\">.</span><span class=\"nb\">next</span> <span class=\"c1\"># Step 2: Copy random pointers</span> <span class=\"n\">curr</span> <span class=\"o\">=</span> <span class=\"n\">head</span> <span class=\"k\">while</span> <span class=\"n\">curr</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"bp\">None</span> <span class=\"ow\">and</span> <span class=\"n\">curr</span><span class=\"p\">.</span><span class=\"nb\">next</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"bp\">None</span><span class=\"p\">:</span> <span class=\"k\">if</span> <span class=\"n\">curr</span><span class=\"p\">.</span><span class=\"n\">random</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"bp\">None</span><span class=\"p\">:</span> <span class=\"n\">curr</span><span class=\"p\">.</span><span class=\"nb\">next</span><span class=\"p\">.</span><span class=\"n\">random</span> <span class=\"o\">=</span> <span class=\"n\">curr</span><span class=\"p\">.</span><span class=\"n\">random</span><span class=\"p\">.</span><span class=\"nb\">next</span> <span class=\"c1\"># Jump always 2 to avoid copied nodes</span> <span class=\"n\">curr</span> <span class=\"o\">=</span> <span class=\"n\">curr</span><span class=\"p\">.</span><span class=\"nb\">next</span><span class=\"p\">.</span><span class=\"nb\">next</span> <span class=\"c1\"># Step 3: Isolate new nodes</span> <span class=\"n\">curr</span> <span class=\"o\">=</span> <span class=\"n\">head</span><span class=\"p\">.</span><span class=\"nb\">next</span> <span class=\"n\">new_head</span> <span class=\"o\">=</span> <span class=\"n\">curr</span> <span class=\"k\">while</span> <span class=\"n\">curr</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"bp\">None</span><span class=\"p\">:</span> <span class=\"k\">if</span> <span class=\"n\">curr</span><span class=\"p\">.</span><span class=\"nb\">next</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"bp\">None</span><span class=\"p\">:</span> <span class=\"n\">curr</span><span class=\"p\">.</span><span class=\"nb\">next</span> <span class=\"o\">=</span> <span class=\"n\">curr</span><span class=\"p\">.</span><span class=\"nb\">next</span><span class=\"p\">.</span><span class=\"nb\">next</span> <span class=\"n\">curr</span> <span class=\"o\">=</span> <span class=\"n\">curr</span><span class=\"p\">.</span><span class=\"nb\">next</span> <span class=\"k\">return</span> <span class=\"n\">new_head</span></code></pre></figure>", "date_published": "2022-11-03T20:00:00+00:00" }, { "id": "https://fewald.net/leetcode/2022/11/02/leetcode-decode-ways.html", "url": "https://fewald.net/leetcode/2022/11/02/leetcode-decode-ways.html", "title": "Leetcode: Decode ways", "content_html": "<p>Characters can be encoded via different numbers. <code class=\"language-plaintext highlighter-rouge\">A -> 1, B -> 2, ..., Z -> 26</code>. Given a string <code class=\"language-plaintext highlighter-rouge\">s</code> of numbers, return the number of possible decodings. For example <code class=\"language-plaintext highlighter-rouge\">12</code> can be decoded as <code class=\"language-plaintext highlighter-rouge\">A,B</code> and as <code class=\"language-plaintext highlighter-rouge\">L</code>.</p><!--more--><p>We can look at this problem as a recursive problem. By checking the first two characters of each string, we can see if we decode it in zero, one or two ways. It is impossible to decode a string if it starts in <code class=\"language-plaintext highlighter-rouge\">0</code>, according to the rules. In this case we can return immediately and do not need to proceed further.</p><p>Next, we test if the string is at least <code class=\"language-plaintext highlighter-rouge\">2</code> long. If this is the case we can either decode it as a single character or as two characters. The exception for two characters is that the number has to be below or equal to <code class=\"language-plaintext highlighter-rouge\">26</code>.</p><p>Lastly, it is a good idea to add memoization to the algorithm and avoid performing the same operation twice. For example if we have a string of length 4: <code class=\"language-plaintext highlighter-rouge\">1-1-1-1</code>, we can decode it as <code class=\"language-plaintext highlighter-rouge\">11-...</code> or as <code class=\"language-plaintext highlighter-rouge\">1-1...</code>. However, the number of ways the remainder can be decoded stays the same.</p><figure class=\"highlight\"><pre><code class=\"language-python\" data-lang=\"python\"><span class=\"k\">class</span> <span class=\"nc\">Solution</span><span class=\"p\">:</span> <span class=\"k\">def</span> <span class=\"nf\">numDecodings</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">s</span><span class=\"p\">:</span> <span class=\"nb\">str</span><span class=\"p\">)</span> <span class=\"o\">-></span> <span class=\"nb\">int</span><span class=\"p\">:</span> <span class=\"n\">mem</span> <span class=\"o\">=</span> <span class=\"p\">{}</span> <span class=\"k\">def</span> <span class=\"nf\">inner</span><span class=\"p\">(</span><span class=\"n\">s</span><span class=\"p\">):</span> <span class=\"k\">if</span> <span class=\"n\">s</span> <span class=\"ow\">in</span> <span class=\"n\">mem</span><span class=\"p\">:</span> <span class=\"k\">return</span> <span class=\"n\">mem</span><span class=\"p\">[</span><span class=\"n\">s</span><span class=\"p\">]</span> <span class=\"k\">if</span> <span class=\"n\">s</span> <span class=\"o\">==</span> <span class=\"sh\">\"\"</span><span class=\"p\">:</span> <span class=\"k\">return</span> <span class=\"mi\">1</span> <span class=\"k\">if</span> <span class=\"n\">s</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span> <span class=\"o\">==</span> <span class=\"sh\">'</span><span class=\"s\">0</span><span class=\"sh\">'</span><span class=\"p\">:</span> <span class=\"k\">return</span> <span class=\"mi\">0</span> <span class=\"k\">if</span> <span class=\"nf\">len</span><span class=\"p\">(</span><span class=\"n\">s</span><span class=\"p\">)</span> <span class=\"o\">>=</span> <span class=\"mi\">2</span> <span class=\"ow\">and</span> <span class=\"n\">s</span><span class=\"p\">[:</span><span class=\"mi\">2</span><span class=\"p\">]</span> <span class=\"o\"><=</span> <span class=\"sh\">'</span><span class=\"s\">26</span><span class=\"sh\">'</span><span class=\"p\">:</span> <span class=\"n\">mem</span><span class=\"p\">[</span><span class=\"n\">s</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"nf\">inner</span><span class=\"p\">(</span><span class=\"n\">s</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">:])</span> <span class=\"o\">+</span> <span class=\"nf\">inner</span><span class=\"p\">(</span><span class=\"n\">s</span><span class=\"p\">[</span><span class=\"mi\">2</span><span class=\"p\">:])</span> <span class=\"k\">return</span> <span class=\"n\">mem</span><span class=\"p\">[</span><span class=\"n\">s</span><span class=\"p\">]</span> <span class=\"k\">else</span><span class=\"p\">:</span> <span class=\"n\">mem</span><span class=\"p\">[</span><span class=\"n\">s</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"nf\">inner</span><span class=\"p\">(</span><span class=\"n\">s</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">:])</span> <span class=\"k\">return</span> <span class=\"n\">mem</span><span class=\"p\">[</span><span class=\"n\">s</span><span class=\"p\">]</span> <span class=\"k\">return</span> <span class=\"nf\">inner</span><span class=\"p\">(</span><span class=\"n\">s</span><span class=\"p\">)</span><span class=\"k\">if</span> <span class=\"n\">__name__</span> <span class=\"o\">==</span> <span class=\"sh\">'</span><span class=\"s\">__main__</span><span class=\"sh\">'</span><span class=\"p\">:</span> <span class=\"n\">s</span> <span class=\"o\">=</span> <span class=\"nc\">Solution</span><span class=\"p\">().</span><span class=\"n\">numDecodings</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">(</span><span class=\"sh\">'</span><span class=\"s\">11106</span><span class=\"sh\">'</span><span class=\"p\">),</span> <span class=\"mi\">2</span><span class=\"p\">)</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">(</span><span class=\"sh\">'</span><span class=\"s\">06</span><span class=\"sh\">'</span><span class=\"p\">),</span> <span class=\"mi\">0</span><span class=\"p\">)</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">(</span><span class=\"sh\">'</span><span class=\"s\">12</span><span class=\"sh\">'</span><span class=\"p\">),</span> <span class=\"mi\">2</span><span class=\"p\">)</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">(</span><span class=\"sh\">'</span><span class=\"s\">226</span><span class=\"sh\">'</span><span class=\"p\">),</span> <span class=\"mi\">3</span><span class=\"p\">)</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">(</span><span class=\"sh\">\"</span><span class=\"s\">2611055971756562</span><span class=\"sh\">\"</span><span class=\"p\">),</span> <span class=\"mi\">4</span><span class=\"p\">)</span></code></pre></figure><blockquote> <p>Runtime: 74 ms, faster than 8.01% of Python3 online submissions for Decode Ways. Memory Usage: 14.3 MB, less than 6.92% of Python3 online submissions for Decode Ways.</p></blockquote>", "date_published": "2022-11-02T20:00:00+00:00" }, { "id": "https://fewald.net/leetcode/2022/11/01/leetcode-reconstruct-binary-tree.html", "url": "https://fewald.net/leetcode/2022/11/01/leetcode-reconstruct-binary-tree.html", "title": "Leetcode: Reconstruct binary tree", "content_html": "<p>Given two lists of a <code class=\"language-plaintext highlighter-rouge\">preorder</code> and <code class=\"language-plaintext highlighter-rouge\">inorder</code>, create a tree and return the <code class=\"language-plaintext highlighter-rouge\">root</code> node.</p><figure class=\"highlight\"><pre><code class=\"language-plain\" data-lang=\"plain\">preorder: [3,9,20,15,7]inorder: [9,3,15,20,7]Resulting tree: 3 / \\ 9 20 / \\ 15 7</code></pre></figure><p>The problem is not so obvious at first. If the preorder list would also contain <code class=\"language-plaintext highlighter-rouge\">null</code> values for the places where the tree does not contain nodes, we could simply iterate over this list and reconstruct the tree from there. But since the <code class=\"language-plaintext highlighter-rouge\">null</code> values are missing, we also need to take a look at the <code class=\"language-plaintext highlighter-rouge\">inorder</code> list.</p><!--more--><p>We know about the <code class=\"language-plaintext highlighter-rouge\">preorder</code> list that the traversal is as follows: <code class=\"language-plaintext highlighter-rouge\">NLR</code>. This means that first the node is visited, then we go recursively to the left, and then recursively to the right. For <code class=\"language-plaintext highlighter-rouge\">inorder</code> it is <code class=\"language-plaintext highlighter-rouge\">LNR</code>: We go recursively to the left, then output the node, and finally go to the right.</p><p>Because of those properties, we know that the <code class=\"language-plaintext highlighter-rouge\">root</code> node is the first one in the <code class=\"language-plaintext highlighter-rouge\">preorder</code> list. Since there is only one <code class=\"language-plaintext highlighter-rouge\">root</code> node, we know that the next node will be in the next level. We don’t know, from looking at the <code class=\"language-plaintext highlighter-rouge\">preorder</code> list, if the next child node is to the left or right. To figure this out, we need to look at the <code class=\"language-plaintext highlighter-rouge\">inorder</code> list. If the node is to the left of our current element, know that it must be the immediate child to the left. We then determine the position of the node in the <code class=\"language-plaintext highlighter-rouge\">inorder</code> list and pass it recursively to the same method.</p><p>If it is to the right, we remove the left prefix from the <code class=\"language-plaintext highlighter-rouge\">preorder</code> list, add it as a right node, and pass in the left and right lists to the recursive function. Finally, we return the <code class=\"language-plaintext highlighter-rouge\">root</code> node.</p><figure class=\"highlight\"><pre><code class=\"language-python\" data-lang=\"python\"><span class=\"kn\">from</span> <span class=\"n\">typing</span> <span class=\"kn\">import</span> <span class=\"n\">List</span><span class=\"p\">,</span> <span class=\"n\">Optional</span><span class=\"c1\"># Definition for a binary tree node.</span><span class=\"k\">class</span> <span class=\"nc\">TreeNode</span><span class=\"p\">:</span> <span class=\"k\">def</span> <span class=\"nf\">__init__</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">val</span><span class=\"o\">=</span><span class=\"mi\">0</span><span class=\"p\">,</span> <span class=\"n\">left</span><span class=\"o\">=</span><span class=\"bp\">None</span><span class=\"p\">,</span> <span class=\"n\">right</span><span class=\"o\">=</span><span class=\"bp\">None</span><span class=\"p\">):</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">val</span> <span class=\"o\">=</span> <span class=\"n\">val</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">left</span> <span class=\"o\">=</span> <span class=\"n\">left</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">right</span> <span class=\"o\">=</span> <span class=\"n\">right</span> <span class=\"k\">def</span> <span class=\"nf\">__repr__</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">)</span> <span class=\"o\">-></span> <span class=\"nb\">str</span><span class=\"p\">:</span> <span class=\"sh\">\"\"\"</span><span class=\"s\">Convenience function for easy debugging</span><span class=\"sh\">\"\"\"</span> <span class=\"k\">return</span> <span class=\"nf\">str</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">val</span><span class=\"p\">)</span><span class=\"k\">class</span> <span class=\"nc\">Solution</span><span class=\"p\">:</span> <span class=\"k\">def</span> <span class=\"nf\">buildTree</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">preorder</span><span class=\"p\">:</span> <span class=\"n\">List</span><span class=\"p\">[</span><span class=\"nb\">int</span><span class=\"p\">],</span> <span class=\"n\">inorder</span><span class=\"p\">:</span> <span class=\"n\">List</span><span class=\"p\">[</span><span class=\"nb\">int</span><span class=\"p\">])</span> <span class=\"o\">-></span> <span class=\"n\">Optional</span><span class=\"p\">[</span><span class=\"n\">TreeNode</span><span class=\"p\">]:</span> <span class=\"k\">if</span> <span class=\"nf\">len</span><span class=\"p\">(</span><span class=\"n\">preorder</span><span class=\"p\">)</span> <span class=\"o\">==</span> <span class=\"mi\">0</span><span class=\"p\">:</span> <span class=\"k\">return</span> <span class=\"bp\">None</span> <span class=\"k\">def</span> <span class=\"nf\">inner</span><span class=\"p\">(</span><span class=\"n\">root</span><span class=\"p\">,</span> <span class=\"n\">preorder</span><span class=\"p\">,</span> <span class=\"n\">left</span><span class=\"p\">,</span> <span class=\"n\">right</span><span class=\"p\">):</span> <span class=\"k\">if</span> <span class=\"nf\">len</span><span class=\"p\">(</span><span class=\"n\">preorder</span><span class=\"p\">)</span> <span class=\"o\">==</span> <span class=\"mi\">0</span><span class=\"p\">:</span> <span class=\"k\">return</span> <span class=\"c1\"># Determine if the element is left or right</span> <span class=\"n\">curr</span> <span class=\"o\">=</span> <span class=\"n\">preorder</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span> <span class=\"n\">idx</span> <span class=\"o\">=</span> <span class=\"o\">-</span><span class=\"mi\">1</span> <span class=\"k\">for</span> <span class=\"n\">i</span> <span class=\"ow\">in</span> <span class=\"nf\">range</span><span class=\"p\">(</span><span class=\"nf\">len</span><span class=\"p\">(</span><span class=\"n\">left</span><span class=\"p\">)):</span> <span class=\"k\">if</span> <span class=\"n\">left</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">]</span> <span class=\"o\">==</span> <span class=\"n\">curr</span><span class=\"p\">:</span> <span class=\"n\">idx</span> <span class=\"o\">=</span> <span class=\"n\">i</span> <span class=\"k\">break</span> <span class=\"c1\"># Next element is in the left part</span> <span class=\"k\">if</span> <span class=\"n\">idx</span> <span class=\"o\">></span> <span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">:</span> <span class=\"n\">root</span><span class=\"p\">.</span><span class=\"n\">left</span> <span class=\"o\">=</span> <span class=\"nc\">TreeNode</span><span class=\"p\">(</span><span class=\"n\">curr</span><span class=\"p\">)</span> <span class=\"nf\">inner</span><span class=\"p\">(</span><span class=\"n\">root</span><span class=\"p\">.</span><span class=\"n\">left</span><span class=\"p\">,</span> <span class=\"n\">preorder</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">:],</span> <span class=\"n\">left</span><span class=\"p\">[:</span><span class=\"n\">idx</span><span class=\"p\">],</span> <span class=\"n\">left</span><span class=\"p\">[</span><span class=\"n\">idx</span><span class=\"o\">+</span><span class=\"mi\">1</span><span class=\"p\">:])</span> <span class=\"n\">preorder</span> <span class=\"o\">=</span> <span class=\"n\">preorder</span><span class=\"p\">[</span><span class=\"nf\">len</span><span class=\"p\">(</span><span class=\"n\">left</span><span class=\"p\">):]</span> <span class=\"n\">idx</span> <span class=\"o\">=</span> <span class=\"o\">-</span><span class=\"mi\">1</span> <span class=\"k\">for</span> <span class=\"n\">i</span> <span class=\"ow\">in</span> <span class=\"nf\">range</span><span class=\"p\">(</span><span class=\"nf\">len</span><span class=\"p\">(</span><span class=\"n\">right</span><span class=\"p\">)):</span> <span class=\"k\">if</span> <span class=\"n\">right</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">]</span> <span class=\"o\">==</span> <span class=\"n\">preorder</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]:</span> <span class=\"n\">idx</span> <span class=\"o\">=</span> <span class=\"n\">i</span> <span class=\"k\">break</span> <span class=\"k\">if</span> <span class=\"n\">idx</span> <span class=\"o\">></span> <span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">:</span> <span class=\"n\">root</span><span class=\"p\">.</span><span class=\"n\">right</span> <span class=\"o\">=</span> <span class=\"nc\">TreeNode</span><span class=\"p\">(</span><span class=\"n\">preorder</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">])</span> <span class=\"nf\">inner</span><span class=\"p\">(</span><span class=\"n\">root</span><span class=\"p\">.</span><span class=\"n\">right</span><span class=\"p\">,</span> <span class=\"n\">preorder</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">:],</span> <span class=\"n\">right</span><span class=\"p\">[:</span><span class=\"n\">idx</span><span class=\"p\">],</span> <span class=\"n\">right</span><span class=\"p\">[</span><span class=\"n\">idx</span><span class=\"o\">+</span><span class=\"mi\">1</span><span class=\"p\">:])</span> <span class=\"n\">root</span> <span class=\"o\">=</span> <span class=\"nc\">TreeNode</span><span class=\"p\">(</span><span class=\"n\">preorder</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">])</span> <span class=\"n\">idx</span> <span class=\"o\">=</span> <span class=\"o\">-</span><span class=\"mi\">1</span> <span class=\"k\">for</span> <span class=\"n\">i</span> <span class=\"ow\">in</span> <span class=\"nf\">range</span><span class=\"p\">(</span><span class=\"nf\">len</span><span class=\"p\">(</span><span class=\"n\">inorder</span><span class=\"p\">)):</span> <span class=\"k\">if</span> <span class=\"n\">inorder</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">]</span> <span class=\"o\">==</span> <span class=\"n\">preorder</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]:</span> <span class=\"n\">idx</span> <span class=\"o\">=</span> <span class=\"n\">i</span> <span class=\"nf\">inner</span><span class=\"p\">(</span><span class=\"n\">root</span><span class=\"p\">,</span> <span class=\"n\">preorder</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">:],</span> <span class=\"n\">inorder</span><span class=\"p\">[:</span><span class=\"n\">idx</span><span class=\"p\">],</span> <span class=\"n\">inorder</span><span class=\"p\">[</span><span class=\"n\">idx</span><span class=\"o\">+</span><span class=\"mi\">1</span><span class=\"p\">:])</span> <span class=\"k\">return</span> <span class=\"n\">root</span> <span class=\"k\">if</span> <span class=\"n\">__name__</span> <span class=\"o\">==</span> <span class=\"sh\">'</span><span class=\"s\">__main__</span><span class=\"sh\">'</span><span class=\"p\">:</span> <span class=\"n\">s</span> <span class=\"o\">=</span> <span class=\"nc\">Solution</span><span class=\"p\">().</span><span class=\"n\">buildTree</span> <span class=\"n\">t1</span> <span class=\"o\">=</span> <span class=\"nc\">TreeNode</span><span class=\"p\">(</span><span class=\"mi\">3</span><span class=\"p\">,</span> <span class=\"nc\">TreeNode</span><span class=\"p\">(</span><span class=\"mi\">9</span><span class=\"p\">),</span> <span class=\"nc\">TreeNode</span><span class=\"p\">(</span><span class=\"mi\">20</span><span class=\"p\">,</span> <span class=\"nc\">TreeNode</span><span class=\"p\">(</span><span class=\"mi\">15</span><span class=\"p\">),</span> <span class=\"nc\">TreeNode</span><span class=\"p\">(</span><span class=\"mi\">7</span><span class=\"p\">)))</span> <span class=\"c1\"># print(s([3,9,20,15,7,81], [9,3,15,20,81,7]), t1)</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">([</span><span class=\"mi\">3</span><span class=\"p\">,</span><span class=\"mi\">1</span><span class=\"p\">,</span><span class=\"mi\">2</span><span class=\"p\">,</span><span class=\"mi\">4</span><span class=\"p\">],</span> <span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">,</span><span class=\"mi\">2</span><span class=\"p\">,</span><span class=\"mi\">3</span><span class=\"p\">,</span><span class=\"mi\">4</span><span class=\"p\">]))</span></code></pre></figure><blockquote> <p>Runtime: 722 ms, faster than 5.01% of Python3 online submissions for Construct Binary Tree from Preorder and Inorder Traversal. Memory Usage: 89.2 MB, less than 5.37% of Python3 online submissions for Construct Binary Tree from Preorder and Inorder Traversal.</p></blockquote>", "date_published": "2022-11-01T20:00:00+00:00" }, { "id": "https://fewald.net/leetcode/2022/10/31/leetcode-validate-binary-search-tree.html", "url": "https://fewald.net/leetcode/2022/10/31/leetcode-validate-binary-search-tree.html", "title": "Leetcode: Validate Binary Search Tree", "content_html": "<p>Given the <code class=\"language-plaintext highlighter-rouge\">root</code> node of a tree, validate whether it is a valid <strong>Binary Search Tree</strong>. This is a tree where each node is unique, left children are smaller than the root and right children are greater than the root.</p><!--more--><p>Because we’re dealing with a tree, there are two possible algorithms that we can use: DFS and BFS. In this case, I decided to go with a recursive DFS approach. In a simple example we see, that we need to compare the <code class=\"language-plaintext highlighter-rouge\">left</code> child with the <code class=\"language-plaintext highlighter-rouge\">val</code> of the current node. If the <code class=\"language-plaintext highlighter-rouge\">left</code> child is equal or greater than the value of the root node, we can return <code class=\"language-plaintext highlighter-rouge\">False</code> immediately and don’t need to traverse through the rest of the tree. Otherwise, we need to recursively visit the <code class=\"language-plaintext highlighter-rouge\">left</code> and <code class=\"language-plaintext highlighter-rouge\">right</code> children respectively.</p><figure class=\"highlight\"><pre><code class=\"language-plain\" data-lang=\"plain\"> 2 / \\ 1 5</code></pre></figure><p>If we expand the example above, we now see that we need to check also the children of <code class=\"language-plaintext highlighter-rouge\">5</code>. We then need to compare them to the <code class=\"language-plaintext highlighter-rouge\">root</code> of the tree. In this particular example, <code class=\"language-plaintext highlighter-rouge\">2</code> is less than <code class=\"language-plaintext highlighter-rouge\">3</code> and the tree is not a valid binary search tree.</p><p>To make the comparison recursively, we can pass ranges to the method in which the value has to be. We start with <code class=\"language-plaintext highlighter-rouge\">[float('-inf'), float('inf')]</code> and update it once we reach the first node. If we go to the left, we know that the <strong>upper</strong> boundary is now the nodes values. If we go to the right, we set the <strong>lower</strong> boundary to the <code class=\"language-plaintext highlighter-rouge\">max(lower, node.value)</code>.</p><figure class=\"highlight\"><pre><code class=\"language-plain\" data-lang=\"plain\"> 3 / \\ 1 5 / \\ 2 9</code></pre></figure><p>Using <code class=\"language-plaintext highlighter-rouge\">float('-inf')</code> and <code class=\"language-plaintext highlighter-rouge\">float('inf')</code> respectively is a common way to initialize values in Python that need to get updated iteratively. The end result is the following code.</p><figure class=\"highlight\"><pre><code class=\"language-python\" data-lang=\"python\"><span class=\"kn\">from</span> <span class=\"n\">typing</span> <span class=\"kn\">import</span> <span class=\"n\">List</span><span class=\"p\">,</span> <span class=\"n\">Optional</span><span class=\"c1\"># Definition for a binary tree node.</span><span class=\"k\">class</span> <span class=\"nc\">TreeNode</span><span class=\"p\">:</span> <span class=\"k\">def</span> <span class=\"nf\">__init__</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">val</span><span class=\"o\">=</span><span class=\"mi\">0</span><span class=\"p\">,</span> <span class=\"n\">left</span><span class=\"o\">=</span><span class=\"bp\">None</span><span class=\"p\">,</span> <span class=\"n\">right</span><span class=\"o\">=</span><span class=\"bp\">None</span><span class=\"p\">):</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">val</span> <span class=\"o\">=</span> <span class=\"n\">val</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">left</span> <span class=\"o\">=</span> <span class=\"n\">left</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">right</span> <span class=\"o\">=</span> <span class=\"n\">right</span> <span class=\"k\">def</span> <span class=\"nf\">__repr__</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">)</span> <span class=\"o\">-></span> <span class=\"nb\">str</span><span class=\"p\">:</span> <span class=\"sh\">\"\"\"</span><span class=\"s\">Convenience function for easy debugging</span><span class=\"sh\">\"\"\"</span> <span class=\"k\">return</span> <span class=\"nf\">str</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">val</span><span class=\"p\">)</span><span class=\"k\">class</span> <span class=\"nc\">Solution</span><span class=\"p\">:</span> <span class=\"k\">def</span> <span class=\"nf\">isValidBST</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">root</span><span class=\"p\">:</span> <span class=\"n\">Optional</span><span class=\"p\">[</span><span class=\"n\">TreeNode</span><span class=\"p\">])</span> <span class=\"o\">-></span> <span class=\"nb\">bool</span><span class=\"p\">:</span> <span class=\"k\">if</span> <span class=\"n\">root</span> <span class=\"ow\">is</span> <span class=\"bp\">None</span><span class=\"p\">:</span> <span class=\"k\">return</span> <span class=\"bp\">None</span> <span class=\"k\">def</span> <span class=\"nf\">inner</span><span class=\"p\">(</span><span class=\"n\">root</span><span class=\"p\">,</span> <span class=\"n\">lt</span><span class=\"o\">=</span><span class=\"bp\">None</span><span class=\"p\">,</span> <span class=\"n\">gt</span><span class=\"o\">=</span><span class=\"bp\">None</span><span class=\"p\">):</span> <span class=\"k\">if</span> <span class=\"n\">root</span> <span class=\"ow\">is</span> <span class=\"bp\">None</span><span class=\"p\">:</span> <span class=\"k\">return</span> <span class=\"bp\">True</span> <span class=\"k\">if</span> <span class=\"n\">root</span><span class=\"p\">.</span><span class=\"n\">val</span> <span class=\"o\"><=</span> <span class=\"n\">lt</span> <span class=\"ow\">or</span> <span class=\"n\">root</span><span class=\"p\">.</span><span class=\"n\">val</span> <span class=\"o\">>=</span> <span class=\"n\">gt</span><span class=\"p\">:</span> <span class=\"k\">return</span> <span class=\"bp\">False</span> <span class=\"n\">left</span> <span class=\"o\">=</span> <span class=\"nf\">inner</span><span class=\"p\">(</span><span class=\"n\">root</span><span class=\"p\">.</span><span class=\"n\">left</span><span class=\"p\">,</span> <span class=\"n\">lt</span><span class=\"o\">=</span><span class=\"n\">lt</span><span class=\"p\">,</span> <span class=\"n\">gt</span><span class=\"o\">=</span><span class=\"nf\">min</span><span class=\"p\">(</span><span class=\"n\">gt</span><span class=\"p\">,</span> <span class=\"n\">root</span><span class=\"p\">.</span><span class=\"n\">val</span><span class=\"p\">))</span> <span class=\"n\">right</span> <span class=\"o\">=</span> <span class=\"nf\">inner</span><span class=\"p\">(</span><span class=\"n\">root</span><span class=\"p\">.</span><span class=\"n\">right</span><span class=\"p\">,</span> <span class=\"n\">lt</span><span class=\"o\">=</span><span class=\"nf\">max</span><span class=\"p\">(</span><span class=\"n\">lt</span><span class=\"p\">,</span> <span class=\"n\">root</span><span class=\"p\">.</span><span class=\"n\">val</span><span class=\"p\">),</span> <span class=\"n\">gt</span><span class=\"o\">=</span><span class=\"n\">gt</span><span class=\"p\">)</span> <span class=\"k\">return</span> <span class=\"n\">left</span> <span class=\"ow\">and</span> <span class=\"n\">right</span> <span class=\"k\">return</span> <span class=\"nf\">inner</span><span class=\"p\">(</span><span class=\"n\">root</span><span class=\"p\">,</span> <span class=\"nf\">float</span><span class=\"p\">(</span><span class=\"sh\">'</span><span class=\"s\">-inf</span><span class=\"sh\">'</span><span class=\"p\">),</span> <span class=\"nf\">float</span><span class=\"p\">(</span><span class=\"sh\">'</span><span class=\"s\">inf</span><span class=\"sh\">'</span><span class=\"p\">))</span> <span class=\"k\">if</span> <span class=\"n\">__name__</span> <span class=\"o\">==</span> <span class=\"sh\">'</span><span class=\"s\">__main__</span><span class=\"sh\">'</span><span class=\"p\">:</span> <span class=\"n\">s</span> <span class=\"o\">=</span> <span class=\"nc\">Solution</span><span class=\"p\">().</span><span class=\"n\">isValidBST</span> <span class=\"n\">t1</span> <span class=\"o\">=</span> <span class=\"nc\">TreeNode</span><span class=\"p\">(</span><span class=\"mi\">2</span><span class=\"p\">,</span> <span class=\"nc\">TreeNode</span><span class=\"p\">(</span><span class=\"mi\">1</span><span class=\"p\">),</span> <span class=\"nc\">TreeNode</span><span class=\"p\">(</span><span class=\"mi\">3</span><span class=\"p\">))</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">(</span><span class=\"n\">t1</span><span class=\"p\">),</span> <span class=\"bp\">True</span><span class=\"p\">)</span> <span class=\"n\">t2</span> <span class=\"o\">=</span> <span class=\"nc\">TreeNode</span><span class=\"p\">(</span><span class=\"mi\">5</span><span class=\"p\">,</span> <span class=\"bp\">None</span><span class=\"p\">,</span> <span class=\"nc\">TreeNode</span><span class=\"p\">(</span><span class=\"mi\">7</span><span class=\"p\">,</span> <span class=\"nc\">TreeNode</span><span class=\"p\">(</span><span class=\"mi\">4</span><span class=\"p\">)))</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">(</span><span class=\"n\">t2</span><span class=\"p\">),</span> <span class=\"bp\">False</span><span class=\"p\">)</span> <span class=\"n\">t3</span> <span class=\"o\">=</span> <span class=\"nc\">TreeNode</span><span class=\"p\">(</span><span class=\"mi\">0</span><span class=\"p\">,</span> <span class=\"bp\">None</span><span class=\"p\">,</span> <span class=\"nc\">TreeNode</span><span class=\"p\">(</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">))</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">(</span><span class=\"n\">t3</span><span class=\"p\">),</span> <span class=\"bp\">False</span><span class=\"p\">)</span> <span class=\"n\">t4</span> <span class=\"o\">=</span> <span class=\"nc\">TreeNode</span><span class=\"p\">(</span><span class=\"mi\">32</span><span class=\"p\">,</span> <span class=\"nc\">TreeNode</span><span class=\"p\">(</span><span class=\"mi\">26</span><span class=\"p\">,</span> <span class=\"nc\">TreeNode</span><span class=\"p\">(</span><span class=\"mi\">19</span><span class=\"p\">,</span> <span class=\"bp\">None</span><span class=\"p\">,</span> <span class=\"bp\">None</span><span class=\"p\">),</span> <span class=\"nc\">TreeNode</span><span class=\"p\">(</span><span class=\"mi\">47</span><span class=\"p\">,</span> <span class=\"bp\">None</span><span class=\"p\">,</span> <span class=\"nc\">TreeNode</span><span class=\"p\">(</span><span class=\"mi\">56</span><span class=\"p\">,</span> <span class=\"bp\">None</span><span class=\"p\">,</span> <span class=\"nc\">TreeNode</span><span class=\"p\">(</span><span class=\"mi\">27</span><span class=\"p\">)))))</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">(</span><span class=\"n\">t4</span><span class=\"p\">),</span> <span class=\"bp\">False</span><span class=\"p\">)</span></code></pre></figure><blockquote> <p>Runtime: 106 ms, faster than 5.15% of Python3 online submissions for Validate Binary Search Tree. Memory Usage: 16.5 MB, less than 47.01% of Python3 online submissions for Validate Binary Search Tree.</p></blockquote>", "date_published": "2022-10-31T20:00:00+00:00" }, { "id": "https://fewald.net/leetcode/2022/10/30/leetcode-palindrome-partitioning.html", "url": "https://fewald.net/leetcode/2022/10/30/leetcode-palindrome-partitioning.html", "title": "Leetcode: Palindrome partitioning", "content_html": "<p>Given a string <code class=\"language-plaintext highlighter-rouge\">s</code>, return a <code class=\"language-plaintext highlighter-rouge\">list</code> containing of all possible partitions of that string that are palindromes. A palindrome is a string that is the same backwards as forwards. For example, <code class=\"language-plaintext highlighter-rouge\">abba</code> is a palindrome.</p><p>The string <code class=\"language-plaintext highlighter-rouge\">aab</code> can be partitioned as follows: <code class=\"language-plaintext highlighter-rouge\">[['a','a','b'], ['aa','b']]</code>. This is because a single character is by definition a palindrome.</p><!--more--><p>When thinking about the solution, we need to first think about the cases. The palindrome can be</p><ul> <li>at the beginning,</li> <li>in the middle,</li> <li>or at the end</li></ul><p>of the string. Additionally there can be more than one palindrome at the same time. The base case is that every character is a palindrome on its own.</p><p>One possible solution is to look at this as a recursive problem with a prefix and a remainder of the string. We can then attempt to greedily find palindromes in the remainder.</p><h2 id=\"example\">Example</h2><figure class=\"highlight\"><pre><code class=\"language-plain\" data-lang=\"plain\">s = aabStep 1prefix = [], remainder = [a,a,b]Step 2aprefix = [a], remainder = [a,b]Step 3aprefix = [a,a], remainder = [b]Step 4aprefix = [a,a,b] remainder = []Now we can return to step 2a and add one more character and check for palindrome.Step 2bprefix = [aa], remainder = [b]Step 3bprefix = [aa,b], remainder = []Step2c[aab] is not a palindrome and gets discarded.</code></pre></figure><h2 id=\"solution\">Solution</h2><p>The following code snippet shows the recursive implementation.</p><figure class=\"highlight\"><pre><code class=\"language-python\" data-lang=\"python\"><span class=\"kn\">from</span> <span class=\"n\">typing</span> <span class=\"kn\">import</span> <span class=\"n\">List</span><span class=\"p\">,</span> <span class=\"n\">Optional</span><span class=\"k\">class</span> <span class=\"nc\">Solution</span><span class=\"p\">:</span> <span class=\"k\">def</span> <span class=\"nf\">partition</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">s</span><span class=\"p\">:</span> <span class=\"nb\">str</span><span class=\"p\">)</span> <span class=\"o\">-></span> <span class=\"n\">List</span><span class=\"p\">[</span><span class=\"n\">List</span><span class=\"p\">[</span><span class=\"nb\">str</span><span class=\"p\">]]:</span> <span class=\"c1\"># Convert string to list of characters</span> <span class=\"n\">s</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"n\">c</span> <span class=\"k\">for</span> <span class=\"n\">c</span> <span class=\"ow\">in</span> <span class=\"n\">s</span><span class=\"p\">]</span> <span class=\"c1\"># Initialize output array/list.</span> <span class=\"n\">out</span> <span class=\"o\">=</span> <span class=\"p\">[]</span> <span class=\"k\">def</span> <span class=\"nf\">inner</span><span class=\"p\">(</span><span class=\"n\">prefix</span><span class=\"p\">,</span> <span class=\"n\">s</span><span class=\"p\">):</span> <span class=\"k\">if</span> <span class=\"nf\">len</span><span class=\"p\">(</span><span class=\"n\">s</span><span class=\"p\">)</span> <span class=\"o\">==</span> <span class=\"mi\">0</span><span class=\"p\">:</span> <span class=\"n\">out</span><span class=\"p\">.</span><span class=\"nf\">append</span><span class=\"p\">(</span><span class=\"n\">prefix</span><span class=\"p\">)</span> <span class=\"k\">return</span> <span class=\"k\">for</span> <span class=\"n\">j</span> <span class=\"ow\">in</span> <span class=\"nf\">range</span><span class=\"p\">(</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"nf\">len</span><span class=\"p\">(</span><span class=\"n\">s</span><span class=\"p\">)</span><span class=\"o\">+</span><span class=\"mi\">1</span><span class=\"p\">):</span> <span class=\"n\">tmp</span> <span class=\"o\">=</span> <span class=\"n\">s</span><span class=\"p\">[:</span><span class=\"n\">j</span><span class=\"p\">]</span> <span class=\"k\">if</span> <span class=\"n\">tmp</span> <span class=\"o\">==</span> <span class=\"n\">tmp</span><span class=\"p\">[::</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">]:</span> <span class=\"nf\">inner</span><span class=\"p\">(</span><span class=\"n\">prefix</span> <span class=\"o\">+</span> <span class=\"p\">[</span><span class=\"sh\">\"\"</span><span class=\"p\">.</span><span class=\"nf\">join</span><span class=\"p\">(</span><span class=\"n\">tmp</span><span class=\"p\">)],</span> <span class=\"n\">s</span><span class=\"p\">[</span><span class=\"n\">j</span><span class=\"p\">:])</span> <span class=\"c1\"># Call to recursive method </span> <span class=\"nf\">inner</span><span class=\"p\">([],</span><span class=\"n\">s</span><span class=\"p\">)</span> <span class=\"k\">return</span> <span class=\"n\">out</span><span class=\"k\">if</span> <span class=\"n\">__name__</span> <span class=\"o\">==</span> <span class=\"sh\">'</span><span class=\"s\">__main__</span><span class=\"sh\">'</span><span class=\"p\">:</span> <span class=\"n\">s</span> <span class=\"o\">=</span> <span class=\"nc\">Solution</span><span class=\"p\">().</span><span class=\"n\">partition</span> <span class=\"c1\"># print(s('aab'), [['a','a','b'], ['aa', 'b']])</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">(</span><span class=\"sh\">'</span><span class=\"s\">abacccac</span><span class=\"sh\">'</span><span class=\"p\">),</span> <span class=\"p\">[</span> <span class=\"p\">[</span><span class=\"sh\">'</span><span class=\"s\">a</span><span class=\"sh\">'</span><span class=\"p\">,</span><span class=\"sh\">'</span><span class=\"s\">b</span><span class=\"sh\">'</span><span class=\"p\">,</span><span class=\"sh\">'</span><span class=\"s\">a</span><span class=\"sh\">'</span><span class=\"p\">,</span><span class=\"sh\">'</span><span class=\"s\">c</span><span class=\"sh\">'</span><span class=\"p\">,</span><span class=\"sh\">'</span><span class=\"s\">c</span><span class=\"sh\">'</span><span class=\"p\">,</span><span class=\"sh\">'</span><span class=\"s\">c</span><span class=\"sh\">'</span><span class=\"p\">,</span><span class=\"sh\">'</span><span class=\"s\">a</span><span class=\"sh\">'</span><span class=\"p\">,</span><span class=\"sh\">'</span><span class=\"s\">c</span><span class=\"sh\">'</span><span class=\"p\">],</span> <span class=\"p\">[</span><span class=\"sh\">'</span><span class=\"s\">aba</span><span class=\"sh\">'</span><span class=\"p\">,</span> <span class=\"sh\">'</span><span class=\"s\">c</span><span class=\"sh\">'</span><span class=\"p\">,</span> <span class=\"sh\">'</span><span class=\"s\">c</span><span class=\"sh\">'</span><span class=\"p\">,</span><span class=\"sh\">'</span><span class=\"s\">c</span><span class=\"sh\">'</span><span class=\"p\">,</span><span class=\"sh\">'</span><span class=\"s\">a</span><span class=\"sh\">'</span><span class=\"p\">,</span><span class=\"sh\">'</span><span class=\"s\">c</span><span class=\"sh\">'</span><span class=\"p\">],</span> <span class=\"p\">])</span></code></pre></figure><blockquote> <p>Runtime: 1690 ms, faster than 5.03% of Python3 online submissions for Palindrome Partitioning. Memory Usage: 30.4 MB, less than 45.23% of Python3 online submissions for Palindrome Partitioning.</p></blockquote>", "date_published": "2022-10-30T20:00:00+00:00" }, { "id": "https://fewald.net/leetcode/2022/10/29/leetcode-remove-element-from-list.html", "url": "https://fewald.net/leetcode/2022/10/29/leetcode-remove-element-from-list.html", "title": "Leetcode: Remove element from list", "content_html": "<p>Given the <code class=\"language-plaintext highlighter-rouge\">head</code> of a linked list, remove all items with <code class=\"language-plaintext highlighter-rouge\">val</code>. Afterwards, return the new head.</p><!--more--><p>To solve this problem, we need to consider three cases. The element can be in the beginning, in the middle or at the end. For the middle case, we can just define <code class=\"language-plaintext highlighter-rouge\">el.next = el.next.next</code>. This also works for the end, except that we need to make sure that the <code class=\"language-plaintext highlighter-rouge\">next</code> element is not <code class=\"language-plaintext highlighter-rouge\">None</code>. The beginning is a little bit more difficult. Here we can work around this problem by adding a pseudo-node in front of the beginning and then always look at the <code class=\"language-plaintext highlighter-rouge\">next</code> one. At the end we return <code class=\"language-plaintext highlighter-rouge\">new_head.next</code>. The other corner case is if two nodes that need to be deleted are right next to each other. In this case we cannot move the pointer forward.</p><figure class=\"highlight\"><pre><code class=\"language-python\" data-lang=\"python\"><span class=\"kn\">from</span> <span class=\"n\">typing</span> <span class=\"kn\">import</span> <span class=\"n\">Optional</span><span class=\"c1\"># Definition for singly-linked list.</span><span class=\"k\">class</span> <span class=\"nc\">ListNode</span><span class=\"p\">:</span> <span class=\"k\">def</span> <span class=\"nf\">__init__</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">val</span><span class=\"o\">=</span><span class=\"mi\">0</span><span class=\"p\">,</span> <span class=\"nb\">next</span><span class=\"o\">=</span><span class=\"bp\">None</span><span class=\"p\">):</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">val</span> <span class=\"o\">=</span> <span class=\"n\">val</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"nb\">next</span> <span class=\"o\">=</span> <span class=\"nb\">next</span> <span class=\"k\">def</span> <span class=\"nf\">__repr__</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">)</span> <span class=\"o\">-></span> <span class=\"nb\">str</span><span class=\"p\">:</span> <span class=\"n\">l</span> <span class=\"o\">=</span> <span class=\"nf\">str</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">val</span><span class=\"p\">)</span> <span class=\"k\">if</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"nb\">next</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"bp\">None</span><span class=\"p\">:</span> <span class=\"n\">l</span> <span class=\"o\">+=</span> <span class=\"sa\">f</span><span class=\"sh\">\"</span><span class=\"s\">, </span><span class=\"si\">{</span><span class=\"n\">self</span><span class=\"p\">.</span><span class=\"nb\">next</span><span class=\"si\">}</span><span class=\"sh\">\"</span> <span class=\"k\">return</span> <span class=\"n\">l</span><span class=\"k\">class</span> <span class=\"nc\">Solution</span><span class=\"p\">:</span> <span class=\"k\">def</span> <span class=\"nf\">removeElements</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">head</span><span class=\"p\">:</span> <span class=\"n\">Optional</span><span class=\"p\">[</span><span class=\"n\">ListNode</span><span class=\"p\">],</span> <span class=\"n\">val</span><span class=\"p\">:</span> <span class=\"nb\">int</span><span class=\"p\">)</span> <span class=\"o\">-></span> <span class=\"n\">Optional</span><span class=\"p\">[</span><span class=\"n\">ListNode</span><span class=\"p\">]:</span> <span class=\"n\">new_head</span> <span class=\"o\">=</span> <span class=\"nc\">ListNode</span><span class=\"p\">(</span><span class=\"mi\">0</span><span class=\"p\">,</span> <span class=\"n\">head</span><span class=\"p\">)</span> <span class=\"n\">n</span> <span class=\"o\">=</span> <span class=\"n\">new_head</span> <span class=\"k\">while</span> <span class=\"n\">n</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"bp\">None</span><span class=\"p\">:</span> <span class=\"k\">if</span> <span class=\"n\">n</span><span class=\"p\">.</span><span class=\"nb\">next</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"bp\">None</span> <span class=\"ow\">and</span> <span class=\"n\">n</span><span class=\"p\">.</span><span class=\"nb\">next</span><span class=\"p\">.</span><span class=\"n\">val</span> <span class=\"o\">==</span> <span class=\"n\">val</span><span class=\"p\">:</span> <span class=\"n\">n</span><span class=\"p\">.</span><span class=\"nb\">next</span> <span class=\"o\">=</span> <span class=\"n\">n</span><span class=\"p\">.</span><span class=\"nb\">next</span><span class=\"p\">.</span><span class=\"nb\">next</span> <span class=\"k\">else</span><span class=\"p\">:</span> <span class=\"n\">n</span> <span class=\"o\">=</span> <span class=\"n\">n</span><span class=\"p\">.</span><span class=\"nb\">next</span> <span class=\"k\">return</span> <span class=\"n\">new_head</span><span class=\"p\">.</span><span class=\"nb\">next</span><span class=\"k\">if</span> <span class=\"n\">__name__</span> <span class=\"o\">==</span> <span class=\"sh\">'</span><span class=\"s\">__main__</span><span class=\"sh\">'</span><span class=\"p\">:</span> <span class=\"n\">s</span> <span class=\"o\">=</span> <span class=\"nc\">Solution</span><span class=\"p\">().</span><span class=\"n\">removeElements</span> <span class=\"n\">l</span> <span class=\"o\">=</span> <span class=\"nc\">ListNode</span><span class=\"p\">(</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"nc\">ListNode</span><span class=\"p\">(</span><span class=\"mi\">2</span><span class=\"p\">,</span> <span class=\"nc\">ListNode</span><span class=\"p\">(</span><span class=\"mi\">6</span><span class=\"p\">,</span> <span class=\"nc\">ListNode</span><span class=\"p\">(</span><span class=\"mi\">3</span><span class=\"p\">,</span> <span class=\"nc\">ListNode</span><span class=\"p\">(</span><span class=\"mi\">4</span><span class=\"p\">,</span> <span class=\"nc\">ListNode</span><span class=\"p\">(</span><span class=\"mi\">5</span><span class=\"p\">,</span> <span class=\"nc\">ListNode</span><span class=\"p\">(</span><span class=\"mi\">6</span><span class=\"p\">)))))))</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">(</span><span class=\"n\">l</span><span class=\"p\">,</span> <span class=\"mi\">6</span><span class=\"p\">))</span></code></pre></figure><blockquote> <p>Runtime: 169 ms, faster than 5.14% of Python3 online submissions for Remove Linked List Elements. Memory Usage: 17.8 MB, less than 81.69% of Python3 online submissions for Remove Linked List Elements.</p></blockquote>", "date_published": "2022-10-29T20:00:00+00:00" }, { "id": "https://fewald.net/leetcode/2022/10/28/leetcode-array-remove-element.html", "url": "https://fewald.net/leetcode/2022/10/28/leetcode-array-remove-element.html", "title": "Leetcode: Remove element", "content_html": "<p>Given an array <code class=\"language-plaintext highlighter-rouge\">nums</code>, delete all items that are equal to <code class=\"language-plaintext highlighter-rouge\">val</code>. Return the total number of remaining items and perform the deletion in place.</p><!--more--><p>The solution looks as follows. Initially, <code class=\"language-plaintext highlighter-rouge\">k</code> is set to the length of the list. If we remove one element we decrement <code class=\"language-plaintext highlighter-rouge\">k</code> by one. The one thing here is that we advance the pointer <code class=\"language-plaintext highlighter-rouge\">i</code> only if we don’t remove an element. This is due to the fact that the position of the following elements change if we delete an item from the array.</p><figure class=\"highlight\"><pre><code class=\"language-python\" data-lang=\"python\"><span class=\"kn\">from</span> <span class=\"n\">typing</span> <span class=\"kn\">import</span> <span class=\"n\">List</span><span class=\"k\">class</span> <span class=\"nc\">Solution</span><span class=\"p\">:</span> <span class=\"k\">def</span> <span class=\"nf\">removeElement</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">nums</span><span class=\"p\">:</span> <span class=\"n\">List</span><span class=\"p\">[</span><span class=\"nb\">int</span><span class=\"p\">],</span> <span class=\"n\">val</span><span class=\"p\">:</span> <span class=\"nb\">int</span><span class=\"p\">)</span> <span class=\"o\">-></span> <span class=\"nb\">int</span><span class=\"p\">:</span> <span class=\"n\">i</span> <span class=\"o\">=</span> <span class=\"mi\">0</span> <span class=\"n\">k</span> <span class=\"o\">=</span> <span class=\"nf\">len</span><span class=\"p\">(</span><span class=\"n\">nums</span><span class=\"p\">)</span> <span class=\"k\">while</span> <span class=\"n\">i</span> <span class=\"o\"><</span> <span class=\"nf\">len</span><span class=\"p\">(</span><span class=\"n\">nums</span><span class=\"p\">):</span> <span class=\"k\">if</span> <span class=\"n\">nums</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">]</span> <span class=\"o\">==</span> <span class=\"n\">val</span><span class=\"p\">:</span> <span class=\"k\">del</span> <span class=\"n\">nums</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">]</span> <span class=\"n\">k</span> <span class=\"o\">-=</span> <span class=\"mi\">1</span> <span class=\"k\">else</span><span class=\"p\">:</span> <span class=\"n\">i</span> <span class=\"o\">+=</span> <span class=\"mi\">1</span> <span class=\"k\">return</span> <span class=\"n\">k</span> <span class=\"k\">if</span> <span class=\"n\">__name__</span> <span class=\"o\">==</span> <span class=\"sh\">'</span><span class=\"s\">__main__</span><span class=\"sh\">'</span><span class=\"p\">:</span> <span class=\"n\">s</span> <span class=\"o\">=</span> <span class=\"nc\">Solution</span><span class=\"p\">().</span><span class=\"n\">removeElement</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">([</span><span class=\"mi\">3</span><span class=\"p\">,</span><span class=\"mi\">2</span><span class=\"p\">,</span><span class=\"mi\">2</span><span class=\"p\">,</span><span class=\"mi\">3</span><span class=\"p\">],</span> <span class=\"mi\">3</span><span class=\"p\">),</span> <span class=\"mi\">2</span><span class=\"p\">)</span></code></pre></figure>", "date_published": "2022-10-28T20:00:00+00:00" }, { "id": "https://fewald.net/leetcode/2022/10/27/leetcode-binary-tree-zigzag-level-order-traversal.html", "url": "https://fewald.net/leetcode/2022/10/27/leetcode-binary-tree-zigzag-level-order-traversal.html", "title": "Leetcode: Binary tree zigzag level order traversal", "content_html": "<p>Traverse a tree where the <code class=\"language-plaintext highlighter-rouge\">root</code> node is given with a zig-zag level and return the values in a <code class=\"language-plaintext highlighter-rouge\">list</code> with one entry per level. For example:</p><figure class=\"highlight\"><pre><code class=\"language-plain\" data-lang=\"plain\">--> 3 / \\ 9 5 <-- / \\--> 7 8Returns: [[3], [5,9], [7,8]]</code></pre></figure><!--more--><p>This can be achieved with the same BFS algorithm from before, with an additional introduction of a <code class=\"language-plaintext highlighter-rouge\">reverse</code> boolean variable. If the order is reversed, the output values are prepended instead of appended. After each level, the reverse variable is toggled via <code class=\"language-plaintext highlighter-rouge\">reverse = not reverse</code>.</p><figure class=\"highlight\"><pre><code class=\"language-python\" data-lang=\"python\"><span class=\"kn\">from</span> <span class=\"n\">typing</span> <span class=\"kn\">import</span> <span class=\"n\">List</span><span class=\"p\">,</span> <span class=\"n\">Optional</span><span class=\"c1\"># Definition for a binary tree node.</span><span class=\"k\">class</span> <span class=\"nc\">TreeNode</span><span class=\"p\">:</span> <span class=\"k\">def</span> <span class=\"nf\">__init__</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">val</span><span class=\"o\">=</span><span class=\"mi\">0</span><span class=\"p\">,</span> <span class=\"n\">left</span><span class=\"o\">=</span><span class=\"bp\">None</span><span class=\"p\">,</span> <span class=\"n\">right</span><span class=\"o\">=</span><span class=\"bp\">None</span><span class=\"p\">):</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">val</span> <span class=\"o\">=</span> <span class=\"n\">val</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">left</span> <span class=\"o\">=</span> <span class=\"n\">left</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">right</span> <span class=\"o\">=</span> <span class=\"n\">right</span> <span class=\"k\">def</span> <span class=\"nf\">__repr__</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">)</span> <span class=\"o\">-></span> <span class=\"nb\">str</span><span class=\"p\">:</span> <span class=\"k\">return</span> <span class=\"sa\">f</span><span class=\"sh\">\"</span><span class=\"si\">{</span><span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">val</span><span class=\"si\">}</span><span class=\"sh\">\"</span><span class=\"k\">class</span> <span class=\"nc\">Solution</span><span class=\"p\">:</span> <span class=\"k\">def</span> <span class=\"nf\">zigzagLevelOrder</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">root</span><span class=\"p\">:</span> <span class=\"n\">Optional</span><span class=\"p\">[</span><span class=\"n\">TreeNode</span><span class=\"p\">])</span> <span class=\"o\">-></span> <span class=\"n\">List</span><span class=\"p\">[</span><span class=\"n\">List</span><span class=\"p\">[</span><span class=\"nb\">int</span><span class=\"p\">]]:</span> <span class=\"k\">if</span> <span class=\"n\">root</span> <span class=\"ow\">is</span> <span class=\"bp\">None</span><span class=\"p\">:</span> <span class=\"k\">return</span> <span class=\"p\">[]</span> <span class=\"n\">res</span> <span class=\"o\">=</span> <span class=\"p\">[]</span> <span class=\"n\">queue</span> <span class=\"o\">=</span> <span class=\"p\">[[</span><span class=\"n\">root</span><span class=\"p\">]]</span> <span class=\"n\">reverse</span> <span class=\"o\">=</span> <span class=\"bp\">False</span> <span class=\"k\">while</span> <span class=\"nf\">len</span><span class=\"p\">(</span><span class=\"n\">queue</span><span class=\"p\">)</span> <span class=\"o\">></span> <span class=\"mi\">0</span><span class=\"p\">:</span> <span class=\"n\">itms</span> <span class=\"o\">=</span> <span class=\"n\">queue</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span> <span class=\"n\">res</span><span class=\"p\">.</span><span class=\"nf\">append</span><span class=\"p\">([])</span> <span class=\"n\">queue</span><span class=\"p\">.</span><span class=\"nf\">append</span><span class=\"p\">([])</span> <span class=\"k\">for</span> <span class=\"n\">item</span> <span class=\"ow\">in</span> <span class=\"n\">itms</span><span class=\"p\">:</span> <span class=\"k\">if</span> <span class=\"ow\">not</span> <span class=\"n\">item</span><span class=\"p\">:</span> <span class=\"k\">continue</span> <span class=\"k\">if</span> <span class=\"n\">reverse</span><span class=\"p\">:</span> <span class=\"c1\"># prepend</span> <span class=\"n\">res</span><span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"n\">item</span><span class=\"p\">.</span><span class=\"n\">val</span><span class=\"p\">]</span> <span class=\"o\">+</span> <span class=\"n\">res</span><span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">]</span> <span class=\"k\">else</span><span class=\"p\">:</span> <span class=\"n\">res</span><span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">].</span><span class=\"nf\">append</span><span class=\"p\">(</span><span class=\"n\">item</span><span class=\"p\">.</span><span class=\"n\">val</span><span class=\"p\">)</span> <span class=\"n\">queue</span><span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">].</span><span class=\"nf\">append</span><span class=\"p\">(</span><span class=\"n\">item</span><span class=\"p\">.</span><span class=\"n\">left</span><span class=\"p\">)</span> <span class=\"n\">queue</span><span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">].</span><span class=\"nf\">append</span><span class=\"p\">(</span><span class=\"n\">item</span><span class=\"p\">.</span><span class=\"n\">right</span><span class=\"p\">)</span> <span class=\"k\">if</span> <span class=\"nf\">len</span><span class=\"p\">(</span><span class=\"n\">res</span><span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">])</span> <span class=\"o\">==</span> <span class=\"mi\">0</span><span class=\"p\">:</span> <span class=\"n\">queue</span><span class=\"p\">.</span><span class=\"nf\">pop</span><span class=\"p\">()</span> <span class=\"n\">queue</span> <span class=\"o\">=</span> <span class=\"n\">queue</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">:]</span> <span class=\"c1\"># Toggle reverse for next level</span> <span class=\"n\">reverse</span> <span class=\"o\">=</span> <span class=\"ow\">not</span> <span class=\"n\">reverse</span> <span class=\"k\">if</span> <span class=\"nf\">len</span><span class=\"p\">(</span><span class=\"n\">res</span><span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">])</span> <span class=\"o\">==</span> <span class=\"mi\">0</span><span class=\"p\">:</span> <span class=\"n\">res</span><span class=\"p\">.</span><span class=\"nf\">pop</span><span class=\"p\">()</span> <span class=\"k\">return</span> <span class=\"n\">res</span><span class=\"k\">if</span> <span class=\"n\">__name__</span> <span class=\"o\">==</span> <span class=\"sh\">'</span><span class=\"s\">__main__</span><span class=\"sh\">'</span><span class=\"p\">:</span> <span class=\"n\">s</span> <span class=\"o\">=</span> <span class=\"nc\">Solution</span><span class=\"p\">().</span><span class=\"n\">zigzagLevelOrder</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">(</span><span class=\"nc\">TreeNode</span><span class=\"p\">(</span><span class=\"mi\">3</span><span class=\"p\">,</span> <span class=\"nc\">TreeNode</span><span class=\"p\">(</span><span class=\"mi\">9</span><span class=\"p\">),</span> <span class=\"nc\">TreeNode</span><span class=\"p\">(</span><span class=\"mi\">20</span><span class=\"p\">,</span> <span class=\"nc\">TreeNode</span><span class=\"p\">(</span><span class=\"mi\">15</span><span class=\"p\">),</span> <span class=\"nc\">TreeNode</span><span class=\"p\">(</span><span class=\"mi\">7</span><span class=\"p\">)))),</span> <span class=\"p\">[[</span><span class=\"mi\">3</span><span class=\"p\">],</span> <span class=\"p\">[</span><span class=\"mi\">20</span><span class=\"p\">,</span><span class=\"mi\">9</span><span class=\"p\">],</span> <span class=\"p\">[</span><span class=\"mi\">15</span><span class=\"p\">,</span><span class=\"mi\">7</span><span class=\"p\">]])</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">(</span><span class=\"nc\">TreeNode</span><span class=\"p\">(</span><span class=\"mi\">1</span><span class=\"p\">)),</span> <span class=\"p\">[[</span><span class=\"mi\">1</span><span class=\"p\">]])</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">(</span><span class=\"bp\">None</span><span class=\"p\">),</span> <span class=\"p\">[])</span></code></pre></figure>", "date_published": "2022-10-27T20:00:00+00:00" }, { "id": "https://fewald.net/leetcode/2022/10/26/leetcode-binary-tree-level-order-traversal.html", "url": "https://fewald.net/leetcode/2022/10/26/leetcode-binary-tree-level-order-traversal.html", "title": "Leetcode: Binary tree level order traversal", "content_html": "<p>Given the <code class=\"language-plaintext highlighter-rouge\">root</code> node of a binary tree, print all values in order, meaning from left to right on the same level.</p><p>To solve this, we can use the standard breadth-first-search (BFS) algorithm in an iterative fashion with a <code class=\"language-plaintext highlighter-rouge\">queue</code>. As an output we use a <code class=\"language-plaintext highlighter-rouge\">list</code> and leverage the position <code class=\"language-plaintext highlighter-rouge\">-1</code> to add the current level to the list. For every level we append one new element to the end of the list.</p><!--more--><figure class=\"highlight\"><pre><code class=\"language-python\" data-lang=\"python\"><span class=\"kn\">from</span> <span class=\"n\">typing</span> <span class=\"kn\">import</span> <span class=\"n\">List</span><span class=\"p\">,</span> <span class=\"n\">Optional</span><span class=\"c1\"># Definition for a binary tree node.</span><span class=\"k\">class</span> <span class=\"nc\">TreeNode</span><span class=\"p\">:</span> <span class=\"k\">def</span> <span class=\"nf\">__init__</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">val</span><span class=\"o\">=</span><span class=\"mi\">0</span><span class=\"p\">,</span> <span class=\"n\">left</span><span class=\"o\">=</span><span class=\"bp\">None</span><span class=\"p\">,</span> <span class=\"n\">right</span><span class=\"o\">=</span><span class=\"bp\">None</span><span class=\"p\">):</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">val</span> <span class=\"o\">=</span> <span class=\"n\">val</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">left</span> <span class=\"o\">=</span> <span class=\"n\">left</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">right</span> <span class=\"o\">=</span> <span class=\"n\">right</span><span class=\"k\">class</span> <span class=\"nc\">Solution</span><span class=\"p\">:</span> <span class=\"k\">def</span> <span class=\"nf\">levelOrder</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">root</span><span class=\"p\">:</span> <span class=\"n\">Optional</span><span class=\"p\">[</span><span class=\"n\">TreeNode</span><span class=\"p\">])</span> <span class=\"o\">-></span> <span class=\"n\">List</span><span class=\"p\">[</span><span class=\"n\">List</span><span class=\"p\">[</span><span class=\"nb\">int</span><span class=\"p\">]]:</span> <span class=\"k\">if</span> <span class=\"n\">root</span> <span class=\"ow\">is</span> <span class=\"bp\">None</span><span class=\"p\">:</span> <span class=\"k\">return</span> <span class=\"p\">[]</span> <span class=\"n\">res</span> <span class=\"o\">=</span> <span class=\"p\">[]</span> <span class=\"n\">queue</span> <span class=\"o\">=</span> <span class=\"p\">[[</span><span class=\"n\">root</span><span class=\"p\">]]</span> <span class=\"k\">while</span> <span class=\"nf\">len</span><span class=\"p\">(</span><span class=\"n\">queue</span><span class=\"p\">)</span> <span class=\"o\">></span> <span class=\"mi\">0</span><span class=\"p\">:</span> <span class=\"n\">itms</span> <span class=\"o\">=</span> <span class=\"n\">queue</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span> <span class=\"n\">res</span><span class=\"p\">.</span><span class=\"nf\">append</span><span class=\"p\">([])</span> <span class=\"n\">queue</span><span class=\"p\">.</span><span class=\"nf\">append</span><span class=\"p\">([])</span> <span class=\"k\">for</span> <span class=\"n\">item</span> <span class=\"ow\">in</span> <span class=\"n\">itms</span><span class=\"p\">:</span> <span class=\"n\">res</span><span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">].</span><span class=\"nf\">append</span><span class=\"p\">(</span><span class=\"n\">item</span><span class=\"p\">.</span><span class=\"n\">val</span><span class=\"p\">)</span> <span class=\"k\">if</span> <span class=\"n\">item</span><span class=\"p\">.</span><span class=\"n\">left</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"bp\">None</span><span class=\"p\">:</span> <span class=\"n\">queue</span><span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">].</span><span class=\"nf\">append</span><span class=\"p\">(</span><span class=\"n\">item</span><span class=\"p\">.</span><span class=\"n\">left</span><span class=\"p\">)</span> <span class=\"k\">if</span> <span class=\"n\">item</span><span class=\"p\">.</span><span class=\"n\">right</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"bp\">None</span><span class=\"p\">:</span> <span class=\"n\">queue</span><span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">].</span><span class=\"nf\">append</span><span class=\"p\">(</span><span class=\"n\">item</span><span class=\"p\">.</span><span class=\"n\">right</span><span class=\"p\">)</span> <span class=\"k\">if</span> <span class=\"nf\">len</span><span class=\"p\">(</span><span class=\"n\">queue</span><span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">])</span> <span class=\"o\">==</span> <span class=\"mi\">0</span><span class=\"p\">:</span> <span class=\"n\">queue</span><span class=\"p\">.</span><span class=\"nf\">pop</span><span class=\"p\">()</span> <span class=\"n\">queue</span> <span class=\"o\">=</span> <span class=\"n\">queue</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">:]</span> <span class=\"k\">return</span> <span class=\"n\">res</span><span class=\"k\">if</span> <span class=\"n\">__name__</span> <span class=\"o\">==</span> <span class=\"sh\">'</span><span class=\"s\">__main__</span><span class=\"sh\">'</span><span class=\"p\">:</span> <span class=\"n\">s</span> <span class=\"o\">=</span> <span class=\"nc\">Solution</span><span class=\"p\">().</span><span class=\"n\">levelOrder</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">(</span><span class=\"nc\">TreeNode</span><span class=\"p\">(</span><span class=\"mi\">3</span><span class=\"p\">,</span> <span class=\"nc\">TreeNode</span><span class=\"p\">(</span><span class=\"mi\">9</span><span class=\"p\">),</span> <span class=\"nc\">TreeNode</span><span class=\"p\">(</span><span class=\"mi\">20</span><span class=\"p\">,</span> <span class=\"nc\">TreeNode</span><span class=\"p\">(</span><span class=\"mi\">15</span><span class=\"p\">),</span> <span class=\"nc\">TreeNode</span><span class=\"p\">(</span><span class=\"mi\">7</span><span class=\"p\">)))),</span> <span class=\"p\">[[</span><span class=\"mi\">3</span><span class=\"p\">],</span> <span class=\"p\">[</span><span class=\"mi\">9</span><span class=\"p\">,</span><span class=\"mi\">20</span><span class=\"p\">],</span> <span class=\"p\">[</span><span class=\"mi\">15</span><span class=\"p\">,</span><span class=\"mi\">7</span><span class=\"p\">]])</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">(</span><span class=\"nc\">TreeNode</span><span class=\"p\">(</span><span class=\"mi\">1</span><span class=\"p\">)),</span> <span class=\"p\">[[</span><span class=\"mi\">1</span><span class=\"p\">]])</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">(</span><span class=\"bp\">None</span><span class=\"p\">),</span> <span class=\"p\">[])</span></code></pre></figure><blockquote> <p>Runtime: 74 ms, faster than 10.45% of Python3 online submissions for Binary Tree Level Order Traversal. Memory Usage: 14.2 MB, less than 84.74% of Python3 online submissions for Binary Tree Level Order Traversal.</p></blockquote>", "date_published": "2022-10-26T20:00:00+00:00" }, { "id": "https://fewald.net/leetcode/2022/10/25/leetcode-valid-sudoku.html", "url": "https://fewald.net/leetcode/2022/10/25/leetcode-valid-sudoku.html", "title": "Leetcode: Valid sudoku", "content_html": "<p>Given a Sudoku field as a two-dimension list, determine if the field is valid. A valid field only has the number 1-9 once in each sub-field, each row, and each column. The field is not completely filled and we don’t need to check for a valid solution.</p><!--more--><p>The solution for this task is written in the conditions for a valid Sudoku field. We create a <code class=\"language-plaintext highlighter-rouge\">set</code> for each row, each column, and each sub-field. If a number is duplicated in any of those, the field is not valid. If we don’t find any violation until the end, the field is valid.</p><p>The remaining problem is to filter out the empty fields (<code class=\"language-plaintext highlighter-rouge\">.</code>) and to find the correct sub-field. For the second part, we can leverage Pythons full integer division and determine the field as follows: <code class=\"language-plaintext highlighter-rouge\">field = 3 * (row // 3) + (column // 3)</code>. This yields numbers from <code class=\"language-plaintext highlighter-rouge\">[0-8]</code>.</p><p>This solution is faster than 96% of the submitted solutions at leetcode. It does use <code class=\"language-plaintext highlighter-rouge\">O(3*n)</code> memory in the worst case, as every element needs to be stored in each set.</p><figure class=\"highlight\"><pre><code class=\"language-python\" data-lang=\"python\"><span class=\"kn\">from</span> <span class=\"n\">typing</span> <span class=\"kn\">import</span> <span class=\"n\">List</span><span class=\"k\">class</span> <span class=\"nc\">Solution</span><span class=\"p\">:</span> <span class=\"k\">def</span> <span class=\"nf\">isValidSudoku</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">board</span><span class=\"p\">:</span> <span class=\"n\">List</span><span class=\"p\">[</span><span class=\"n\">List</span><span class=\"p\">[</span><span class=\"nb\">str</span><span class=\"p\">]])</span> <span class=\"o\">-></span> <span class=\"nb\">bool</span><span class=\"p\">:</span> <span class=\"n\">rows</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"nf\">set</span><span class=\"p\">()</span> <span class=\"k\">for</span> <span class=\"n\">_</span> <span class=\"ow\">in</span> <span class=\"n\">board</span><span class=\"p\">]</span> <span class=\"n\">cols</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"nf\">set</span><span class=\"p\">()</span> <span class=\"k\">for</span> <span class=\"n\">_</span> <span class=\"ow\">in</span> <span class=\"n\">board</span><span class=\"p\">]</span> <span class=\"n\">subfields</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"nf\">set</span><span class=\"p\">()</span> <span class=\"k\">for</span> <span class=\"n\">_</span> <span class=\"ow\">in</span> <span class=\"nf\">range</span><span class=\"p\">(</span><span class=\"mi\">9</span><span class=\"p\">)]</span> <span class=\"k\">for</span> <span class=\"n\">i</span> <span class=\"ow\">in</span> <span class=\"nf\">range</span><span class=\"p\">(</span><span class=\"nf\">len</span><span class=\"p\">(</span><span class=\"n\">board</span><span class=\"p\">)):</span> <span class=\"k\">for</span> <span class=\"n\">j</span> <span class=\"ow\">in</span> <span class=\"nf\">range</span><span class=\"p\">(</span><span class=\"nf\">len</span><span class=\"p\">(</span><span class=\"n\">board</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">])):</span> <span class=\"k\">if</span> <span class=\"n\">board</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">][</span><span class=\"n\">j</span><span class=\"p\">]</span> <span class=\"o\">==</span> <span class=\"sh\">'</span><span class=\"s\">.</span><span class=\"sh\">'</span><span class=\"p\">:</span> <span class=\"k\">continue</span> <span class=\"k\">if</span> <span class=\"n\">board</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">][</span><span class=\"n\">j</span><span class=\"p\">]</span> <span class=\"ow\">in</span> <span class=\"n\">rows</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">]:</span> <span class=\"k\">return</span> <span class=\"bp\">False</span> <span class=\"n\">rows</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">].</span><span class=\"nf\">add</span><span class=\"p\">(</span><span class=\"n\">board</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">][</span><span class=\"n\">j</span><span class=\"p\">])</span> <span class=\"k\">if</span> <span class=\"n\">board</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">][</span><span class=\"n\">j</span><span class=\"p\">]</span> <span class=\"ow\">in</span> <span class=\"n\">cols</span><span class=\"p\">[</span><span class=\"n\">j</span><span class=\"p\">]:</span> <span class=\"k\">return</span> <span class=\"bp\">False</span> <span class=\"n\">cols</span><span class=\"p\">[</span><span class=\"n\">j</span><span class=\"p\">].</span><span class=\"nf\">add</span><span class=\"p\">(</span><span class=\"n\">board</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">][</span><span class=\"n\">j</span><span class=\"p\">])</span> <span class=\"n\">field</span> <span class=\"o\">=</span> <span class=\"mi\">3</span> <span class=\"o\">*</span> <span class=\"p\">(</span><span class=\"n\">i</span> <span class=\"o\">//</span> <span class=\"mi\">3</span><span class=\"p\">)</span> <span class=\"o\">+</span> <span class=\"p\">(</span><span class=\"n\">j</span> <span class=\"o\">//</span> <span class=\"mi\">3</span><span class=\"p\">)</span> <span class=\"k\">if</span> <span class=\"n\">board</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">][</span><span class=\"n\">j</span><span class=\"p\">]</span> <span class=\"ow\">in</span> <span class=\"n\">subfields</span><span class=\"p\">[</span><span class=\"n\">field</span><span class=\"p\">]:</span> <span class=\"k\">return</span> <span class=\"bp\">False</span> <span class=\"n\">subfields</span><span class=\"p\">[</span><span class=\"n\">field</span><span class=\"p\">].</span><span class=\"nf\">add</span><span class=\"p\">(</span><span class=\"n\">board</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">][</span><span class=\"n\">j</span><span class=\"p\">])</span> <span class=\"k\">return</span> <span class=\"bp\">True</span><span class=\"k\">if</span> <span class=\"n\">__name__</span> <span class=\"o\">==</span> <span class=\"sh\">'</span><span class=\"s\">__main__</span><span class=\"sh\">'</span><span class=\"p\">:</span> <span class=\"n\">s</span> <span class=\"o\">=</span> <span class=\"nc\">Solution</span><span class=\"p\">()</span> <span class=\"c1\"># Valid board</span> <span class=\"n\">board1</span> <span class=\"o\">=</span> <span class=\"p\">[[</span><span class=\"sh\">\"</span><span class=\"s\">5</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">3</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">.</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">.</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">7</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">.</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">.</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">.</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">.</span><span class=\"sh\">\"</span><span class=\"p\">]</span> <span class=\"p\">,[</span><span class=\"sh\">\"</span><span class=\"s\">6</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">.</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">.</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">1</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">9</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">5</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">.</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">.</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">.</span><span class=\"sh\">\"</span><span class=\"p\">]</span> <span class=\"p\">,[</span><span class=\"sh\">\"</span><span class=\"s\">.</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">9</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">8</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">.</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">.</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">.</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">.</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">6</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">.</span><span class=\"sh\">\"</span><span class=\"p\">]</span> <span class=\"p\">,[</span><span class=\"sh\">\"</span><span class=\"s\">8</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">.</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">.</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">.</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">6</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">.</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">.</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">.</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">3</span><span class=\"sh\">\"</span><span class=\"p\">]</span> <span class=\"p\">,[</span><span class=\"sh\">\"</span><span class=\"s\">4</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">.</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">.</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">8</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">.</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">3</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">.</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">.</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">1</span><span class=\"sh\">\"</span><span class=\"p\">]</span> <span class=\"p\">,[</span><span class=\"sh\">\"</span><span class=\"s\">7</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">.</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">.</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">.</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">2</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">.</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">.</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">.</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">6</span><span class=\"sh\">\"</span><span class=\"p\">]</span> <span class=\"p\">,[</span><span class=\"sh\">\"</span><span class=\"s\">.</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">6</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">.</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">.</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">.</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">.</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">2</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">8</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">.</span><span class=\"sh\">\"</span><span class=\"p\">]</span> <span class=\"p\">,[</span><span class=\"sh\">\"</span><span class=\"s\">.</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">.</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">.</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">4</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">1</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">9</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">.</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">.</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">5</span><span class=\"sh\">\"</span><span class=\"p\">]</span> <span class=\"p\">,[</span><span class=\"sh\">\"</span><span class=\"s\">.</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">.</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">.</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">.</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">8</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">.</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">.</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">7</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">9</span><span class=\"sh\">\"</span><span class=\"p\">]]</span> <span class=\"c1\"># Invalid board</span> <span class=\"n\">board2</span> <span class=\"o\">=</span> <span class=\"p\">[[</span><span class=\"sh\">\"</span><span class=\"s\">8</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">3</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">.</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">.</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">7</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">.</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">.</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">.</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">.</span><span class=\"sh\">\"</span><span class=\"p\">]</span> <span class=\"p\">,[</span><span class=\"sh\">\"</span><span class=\"s\">6</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">.</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">.</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">1</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">9</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">5</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">.</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">.</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">.</span><span class=\"sh\">\"</span><span class=\"p\">]</span> <span class=\"p\">,[</span><span class=\"sh\">\"</span><span class=\"s\">.</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">9</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">8</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">.</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">.</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">.</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">.</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">6</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">.</span><span class=\"sh\">\"</span><span class=\"p\">]</span> <span class=\"p\">,[</span><span class=\"sh\">\"</span><span class=\"s\">8</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">.</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">.</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">.</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">6</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">.</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">.</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">.</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">3</span><span class=\"sh\">\"</span><span class=\"p\">]</span> <span class=\"p\">,[</span><span class=\"sh\">\"</span><span class=\"s\">4</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">.</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">.</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">8</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">.</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">3</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">.</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">.</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">1</span><span class=\"sh\">\"</span><span class=\"p\">]</span> <span class=\"p\">,[</span><span class=\"sh\">\"</span><span class=\"s\">7</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">.</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">.</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">.</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">2</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">.</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">.</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">.</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">6</span><span class=\"sh\">\"</span><span class=\"p\">]</span> <span class=\"p\">,[</span><span class=\"sh\">\"</span><span class=\"s\">.</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">6</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">.</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">.</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">.</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">.</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">2</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">8</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">.</span><span class=\"sh\">\"</span><span class=\"p\">]</span> <span class=\"p\">,[</span><span class=\"sh\">\"</span><span class=\"s\">.</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">.</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">.</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">4</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">1</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">9</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">.</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">.</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">5</span><span class=\"sh\">\"</span><span class=\"p\">]</span> <span class=\"p\">,[</span><span class=\"sh\">\"</span><span class=\"s\">.</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">.</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">.</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">.</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">8</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">.</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">.</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">7</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">9</span><span class=\"sh\">\"</span><span class=\"p\">]]</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"n\">s</span><span class=\"p\">.</span><span class=\"nf\">isValidSudoku</span><span class=\"p\">(</span><span class=\"n\">board1</span><span class=\"p\">),</span> <span class=\"bp\">True</span><span class=\"p\">)</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"n\">s</span><span class=\"p\">.</span><span class=\"nf\">isValidSudoku</span><span class=\"p\">(</span><span class=\"n\">board2</span><span class=\"p\">),</span> <span class=\"bp\">False</span><span class=\"p\">)</span></code></pre></figure>", "date_published": "2022-10-25T20:00:00+00:00" }, { "id": "https://fewald.net/leetcode/2022/10/24/leetcode-top-k-frequent-elements.html", "url": "https://fewald.net/leetcode/2022/10/24/leetcode-top-k-frequent-elements.html", "title": "Leetcode: Top k frequent elements", "content_html": "<p>Given a list <code class=\"language-plaintext highlighter-rouge\">nums</code> and a positive integer <code class=\"language-plaintext highlighter-rouge\">k</code>, return the top <code class=\"language-plaintext highlighter-rouge\">k</code> frequent items from the list. A time complexity constraint is not given for this task.</p><!--more--><p>The task can be broken down into two problems. First, identifying the most frequent items and then returning them. For the first part, I used a simple map to count the occurrences. Afterwards, I iterated over the map and flipped the <code class=\"language-plaintext highlighter-rouge\">key</code> and <code class=\"language-plaintext highlighter-rouge\">value</code> around in a tuple. If for example the number <code class=\"language-plaintext highlighter-rouge\">10</code> occurred <code class=\"language-plaintext highlighter-rouge\">5</code> times, the corresponding tuple would be <code class=\"language-plaintext highlighter-rouge\">(5, 10)</code>. With this structure I was able to use the <code class=\"language-plaintext highlighter-rouge\">heapq</code> package in Python. This library uses the first element of a tuple to determine the order of elements. As his library creates by default a <strong>min</strong> heap and we are interested in the <strong>maximum</strong> elements, we can simply make the values negative. This puts the most frequent elements at the top of the heap.</p><figure class=\"highlight\"><pre><code class=\"language-python\" data-lang=\"python\"><span class=\"kn\">import</span> <span class=\"n\">heapq</span><span class=\"kn\">from</span> <span class=\"n\">typing</span> <span class=\"kn\">import</span> <span class=\"n\">List</span><span class=\"p\">,</span> <span class=\"n\">Optional</span><span class=\"k\">class</span> <span class=\"nc\">Solution</span><span class=\"p\">:</span> <span class=\"k\">def</span> <span class=\"nf\">topKFrequent</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">nums</span><span class=\"p\">:</span> <span class=\"n\">List</span><span class=\"p\">[</span><span class=\"nb\">int</span><span class=\"p\">],</span> <span class=\"n\">k</span><span class=\"p\">:</span> <span class=\"nb\">int</span><span class=\"p\">)</span> <span class=\"o\">-></span> <span class=\"n\">List</span><span class=\"p\">[</span><span class=\"nb\">int</span><span class=\"p\">]:</span> <span class=\"c1\"># Count all occurences</span> <span class=\"n\">m</span> <span class=\"o\">=</span> <span class=\"p\">{}</span> <span class=\"k\">for</span> <span class=\"n\">n</span> <span class=\"ow\">in</span> <span class=\"n\">nums</span><span class=\"p\">:</span> <span class=\"k\">if</span> <span class=\"n\">n</span> <span class=\"ow\">not</span> <span class=\"ow\">in</span> <span class=\"n\">m</span><span class=\"p\">:</span> <span class=\"n\">m</span><span class=\"p\">[</span><span class=\"n\">n</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"mi\">0</span> <span class=\"n\">m</span><span class=\"p\">[</span><span class=\"n\">n</span><span class=\"p\">]</span> <span class=\"o\">+=</span> <span class=\"mi\">1</span> <span class=\"n\">l</span> <span class=\"o\">=</span> <span class=\"p\">[]</span> <span class=\"k\">for</span> <span class=\"n\">key</span><span class=\"p\">,</span> <span class=\"n\">v</span> <span class=\"ow\">in</span> <span class=\"n\">m</span><span class=\"p\">.</span><span class=\"nf\">items</span><span class=\"p\">():</span> <span class=\"n\">l</span><span class=\"p\">.</span><span class=\"nf\">append</span><span class=\"p\">((</span><span class=\"o\">-</span><span class=\"n\">key</span><span class=\"p\">,</span><span class=\"n\">v</span><span class=\"p\">))</span> <span class=\"n\">heapq</span><span class=\"p\">.</span><span class=\"nf\">heapify</span><span class=\"p\">(</span><span class=\"n\">l</span><span class=\"p\">)</span> <span class=\"n\">output</span> <span class=\"o\">=</span> <span class=\"p\">[]</span> <span class=\"k\">for</span> <span class=\"n\">_</span> <span class=\"ow\">in</span> <span class=\"nf\">range</span><span class=\"p\">(</span><span class=\"n\">k</span><span class=\"p\">):</span> <span class=\"n\">output</span><span class=\"p\">.</span><span class=\"nf\">append</span><span class=\"p\">(</span><span class=\"n\">heapq</span><span class=\"p\">.</span><span class=\"nf\">heappop</span><span class=\"p\">(</span><span class=\"n\">l</span><span class=\"p\">)[</span><span class=\"mi\">1</span><span class=\"p\">])</span> <span class=\"k\">return</span> <span class=\"n\">output</span><span class=\"k\">if</span> <span class=\"n\">__name__</span> <span class=\"o\">==</span> <span class=\"sh\">'</span><span class=\"s\">__main__</span><span class=\"sh\">'</span><span class=\"p\">:</span> <span class=\"n\">s</span> <span class=\"o\">=</span> <span class=\"nc\">Solution</span><span class=\"p\">().</span><span class=\"n\">topKFrequent</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">([</span><span class=\"mi\">1</span><span class=\"p\">,</span><span class=\"mi\">1</span><span class=\"p\">,</span><span class=\"mi\">1</span><span class=\"p\">,</span><span class=\"mi\">2</span><span class=\"p\">,</span><span class=\"mi\">2</span><span class=\"p\">,</span><span class=\"mi\">3</span><span class=\"p\">],</span> <span class=\"mi\">2</span><span class=\"p\">),</span> <span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">,</span><span class=\"mi\">2</span><span class=\"p\">])</span></code></pre></figure><blockquote> <p>Runtime: 227 ms, faster than 14.08% of Python3 online submissions for Top K Frequent Elements. Memory Usage: 18.7 MB, less than 71.72% of Python3 online submissions for Top K Frequent Elements.</p></blockquote>", "date_published": "2022-10-24T20:00:00+00:00" }, { "id": "https://fewald.net/leetcode/2022/10/23/leetcode-find-peak-element.html", "url": "https://fewald.net/leetcode/2022/10/23/leetcode-find-peak-element.html", "title": "Leetcode: Find peak element", "content_html": "<p>Given an array <code class=\"language-plaintext highlighter-rouge\">n</code> of integers, find one peak in <code class=\"language-plaintext highlighter-rouge\">O(log*n)</code> time. A peak is defined as a number where the two numbers immediately left and right are strictly less than the number. Numbers outside of the bounds of this array are considered to be smaller.</p><!--more--><p>We can leverage the binary search algorithm to find a peak. This is because we can split the array in two parts and look in the middle. If left and right are smaller, it is a peak, otherwise we move in the direction of the higher element. This allows us to find the peak in <code class=\"language-plaintext highlighter-rouge\">log*n</code> steps.</p><figure class=\"highlight\"><pre><code class=\"language-python\" data-lang=\"python\"><span class=\"kn\">from</span> <span class=\"n\">typing</span> <span class=\"kn\">import</span> <span class=\"n\">List</span><span class=\"k\">class</span> <span class=\"nc\">Solution</span><span class=\"p\">:</span> <span class=\"k\">def</span> <span class=\"nf\">findPeakElement</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">nums</span><span class=\"p\">:</span> <span class=\"n\">List</span><span class=\"p\">[</span><span class=\"nb\">int</span><span class=\"p\">])</span> <span class=\"o\">-></span> <span class=\"nb\">int</span><span class=\"p\">:</span> <span class=\"n\">l</span> <span class=\"o\">=</span> <span class=\"mi\">0</span> <span class=\"n\">r</span> <span class=\"o\">=</span> <span class=\"nf\">len</span><span class=\"p\">(</span><span class=\"n\">nums</span><span class=\"p\">)</span> <span class=\"o\">-</span> <span class=\"mi\">1</span> <span class=\"n\">m</span> <span class=\"o\">=</span> <span class=\"p\">(</span><span class=\"n\">l</span><span class=\"o\">+</span><span class=\"n\">r</span><span class=\"p\">)</span><span class=\"o\">//</span><span class=\"mi\">2</span> <span class=\"k\">while</span> <span class=\"n\">l</span> <span class=\"o\"><</span> <span class=\"n\">r</span><span class=\"p\">:</span> <span class=\"n\">peak</span> <span class=\"o\">=</span> <span class=\"n\">nums</span><span class=\"p\">[</span><span class=\"n\">m</span><span class=\"p\">]</span> <span class=\"n\">lsm</span> <span class=\"o\">=</span> <span class=\"bp\">True</span> <span class=\"k\">if</span> <span class=\"n\">m</span> <span class=\"o\">==</span> <span class=\"mi\">0</span> <span class=\"ow\">or</span> <span class=\"n\">nums</span><span class=\"p\">[</span><span class=\"n\">m</span><span class=\"p\">]</span> <span class=\"o\">></span> <span class=\"n\">nums</span><span class=\"p\">[</span><span class=\"n\">m</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">]</span> <span class=\"k\">else</span> <span class=\"bp\">False</span> <span class=\"n\">rsm</span> <span class=\"o\">=</span> <span class=\"bp\">True</span> <span class=\"k\">if</span> <span class=\"n\">m</span> <span class=\"o\">==</span> <span class=\"nf\">len</span><span class=\"p\">(</span><span class=\"n\">nums</span><span class=\"p\">)</span><span class=\"o\">-</span><span class=\"mi\">1</span> <span class=\"ow\">or</span> <span class=\"n\">nums</span><span class=\"p\">[</span><span class=\"n\">m</span><span class=\"p\">]</span> <span class=\"o\">></span> <span class=\"n\">nums</span><span class=\"p\">[</span><span class=\"n\">m</span><span class=\"o\">+</span><span class=\"mi\">1</span><span class=\"p\">]</span> <span class=\"k\">else</span> <span class=\"bp\">False</span> <span class=\"k\">if</span> <span class=\"n\">lsm</span> <span class=\"ow\">and</span> <span class=\"n\">rsm</span><span class=\"p\">:</span> <span class=\"k\">return</span> <span class=\"n\">m</span> <span class=\"k\">if</span> <span class=\"n\">lsm</span><span class=\"p\">:</span> <span class=\"n\">l</span> <span class=\"o\">=</span> <span class=\"n\">m</span><span class=\"o\">+</span><span class=\"mi\">1</span> <span class=\"k\">else</span><span class=\"p\">:</span> <span class=\"n\">r</span> <span class=\"o\">=</span> <span class=\"n\">m</span> <span class=\"n\">m</span> <span class=\"o\">=</span> <span class=\"p\">(</span><span class=\"n\">l</span><span class=\"o\">+</span><span class=\"n\">r</span><span class=\"p\">)</span><span class=\"o\">//</span><span class=\"mi\">2</span> <span class=\"k\">return</span> <span class=\"n\">m</span> <span class=\"k\">if</span> <span class=\"n\">__name__</span> <span class=\"o\">==</span> <span class=\"sh\">'</span><span class=\"s\">__main__</span><span class=\"sh\">'</span><span class=\"p\">:</span> <span class=\"n\">s</span> <span class=\"o\">=</span> <span class=\"nc\">Solution</span><span class=\"p\">().</span><span class=\"n\">findPeakElement</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">([</span><span class=\"mi\">1</span><span class=\"p\">,</span><span class=\"mi\">2</span><span class=\"p\">,</span><span class=\"mi\">3</span><span class=\"p\">,</span><span class=\"mi\">1</span><span class=\"p\">]),</span> <span class=\"mi\">2</span><span class=\"p\">)</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">([</span><span class=\"mi\">5</span><span class=\"p\">,</span><span class=\"mi\">4</span><span class=\"p\">,</span><span class=\"mi\">3</span><span class=\"p\">,</span><span class=\"mi\">2</span><span class=\"p\">,</span><span class=\"mi\">1</span><span class=\"p\">,</span><span class=\"mi\">0</span><span class=\"p\">,</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">,</span><span class=\"o\">-</span><span class=\"mi\">2</span><span class=\"p\">,</span><span class=\"o\">-</span><span class=\"mi\">3</span><span class=\"p\">,</span><span class=\"o\">-</span><span class=\"mi\">4</span><span class=\"p\">]),</span> <span class=\"mi\">0</span><span class=\"p\">)</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">([</span><span class=\"mi\">0</span><span class=\"p\">,</span><span class=\"mi\">1</span><span class=\"p\">,</span><span class=\"mi\">2</span><span class=\"p\">,</span><span class=\"mi\">3</span><span class=\"p\">,</span><span class=\"mi\">4</span><span class=\"p\">,</span><span class=\"mi\">5</span><span class=\"p\">,</span><span class=\"mi\">6</span><span class=\"p\">,</span><span class=\"mi\">5</span><span class=\"p\">,</span><span class=\"mi\">4</span><span class=\"p\">,</span><span class=\"mi\">3</span><span class=\"p\">]),</span> <span class=\"mi\">6</span><span class=\"p\">)</span></code></pre></figure>", "date_published": "2022-10-23T20:00:00+00:00" }, { "id": "https://fewald.net/leetcode/2022/10/22/leetcode-minimum-stack.html", "url": "https://fewald.net/leetcode/2022/10/22/leetcode-minimum-stack.html", "title": "Leetcode: Minimum Stack", "content_html": "<p>Create a stack implementation that is able to return the minimum element as well as <code class=\"language-plaintext highlighter-rouge\">push</code> and <code class=\"language-plaintext highlighter-rouge\">pop</code> elements, all in constant time <code class=\"language-plaintext highlighter-rouge\">O(1)</code>.</p><!--more--><p>I used the builtin <code class=\"language-plaintext highlighter-rouge\">heapq</code> <a href=\"https://docs.python.org/3/library/heapq.html\">library</a> which provides a heap implementation. This works realiably to find the minimum element. When deleting element from the stack structure we don’t know where on the heap the element is stored. Any type of scanning the heap would violate the <code class=\"language-plaintext highlighter-rouge\">O(1)</code> requirement. Instead, I chose to store the deleted elements in a <code class=\"language-plaintext highlighter-rouge\">dictionary</code>. If the min element should be returned, the tombstones are checked. If the element is marked as deleted, the next item is checked, and so on. I use a list as the actual stack because <code class=\"language-plaintext highlighter-rouge\">append</code> and <code class=\"language-plaintext highlighter-rouge\">pop</code> perform both in <code class=\"language-plaintext highlighter-rouge\">O(1)</code>.</p><figure class=\"highlight\"><pre><code class=\"language-python\" data-lang=\"python\"><span class=\"kn\">import</span> <span class=\"n\">heapq</span><span class=\"k\">class</span> <span class=\"nc\">MinStack</span><span class=\"p\">:</span> <span class=\"k\">def</span> <span class=\"nf\">__init__</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">):</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">_s</span> <span class=\"o\">=</span> <span class=\"p\">[]</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">_h</span> <span class=\"o\">=</span> <span class=\"p\">[]</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">_popped</span> <span class=\"o\">=</span> <span class=\"p\">{}</span> <span class=\"k\">def</span> <span class=\"nf\">push</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">val</span><span class=\"p\">:</span> <span class=\"nb\">int</span><span class=\"p\">)</span> <span class=\"o\">-></span> <span class=\"bp\">None</span><span class=\"p\">:</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">_s</span><span class=\"p\">.</span><span class=\"nf\">append</span><span class=\"p\">(</span><span class=\"n\">val</span><span class=\"p\">)</span> <span class=\"n\">heapq</span><span class=\"p\">.</span><span class=\"nf\">heappush</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">_h</span><span class=\"p\">,</span> <span class=\"n\">val</span><span class=\"p\">)</span> <span class=\"k\">def</span> <span class=\"nf\">pop</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">)</span> <span class=\"o\">-></span> <span class=\"bp\">None</span><span class=\"p\">:</span> <span class=\"n\">item</span> <span class=\"o\">=</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">_s</span><span class=\"p\">.</span><span class=\"nf\">pop</span><span class=\"p\">()</span> <span class=\"k\">if</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">_h</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span> <span class=\"o\">==</span> <span class=\"n\">item</span><span class=\"p\">:</span> <span class=\"n\">heapq</span><span class=\"p\">.</span><span class=\"nf\">heappop</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">_h</span><span class=\"p\">)</span> <span class=\"k\">else</span><span class=\"p\">:</span> <span class=\"k\">if</span> <span class=\"n\">item</span> <span class=\"ow\">not</span> <span class=\"ow\">in</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">_popped</span><span class=\"p\">:</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">_popped</span><span class=\"p\">[</span><span class=\"n\">item</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"mi\">0</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">_popped</span><span class=\"p\">[</span><span class=\"n\">item</span><span class=\"p\">]</span> <span class=\"o\">+=</span> <span class=\"mi\">1</span> <span class=\"k\">def</span> <span class=\"nf\">top</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">)</span> <span class=\"o\">-></span> <span class=\"nb\">int</span><span class=\"p\">:</span> <span class=\"k\">return</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">_s</span><span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">]</span> <span class=\"k\">def</span> <span class=\"nf\">getMin</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">)</span> <span class=\"o\">-></span> <span class=\"nb\">int</span><span class=\"p\">:</span> <span class=\"k\">while</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">_h</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span> <span class=\"ow\">in</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">_popped</span><span class=\"p\">:</span> <span class=\"n\">item</span> <span class=\"o\">=</span> <span class=\"n\">heapq</span><span class=\"p\">.</span><span class=\"nf\">heappop</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">_h</span><span class=\"p\">)</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">_popped</span><span class=\"p\">[</span><span class=\"n\">item</span><span class=\"p\">]</span> <span class=\"o\">-=</span> <span class=\"mi\">1</span> <span class=\"k\">if</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">_popped</span><span class=\"p\">[</span><span class=\"n\">item</span><span class=\"p\">]</span> <span class=\"o\">==</span> <span class=\"mi\">0</span><span class=\"p\">:</span> <span class=\"k\">del</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">_popped</span><span class=\"p\">[</span><span class=\"n\">item</span><span class=\"p\">]</span> <span class=\"k\">return</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">_h</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span></code></pre></figure><blockquote> <p>Runtime: 157 ms, faster than 12.25% of Python3 online submissions for Min Stack. Memory Usage: 18 MB, less than 60.07% of Python3 online submissions for Min Stack.</p></blockquote>", "date_published": "2022-10-22T20:00:00+00:00" }, { "id": "https://fewald.net/leetcode/2022/10/21/leetcode-populate-next-pointers.html", "url": "https://fewald.net/leetcode/2022/10/21/leetcode-populate-next-pointers.html", "title": "Leetcode: Populate next pointers in tree", "content_html": "<p>Given a perfect binary search tree, connect all the nodes to the node on their right</p><p>The solution is to do breadth-first-search in an iterative fashion. This puts all the nodes at the same level in a queue. By iterating over the queue we can connect each node to its successor. During this process we add the children of each node as the next entry. We repeat this process until the queue is empty.</p><!--more--><figure class=\"highlight\"><pre><code class=\"language-python\" data-lang=\"python\"><span class=\"k\">class</span> <span class=\"nc\">Node</span><span class=\"p\">:</span> <span class=\"k\">def</span> <span class=\"nf\">__init__</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">val</span><span class=\"o\">=</span><span class=\"mi\">0</span><span class=\"p\">,</span> <span class=\"n\">left</span><span class=\"o\">=</span><span class=\"bp\">None</span><span class=\"p\">,</span> <span class=\"n\">right</span><span class=\"o\">=</span><span class=\"bp\">None</span><span class=\"p\">,</span> <span class=\"nb\">next</span><span class=\"o\">=</span><span class=\"bp\">None</span><span class=\"p\">):</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">val</span> <span class=\"o\">=</span> <span class=\"n\">val</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">left</span> <span class=\"o\">=</span> <span class=\"n\">left</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">right</span> <span class=\"o\">=</span> <span class=\"n\">right</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"nb\">next</span> <span class=\"o\">=</span> <span class=\"nb\">next</span> <span class=\"k\">def</span> <span class=\"nf\">__repr__</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">)</span> <span class=\"o\">-></span> <span class=\"nb\">str</span><span class=\"p\">:</span> <span class=\"k\">return</span> <span class=\"sa\">f</span><span class=\"sh\">'</span><span class=\"si\">{</span><span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">val</span><span class=\"si\">}</span><span class=\"sh\">'</span><span class=\"k\">class</span> <span class=\"nc\">Solution</span><span class=\"p\">:</span> <span class=\"k\">def</span> <span class=\"nf\">connect</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">root</span><span class=\"p\">):</span> <span class=\"n\">queue</span> <span class=\"o\">=</span> <span class=\"p\">[[</span><span class=\"n\">root</span><span class=\"p\">]]</span> <span class=\"k\">while</span> <span class=\"nf\">len</span><span class=\"p\">(</span><span class=\"n\">queue</span><span class=\"p\">)</span> <span class=\"o\">></span> <span class=\"mi\">0</span><span class=\"p\">:</span> <span class=\"k\">for</span> <span class=\"n\">i</span> <span class=\"ow\">in</span> <span class=\"nf\">range</span><span class=\"p\">(</span><span class=\"nf\">len</span><span class=\"p\">(</span><span class=\"n\">queue</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">])</span> <span class=\"o\">-</span> <span class=\"mi\">1</span><span class=\"p\">):</span> <span class=\"n\">queue</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">][</span><span class=\"n\">i</span><span class=\"p\">].</span><span class=\"nb\">next</span> <span class=\"o\">=</span> <span class=\"n\">queue</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">][</span><span class=\"n\">i</span><span class=\"o\">+</span><span class=\"mi\">1</span><span class=\"p\">]</span> <span class=\"n\">queue</span><span class=\"p\">.</span><span class=\"nf\">append</span><span class=\"p\">([])</span> <span class=\"k\">for</span> <span class=\"n\">i</span> <span class=\"ow\">in</span> <span class=\"nf\">range</span><span class=\"p\">(</span><span class=\"nf\">len</span><span class=\"p\">(</span><span class=\"n\">queue</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">])):</span> <span class=\"n\">item</span> <span class=\"o\">=</span> <span class=\"n\">queue</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">][</span><span class=\"n\">i</span><span class=\"p\">]</span> <span class=\"k\">if</span> <span class=\"n\">item</span><span class=\"p\">.</span><span class=\"n\">left</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"bp\">None</span><span class=\"p\">:</span> <span class=\"n\">queue</span><span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">].</span><span class=\"nf\">append</span><span class=\"p\">(</span><span class=\"n\">item</span><span class=\"p\">.</span><span class=\"n\">left</span><span class=\"p\">)</span> <span class=\"k\">if</span> <span class=\"n\">item</span><span class=\"p\">.</span><span class=\"n\">right</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"bp\">None</span><span class=\"p\">:</span> <span class=\"n\">queue</span><span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">].</span><span class=\"nf\">append</span><span class=\"p\">(</span><span class=\"n\">item</span><span class=\"p\">.</span><span class=\"n\">right</span><span class=\"p\">)</span> <span class=\"k\">if</span> <span class=\"nf\">len</span><span class=\"p\">(</span><span class=\"n\">queue</span><span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">]):</span> <span class=\"n\">queue</span><span class=\"p\">.</span><span class=\"nf\">pop</span><span class=\"p\">()</span> <span class=\"n\">queue</span> <span class=\"o\">=</span> <span class=\"n\">queue</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">:]</span> <span class=\"k\">return</span> <span class=\"n\">root</span><span class=\"k\">if</span> <span class=\"n\">__name__</span> <span class=\"o\">==</span> <span class=\"sh\">'</span><span class=\"s\">__main__</span><span class=\"sh\">'</span><span class=\"p\">:</span> <span class=\"n\">s</span> <span class=\"o\">=</span> <span class=\"nc\">Solution</span><span class=\"p\">().</span><span class=\"n\">connect</span> <span class=\"n\">r</span> <span class=\"o\">=</span> <span class=\"nc\">Node</span><span class=\"p\">(</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"nc\">Node</span><span class=\"p\">(</span><span class=\"mi\">2</span><span class=\"p\">,</span> <span class=\"nc\">Node</span><span class=\"p\">(</span><span class=\"mi\">4</span><span class=\"p\">),</span> <span class=\"nc\">Node</span><span class=\"p\">(</span><span class=\"mi\">5</span><span class=\"p\">)),</span> <span class=\"nc\">Node</span><span class=\"p\">(</span><span class=\"mi\">3</span><span class=\"p\">,</span> <span class=\"nc\">Node</span><span class=\"p\">(</span><span class=\"mi\">6</span><span class=\"p\">),</span> <span class=\"nc\">Node</span><span class=\"p\">(</span><span class=\"mi\">7</span><span class=\"p\">)))</span> <span class=\"nf\">s</span><span class=\"p\">(</span><span class=\"n\">r</span><span class=\"p\">)</span></code></pre></figure><blockquote> <p>Runtime: 84 ms, faster than 70.50% of Python3 online submissions for Populating Next Right Pointers in Each Node. Memory Usage: 15.8 MB, less than 49.85% of Python3 online submissions for Populating Next Right Pointers in Each Node.</p></blockquote>", "date_published": "2022-10-21T20:00:00+00:00" }, { "id": "https://fewald.net/leetcode/2022/10/20/leetcode-generate-parentheses.html", "url": "https://fewald.net/leetcode/2022/10/20/leetcode-generate-parentheses.html", "title": "Leetcode: Generate parentheses", "content_html": "<p>Given a strictly positive integer <code class=\"language-plaintext highlighter-rouge\">n</code>, write a function that returns all possible combinations of well-formed parentheses.</p><p>Parentheses can be nested and added one after the other. It is important that we don’t create invalid combinations, such as <code class=\"language-plaintext highlighter-rouge\">)(</code>. The idea then becomes to start with a single set of parentheses <code class=\"language-plaintext highlighter-rouge\">()</code>. We can add another set of parentheses at three possible places: <code class=\"language-plaintext highlighter-rouge\">1(2)3</code>. When looking closely, we see that <code class=\"language-plaintext highlighter-rouge\">1</code> and <code class=\"language-plaintext highlighter-rouge\">3</code> are the same position.</p><p>We can then utilize Pythons string splitting capabilities which allow us to insert one or more characters at any place in the string. We do this by iterating over the string and inserting <code class=\"language-plaintext highlighter-rouge\">()</code> at every possible position. This creates all valid pairs like <code class=\"language-plaintext highlighter-rouge\">(())</code> and <code class=\"language-plaintext highlighter-rouge\">()()</code> etc.</p><p>To avoid the aforementioned duplicates we can add a memory to the function and store all the visited possible combinations. This allows us to speed the process up significantly. For example when we visit <code class=\"language-plaintext highlighter-rouge\">()()</code>, we don’t need to visit it again to form <code class=\"language-plaintext highlighter-rouge\">()()()</code> or <code class=\"language-plaintext highlighter-rouge\">()(())</code> (for <code class=\"language-plaintext highlighter-rouge\">n=3</code>) because they would already been visited.</p><!--more--><figure class=\"highlight\"><pre><code class=\"language-python\" data-lang=\"python\"><span class=\"kn\">from</span> <span class=\"n\">typing</span> <span class=\"kn\">import</span> <span class=\"n\">List</span><span class=\"k\">class</span> <span class=\"nc\">Solution</span><span class=\"p\">:</span> <span class=\"k\">def</span> <span class=\"nf\">generateParenthesis</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">n</span><span class=\"p\">:</span> <span class=\"nb\">int</span><span class=\"p\">)</span> <span class=\"o\">-></span> <span class=\"n\">List</span><span class=\"p\">[</span><span class=\"nb\">str</span><span class=\"p\">]:</span> <span class=\"k\">if</span> <span class=\"n\">n</span> <span class=\"o\">==</span> <span class=\"mi\">0</span><span class=\"p\">:</span> <span class=\"k\">return</span> <span class=\"p\">[]</span> <span class=\"n\">memo</span> <span class=\"o\">=</span> <span class=\"nf\">set</span><span class=\"p\">()</span> <span class=\"k\">def</span> <span class=\"nf\">inner</span><span class=\"p\">(</span><span class=\"n\">n</span><span class=\"p\">,</span> <span class=\"n\">s</span><span class=\"p\">):</span> <span class=\"k\">if</span> <span class=\"n\">n</span> <span class=\"o\">==</span> <span class=\"mi\">0</span><span class=\"p\">:</span> <span class=\"k\">return</span> <span class=\"p\">[</span><span class=\"n\">s</span><span class=\"p\">]</span> <span class=\"n\">res</span> <span class=\"o\">=</span> <span class=\"p\">[]</span> <span class=\"k\">for</span> <span class=\"n\">p</span> <span class=\"ow\">in</span> <span class=\"nf\">range</span><span class=\"p\">(</span><span class=\"nf\">len</span><span class=\"p\">(</span><span class=\"n\">s</span><span class=\"p\">)):</span> <span class=\"n\">cand</span> <span class=\"o\">=</span> <span class=\"n\">s</span><span class=\"p\">[:</span><span class=\"n\">p</span><span class=\"p\">]</span> <span class=\"o\">+</span> <span class=\"sh\">'</span><span class=\"s\">()</span><span class=\"sh\">'</span> <span class=\"o\">+</span> <span class=\"n\">s</span><span class=\"p\">[</span><span class=\"n\">p</span><span class=\"p\">:]</span> <span class=\"k\">if</span> <span class=\"n\">cand</span> <span class=\"ow\">in</span> <span class=\"n\">memo</span><span class=\"p\">:</span> <span class=\"k\">continue</span> <span class=\"n\">memo</span><span class=\"p\">.</span><span class=\"nf\">add</span><span class=\"p\">(</span><span class=\"n\">cand</span><span class=\"p\">)</span> <span class=\"n\">res</span> <span class=\"o\">+=</span> <span class=\"nf\">inner</span><span class=\"p\">(</span><span class=\"n\">n</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"n\">cand</span><span class=\"p\">)</span> <span class=\"k\">return</span> <span class=\"n\">res</span> <span class=\"n\">res</span> <span class=\"o\">=</span> <span class=\"nf\">inner</span><span class=\"p\">(</span><span class=\"n\">n</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"sh\">'</span><span class=\"s\">()</span><span class=\"sh\">'</span><span class=\"p\">)</span> <span class=\"k\">return</span> <span class=\"n\">res</span> <span class=\"k\">if</span> <span class=\"n\">__name__</span> <span class=\"o\">==</span> <span class=\"sh\">'</span><span class=\"s\">__main__</span><span class=\"sh\">'</span><span class=\"p\">:</span> <span class=\"n\">s</span> <span class=\"o\">=</span> <span class=\"nc\">Solution</span><span class=\"p\">().</span><span class=\"n\">generateParenthesis</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">(</span><span class=\"mi\">0</span><span class=\"p\">),</span> <span class=\"p\">[])</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">(</span><span class=\"mi\">1</span><span class=\"p\">),</span> <span class=\"p\">[</span><span class=\"sh\">'</span><span class=\"s\">()</span><span class=\"sh\">'</span><span class=\"p\">])</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">(</span><span class=\"mi\">2</span><span class=\"p\">),</span> <span class=\"p\">[</span><span class=\"sh\">'</span><span class=\"s\">()()</span><span class=\"sh\">'</span><span class=\"p\">,</span> <span class=\"sh\">'</span><span class=\"s\">(())</span><span class=\"sh\">'</span><span class=\"p\">])</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">(</span><span class=\"mi\">3</span><span class=\"p\">),</span> <span class=\"p\">[</span><span class=\"sh\">'</span><span class=\"s\">((()))</span><span class=\"sh\">'</span><span class=\"p\">,</span> <span class=\"sh\">'</span><span class=\"s\">(()())</span><span class=\"sh\">'</span><span class=\"p\">,</span> <span class=\"sh\">'</span><span class=\"s\">(())()</span><span class=\"sh\">'</span><span class=\"p\">,</span> <span class=\"sh\">'</span><span class=\"s\">()(())</span><span class=\"sh\">'</span><span class=\"p\">,</span> <span class=\"sh\">'</span><span class=\"s\">()()()</span><span class=\"sh\">'</span><span class=\"p\">])</span></code></pre></figure><p>This solution beats 98% of all submitted solutions in terms of speed.</p><h2 id=\"2024-update\">2024 Update</h2><p>When examining this problem again, I wanted to find a solution without memory overhead.</p><figure class=\"highlight\"><pre><code class=\"language-python\" data-lang=\"python\"><span class=\"k\">class</span> <span class=\"nc\">Solution</span><span class=\"p\">:</span> <span class=\"k\">def</span> <span class=\"nf\">generateParenthesis</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">n</span><span class=\"p\">:</span> <span class=\"nb\">int</span><span class=\"p\">)</span> <span class=\"o\">-></span> <span class=\"n\">List</span><span class=\"p\">[</span><span class=\"nb\">str</span><span class=\"p\">]:</span> <span class=\"n\">results</span> <span class=\"o\">=</span> <span class=\"p\">[]</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"nf\">inner</span><span class=\"p\">(</span><span class=\"mi\">0</span><span class=\"p\">,</span><span class=\"mi\">0</span><span class=\"p\">,</span><span class=\"n\">n</span><span class=\"p\">,[],</span><span class=\"n\">results</span><span class=\"p\">)</span> <span class=\"k\">return</span> <span class=\"n\">results</span> <span class=\"k\">def</span> <span class=\"nf\">inner</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">left</span><span class=\"p\">:</span> <span class=\"nb\">int</span><span class=\"p\">,</span> <span class=\"n\">right</span><span class=\"p\">:</span> <span class=\"nb\">int</span><span class=\"p\">,</span> <span class=\"n\">n</span><span class=\"p\">:</span> <span class=\"nb\">int</span><span class=\"p\">,</span> <span class=\"n\">path</span><span class=\"p\">:</span> <span class=\"n\">List</span><span class=\"p\">[</span><span class=\"nb\">str</span><span class=\"p\">],</span> <span class=\"n\">result</span><span class=\"p\">:</span> <span class=\"n\">List</span><span class=\"p\">[</span><span class=\"nb\">str</span><span class=\"p\">])</span> <span class=\"o\">-></span> <span class=\"bp\">None</span><span class=\"p\">:</span> <span class=\"k\">if</span> <span class=\"n\">left</span> <span class=\"o\">==</span> <span class=\"n\">n</span> <span class=\"ow\">and</span> <span class=\"n\">right</span> <span class=\"o\">==</span> <span class=\"n\">n</span><span class=\"p\">:</span> <span class=\"n\">result</span><span class=\"p\">.</span><span class=\"nf\">append</span><span class=\"p\">(</span><span class=\"sh\">\"\"</span><span class=\"p\">.</span><span class=\"nf\">join</span><span class=\"p\">(</span><span class=\"n\">path</span><span class=\"p\">))</span> <span class=\"k\">if</span> <span class=\"n\">left</span> <span class=\"o\"><</span> <span class=\"n\">n</span><span class=\"p\">:</span> <span class=\"n\">path</span><span class=\"p\">.</span><span class=\"nf\">append</span><span class=\"p\">(</span><span class=\"sh\">'</span><span class=\"s\">(</span><span class=\"sh\">'</span><span class=\"p\">)</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"nf\">inner</span><span class=\"p\">(</span><span class=\"n\">left</span><span class=\"o\">+</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"n\">right</span><span class=\"p\">,</span> <span class=\"n\">n</span><span class=\"p\">,</span> <span class=\"n\">path</span><span class=\"p\">,</span> <span class=\"n\">result</span><span class=\"p\">)</span> <span class=\"n\">path</span><span class=\"p\">.</span><span class=\"nf\">pop</span><span class=\"p\">()</span> <span class=\"k\">if</span> <span class=\"n\">right</span> <span class=\"o\"><</span> <span class=\"n\">left</span><span class=\"p\">:</span> <span class=\"n\">path</span><span class=\"p\">.</span><span class=\"nf\">append</span><span class=\"p\">(</span><span class=\"sh\">'</span><span class=\"s\">)</span><span class=\"sh\">'</span><span class=\"p\">)</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"nf\">inner</span><span class=\"p\">(</span><span class=\"n\">left</span><span class=\"p\">,</span> <span class=\"n\">right</span><span class=\"o\">+</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"n\">n</span><span class=\"p\">,</span> <span class=\"n\">path</span><span class=\"p\">,</span> <span class=\"n\">result</span><span class=\"p\">)</span> <span class=\"n\">path</span><span class=\"p\">.</span><span class=\"nf\">pop</span><span class=\"p\">()</span></code></pre></figure><p>This solution adds the parentheses individually instead of all at once. It first tries to add <code class=\"language-plaintext highlighter-rouge\">left</code> parentheses to <code class=\"language-plaintext highlighter-rouge\">path</code>, until it is no longer possible. Then it attempts to add <code class=\"language-plaintext highlighter-rouge\">right</code> parentheses until <code class=\"language-plaintext highlighter-rouge\">left == right</code>. At this point we know we have a valid <code class=\"language-plaintext highlighter-rouge\">output</code> path gets transformed into a <code class=\"language-plaintext highlighter-rouge\">result</code>: <code class=\"language-plaintext highlighter-rouge\">((()))</code>.</p><p>Then the backtracking begins by going one level up and adding a <code class=\"language-plaintext highlighter-rouge\">right</code> parentheses, going again a level deeper <code class=\"language-plaintext highlighter-rouge\">(()</code>. Now it’s possible to add a <code class=\"language-plaintext highlighter-rouge\">left</code> parenthesis again <code class=\"language-plaintext highlighter-rouge\">(()(</code>, followed by two <code class=\"language-plaintext highlighter-rouge\">right</code> parentheses. This ultimately yields all possible solutions without duplicates.</p>", "date_published": "2022-10-20T20:00:00+00:00" }, { "id": "https://fewald.net/leetcode/2022/10/19/leetcode-word-break.html", "url": "https://fewald.net/leetcode/2022/10/19/leetcode-word-break.html", "title": "Leetcode: Word break", "content_html": "<p>Given a string <code class=\"language-plaintext highlighter-rouge\">s</code> and a list of <code class=\"language-plaintext highlighter-rouge\">words</code>, return <code class=\"language-plaintext highlighter-rouge\">True</code> if the string can be constructed from any combination of the words and <code class=\"language-plaintext highlighter-rouge\">False</code> otherwise. The alphabet contains only lowercase English characters.</p><p>My initial idea was to replace all occurrences of a <code class=\"language-plaintext highlighter-rouge\">word</code> in the string <code class=\"language-plaintext highlighter-rouge\">s</code>. The problem with this approach is that a string <code class=\"language-plaintext highlighter-rouge\">aabb</code> with the words <code class=\"language-plaintext highlighter-rouge\">['ab']</code> is considered valid, while it is not. I then tried on adding breaking characters (<code class=\"language-plaintext highlighter-rouge\">.</code>) to prevent this. It worked although very slowly.</p><!--more--><p>My next approach was to start only from the beginning and remove the current <code class=\"language-plaintext highlighter-rouge\">word</code> from <code class=\"language-plaintext highlighter-rouge\">s</code> if it was the prefix. The advantage is that this alrogrithm is relatively straightforward. The disadvantage is that it is relatively time-intensive. The same words will be checked over and over again.</p><figure class=\"highlight\"><pre><code class=\"language-python\" data-lang=\"python\"><span class=\"k\">class</span> <span class=\"nc\">Solution</span><span class=\"p\">:</span> <span class=\"k\">def</span> <span class=\"nf\">wordBreak</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">s</span><span class=\"p\">:</span> <span class=\"nb\">str</span><span class=\"p\">,</span> <span class=\"n\">wordDict</span><span class=\"p\">:</span> <span class=\"n\">List</span><span class=\"p\">[</span><span class=\"nb\">str</span><span class=\"p\">])</span> <span class=\"o\">-></span> <span class=\"nb\">bool</span><span class=\"p\">:</span> <span class=\"k\">if</span> <span class=\"n\">s</span> <span class=\"o\">==</span> <span class=\"sh\">\"\"</span><span class=\"p\">:</span> <span class=\"k\">return</span> <span class=\"bp\">True</span> <span class=\"n\">res</span> <span class=\"o\">=</span> <span class=\"bp\">False</span> <span class=\"k\">for</span> <span class=\"n\">i</span><span class=\"p\">,</span> <span class=\"n\">word</span> <span class=\"ow\">in</span> <span class=\"nf\">enumerate</span><span class=\"p\">(</span><span class=\"n\">wordDict</span><span class=\"p\">):</span> <span class=\"k\">if</span> <span class=\"n\">s</span><span class=\"p\">.</span><span class=\"nf\">startswith</span><span class=\"p\">(</span><span class=\"n\">word</span><span class=\"p\">):</span> <span class=\"n\">res</span> <span class=\"o\">=</span> <span class=\"n\">res</span> <span class=\"ow\">or</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"nf\">wordBreak</span><span class=\"p\">(</span><span class=\"n\">s</span><span class=\"p\">[</span><span class=\"nf\">len</span><span class=\"p\">(</span><span class=\"n\">word</span><span class=\"p\">):],</span> <span class=\"n\">wordDict</span><span class=\"p\">)</span> <span class=\"k\">return</span> <span class=\"n\">res</span></code></pre></figure><p>Adding memoization speeds up the solution by quite a bit. Here, we initialize a <code class=\"language-plaintext highlighter-rouge\">map</code> or <code class=\"language-plaintext highlighter-rouge\">dictionary</code>, that contains all previously seen and invalid or valid substrings. Before going into the recursion, we check whether the word was already seen and if it was, we return the previously computed value.</p><figure class=\"highlight\"><pre><code class=\"language-python\" data-lang=\"python\"><span class=\"kn\">from</span> <span class=\"n\">typing</span> <span class=\"kn\">import</span> <span class=\"n\">List</span><span class=\"k\">class</span> <span class=\"nc\">Solution</span><span class=\"p\">:</span> <span class=\"k\">def</span> <span class=\"nf\">wordBreak</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">s</span><span class=\"p\">:</span> <span class=\"nb\">str</span><span class=\"p\">,</span> <span class=\"n\">wordDict</span><span class=\"p\">:</span> <span class=\"n\">List</span><span class=\"p\">[</span><span class=\"nb\">str</span><span class=\"p\">])</span> <span class=\"o\">-></span> <span class=\"nb\">bool</span><span class=\"p\">:</span> <span class=\"n\">memo</span> <span class=\"o\">=</span> <span class=\"p\">{}</span> <span class=\"k\">def</span> <span class=\"nf\">inner</span><span class=\"p\">(</span><span class=\"n\">s</span><span class=\"p\">,</span> <span class=\"n\">wordDict</span><span class=\"p\">):</span> <span class=\"k\">if</span> <span class=\"n\">s</span> <span class=\"o\">==</span> <span class=\"sh\">\"\"</span><span class=\"p\">:</span> <span class=\"k\">return</span> <span class=\"bp\">True</span> <span class=\"k\">if</span> <span class=\"n\">s</span> <span class=\"ow\">in</span> <span class=\"n\">memo</span><span class=\"p\">:</span> <span class=\"k\">return</span> <span class=\"n\">memo</span><span class=\"p\">[</span><span class=\"n\">s</span><span class=\"p\">]</span> <span class=\"k\">for</span> <span class=\"n\">word</span> <span class=\"ow\">in</span> <span class=\"n\">wordDict</span><span class=\"p\">:</span> <span class=\"k\">if</span> <span class=\"n\">s</span><span class=\"p\">.</span><span class=\"nf\">startswith</span><span class=\"p\">(</span><span class=\"n\">word</span><span class=\"p\">):</span> <span class=\"k\">if</span> <span class=\"nf\">inner</span><span class=\"p\">(</span><span class=\"n\">s</span><span class=\"p\">[</span><span class=\"nf\">len</span><span class=\"p\">(</span><span class=\"n\">word</span><span class=\"p\">):],</span> <span class=\"n\">wordDict</span><span class=\"p\">):</span> <span class=\"n\">memo</span><span class=\"p\">[</span><span class=\"n\">s</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"bp\">True</span> <span class=\"k\">return</span> <span class=\"bp\">True</span> <span class=\"n\">memo</span><span class=\"p\">[</span><span class=\"n\">s</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"bp\">False</span> <span class=\"k\">return</span> <span class=\"bp\">False</span> <span class=\"k\">return</span> <span class=\"nf\">inner</span><span class=\"p\">(</span><span class=\"n\">s</span><span class=\"p\">,</span> <span class=\"n\">wordDict</span><span class=\"p\">)</span><span class=\"k\">if</span> <span class=\"n\">__name__</span> <span class=\"o\">==</span> <span class=\"sh\">'</span><span class=\"s\">__main__</span><span class=\"sh\">'</span><span class=\"p\">:</span> <span class=\"n\">s</span> <span class=\"o\">=</span> <span class=\"nc\">Solution</span><span class=\"p\">().</span><span class=\"n\">wordBreak</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">(</span><span class=\"sh\">'</span><span class=\"s\">leetcode</span><span class=\"sh\">'</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"sh\">\"</span><span class=\"s\">leet</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">code</span><span class=\"sh\">\"</span><span class=\"p\">]),</span> <span class=\"bp\">True</span><span class=\"p\">)</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">(</span><span class=\"sh\">'</span><span class=\"s\">applepenapple</span><span class=\"sh\">'</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"sh\">\"</span><span class=\"s\">apple</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">pen</span><span class=\"sh\">\"</span><span class=\"p\">]),</span> <span class=\"bp\">True</span><span class=\"p\">)</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">(</span><span class=\"sh\">'</span><span class=\"s\">catsandog</span><span class=\"sh\">'</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"sh\">\"</span><span class=\"s\">cats</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">dog</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">sand</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">and</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">cat</span><span class=\"sh\">\"</span><span class=\"p\">]),</span> <span class=\"bp\">False</span><span class=\"p\">)</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">(</span><span class=\"sh\">'</span><span class=\"s\">ccbb</span><span class=\"sh\">'</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"sh\">'</span><span class=\"s\">cb</span><span class=\"sh\">'</span><span class=\"p\">]),</span> <span class=\"bp\">False</span><span class=\"p\">)</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">(</span><span class=\"sh\">'</span><span class=\"s\">cbca</span><span class=\"sh\">'</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"sh\">'</span><span class=\"s\">bc</span><span class=\"sh\">'</span><span class=\"p\">,</span><span class=\"sh\">'</span><span class=\"s\">ca</span><span class=\"sh\">'</span><span class=\"p\">]),</span> <span class=\"bp\">False</span><span class=\"p\">)</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">(</span><span class=\"sh\">\"</span><span class=\"s\">ddadddbdddadd</span><span class=\"sh\">\"</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"sh\">\"</span><span class=\"s\">dd</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">ad</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">da</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">b</span><span class=\"sh\">\"</span><span class=\"p\">]),</span> <span class=\"bp\">True</span><span class=\"p\">)</span></code></pre></figure><blockquote> <p>Runtime: 75 ms, faster than 25.22% of Python3 online submissions for Word Break. Memory Usage: 14.2 MB, less than 14.55% of Python3 online submissions for Word Break.</p></blockquote><p>A good explanation on dynamic programming and memoization can be found <a href=\"https://www.freecodecamp.org/news/follow-these-steps-to-solve-any-dynamic-programming-interview-problem-cc98e508cd0e/\">here</a>.</p>", "date_published": "2022-10-19T20:00:00+00:00" }, { "id": "https://fewald.net/leetcode/2022/10/18/leetcode-maximum-product-subarray.html", "url": "https://fewald.net/leetcode/2022/10/18/leetcode-maximum-product-subarray.html", "title": "Leetcode: Maximum product subarray", "content_html": "<p>Given an array <code class=\"language-plaintext highlighter-rouge\">nums</code> with integer values <code class=\"language-plaintext highlighter-rouge\">-10 <= x <= 10</code>, calculate the maximum consecutive product. For example, the array <code class=\"language-plaintext highlighter-rouge\">[2,3,-1,4]</code> produces the maximum product <code class=\"language-plaintext highlighter-rouge\">6</code> because <code class=\"language-plaintext highlighter-rouge\">2*3=6</code>.</p><p>The first obsveration that we can make is that whenever a <code class=\"language-plaintext highlighter-rouge\">0</code> is encountered, it sets the whole product to <code class=\"language-plaintext highlighter-rouge\">0</code>. This means, if a <code class=\"language-plaintext highlighter-rouge\">0</code> is somewhere in the middle of the array, we need to look at the left and right part individually because they cannot be connected.</p><p>Secondly, an odd amount of negative numbers makes the whole product negative. Having <code class=\"language-plaintext highlighter-rouge\">2</code>, <code class=\"language-plaintext highlighter-rouge\">4,</code>, <code class=\"language-plaintext highlighter-rouge\">6</code>, … negative numbers will keep the product at the same amount (if all of them are <code class=\"language-plaintext highlighter-rouge\">-1</code>) or increase it.</p><p>Finally, since those numbers are all integers, the longer the chain of multiplied numbers, the higher to outcome.</p><!--more--><p>The algorithm that I came up with iterates twice over the whole array and has a time complexity of <code class=\"language-plaintext highlighter-rouge\">O(n)</code> and constant space complexity <code class=\"language-plaintext highlighter-rouge\">O(1)</code>. Given the following example <code class=\"language-plaintext highlighter-rouge\">[2,-2,3,-2,0,9]</code> we can define two pointers, <code class=\"language-plaintext highlighter-rouge\">i</code> and <code class=\"language-plaintext highlighter-rouge\">j</code> and two helper variables, <code class=\"language-plaintext highlighter-rouge\">max_product</code> and <code class=\"language-plaintext highlighter-rouge\">current_product</code>. We start at position <code class=\"language-plaintext highlighter-rouge\">0,0</code>, then move the <code class=\"language-plaintext highlighter-rouge\">j</code> pointer to the right and multiply the numbers that we encounter until we hit a <code class=\"language-plaintext highlighter-rouge\">0</code>. This way we slowly increment our product. At each step we compare the current product with the overal maximum. Once we reach the end or <code class=\"language-plaintext highlighter-rouge\">0</code>, we move <code class=\"language-plaintext highlighter-rouge\">i</code> to the right and divide at each step until we reach <code class=\"language-plaintext highlighter-rouge\">j</code>. If we reached a <code class=\"language-plaintext highlighter-rouge\">0</code> we add this as possible maximum and then jump with <code class=\"language-plaintext highlighter-rouge\">i</code> and <code class=\"language-plaintext highlighter-rouge\">j</code> over the <code class=\"language-plaintext highlighter-rouge\">0</code>, starting the above process again.</p><figure class=\"highlight\"><pre><code class=\"language-plain\" data-lang=\"plain\">[2,-2,3,-2,0,9] cur_prod=2, max_prod=2 ^ i[2,-2,3,-2,0,9] cur_prod=-4, max_prod=2 ^ ^ i j[2,-2,3,-2,0,9] cur_prod=-12, max_prod=2 ^ ^ i j[2,-2,3,-2,0,9] cur_prod=24, max_prod=24 ^ ^ i j[2,-2,3,-2,0,9] cur_prod=12, max_prod=24 ^ ^ i j[2,-2,3,-2,0,9] cur_prod=-6, max_prod=24 ^ ^ i j[2,-2,3,-2,0,9] cur_prod=-2, max_prod=24 ^^ ij[2,-2,3,-2,0,9] cur_prod=9, max_prod=24 ^ i j</code></pre></figure><p>The Python code handles some more corner cases, for example if there’s only one element, and looks like this:</p><figure class=\"highlight\"><pre><code class=\"language-python\" data-lang=\"python\"><span class=\"kn\">from</span> <span class=\"n\">typing</span> <span class=\"kn\">import</span> <span class=\"n\">List</span><span class=\"k\">class</span> <span class=\"nc\">Solution</span><span class=\"p\">:</span> <span class=\"k\">def</span> <span class=\"nf\">maxProduct</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">nums</span><span class=\"p\">:</span> <span class=\"n\">List</span><span class=\"p\">[</span><span class=\"nb\">int</span><span class=\"p\">])</span> <span class=\"o\">-></span> <span class=\"nb\">int</span><span class=\"p\">:</span> <span class=\"n\">i</span><span class=\"p\">,</span><span class=\"n\">j</span> <span class=\"o\">=</span> <span class=\"mi\">0</span><span class=\"p\">,</span><span class=\"mi\">0</span> <span class=\"n\">cur_prod</span> <span class=\"o\">=</span> <span class=\"n\">nums</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span> <span class=\"n\">max_prod</span> <span class=\"o\">=</span> <span class=\"n\">nums</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span> <span class=\"k\">while</span> <span class=\"n\">j</span> <span class=\"o\"><</span> <span class=\"nf\">len</span><span class=\"p\">(</span><span class=\"n\">nums</span><span class=\"p\">):</span> <span class=\"n\">cur_prod</span> <span class=\"o\">=</span> <span class=\"n\">nums</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">]</span> <span class=\"n\">max_prod</span> <span class=\"o\">=</span> <span class=\"nf\">max</span><span class=\"p\">(</span><span class=\"n\">max_prod</span><span class=\"p\">,</span> <span class=\"n\">cur_prod</span><span class=\"p\">)</span> <span class=\"k\">if</span> <span class=\"n\">cur_prod</span> <span class=\"o\">==</span> <span class=\"mi\">0</span><span class=\"p\">:</span> <span class=\"n\">i</span> <span class=\"o\">+=</span> <span class=\"mi\">1</span> <span class=\"n\">j</span> <span class=\"o\">+=</span> <span class=\"mi\">1</span> <span class=\"k\">while</span> <span class=\"n\">i</span> <span class=\"o\"><</span> <span class=\"n\">j</span><span class=\"p\">:</span> <span class=\"k\">if</span> <span class=\"n\">j</span> <span class=\"o\"><</span> <span class=\"nf\">len</span><span class=\"p\">(</span><span class=\"n\">nums</span><span class=\"p\">)</span> <span class=\"ow\">and</span> <span class=\"n\">nums</span><span class=\"p\">[</span><span class=\"n\">j</span><span class=\"p\">]</span> <span class=\"o\">!=</span> <span class=\"mi\">0</span><span class=\"p\">:</span> <span class=\"n\">cur_prod</span> <span class=\"o\">*=</span> <span class=\"n\">nums</span><span class=\"p\">[</span><span class=\"n\">j</span><span class=\"p\">]</span> <span class=\"n\">j</span><span class=\"o\">+=</span><span class=\"mi\">1</span> <span class=\"k\">else</span><span class=\"p\">:</span> <span class=\"k\">if</span> <span class=\"n\">i</span> <span class=\"o\">+</span> <span class=\"mi\">1</span> <span class=\"o\"><</span> <span class=\"n\">j</span><span class=\"p\">:</span> <span class=\"n\">cur_prod</span> <span class=\"o\">//=</span> <span class=\"n\">nums</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">]</span> <span class=\"n\">i</span> <span class=\"o\">+=</span> <span class=\"mi\">1</span> <span class=\"n\">max_prod</span> <span class=\"o\">=</span> <span class=\"nf\">max</span><span class=\"p\">(</span><span class=\"n\">max_prod</span><span class=\"p\">,</span> <span class=\"n\">cur_prod</span><span class=\"p\">)</span> <span class=\"c1\"># max_prod = max(max_prod, cur_prod)</span> <span class=\"k\">return</span> <span class=\"n\">max_prod</span> <span class=\"k\">if</span> <span class=\"n\">__name__</span> <span class=\"o\">==</span> <span class=\"sh\">'</span><span class=\"s\">__main__</span><span class=\"sh\">'</span><span class=\"p\">:</span> <span class=\"n\">s</span> <span class=\"o\">=</span> <span class=\"nc\">Solution</span><span class=\"p\">().</span><span class=\"n\">maxProduct</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">([</span><span class=\"mi\">2</span><span class=\"p\">,</span><span class=\"mi\">3</span><span class=\"p\">,</span><span class=\"o\">-</span><span class=\"mi\">2</span><span class=\"p\">,</span><span class=\"mi\">4</span><span class=\"p\">]),</span> <span class=\"mi\">6</span><span class=\"p\">)</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">([</span><span class=\"o\">-</span><span class=\"mi\">2</span><span class=\"p\">,</span> <span class=\"mi\">4</span><span class=\"p\">,</span> <span class=\"o\">-</span><span class=\"mi\">2</span><span class=\"p\">]),</span> <span class=\"mi\">16</span><span class=\"p\">)</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">([</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">,</span><span class=\"o\">-</span><span class=\"mi\">2</span><span class=\"p\">,</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">,</span><span class=\"mi\">2</span><span class=\"p\">,</span><span class=\"o\">-</span><span class=\"mi\">2</span><span class=\"p\">,</span> <span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">]),</span> <span class=\"mi\">8</span><span class=\"p\">)</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">([</span><span class=\"mi\">1</span><span class=\"p\">,</span><span class=\"mi\">2</span><span class=\"p\">,</span><span class=\"mi\">0</span><span class=\"p\">,</span><span class=\"mi\">9</span><span class=\"p\">]),</span> <span class=\"mi\">9</span><span class=\"p\">)</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">([</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">]),</span> <span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">)</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">([</span><span class=\"mi\">10</span><span class=\"p\">]),</span> <span class=\"mi\">10</span><span class=\"p\">)</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">([</span><span class=\"o\">-</span><span class=\"mi\">2</span><span class=\"p\">,</span><span class=\"mi\">0</span><span class=\"p\">,</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">]),</span><span class=\"mi\">0</span><span class=\"p\">)</span></code></pre></figure>", "date_published": "2022-10-18T20:00:00+00:00" }, { "id": "https://fewald.net/leetcode/2022/10/17/leetcode-sort-list.html", "url": "https://fewald.net/leetcode/2022/10/17/leetcode-sort-list.html", "title": "Leetcode: Sort list", "content_html": "<p>Given a single linked list, sort the values in ascending order.</p><figure class=\"highlight\"><pre><code class=\"language-md\" data-lang=\"md\"><span class=\"gh\"># Example</span>Input: (4)->(3)->(1)->(2)Output: (1)->(2)->(3)-(4)</code></pre></figure><!--more--><p>The solution for the single linked list looks as follows. It has a time complexity of <code class=\"language-plaintext highlighter-rouge\">O(n*log(n))</code>. The technique here is first split the list in two lists of (almost) equal length. Then split the resulting lists again along the middle until the list contains only <code class=\"language-plaintext highlighter-rouge\">1</code> or <code class=\"language-plaintext highlighter-rouge\">0</code> elements.</p><p>This leaves only at most <code class=\"language-plaintext highlighter-rouge\">2</code> elements to compare. If the <code class=\"language-plaintext highlighter-rouge\">left</code> one is less than the <code class=\"language-plaintext highlighter-rouge\">right</code> one, attach the <code class=\"language-plaintext highlighter-rouge\">left</code> one to <code class=\"language-plaintext highlighter-rouge\">right.next</code> and vice versa. This small list is now sorted. When going up the stack, the <code class=\"language-plaintext highlighter-rouge\">left</code> and <code class=\"language-plaintext highlighter-rouge\">right</code> lists are therefore sorted as well and can be merged in a similar fashion. This ultimately results in a completely sorted list.</p><figure class=\"highlight\"><pre><code class=\"language-python\" data-lang=\"python\"><span class=\"kn\">from</span> <span class=\"n\">typing</span> <span class=\"kn\">import</span> <span class=\"n\">Optional</span><span class=\"c1\"># Definition for singly-linked list.</span><span class=\"k\">class</span> <span class=\"nc\">ListNode</span><span class=\"p\">:</span> <span class=\"k\">def</span> <span class=\"nf\">__init__</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">val</span><span class=\"o\">=</span><span class=\"mi\">0</span><span class=\"p\">,</span> <span class=\"nb\">next</span><span class=\"o\">=</span><span class=\"bp\">None</span><span class=\"p\">):</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">val</span> <span class=\"o\">=</span> <span class=\"n\">val</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"nb\">next</span> <span class=\"o\">=</span> <span class=\"nb\">next</span> <span class=\"k\">def</span> <span class=\"nf\">__str__</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">)</span> <span class=\"o\">-></span> <span class=\"nb\">str</span><span class=\"p\">:</span> <span class=\"n\">s</span> <span class=\"o\">=</span> <span class=\"sa\">f</span><span class=\"sh\">\"</span><span class=\"si\">{</span><span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">val</span><span class=\"si\">}</span><span class=\"sh\">\"</span> <span class=\"k\">if</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"nb\">next</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"bp\">None</span><span class=\"p\">:</span> <span class=\"n\">s</span> <span class=\"o\">+=</span> <span class=\"sa\">f</span><span class=\"sh\">\"</span><span class=\"s\">, </span><span class=\"si\">{</span><span class=\"n\">self</span><span class=\"p\">.</span><span class=\"nb\">next</span><span class=\"si\">}</span><span class=\"sh\">\"</span> <span class=\"k\">return</span> <span class=\"n\">s</span><span class=\"k\">class</span> <span class=\"nc\">Solution</span><span class=\"p\">:</span> <span class=\"k\">def</span> <span class=\"nf\">sortList</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">head</span><span class=\"p\">:</span> <span class=\"n\">Optional</span><span class=\"p\">[</span><span class=\"n\">ListNode</span><span class=\"p\">])</span> <span class=\"o\">-></span> <span class=\"n\">Optional</span><span class=\"p\">[</span><span class=\"n\">ListNode</span><span class=\"p\">]:</span> <span class=\"k\">return</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"nf\">mergeSort</span><span class=\"p\">(</span><span class=\"n\">head</span><span class=\"p\">)</span> <span class=\"k\">def</span> <span class=\"nf\">mergeSort</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">h</span><span class=\"p\">):</span> <span class=\"k\">if</span> <span class=\"n\">h</span> <span class=\"ow\">is</span> <span class=\"bp\">None</span> <span class=\"ow\">or</span> <span class=\"n\">h</span><span class=\"p\">.</span><span class=\"nb\">next</span> <span class=\"ow\">is</span> <span class=\"bp\">None</span><span class=\"p\">:</span> <span class=\"k\">return</span> <span class=\"n\">h</span> <span class=\"n\">middle</span> <span class=\"o\">=</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"nf\">findMiddle</span><span class=\"p\">(</span><span class=\"n\">h</span><span class=\"p\">)</span> <span class=\"n\">middle_next</span> <span class=\"o\">=</span> <span class=\"n\">middle</span><span class=\"p\">.</span><span class=\"nb\">next</span> <span class=\"n\">middle</span><span class=\"p\">.</span><span class=\"nb\">next</span> <span class=\"o\">=</span> <span class=\"bp\">None</span> <span class=\"n\">left</span> <span class=\"o\">=</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"nf\">mergeSort</span><span class=\"p\">(</span><span class=\"n\">h</span><span class=\"p\">)</span> <span class=\"n\">right</span> <span class=\"o\">=</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"nf\">mergeSort</span><span class=\"p\">(</span><span class=\"n\">middle_next</span><span class=\"p\">)</span> <span class=\"n\">sorted_list</span> <span class=\"o\">=</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"nf\">sort</span><span class=\"p\">(</span><span class=\"n\">left</span><span class=\"p\">,</span> <span class=\"n\">right</span><span class=\"p\">)</span> <span class=\"k\">return</span> <span class=\"n\">sorted_list</span> <span class=\"k\">def</span> <span class=\"nf\">sort</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">l</span><span class=\"p\">,</span> <span class=\"n\">r</span><span class=\"p\">):</span> <span class=\"n\">result</span> <span class=\"o\">=</span> <span class=\"bp\">None</span> <span class=\"k\">if</span> <span class=\"n\">l</span> <span class=\"ow\">is</span> <span class=\"bp\">None</span><span class=\"p\">:</span> <span class=\"k\">return</span> <span class=\"n\">r</span> <span class=\"k\">if</span> <span class=\"n\">r</span> <span class=\"ow\">is</span> <span class=\"bp\">None</span><span class=\"p\">:</span> <span class=\"k\">return</span> <span class=\"n\">l</span> <span class=\"k\">if</span> <span class=\"n\">l</span><span class=\"p\">.</span><span class=\"n\">val</span> <span class=\"o\"><=</span> <span class=\"n\">r</span><span class=\"p\">.</span><span class=\"n\">val</span><span class=\"p\">:</span> <span class=\"n\">result</span> <span class=\"o\">=</span> <span class=\"n\">l</span> <span class=\"n\">result</span><span class=\"p\">.</span><span class=\"nb\">next</span> <span class=\"o\">=</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"nf\">sort</span><span class=\"p\">(</span><span class=\"n\">l</span><span class=\"p\">.</span><span class=\"nb\">next</span><span class=\"p\">,</span> <span class=\"n\">r</span><span class=\"p\">)</span> <span class=\"k\">else</span><span class=\"p\">:</span> <span class=\"n\">result</span> <span class=\"o\">=</span> <span class=\"n\">r</span> <span class=\"n\">result</span><span class=\"p\">.</span><span class=\"nb\">next</span> <span class=\"o\">=</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"nf\">sort</span><span class=\"p\">(</span><span class=\"n\">l</span><span class=\"p\">,</span> <span class=\"n\">r</span><span class=\"p\">.</span><span class=\"nb\">next</span><span class=\"p\">)</span> <span class=\"k\">return</span> <span class=\"n\">result</span> <span class=\"k\">def</span> <span class=\"nf\">findMiddle</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">head</span><span class=\"p\">):</span> <span class=\"k\">if</span> <span class=\"n\">head</span> <span class=\"ow\">is</span> <span class=\"bp\">None</span><span class=\"p\">:</span> <span class=\"k\">return</span> <span class=\"n\">head</span> <span class=\"n\">slow</span> <span class=\"o\">=</span> <span class=\"n\">head</span> <span class=\"n\">fast</span> <span class=\"o\">=</span> <span class=\"n\">head</span> <span class=\"k\">while</span> <span class=\"n\">fast</span><span class=\"p\">.</span><span class=\"nb\">next</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"bp\">None</span> <span class=\"ow\">and</span> <span class=\"n\">fast</span><span class=\"p\">.</span><span class=\"nb\">next</span><span class=\"p\">.</span><span class=\"nb\">next</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"bp\">None</span><span class=\"p\">:</span> <span class=\"n\">slow</span> <span class=\"o\">=</span> <span class=\"n\">slow</span><span class=\"p\">.</span><span class=\"nb\">next</span> <span class=\"n\">fast</span> <span class=\"o\">=</span> <span class=\"n\">fast</span><span class=\"p\">.</span><span class=\"nb\">next</span><span class=\"p\">.</span><span class=\"nb\">next</span> <span class=\"k\">return</span> <span class=\"n\">slow</span><span class=\"k\">if</span> <span class=\"n\">__name__</span> <span class=\"o\">==</span> <span class=\"sh\">'</span><span class=\"s\">__main__</span><span class=\"sh\">'</span><span class=\"p\">:</span> <span class=\"n\">s</span> <span class=\"o\">=</span> <span class=\"nc\">Solution</span><span class=\"p\">().</span><span class=\"n\">sortList</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">(</span><span class=\"nc\">ListNode</span><span class=\"p\">(</span><span class=\"mi\">4</span><span class=\"p\">,</span> <span class=\"nc\">ListNode</span><span class=\"p\">(</span><span class=\"mi\">2</span><span class=\"p\">,</span> <span class=\"nc\">ListNode</span><span class=\"p\">(</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"nc\">ListNode</span><span class=\"p\">(</span><span class=\"mi\">3</span><span class=\"p\">))))),</span> <span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">,</span><span class=\"mi\">2</span><span class=\"p\">,</span><span class=\"mi\">3</span><span class=\"p\">,</span><span class=\"mi\">4</span><span class=\"p\">])</span></code></pre></figure><blockquote> <p>Runtime: 1282 ms, faster than 22.47% of Python3 online submissions for Sort List. Memory Usage: 86.7 MB, less than 5.62% of Python3 online submissions for Sort List.</p></blockquote><p>Another option is a merge sort for a standard list in Python:</p><figure class=\"highlight\"><pre><code class=\"language-python\" data-lang=\"python\"><span class=\"k\">class</span> <span class=\"nc\">Solution</span><span class=\"p\">:</span> <span class=\"k\">def</span> <span class=\"nf\">sortList</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">l</span><span class=\"p\">):</span> <span class=\"k\">return</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"nf\">mergeSort</span><span class=\"p\">(</span><span class=\"n\">l</span><span class=\"p\">)</span> <span class=\"k\">def</span> <span class=\"nf\">mergeSort</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">l</span><span class=\"p\">):</span> <span class=\"c1\"># If the length of the list is one element or less,</span> <span class=\"c1\"># return it as it means we reached the innermost</span> <span class=\"c1\"># recursion.</span> <span class=\"k\">if</span> <span class=\"nf\">len</span><span class=\"p\">(</span><span class=\"n\">l</span><span class=\"p\">)</span> <span class=\"o\"><=</span> <span class=\"mi\">1</span><span class=\"p\">:</span> <span class=\"k\">return</span> <span class=\"n\">l</span> <span class=\"c1\"># Find middle element with floor integer division</span> <span class=\"n\">middle</span> <span class=\"o\">=</span> <span class=\"nf\">len</span><span class=\"p\">(</span><span class=\"n\">l</span><span class=\"p\">)</span> <span class=\"o\">//</span> <span class=\"mi\">2</span> <span class=\"c1\"># Recursively create left and right until left and right are only</span> <span class=\"c1\"># one element long, then merge</span> <span class=\"n\">left</span> <span class=\"o\">=</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"nf\">mergeSort</span><span class=\"p\">(</span><span class=\"n\">l</span><span class=\"p\">[:</span><span class=\"n\">middle</span><span class=\"p\">])</span> <span class=\"n\">right</span> <span class=\"o\">=</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"nf\">mergeSort</span><span class=\"p\">(</span><span class=\"n\">l</span><span class=\"p\">[</span><span class=\"n\">middle</span><span class=\"p\">:])</span> <span class=\"n\">pl</span> <span class=\"o\">=</span> <span class=\"mi\">0</span> <span class=\"n\">pr</span> <span class=\"o\">=</span> <span class=\"mi\">0</span> <span class=\"n\">sorted_list</span> <span class=\"o\">=</span> <span class=\"p\">[]</span> <span class=\"k\">while</span> <span class=\"n\">pl</span> <span class=\"o\"><</span> <span class=\"nf\">len</span><span class=\"p\">(</span><span class=\"n\">left</span><span class=\"p\">)</span> <span class=\"ow\">and</span> <span class=\"n\">pr</span> <span class=\"o\"><</span> <span class=\"nf\">len</span><span class=\"p\">(</span><span class=\"n\">right</span><span class=\"p\">):</span> <span class=\"k\">if</span> <span class=\"n\">left</span><span class=\"p\">[</span><span class=\"n\">pl</span><span class=\"p\">]</span> <span class=\"o\"><=</span> <span class=\"n\">right</span><span class=\"p\">[</span><span class=\"n\">pr</span><span class=\"p\">]:</span> <span class=\"n\">sorted_list</span><span class=\"p\">.</span><span class=\"nf\">append</span><span class=\"p\">(</span><span class=\"n\">left</span><span class=\"p\">[</span><span class=\"n\">pl</span><span class=\"p\">])</span> <span class=\"n\">pl</span> <span class=\"o\">+=</span> <span class=\"mi\">1</span> <span class=\"k\">else</span><span class=\"p\">:</span> <span class=\"n\">sorted_list</span><span class=\"p\">.</span><span class=\"nf\">append</span><span class=\"p\">(</span><span class=\"n\">right</span><span class=\"p\">[</span><span class=\"n\">pr</span><span class=\"p\">])</span> <span class=\"n\">pr</span> <span class=\"o\">+=</span> <span class=\"mi\">1</span> <span class=\"c1\"># Add the remainders of the list</span> <span class=\"n\">sorted_list</span> <span class=\"o\">+=</span> <span class=\"n\">left</span><span class=\"p\">[</span><span class=\"n\">pl</span><span class=\"p\">:]</span> <span class=\"n\">sorted_list</span> <span class=\"o\">+=</span> <span class=\"n\">right</span><span class=\"p\">[</span><span class=\"n\">pr</span><span class=\"p\">:]</span> <span class=\"k\">return</span> <span class=\"n\">sorted_list</span> <span class=\"k\">if</span> <span class=\"n\">__name__</span> <span class=\"o\">==</span> <span class=\"sh\">'</span><span class=\"s\">__main__</span><span class=\"sh\">'</span><span class=\"p\">:</span> <span class=\"n\">s</span> <span class=\"o\">=</span> <span class=\"nc\">Solution</span><span class=\"p\">().</span><span class=\"n\">sortList</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">([</span><span class=\"mi\">4</span><span class=\"p\">,</span><span class=\"mi\">3</span><span class=\"p\">,</span><span class=\"mi\">1</span><span class=\"p\">,</span><span class=\"mi\">2</span><span class=\"p\">]),</span> <span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">,</span><span class=\"mi\">2</span><span class=\"p\">,</span><span class=\"mi\">3</span><span class=\"p\">,</span><span class=\"mi\">4</span><span class=\"p\">])</span></code></pre></figure>", "date_published": "2022-10-17T20:00:00+00:00" }, { "id": "https://fewald.net/leetcode/2022/10/16/leetcode-gas-station.html", "url": "https://fewald.net/leetcode/2022/10/16/leetcode-gas-station.html", "title": "Leetcode: Gas station", "content_html": "<p>Given two arrays, <code class=\"language-plaintext highlighter-rouge\">gas</code> and <code class=\"language-plaintext highlighter-rouge\">cost</code> and an infinite tank, it costs <code class=\"language-plaintext highlighter-rouge\">costs[i]</code> to go from one index to the other. The most a car can get gas is <code class=\"language-plaintext highlighter-rouge\">gas[i]</code>. The task is to determine whether a car can go a full round for any possible starting point. The program should return the starting index if it is possible and <code class=\"language-plaintext highlighter-rouge\">-1</code> if it is not possible to do so.</p><p>Example:</p><figure class=\"highlight\"><pre><code class=\"language-python\" data-lang=\"python\"><span class=\"n\">gas</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">,</span><span class=\"mi\">1</span><span class=\"p\">,</span><span class=\"mi\">2</span><span class=\"p\">]</span><span class=\"n\">cost</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"mi\">2</span><span class=\"p\">,</span><span class=\"mi\">1</span><span class=\"p\">,</span><span class=\"mi\">1</span><span class=\"p\">]</span><span class=\"c1\"># result: 2</span></code></pre></figure><p>The result is <code class=\"language-plaintext highlighter-rouge\">2</code>, because we can start from index <code class=\"language-plaintext highlighter-rouge\">2</code>, get <code class=\"language-plaintext highlighter-rouge\">2</code> units of gas, and it costs us <code class=\"language-plaintext highlighter-rouge\">1</code> unit to go to <code class=\"language-plaintext highlighter-rouge\">1</code>, leaving us with <code class=\"language-plaintext highlighter-rouge\">1</code> unit. Then we can get another unit which is exactly the required <code class=\"language-plaintext highlighter-rouge\">2</code> units it takes us to get to <code class=\"language-plaintext highlighter-rouge\">1</code> and from there we get <code class=\"language-plaintext highlighter-rouge\">1</code> leaving us with <code class=\"language-plaintext highlighter-rouge\">0</code> at <code class=\"language-plaintext highlighter-rouge\">2</code> and completing the cycle.</p><!--more--><p>The initial solution that I came up with is listed below. For each possible starting point, calculate if we can reach the point again. This is not very efficient as it attempts to solve this problem for every possible starting point. This solution exceeds the runtime limit and is not successful.</p><figure class=\"highlight\"><pre><code class=\"language-python\" data-lang=\"python\"><span class=\"kn\">from</span> <span class=\"n\">typing</span> <span class=\"kn\">import</span> <span class=\"n\">List</span><span class=\"p\">,</span> <span class=\"n\">Optional</span><span class=\"k\">class</span> <span class=\"nc\">Solution</span><span class=\"p\">:</span> <span class=\"k\">def</span> <span class=\"nf\">canCompleteCircuit</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">gas</span><span class=\"p\">:</span> <span class=\"n\">List</span><span class=\"p\">[</span><span class=\"nb\">int</span><span class=\"p\">],</span> <span class=\"n\">cost</span><span class=\"p\">:</span> <span class=\"n\">List</span><span class=\"p\">[</span><span class=\"nb\">int</span><span class=\"p\">])</span> <span class=\"o\">-></span> <span class=\"nb\">int</span><span class=\"p\">:</span> <span class=\"k\">def</span> <span class=\"nf\">inner</span><span class=\"p\">(</span><span class=\"n\">g</span><span class=\"p\">,</span> <span class=\"n\">c</span><span class=\"p\">,</span> <span class=\"n\">start</span><span class=\"p\">,</span> <span class=\"n\">balance</span><span class=\"p\">):</span> <span class=\"k\">if</span> <span class=\"n\">balance</span> <span class=\"o\"><</span> <span class=\"mi\">0</span><span class=\"p\">:</span> <span class=\"k\">return</span> <span class=\"o\">-</span><span class=\"mi\">1</span> <span class=\"k\">if</span> <span class=\"nf\">len</span><span class=\"p\">(</span><span class=\"n\">g</span><span class=\"p\">)</span> <span class=\"o\">==</span> <span class=\"mi\">0</span><span class=\"p\">:</span> <span class=\"k\">return</span> <span class=\"n\">start</span> <span class=\"k\">return</span> <span class=\"nf\">inner</span><span class=\"p\">(</span><span class=\"n\">g</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">:],</span> <span class=\"n\">c</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">:],</span> <span class=\"n\">start</span><span class=\"p\">,</span> <span class=\"n\">balance</span> <span class=\"o\">+</span> <span class=\"p\">(</span><span class=\"n\">g</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span><span class=\"o\">-</span><span class=\"n\">c</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]))</span> <span class=\"k\">for</span> <span class=\"n\">i</span> <span class=\"ow\">in</span> <span class=\"nf\">range</span><span class=\"p\">(</span><span class=\"nf\">len</span><span class=\"p\">(</span><span class=\"n\">gas</span><span class=\"p\">)):</span> <span class=\"n\">g</span> <span class=\"o\">=</span> <span class=\"n\">gas</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"o\">+</span><span class=\"mi\">1</span><span class=\"p\">:]</span> <span class=\"o\">+</span> <span class=\"n\">gas</span><span class=\"p\">[:</span><span class=\"n\">i</span><span class=\"p\">]</span> <span class=\"o\">+</span> <span class=\"p\">[</span><span class=\"n\">gas</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">]]</span> <span class=\"n\">c</span> <span class=\"o\">=</span> <span class=\"n\">cost</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"o\">+</span><span class=\"mi\">1</span><span class=\"p\">:]</span> <span class=\"o\">+</span> <span class=\"n\">cost</span><span class=\"p\">[:</span><span class=\"n\">i</span><span class=\"p\">]</span> <span class=\"o\">+</span> <span class=\"p\">[</span><span class=\"n\">cost</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">]]</span> <span class=\"k\">if</span> <span class=\"nf\">inner</span><span class=\"p\">(</span><span class=\"n\">g</span><span class=\"p\">,</span> <span class=\"n\">c</span><span class=\"p\">,</span> <span class=\"n\">i</span><span class=\"p\">,</span> <span class=\"n\">gas</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">]</span> <span class=\"o\">-</span> <span class=\"n\">cost</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">])</span> <span class=\"o\">></span> <span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">:</span> <span class=\"k\">return</span> <span class=\"n\">i</span> <span class=\"k\">return</span> <span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"k\">if</span> <span class=\"n\">__name__</span> <span class=\"o\">==</span> <span class=\"sh\">'</span><span class=\"s\">__main__</span><span class=\"sh\">'</span><span class=\"p\">:</span> <span class=\"n\">s</span> <span class=\"o\">=</span> <span class=\"nc\">Solution</span><span class=\"p\">().</span><span class=\"n\">canCompleteCircuit</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">([</span><span class=\"mi\">1</span><span class=\"p\">,</span><span class=\"mi\">2</span><span class=\"p\">,</span><span class=\"mi\">3</span><span class=\"p\">,</span><span class=\"mi\">4</span><span class=\"p\">,</span><span class=\"mi\">5</span><span class=\"p\">],</span> <span class=\"p\">[</span><span class=\"mi\">3</span><span class=\"p\">,</span><span class=\"mi\">4</span><span class=\"p\">,</span><span class=\"mi\">5</span><span class=\"p\">,</span><span class=\"mi\">1</span><span class=\"p\">,</span><span class=\"mi\">2</span><span class=\"p\">]),</span> <span class=\"mi\">3</span><span class=\"p\">)</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">([</span><span class=\"mi\">2</span><span class=\"p\">,</span><span class=\"mi\">3</span><span class=\"p\">,</span><span class=\"mi\">4</span><span class=\"p\">],</span> <span class=\"p\">[</span><span class=\"mi\">3</span><span class=\"p\">,</span><span class=\"mi\">4</span><span class=\"p\">,</span><span class=\"mi\">3</span><span class=\"p\">]),</span> <span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">)</span></code></pre></figure><p>A more elegant way of solving this is to try to start at the beginning and calculate the balance and the total balance in one iteration. If the balance goes below <code class=\"language-plaintext highlighter-rouge\">0</code> at any point in time the start index is not the correct one. Neither is any one of the indexes up to the current position and we can set the index to the next position. We set the running balance to <code class=\"language-plaintext highlighter-rouge\">0</code>. When we reach the end of the loop, we have to check if the total balance is above <code class=\"language-plaintext highlighter-rouge\">0</code> to make sure that we are able to complete the loop. Otherwise we return <code class=\"language-plaintext highlighter-rouge\">-1</code>.</p><figure class=\"highlight\"><pre><code class=\"language-python\" data-lang=\"python\"><span class=\"kn\">from</span> <span class=\"n\">typing</span> <span class=\"kn\">import</span> <span class=\"n\">List</span><span class=\"k\">class</span> <span class=\"nc\">Solution</span><span class=\"p\">:</span> <span class=\"k\">def</span> <span class=\"nf\">canCompleteCircuit</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">gas</span><span class=\"p\">:</span> <span class=\"n\">List</span><span class=\"p\">[</span><span class=\"nb\">int</span><span class=\"p\">],</span> <span class=\"n\">cost</span><span class=\"p\">:</span> <span class=\"n\">List</span><span class=\"p\">[</span><span class=\"nb\">int</span><span class=\"p\">])</span> <span class=\"o\">-></span> <span class=\"nb\">int</span><span class=\"p\">:</span> <span class=\"n\">gas_balance</span> <span class=\"o\">=</span> <span class=\"mi\">0</span> <span class=\"n\">total_gas</span> <span class=\"o\">=</span> <span class=\"mi\">0</span> <span class=\"n\">start_idx</span> <span class=\"o\">=</span> <span class=\"mi\">0</span> <span class=\"k\">for</span> <span class=\"n\">i</span> <span class=\"ow\">in</span> <span class=\"nf\">range</span><span class=\"p\">(</span><span class=\"nf\">len</span><span class=\"p\">(</span><span class=\"n\">gas</span><span class=\"p\">)):</span> <span class=\"n\">gas_balance</span> <span class=\"o\">=</span> <span class=\"n\">gas_balance</span> <span class=\"o\">+</span> <span class=\"p\">(</span><span class=\"n\">gas</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">]</span> <span class=\"o\">-</span> <span class=\"n\">cost</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">])</span> <span class=\"n\">total_gas</span> <span class=\"o\">=</span> <span class=\"n\">total_gas</span> <span class=\"o\">+</span> <span class=\"p\">(</span><span class=\"n\">gas</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">]</span> <span class=\"o\">-</span> <span class=\"n\">cost</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">])</span> <span class=\"k\">if</span> <span class=\"n\">gas_balance</span> <span class=\"o\"><</span> <span class=\"mi\">0</span><span class=\"p\">:</span> <span class=\"n\">gas_balance</span> <span class=\"o\">=</span> <span class=\"mi\">0</span> <span class=\"n\">start_idx</span> <span class=\"o\">=</span> <span class=\"n\">i</span> <span class=\"o\">+</span> <span class=\"mi\">1</span> <span class=\"k\">if</span> <span class=\"n\">total_gas</span> <span class=\"o\"><</span> <span class=\"mi\">0</span><span class=\"p\">:</span> <span class=\"k\">return</span> <span class=\"o\">-</span><span class=\"mi\">1</span> <span class=\"k\">return</span> <span class=\"n\">start_idx</span><span class=\"k\">if</span> <span class=\"n\">__name__</span> <span class=\"o\">==</span> <span class=\"sh\">'</span><span class=\"s\">__main__</span><span class=\"sh\">'</span><span class=\"p\">:</span> <span class=\"n\">s</span> <span class=\"o\">=</span> <span class=\"nc\">Solution</span><span class=\"p\">().</span><span class=\"n\">canCompleteCircuit</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">([</span><span class=\"mi\">1</span><span class=\"p\">,</span><span class=\"mi\">2</span><span class=\"p\">,</span><span class=\"mi\">3</span><span class=\"p\">,</span><span class=\"mi\">4</span><span class=\"p\">,</span><span class=\"mi\">5</span><span class=\"p\">],</span> <span class=\"p\">[</span><span class=\"mi\">3</span><span class=\"p\">,</span><span class=\"mi\">4</span><span class=\"p\">,</span><span class=\"mi\">5</span><span class=\"p\">,</span><span class=\"mi\">1</span><span class=\"p\">,</span><span class=\"mi\">2</span><span class=\"p\">]),</span> <span class=\"mi\">3</span><span class=\"p\">)</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">([</span><span class=\"mi\">2</span><span class=\"p\">,</span><span class=\"mi\">3</span><span class=\"p\">,</span><span class=\"mi\">4</span><span class=\"p\">],</span> <span class=\"p\">[</span><span class=\"mi\">3</span><span class=\"p\">,</span><span class=\"mi\">4</span><span class=\"p\">,</span><span class=\"mi\">3</span><span class=\"p\">]),</span> <span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">)</span></code></pre></figure><blockquote> <p>Runtime: 706 ms, faster than 91.03% of Python3 online submissions for Gas Station. Memory Usage: 19.1 MB, less than 75.91% of Python3 online submissions for Gas Station.</p></blockquote>", "date_published": "2022-10-16T20:00:00+00:00" }, { "id": "https://fewald.net/leetcode/2022/10/15/leetcode-lru-cache.html", "url": "https://fewald.net/leetcode/2022/10/15/leetcode-lru-cache.html", "title": "Leetcode: LRU cache", "content_html": "<p>Given the following code skeleton, implement an <strong>LRU cache</strong> with a variable capacity. The time complexity for <code class=\"language-plaintext highlighter-rouge\">get</code> and <code class=\"language-plaintext highlighter-rouge\">put</code> should be <code class=\"language-plaintext highlighter-rouge\">O(1)</code> respectively.</p><figure class=\"highlight\"><pre><code class=\"language-python\" data-lang=\"python\"><span class=\"k\">class</span> <span class=\"nc\">LRUCache</span><span class=\"p\">:</span> <span class=\"k\">def</span> <span class=\"nf\">__init__</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">capacity</span><span class=\"p\">:</span> <span class=\"nb\">int</span><span class=\"p\">):</span> <span class=\"k\">pass</span> <span class=\"k\">def</span> <span class=\"nf\">get</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">key</span><span class=\"p\">:</span> <span class=\"nb\">int</span><span class=\"p\">)</span> <span class=\"o\">-></span> <span class=\"nb\">int</span><span class=\"p\">:</span> <span class=\"k\">pass</span> <span class=\"k\">def</span> <span class=\"nf\">put</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">key</span><span class=\"p\">:</span> <span class=\"nb\">int</span><span class=\"p\">,</span> <span class=\"n\">value</span><span class=\"p\">:</span> <span class=\"nb\">int</span><span class=\"p\">)</span> <span class=\"o\">-></span> <span class=\"bp\">None</span><span class=\"p\">:</span> <span class=\"k\">pass</span></code></pre></figure><p>In general, a cache is just a map which assigns keys to values. What makes a cache special is that values get evicted. This can be either after a certain time or when values are not used. In the case of an LRU cache, the least recently used element should be deleted once a cache reaches its predefined capacity.</p><!--more--><p>To solve this problem, we need to think about two scenarios: Inserting and retrieving the values. For the insert operation, we just need to write the <code class=\"language-plaintext highlighter-rouge\">value</code> in the map at the <code class=\"language-plaintext highlighter-rouge\">key</code> position. This operation is <code class=\"language-plaintext highlighter-rouge\">O(n)</code>. If the value already exists, we need to update it.</p><p>This map unfortunately has no information at what time an item was added to the queue. For this reason we need another data structure that allows us to load, move, insert and delete an item with <code class=\"language-plaintext highlighter-rouge\">O(1)</code>. A doubly linked list allows us to do exactly this: We can store a reference to the item in the map. Then we can move it out of the list with a few operations, add it to the end and we also have constant access to the beginning of the list. Unfortunately, Python does not have a doubly linked list builtin and we need to create it ourselves.</p><p>I chose to create a dummy <code class=\"language-plaintext highlighter-rouge\">head</code> and <code class=\"language-plaintext highlighter-rouge\">tail</code> element to be able to skip several <code class=\"language-plaintext highlighter-rouge\">if/else</code> checks. The solution then looks as follows:</p><figure class=\"highlight\"><pre><code class=\"language-python\" data-lang=\"python\"><span class=\"k\">class</span> <span class=\"nc\">Node</span><span class=\"p\">:</span> <span class=\"k\">def</span> <span class=\"nf\">__init__</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">k</span><span class=\"p\">,</span> <span class=\"n\">v</span><span class=\"p\">,</span> <span class=\"n\">p</span><span class=\"o\">=</span><span class=\"bp\">None</span><span class=\"p\">,</span> <span class=\"n\">n</span><span class=\"o\">=</span><span class=\"bp\">None</span><span class=\"p\">)</span> <span class=\"o\">-></span> <span class=\"bp\">None</span><span class=\"p\">:</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">k</span> <span class=\"o\">=</span> <span class=\"n\">k</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">v</span> <span class=\"o\">=</span> <span class=\"n\">v</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">p</span> <span class=\"o\">=</span> <span class=\"n\">p</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">n</span> <span class=\"o\">=</span> <span class=\"n\">n</span><span class=\"k\">class</span> <span class=\"nc\">DoubleLinkedList</span><span class=\"p\">:</span> <span class=\"k\">def</span> <span class=\"nf\">__init__</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">):</span> <span class=\"c1\"># Head and tail are dummy elements</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">_head</span> <span class=\"o\">=</span> <span class=\"nc\">Node</span><span class=\"p\">(</span><span class=\"bp\">None</span><span class=\"p\">,</span> <span class=\"bp\">None</span><span class=\"p\">,</span> <span class=\"bp\">None</span><span class=\"p\">,</span> <span class=\"bp\">None</span><span class=\"p\">)</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">_tail</span> <span class=\"o\">=</span> <span class=\"nc\">Node</span><span class=\"p\">(</span><span class=\"bp\">None</span><span class=\"p\">,</span> <span class=\"bp\">None</span><span class=\"p\">,</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">_head</span><span class=\"p\">,</span> <span class=\"bp\">None</span><span class=\"p\">)</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">_head</span><span class=\"p\">.</span><span class=\"n\">n</span> <span class=\"o\">=</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">_tail</span> <span class=\"k\">def</span> <span class=\"nf\">add</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">node</span><span class=\"p\">):</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">_tail</span><span class=\"p\">.</span><span class=\"n\">p</span><span class=\"p\">.</span><span class=\"n\">n</span> <span class=\"o\">=</span> <span class=\"n\">node</span> <span class=\"n\">node</span><span class=\"p\">.</span><span class=\"n\">p</span> <span class=\"o\">=</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">_tail</span><span class=\"p\">.</span><span class=\"n\">p</span> <span class=\"n\">node</span><span class=\"p\">.</span><span class=\"n\">n</span> <span class=\"o\">=</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">_tail</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">_tail</span><span class=\"p\">.</span><span class=\"n\">p</span> <span class=\"o\">=</span> <span class=\"n\">node</span> <span class=\"k\">def</span> <span class=\"nf\">remove</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">node</span><span class=\"p\">):</span> <span class=\"n\">node</span><span class=\"p\">.</span><span class=\"n\">p</span><span class=\"p\">.</span><span class=\"n\">n</span> <span class=\"o\">=</span> <span class=\"n\">node</span><span class=\"p\">.</span><span class=\"n\">n</span> <span class=\"n\">node</span><span class=\"p\">.</span><span class=\"n\">n</span><span class=\"p\">.</span><span class=\"n\">p</span> <span class=\"o\">=</span> <span class=\"n\">node</span><span class=\"p\">.</span><span class=\"n\">p</span> <span class=\"k\">def</span> <span class=\"nf\">pop</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">):</span> <span class=\"k\">if</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">_head</span><span class=\"p\">.</span><span class=\"n\">n</span> <span class=\"o\">==</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">_tail</span><span class=\"p\">:</span> <span class=\"k\">return</span> <span class=\"bp\">None</span> <span class=\"n\">n</span> <span class=\"o\">=</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">_head</span><span class=\"p\">.</span><span class=\"n\">n</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">_head</span><span class=\"p\">.</span><span class=\"n\">n</span> <span class=\"o\">=</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">_head</span><span class=\"p\">.</span><span class=\"n\">n</span><span class=\"p\">.</span><span class=\"n\">n</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">_head</span><span class=\"p\">.</span><span class=\"n\">n</span><span class=\"p\">.</span><span class=\"n\">p</span> <span class=\"o\">=</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">_head</span> <span class=\"k\">return</span> <span class=\"n\">n</span> <span class=\"k\">def</span> <span class=\"nf\">move_to_end</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">node</span><span class=\"p\">):</span> <span class=\"n\">node</span><span class=\"p\">.</span><span class=\"n\">p</span><span class=\"p\">.</span><span class=\"n\">n</span> <span class=\"o\">=</span> <span class=\"n\">node</span><span class=\"p\">.</span><span class=\"n\">n</span> <span class=\"n\">node</span><span class=\"p\">.</span><span class=\"n\">n</span><span class=\"p\">.</span><span class=\"n\">p</span> <span class=\"o\">=</span> <span class=\"n\">node</span><span class=\"p\">.</span><span class=\"n\">p</span> <span class=\"n\">node</span><span class=\"p\">.</span><span class=\"n\">n</span> <span class=\"o\">=</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">_tail</span> <span class=\"n\">node</span><span class=\"p\">.</span><span class=\"n\">p</span> <span class=\"o\">=</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">_tail</span><span class=\"p\">.</span><span class=\"n\">p</span> <span class=\"n\">node</span><span class=\"p\">.</span><span class=\"n\">p</span><span class=\"p\">.</span><span class=\"n\">n</span> <span class=\"o\">=</span> <span class=\"n\">node</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">_tail</span><span class=\"p\">.</span><span class=\"n\">p</span> <span class=\"o\">=</span> <span class=\"n\">node</span><span class=\"k\">class</span> <span class=\"nc\">LRUCache</span><span class=\"p\">:</span> <span class=\"k\">def</span> <span class=\"nf\">__init__</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">capacity</span><span class=\"p\">:</span> <span class=\"nb\">int</span><span class=\"p\">):</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">_cap</span> <span class=\"o\">=</span> <span class=\"n\">capacity</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">_cache</span> <span class=\"o\">=</span> <span class=\"p\">{}</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">_lru</span> <span class=\"o\">=</span> <span class=\"nc\">DoubleLinkedList</span><span class=\"p\">()</span> <span class=\"k\">def</span> <span class=\"nf\">get</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">key</span><span class=\"p\">:</span> <span class=\"nb\">int</span><span class=\"p\">)</span> <span class=\"o\">-></span> <span class=\"nb\">int</span><span class=\"p\">:</span> <span class=\"k\">if</span> <span class=\"n\">key</span> <span class=\"ow\">not</span> <span class=\"ow\">in</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">_cache</span><span class=\"p\">:</span> <span class=\"k\">return</span> <span class=\"o\">-</span><span class=\"mi\">1</span> <span class=\"n\">n</span> <span class=\"o\">=</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">_cache</span><span class=\"p\">[</span><span class=\"n\">key</span><span class=\"p\">]</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">_lru</span><span class=\"p\">.</span><span class=\"nf\">move_to_end</span><span class=\"p\">(</span><span class=\"n\">n</span><span class=\"p\">)</span> <span class=\"k\">return</span> <span class=\"n\">n</span><span class=\"p\">.</span><span class=\"n\">v</span> <span class=\"k\">def</span> <span class=\"nf\">put</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">key</span><span class=\"p\">:</span> <span class=\"nb\">int</span><span class=\"p\">,</span> <span class=\"n\">value</span><span class=\"p\">:</span> <span class=\"nb\">int</span><span class=\"p\">)</span> <span class=\"o\">-></span> <span class=\"bp\">None</span><span class=\"p\">:</span> <span class=\"k\">if</span> <span class=\"n\">key</span> <span class=\"ow\">in</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">_cache</span><span class=\"p\">:</span> <span class=\"n\">n</span> <span class=\"o\">=</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">_cache</span><span class=\"p\">[</span><span class=\"n\">key</span><span class=\"p\">]</span> <span class=\"n\">n</span><span class=\"p\">.</span><span class=\"n\">v</span> <span class=\"o\">=</span> <span class=\"n\">value</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">_lru</span><span class=\"p\">.</span><span class=\"nf\">move_to_end</span><span class=\"p\">(</span><span class=\"n\">n</span><span class=\"p\">)</span> <span class=\"k\">else</span><span class=\"p\">:</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">_cache</span><span class=\"p\">[</span><span class=\"n\">key</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"nc\">Node</span><span class=\"p\">(</span><span class=\"n\">key</span><span class=\"p\">,</span> <span class=\"n\">value</span><span class=\"p\">)</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">_lru</span><span class=\"p\">.</span><span class=\"nf\">add</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">_cache</span><span class=\"p\">[</span><span class=\"n\">key</span><span class=\"p\">])</span> <span class=\"k\">if</span> <span class=\"nf\">len</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">_cache</span><span class=\"p\">)</span> <span class=\"o\">></span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">_cap</span><span class=\"p\">:</span> <span class=\"n\">n</span> <span class=\"o\">=</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">_lru</span><span class=\"p\">.</span><span class=\"nf\">pop</span><span class=\"p\">()</span> <span class=\"k\">del</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">_cache</span><span class=\"p\">[</span><span class=\"n\">n</span><span class=\"p\">.</span><span class=\"n\">k</span><span class=\"p\">]</span><span class=\"n\">lru</span> <span class=\"o\">=</span> <span class=\"nc\">LRUCache</span><span class=\"p\">(</span><span class=\"mi\">2</span><span class=\"p\">)</span><span class=\"n\">lru</span><span class=\"p\">.</span><span class=\"nf\">put</span><span class=\"p\">(</span><span class=\"mi\">1</span><span class=\"p\">,</span><span class=\"mi\">2</span><span class=\"p\">)</span><span class=\"n\">lru</span><span class=\"p\">.</span><span class=\"nf\">put</span><span class=\"p\">(</span><span class=\"mi\">2</span><span class=\"p\">,</span><span class=\"mi\">2</span><span class=\"p\">)</span><span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"n\">lru</span><span class=\"p\">.</span><span class=\"nf\">get</span><span class=\"p\">(</span><span class=\"mi\">1</span><span class=\"p\">))</span><span class=\"n\">lru</span><span class=\"p\">.</span><span class=\"nf\">put</span><span class=\"p\">(</span><span class=\"mi\">3</span><span class=\"p\">,</span> <span class=\"mi\">2</span><span class=\"p\">)</span><span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"n\">lru</span><span class=\"p\">.</span><span class=\"nf\">get</span><span class=\"p\">(</span><span class=\"mi\">2</span><span class=\"p\">))</span><span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"n\">lru</span><span class=\"p\">.</span><span class=\"nf\">get</span><span class=\"p\">(</span><span class=\"mi\">3</span><span class=\"p\">))</span></code></pre></figure><blockquote> <p>Runtime: 949 ms, faster than 84.93% of Python3 online submissions for LRU Cache. Memory Usage: 75 MB, less than 82.05% of Python3 online submissions for LRU Cache.</p></blockquote><h2 id=\"using-ordereddict\">Using <code class=\"language-plaintext highlighter-rouge\">OrderedDict</code></h2><p>A much simpler way when solving this with Python is to use a <code class=\"language-plaintext highlighter-rouge\">collections.OrderedDict</code>. Under the hood, this dictionary (map) keeps the order of the inserted keys via a double linked list. The implementation looks as follows:</p><figure class=\"highlight\"><pre><code class=\"language-python\" data-lang=\"python\"><span class=\"kn\">from</span> <span class=\"n\">collections</span> <span class=\"kn\">import</span> <span class=\"n\">OrderedDict</span><span class=\"k\">class</span> <span class=\"nc\">LRUCache</span><span class=\"p\">:</span> <span class=\"k\">def</span> <span class=\"nf\">__init__</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">capacity</span><span class=\"p\">:</span> <span class=\"nb\">int</span><span class=\"p\">):</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">_store</span> <span class=\"o\">=</span> <span class=\"nc\">OrderedDict</span><span class=\"p\">()</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">_cap</span> <span class=\"o\">=</span> <span class=\"n\">capacity</span> <span class=\"k\">def</span> <span class=\"nf\">get</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">key</span><span class=\"p\">:</span> <span class=\"nb\">int</span><span class=\"p\">)</span> <span class=\"o\">-></span> <span class=\"nb\">int</span><span class=\"p\">:</span> <span class=\"k\">if</span> <span class=\"n\">key</span> <span class=\"ow\">not</span> <span class=\"ow\">in</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">_store</span><span class=\"p\">:</span> <span class=\"k\">return</span> <span class=\"o\">-</span><span class=\"mi\">1</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">_store</span><span class=\"p\">.</span><span class=\"nf\">move_to_end</span><span class=\"p\">(</span><span class=\"n\">key</span><span class=\"p\">)</span> <span class=\"k\">return</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">_store</span><span class=\"p\">[</span><span class=\"n\">key</span><span class=\"p\">]</span> <span class=\"k\">def</span> <span class=\"nf\">put</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">key</span><span class=\"p\">:</span> <span class=\"nb\">int</span><span class=\"p\">,</span> <span class=\"n\">value</span><span class=\"p\">:</span> <span class=\"nb\">int</span><span class=\"p\">)</span> <span class=\"o\">-></span> <span class=\"bp\">None</span><span class=\"p\">:</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">_store</span><span class=\"p\">[</span><span class=\"n\">key</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">value</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">_store</span><span class=\"p\">.</span><span class=\"nf\">move_to_end</span><span class=\"p\">(</span><span class=\"n\">key</span><span class=\"p\">)</span> <span class=\"k\">if</span> <span class=\"nf\">len</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">_store</span><span class=\"p\">)</span> <span class=\"o\">></span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">_cap</span><span class=\"p\">:</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">_store</span><span class=\"p\">.</span><span class=\"nf\">popitem</span><span class=\"p\">(</span><span class=\"n\">last</span><span class=\"o\">=</span><span class=\"bp\">False</span><span class=\"p\">)</span></code></pre></figure>", "date_published": "2022-10-15T20:00:00+00:00" }, { "id": "https://fewald.net/leetcode/2022/10/14/leetcode-merge-sorted-array.html", "url": "https://fewald.net/leetcode/2022/10/14/leetcode-merge-sorted-array.html", "title": "Leetcode: Merge sorted array", "content_html": "<p>Given two lists or arrays, <code class=\"language-plaintext highlighter-rouge\">nums1</code> and <code class=\"language-plaintext highlighter-rouge\">nums2</code> as well as two integers <code class=\"language-plaintext highlighter-rouge\">m</code> and <code class=\"language-plaintext highlighter-rouge\">n</code> which give the length of the arrays <code class=\"language-plaintext highlighter-rouge\">nums1</code> and <code class=\"language-plaintext highlighter-rouge\">nums2</code> respectively. <code class=\"language-plaintext highlighter-rouge\">nums1</code> should be modified in place.</p><p>The first idea that came to my mind was a merge-sort. Given that those initial arrays are already sorted, I could have two pointers and iterate over both arrays simulatenously, copying the values into a third one. The problem here is that the array should be modified in place. The way to achieve this in <code class=\"language-plaintext highlighter-rouge\">O(2(n+m)) => O(n+m)</code> is to iterate over the temporary array and write it back to the initial array.</p><!--more--><p>The code is listed below.</p><figure class=\"highlight\"><pre><code class=\"language-python\" data-lang=\"python\"><span class=\"kn\">from</span> <span class=\"n\">typing</span> <span class=\"kn\">import</span> <span class=\"n\">List</span><span class=\"p\">,</span> <span class=\"n\">Optional</span><span class=\"k\">class</span> <span class=\"nc\">Solution</span><span class=\"p\">:</span> <span class=\"k\">def</span> <span class=\"nf\">merge</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">nums1</span><span class=\"p\">:</span> <span class=\"n\">List</span><span class=\"p\">[</span><span class=\"nb\">int</span><span class=\"p\">],</span> <span class=\"n\">m</span><span class=\"p\">:</span> <span class=\"nb\">int</span><span class=\"p\">,</span> <span class=\"n\">nums2</span><span class=\"p\">:</span> <span class=\"n\">List</span><span class=\"p\">[</span><span class=\"nb\">int</span><span class=\"p\">],</span> <span class=\"n\">n</span><span class=\"p\">:</span> <span class=\"nb\">int</span><span class=\"p\">)</span> <span class=\"o\">-></span> <span class=\"bp\">None</span><span class=\"p\">:</span> <span class=\"sh\">\"\"\"</span><span class=\"s\"> Do not return anything, modify nums1 in-place instead. </span><span class=\"sh\">\"\"\"</span> <span class=\"n\">p1</span> <span class=\"o\">=</span> <span class=\"mi\">0</span> <span class=\"n\">p2</span> <span class=\"o\">=</span> <span class=\"mi\">0</span> <span class=\"n\">t</span> <span class=\"o\">=</span> <span class=\"p\">[]</span> <span class=\"k\">while</span> <span class=\"n\">p1</span> <span class=\"o\"><</span> <span class=\"n\">m</span> <span class=\"ow\">and</span> <span class=\"n\">p2</span> <span class=\"o\"><</span> <span class=\"n\">n</span><span class=\"p\">:</span> <span class=\"k\">if</span> <span class=\"n\">nums1</span><span class=\"p\">[</span><span class=\"n\">p1</span><span class=\"p\">]</span> <span class=\"o\"><</span> <span class=\"n\">nums2</span><span class=\"p\">[</span><span class=\"n\">p2</span><span class=\"p\">]:</span> <span class=\"n\">t</span><span class=\"p\">.</span><span class=\"nf\">append</span><span class=\"p\">(</span><span class=\"n\">nums1</span><span class=\"p\">[</span><span class=\"n\">p1</span><span class=\"p\">])</span> <span class=\"n\">p1</span> <span class=\"o\">+=</span> <span class=\"mi\">1</span> <span class=\"k\">else</span><span class=\"p\">:</span> <span class=\"n\">t</span><span class=\"p\">.</span><span class=\"nf\">append</span><span class=\"p\">(</span><span class=\"n\">nums2</span><span class=\"p\">[</span><span class=\"n\">p2</span><span class=\"p\">])</span> <span class=\"n\">p2</span> <span class=\"o\">+=</span> <span class=\"mi\">1</span> <span class=\"n\">t</span> <span class=\"o\">+=</span> <span class=\"n\">nums1</span><span class=\"p\">[</span><span class=\"n\">p1</span><span class=\"p\">:</span><span class=\"n\">m</span><span class=\"p\">]</span> <span class=\"n\">t</span> <span class=\"o\">+=</span> <span class=\"n\">nums2</span><span class=\"p\">[</span><span class=\"n\">p2</span><span class=\"p\">:]</span> <span class=\"k\">for</span> <span class=\"n\">i</span> <span class=\"ow\">in</span> <span class=\"nf\">range</span><span class=\"p\">(</span><span class=\"nf\">len</span><span class=\"p\">(</span><span class=\"n\">t</span><span class=\"p\">)):</span> <span class=\"n\">nums1</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">t</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">]</span><span class=\"k\">if</span> <span class=\"n\">__name__</span> <span class=\"o\">==</span> <span class=\"sh\">'</span><span class=\"s\">__main__</span><span class=\"sh\">'</span><span class=\"p\">:</span> <span class=\"n\">s</span> <span class=\"o\">=</span> <span class=\"nc\">Solution</span><span class=\"p\">().</span><span class=\"n\">merge</span> <span class=\"n\">l</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">,</span><span class=\"mi\">2</span><span class=\"p\">,</span><span class=\"mi\">3</span><span class=\"p\">,</span><span class=\"mi\">0</span><span class=\"p\">,</span><span class=\"mi\">0</span><span class=\"p\">,</span><span class=\"mi\">0</span><span class=\"p\">]</span> <span class=\"nf\">s</span><span class=\"p\">(</span><span class=\"n\">l</span><span class=\"p\">,</span> <span class=\"mi\">3</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"mi\">2</span><span class=\"p\">,</span><span class=\"mi\">5</span><span class=\"p\">,</span><span class=\"mi\">6</span><span class=\"p\">],</span> <span class=\"mi\">3</span><span class=\"p\">)</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"n\">l</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">,</span><span class=\"mi\">2</span><span class=\"p\">,</span><span class=\"mi\">2</span><span class=\"p\">,</span><span class=\"mi\">3</span><span class=\"p\">,</span><span class=\"mi\">5</span><span class=\"p\">,</span><span class=\"mi\">6</span><span class=\"p\">])</span></code></pre></figure><blockquote> <p>Runtime: 68 ms, faster than 28.82% of Python3 online submissions for Merge Sorted Array. Memory Usage: 13.9 MB, less than 85.86% of Python3 online submissions for Merge Sorted Array.</p></blockquote><p>Looking at the solutions from others I saw that they simply called the <code class=\"language-plaintext highlighter-rouge\">sort</code> function. This is obviously less code to write but more time-consuming since the complexity is <code class=\"language-plaintext highlighter-rouge\">O((n+m)*log(n+m))</code>.</p>", "date_published": "2022-10-14T20:00:00+00:00" }, { "id": "https://fewald.net/leetcode/2022/10/13/leetcode-word-search.html", "url": "https://fewald.net/leetcode/2022/10/13/leetcode-word-search.html", "title": "Leetcode: Word search", "content_html": "<p>Given a two-dimensional array with english upper- and lowercase letters, named <code class=\"language-plaintext highlighter-rouge\">board</code> and a <code class=\"language-plaintext highlighter-rouge\">word</code>, return <code class=\"language-plaintext highlighter-rouge\">True</code> if the word appears on the board and false if not. We can go up, down, left, and right but not diagonal. Letters cannot be used twice.</p><p>When looking at this problem, it helps to imagine the <code class=\"language-plaintext highlighter-rouge\">board</code> as a tree. Every letter is a potential root of the tree, depending if it is equal to the start of the word that we are looking for. This allows us to apply a slightly modified version of the breadth-first-search algorightm (BFS).</p><!--more--><p>Below is an example <code class=\"language-plaintext highlighter-rouge\">board</code> and the tree with a root at <code class=\"language-plaintext highlighter-rouge\">A</code>. Note that the <code class=\"language-plaintext highlighter-rouge\">F</code> on the second level is the same although it appears twice. This is important for the implementation later on. The tree is truncated and not shown completely.</p><figure class=\"highlight\"><pre><code class=\"language-plain\" data-lang=\"plain\">+---+---+---+---+ A|(A)| B | C | E | / \\| S | F | C | S | S B| A | D | E | E | / \\ / \\+---+---+---+---+ F A F C ... ... ...</code></pre></figure><p>Having this information, we can look at the implementation. First, a few helper variables are defined: <code class=\"language-plaintext highlighter-rouge\">rows</code>, <code class=\"language-plaintext highlighter-rouge\">cols</code> represent the number of rows and columns respectively. The <code class=\"language-plaintext highlighter-rouge\">directions</code> are the directions we can move on every step. It is easier to define them upfront in order to be able to loop over them and avoid large <code class=\"language-plaintext highlighter-rouge\">if/else</code> blocks. Lastly, we need an indication if a cell has been visited or not. This is because we can only visit each cell once.</p><p>We can then attempt to use every cell as the starting cell and recursively go to the next cell until either no letters in the word are remaining or until the next letter doesn’t match what is required. In this case we can abort and proceed differently.</p><p>After all options are exhausted, we go a step back and mark the current cell as no longer visited. If none of the paths yielded a valid result, we can return <code class=\"language-plaintext highlighter-rouge\">False</code>.</p><figure class=\"highlight\"><pre><code class=\"language-python\" data-lang=\"python\"><span class=\"kn\">from</span> <span class=\"n\">typing</span> <span class=\"kn\">import</span> <span class=\"n\">List</span><span class=\"k\">class</span> <span class=\"nc\">Solution</span><span class=\"p\">:</span> <span class=\"k\">def</span> <span class=\"nf\">exist</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">board</span><span class=\"p\">:</span> <span class=\"n\">List</span><span class=\"p\">[</span><span class=\"n\">List</span><span class=\"p\">[</span><span class=\"nb\">str</span><span class=\"p\">]],</span> <span class=\"n\">word</span><span class=\"p\">:</span> <span class=\"nb\">str</span><span class=\"p\">)</span> <span class=\"o\">-></span> <span class=\"nb\">bool</span><span class=\"p\">:</span> <span class=\"n\">rows</span> <span class=\"o\">=</span> <span class=\"nf\">len</span><span class=\"p\">(</span><span class=\"n\">board</span><span class=\"p\">)</span> <span class=\"n\">cols</span> <span class=\"o\">=</span> <span class=\"nf\">len</span><span class=\"p\">(</span><span class=\"n\">board</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">])</span> <span class=\"n\">directions</span> <span class=\"o\">=</span> <span class=\"p\">[(</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">0</span><span class=\"p\">),</span> <span class=\"p\">(</span><span class=\"mi\">0</span><span class=\"p\">,</span> <span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">),</span> <span class=\"p\">(</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">0</span><span class=\"p\">),</span> <span class=\"p\">(</span><span class=\"mi\">0</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">)]</span> <span class=\"n\">visited</span> <span class=\"o\">=</span> <span class=\"nf\">set</span><span class=\"p\">()</span> <span class=\"k\">def</span> <span class=\"nf\">dfs</span><span class=\"p\">(</span><span class=\"n\">idx</span><span class=\"p\">,</span> <span class=\"n\">x</span><span class=\"p\">,</span> <span class=\"n\">y</span><span class=\"p\">):</span> <span class=\"k\">if</span> <span class=\"n\">board</span><span class=\"p\">[</span><span class=\"n\">x</span><span class=\"p\">][</span><span class=\"n\">y</span><span class=\"p\">]</span> <span class=\"o\">!=</span> <span class=\"n\">word</span><span class=\"p\">[</span><span class=\"n\">idx</span><span class=\"p\">]:</span> <span class=\"k\">return</span> <span class=\"bp\">False</span> <span class=\"k\">if</span> <span class=\"n\">board</span><span class=\"p\">[</span><span class=\"n\">x</span><span class=\"p\">][</span><span class=\"n\">y</span><span class=\"p\">]</span> <span class=\"o\">==</span> <span class=\"n\">word</span><span class=\"p\">[</span><span class=\"n\">idx</span><span class=\"p\">]</span> <span class=\"ow\">and</span> <span class=\"n\">idx</span> <span class=\"o\">==</span> <span class=\"nf\">len</span><span class=\"p\">(</span><span class=\"n\">word</span><span class=\"p\">)</span> <span class=\"o\">-</span> <span class=\"mi\">1</span><span class=\"p\">:</span> <span class=\"k\">return</span> <span class=\"bp\">True</span> <span class=\"n\">visited</span><span class=\"p\">.</span><span class=\"nf\">add</span><span class=\"p\">((</span><span class=\"n\">x</span><span class=\"p\">,</span><span class=\"n\">y</span><span class=\"p\">))</span> <span class=\"k\">for</span> <span class=\"n\">d</span> <span class=\"ow\">in</span> <span class=\"n\">directions</span><span class=\"p\">:</span> <span class=\"n\">new_x</span> <span class=\"o\">=</span> <span class=\"n\">x</span> <span class=\"o\">+</span> <span class=\"n\">d</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span> <span class=\"n\">new_y</span> <span class=\"o\">=</span> <span class=\"n\">y</span> <span class=\"o\">+</span> <span class=\"n\">d</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">]</span> <span class=\"k\">if</span> <span class=\"n\">new_x</span> <span class=\"ow\">in</span> <span class=\"nf\">range</span><span class=\"p\">(</span><span class=\"n\">rows</span><span class=\"p\">)</span> <span class=\"ow\">and</span> <span class=\"n\">new_y</span> <span class=\"ow\">in</span> <span class=\"nf\">range</span><span class=\"p\">(</span><span class=\"n\">cols</span><span class=\"p\">)</span> <span class=\"ow\">and</span> <span class=\"p\">(</span><span class=\"n\">new_x</span><span class=\"p\">,</span> <span class=\"n\">new_y</span><span class=\"p\">)</span> <span class=\"ow\">not</span> <span class=\"ow\">in</span> <span class=\"n\">visited</span><span class=\"p\">:</span> <span class=\"k\">if</span> <span class=\"nf\">dfs</span><span class=\"p\">(</span><span class=\"n\">idx</span><span class=\"o\">+</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"n\">new_x</span><span class=\"p\">,</span> <span class=\"n\">new_y</span><span class=\"p\">):</span> <span class=\"k\">return</span> <span class=\"bp\">True</span> <span class=\"n\">visited</span><span class=\"p\">.</span><span class=\"nf\">remove</span><span class=\"p\">((</span><span class=\"n\">x</span><span class=\"p\">,</span><span class=\"n\">y</span><span class=\"p\">))</span> <span class=\"k\">return</span> <span class=\"bp\">False</span> <span class=\"k\">for</span> <span class=\"n\">x</span> <span class=\"ow\">in</span> <span class=\"nf\">range</span><span class=\"p\">(</span><span class=\"n\">rows</span><span class=\"p\">):</span> <span class=\"k\">for</span> <span class=\"n\">y</span> <span class=\"ow\">in</span> <span class=\"nf\">range</span><span class=\"p\">(</span><span class=\"n\">cols</span><span class=\"p\">):</span> <span class=\"k\">if</span> <span class=\"nf\">dfs</span><span class=\"p\">(</span><span class=\"mi\">0</span><span class=\"p\">,</span> <span class=\"n\">x</span><span class=\"p\">,</span> <span class=\"n\">y</span><span class=\"p\">):</span> <span class=\"k\">return</span> <span class=\"bp\">True</span> <span class=\"k\">return</span> <span class=\"bp\">False</span> <span class=\"k\">if</span> <span class=\"n\">__name__</span> <span class=\"o\">==</span> <span class=\"sh\">'</span><span class=\"s\">__main__</span><span class=\"sh\">'</span><span class=\"p\">:</span> <span class=\"n\">s</span> <span class=\"o\">=</span> <span class=\"nc\">Solution</span><span class=\"p\">().</span><span class=\"n\">exist</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">([[</span><span class=\"sh\">\"</span><span class=\"s\">A</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">B</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">C</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">E</span><span class=\"sh\">\"</span><span class=\"p\">],[</span><span class=\"sh\">\"</span><span class=\"s\">S</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">F</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">C</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">S</span><span class=\"sh\">\"</span><span class=\"p\">],[</span><span class=\"sh\">\"</span><span class=\"s\">A</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">D</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">E</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">E</span><span class=\"sh\">\"</span><span class=\"p\">]],</span> <span class=\"sh\">\"</span><span class=\"s\">ABCCED</span><span class=\"sh\">\"</span><span class=\"p\">),</span> <span class=\"bp\">True</span><span class=\"p\">)</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">([[</span><span class=\"sh\">\"</span><span class=\"s\">A</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">B</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">C</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">E</span><span class=\"sh\">\"</span><span class=\"p\">],[</span><span class=\"sh\">\"</span><span class=\"s\">S</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">F</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">C</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">S</span><span class=\"sh\">\"</span><span class=\"p\">],[</span><span class=\"sh\">\"</span><span class=\"s\">A</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">D</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">E</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">E</span><span class=\"sh\">\"</span><span class=\"p\">]],</span> <span class=\"sh\">\"</span><span class=\"s\">SEE</span><span class=\"sh\">\"</span><span class=\"p\">),</span> <span class=\"bp\">True</span><span class=\"p\">)</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">([[</span><span class=\"sh\">\"</span><span class=\"s\">A</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">B</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">C</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">E</span><span class=\"sh\">\"</span><span class=\"p\">],[</span><span class=\"sh\">\"</span><span class=\"s\">S</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">F</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">C</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">S</span><span class=\"sh\">\"</span><span class=\"p\">],[</span><span class=\"sh\">\"</span><span class=\"s\">A</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">D</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">E</span><span class=\"sh\">\"</span><span class=\"p\">,</span><span class=\"sh\">\"</span><span class=\"s\">E</span><span class=\"sh\">\"</span><span class=\"p\">]],</span> <span class=\"sh\">\"</span><span class=\"s\">ABCB</span><span class=\"sh\">\"</span><span class=\"p\">),</span> <span class=\"bp\">False</span><span class=\"p\">)</span></code></pre></figure><blockquote> <p>Runtime: 8666 ms, faster than 28.73% of Python3 online submissions for Word Search. Memory Usage: 13.9 MB, less than 50.91% of Python3 online submissions for Word Search.</p></blockquote>", "date_published": "2022-10-13T20:00:00+00:00" }, { "id": "https://fewald.net/leetcode/2022/10/12/leetcode-unique-paths.html", "url": "https://fewald.net/leetcode/2022/10/12/leetcode-unique-paths.html", "title": "Leetcode: Unique paths", "content_html": "<p>Given an <code class=\"language-plaintext highlighter-rouge\">m * n</code> grid, we start in the top left corner at position <code class=\"language-plaintext highlighter-rouge\">(1,1)</code>. We want to move to the bottom right corner with either <code class=\"language-plaintext highlighter-rouge\">right</code> or <code class=\"language-plaintext highlighter-rouge\">down</code> steps. How many different combinations of <code class=\"language-plaintext highlighter-rouge\">right</code> and <code class=\"language-plaintext highlighter-rouge\">down</code> are there for a given grid of size <code class=\"language-plaintext highlighter-rouge\">m * n</code>? We need to find an algorithm that works on arbitrarily large grids.</p><p>Given this example grid of <code class=\"language-plaintext highlighter-rouge\">(2,3)</code>:</p><figure class=\"highlight\"><pre><code class=\"language-plain\" data-lang=\"plain\">+---+---+---+| S | | | S = Start+---+---+---+| | | F | F = Finish+---+---+---+</code></pre></figure><p>There are <code class=\"language-plaintext highlighter-rouge\">3</code> different ways from start to finish:</p><ul> <li>Down, Right Right</li> <li>Right, Down, Right</li> <li>Right, Right, Down</li></ul><p>To simplify this problem, we can think of a down move as <code class=\"language-plaintext highlighter-rouge\">1</code> and of a right move as <code class=\"language-plaintext highlighter-rouge\">0</code>. This shows us, that we can either do <code class=\"language-plaintext highlighter-rouge\">100</code>, <code class=\"language-plaintext highlighter-rouge\">010</code>, or <code class=\"language-plaintext highlighter-rouge\">001</code>. We observe that the one is in every position. Now, two different down moves are identical, hence there are less than <code class=\"language-plaintext highlighter-rouge\">2^n</code> solutions.</p><p>If we think of this problem as a backtracking problem, we can come up with a recursive algorithm. At the first position we can go either down or right. Depending on which way we go, we have to shrink the field either on the x or y-axis. We then add the result of going right to the result of going down. This step is repeated until we can only go down or right in which case we can return <code class=\"language-plaintext highlighter-rouge\">1</code>.</p><!--more--><p>The first solution that I submitted to Leetcode looked like this. While it is technically correct it has one flaw: A lot of fields are calculated over and over again. The algorithm goes first to the very end, then returns a <code class=\"language-plaintext highlighter-rouge\">1</code> and goes back from there. Then for every field it has to recompute the values, even if it visited that field before.</p><p>This solution produces the correct results but times out on Leetcode.</p><figure class=\"highlight\"><pre><code class=\"language-python\" data-lang=\"python\"><span class=\"k\">class</span> <span class=\"nc\">Solution</span><span class=\"p\">:</span> <span class=\"k\">def</span> <span class=\"nf\">uniquePaths</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">m</span><span class=\"p\">:</span> <span class=\"nb\">int</span><span class=\"p\">,</span> <span class=\"n\">n</span><span class=\"p\">:</span> <span class=\"nb\">int</span><span class=\"p\">)</span> <span class=\"o\">-></span> <span class=\"nb\">int</span><span class=\"p\">:</span> <span class=\"k\">if</span> <span class=\"n\">m</span> <span class=\"o\">></span> <span class=\"mi\">1</span> <span class=\"ow\">and</span> <span class=\"n\">n</span> <span class=\"o\">></span> <span class=\"mi\">1</span><span class=\"p\">:</span> <span class=\"k\">return</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"nf\">uniquePaths</span><span class=\"p\">(</span><span class=\"n\">m</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"n\">n</span><span class=\"p\">)</span> <span class=\"o\">+</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"nf\">uniquePaths</span><span class=\"p\">(</span><span class=\"n\">m</span><span class=\"p\">,</span> <span class=\"n\">n</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">)</span> <span class=\"k\">return</span> <span class=\"mi\">1</span><span class=\"k\">if</span> <span class=\"n\">__name__</span> <span class=\"o\">==</span> <span class=\"sh\">'</span><span class=\"s\">__main__</span><span class=\"sh\">'</span><span class=\"p\">:</span> <span class=\"n\">s</span> <span class=\"o\">=</span> <span class=\"nc\">Solution</span><span class=\"p\">().</span><span class=\"n\">uniquePaths</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">(</span><span class=\"mi\">3</span><span class=\"p\">,</span><span class=\"mi\">2</span><span class=\"p\">),</span> <span class=\"mi\">3</span><span class=\"p\">)</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">(</span><span class=\"mi\">3</span><span class=\"p\">,</span><span class=\"mi\">7</span><span class=\"p\">),</span> <span class=\"mi\">28</span><span class=\"p\">)</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">(</span><span class=\"mi\">23</span><span class=\"p\">,</span><span class=\"mi\">12</span><span class=\"p\">),</span> <span class=\"mi\">193536720</span><span class=\"p\">)</span></code></pre></figure><p>The final solution looks like this. I added a <code class=\"language-plaintext highlighter-rouge\">map</code> to avoid calculating the same results over and over again. This is especially beneficial for larger fields where we would reach the same field via many different ways. As keys I used the coordinates of the field.</p><figure class=\"highlight\"><pre><code class=\"language-python\" data-lang=\"python\"><span class=\"k\">class</span> <span class=\"nc\">Solution</span><span class=\"p\">:</span> <span class=\"k\">def</span> <span class=\"nf\">uniquePaths</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">m</span><span class=\"p\">:</span> <span class=\"nb\">int</span><span class=\"p\">,</span> <span class=\"n\">n</span><span class=\"p\">:</span> <span class=\"nb\">int</span><span class=\"p\">)</span> <span class=\"o\">-></span> <span class=\"nb\">int</span><span class=\"p\">:</span> <span class=\"n\">memory</span> <span class=\"o\">=</span> <span class=\"p\">{}</span> <span class=\"k\">def</span> <span class=\"nf\">inner</span><span class=\"p\">(</span><span class=\"n\">i</span><span class=\"p\">,</span> <span class=\"n\">j</span><span class=\"p\">):</span> <span class=\"k\">if</span> <span class=\"n\">i</span> <span class=\"o\">==</span> <span class=\"mi\">0</span> <span class=\"ow\">or</span> <span class=\"n\">j</span> <span class=\"o\">==</span> <span class=\"mi\">0</span><span class=\"p\">:</span> <span class=\"k\">return</span> <span class=\"mi\">1</span> <span class=\"nf\">if </span><span class=\"p\">(</span><span class=\"n\">i</span><span class=\"p\">,</span><span class=\"n\">j</span><span class=\"p\">)</span> <span class=\"ow\">not</span> <span class=\"ow\">in</span> <span class=\"n\">memory</span><span class=\"p\">:</span> <span class=\"n\">memory</span><span class=\"p\">[(</span><span class=\"n\">i</span><span class=\"p\">,</span><span class=\"n\">j</span><span class=\"p\">)]</span> <span class=\"o\">=</span> <span class=\"nf\">inner</span><span class=\"p\">(</span><span class=\"n\">i</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"n\">j</span><span class=\"p\">)</span> <span class=\"o\">+</span> <span class=\"nf\">inner</span><span class=\"p\">(</span><span class=\"n\">i</span><span class=\"p\">,</span> <span class=\"n\">j</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">)</span> <span class=\"k\">return</span> <span class=\"n\">memory</span><span class=\"p\">[(</span><span class=\"n\">i</span><span class=\"p\">,</span><span class=\"n\">j</span><span class=\"p\">)]</span> <span class=\"k\">return</span> <span class=\"nf\">inner</span><span class=\"p\">(</span><span class=\"n\">m</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"n\">n</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">)</span><span class=\"k\">if</span> <span class=\"n\">__name__</span> <span class=\"o\">==</span> <span class=\"sh\">'</span><span class=\"s\">__main__</span><span class=\"sh\">'</span><span class=\"p\">:</span> <span class=\"n\">s</span> <span class=\"o\">=</span> <span class=\"nc\">Solution</span><span class=\"p\">().</span><span class=\"n\">uniquePaths</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">(</span><span class=\"mi\">3</span><span class=\"p\">,</span><span class=\"mi\">2</span><span class=\"p\">),</span> <span class=\"mi\">3</span><span class=\"p\">)</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">(</span><span class=\"mi\">3</span><span class=\"p\">,</span><span class=\"mi\">7</span><span class=\"p\">),</span> <span class=\"mi\">28</span><span class=\"p\">)</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">(</span><span class=\"mi\">23</span><span class=\"p\">,</span><span class=\"mi\">12</span><span class=\"p\">),</span> <span class=\"mi\">193536720</span><span class=\"p\">)</span></code></pre></figure><blockquote> <p>Runtime: 44 ms, faster than 65.61% of Python3 online submissions for Unique Paths. Memory Usage: 14.3 MB, less than 6.40% of Python3 online submissions for Unique Paths.</p></blockquote>", "date_published": "2022-10-12T20:00:00+00:00" }, { "id": "https://fewald.net/leetcode/2022/10/11/leetcode-merge-intervals.html", "url": "https://fewald.net/leetcode/2022/10/11/leetcode-merge-intervals.html", "title": "Leetcode: Merge intervals", "content_html": "<p>Given an array of intervals of the form <code class=\"language-plaintext highlighter-rouge\">[start, end]</code>, merge all overlapping intervals and return an array of non-overlapping intervals.</p><p>One example is the following array <code class=\"language-plaintext highlighter-rouge\">[[1,2], [3,4]]</code>. There is no overlap here. Hence the result is the same as the input. Another example is <code class=\"language-plaintext highlighter-rouge\">[[1,2], [1,4]]</code>. They are overlapping and the result is <code class=\"language-plaintext highlighter-rouge\">[[1,4]]</code>. If the start number of the next element is the same as the end number of the previous element, the items should be treated as overlapping.</p><p>One possible solution is to first sort the items by start element. This can be achieved with an in-place sorting and a <code class=\"language-plaintext highlighter-rouge\">lambda</code> expression: <code class=\"language-plaintext highlighter-rouge\">intervals.sort(key=lambda item: item[0])</code>.</p><!--more--><p>After this, we can save the first element as the result immediately. Then we can iterate over the second to the last element and always compare the start time of the next element with the start time of the previous element. If it is equal or less then we can consider it to be overlapping and need to change the element to the maximum of both end elements.</p><p>In all other cases there is no overlap and we add the whole item as is to the end of the result list.</p><figure class=\"highlight\"><pre><code class=\"language-python\" data-lang=\"python\"><span class=\"kn\">from</span> <span class=\"n\">typing</span> <span class=\"kn\">import</span> <span class=\"n\">List</span><span class=\"k\">class</span> <span class=\"nc\">Solution</span><span class=\"p\">:</span> <span class=\"k\">def</span> <span class=\"nf\">merge</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">intervals</span><span class=\"p\">:</span> <span class=\"n\">List</span><span class=\"p\">[</span><span class=\"n\">List</span><span class=\"p\">[</span><span class=\"nb\">int</span><span class=\"p\">]])</span> <span class=\"o\">-></span> <span class=\"n\">List</span><span class=\"p\">[</span><span class=\"n\">List</span><span class=\"p\">[</span><span class=\"nb\">int</span><span class=\"p\">]]:</span> <span class=\"c1\"># Sort in-place by start of interval</span> <span class=\"n\">intervals</span><span class=\"p\">.</span><span class=\"nf\">sort</span><span class=\"p\">(</span><span class=\"n\">key</span><span class=\"o\">=</span><span class=\"k\">lambda</span> <span class=\"n\">item</span><span class=\"p\">:</span> <span class=\"n\">item</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">])</span> <span class=\"n\">res</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"n\">intervals</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]]</span> <span class=\"k\">for</span> <span class=\"n\">i</span> <span class=\"ow\">in</span> <span class=\"nf\">range</span><span class=\"p\">(</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"nf\">len</span><span class=\"p\">(</span><span class=\"n\">intervals</span><span class=\"p\">)):</span> <span class=\"k\">if</span> <span class=\"n\">intervals</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">][</span><span class=\"mi\">0</span><span class=\"p\">]</span> <span class=\"o\"><=</span> <span class=\"n\">res</span><span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">][</span><span class=\"mi\">1</span><span class=\"p\">]:</span> <span class=\"n\">res</span><span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">][</span><span class=\"mi\">1</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"nf\">max</span><span class=\"p\">(</span><span class=\"n\">res</span><span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">][</span><span class=\"mi\">1</span><span class=\"p\">],</span> <span class=\"n\">intervals</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">][</span><span class=\"mi\">1</span><span class=\"p\">])</span> <span class=\"k\">else</span><span class=\"p\">:</span> <span class=\"n\">res</span><span class=\"p\">.</span><span class=\"nf\">append</span><span class=\"p\">(</span><span class=\"n\">intervals</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">])</span> <span class=\"k\">return</span> <span class=\"n\">res</span><span class=\"k\">if</span> <span class=\"n\">__name__</span> <span class=\"o\">==</span> <span class=\"sh\">'</span><span class=\"s\">__main__</span><span class=\"sh\">'</span><span class=\"p\">:</span> <span class=\"n\">s</span> <span class=\"o\">=</span> <span class=\"nc\">Solution</span><span class=\"p\">().</span><span class=\"n\">merge</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">([[</span><span class=\"mi\">1</span><span class=\"p\">,</span><span class=\"mi\">3</span><span class=\"p\">],[</span><span class=\"mi\">2</span><span class=\"p\">,</span><span class=\"mi\">6</span><span class=\"p\">],[</span><span class=\"mi\">8</span><span class=\"p\">,</span><span class=\"mi\">10</span><span class=\"p\">],[</span><span class=\"mi\">15</span><span class=\"p\">,</span><span class=\"mi\">18</span><span class=\"p\">]]),</span> <span class=\"p\">[[</span><span class=\"mi\">1</span><span class=\"p\">,</span><span class=\"mi\">6</span><span class=\"p\">],[</span><span class=\"mi\">8</span><span class=\"p\">,</span><span class=\"mi\">10</span><span class=\"p\">],[</span><span class=\"mi\">15</span><span class=\"p\">,</span><span class=\"mi\">18</span><span class=\"p\">]])</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">([[</span><span class=\"mi\">1</span><span class=\"p\">,</span><span class=\"mi\">4</span><span class=\"p\">],[</span><span class=\"mi\">4</span><span class=\"p\">,</span><span class=\"mi\">5</span><span class=\"p\">]]),</span> <span class=\"p\">[[</span><span class=\"mi\">1</span><span class=\"p\">,</span><span class=\"mi\">5</span><span class=\"p\">]])</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">([[</span><span class=\"mi\">1</span><span class=\"p\">,</span><span class=\"mi\">2</span><span class=\"p\">]]),</span> <span class=\"p\">[[</span><span class=\"mi\">1</span><span class=\"p\">,</span><span class=\"mi\">2</span><span class=\"p\">]])</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">([[</span><span class=\"mi\">1</span><span class=\"p\">,</span><span class=\"mi\">2</span><span class=\"p\">],</span> <span class=\"p\">[</span><span class=\"mi\">3</span><span class=\"p\">,</span><span class=\"mi\">4</span><span class=\"p\">]]),</span> <span class=\"p\">[[</span><span class=\"mi\">1</span><span class=\"p\">,</span><span class=\"mi\">2</span><span class=\"p\">],</span> <span class=\"p\">[</span><span class=\"mi\">3</span><span class=\"p\">,</span><span class=\"mi\">4</span><span class=\"p\">]])</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">([[</span><span class=\"mi\">1</span><span class=\"p\">,</span><span class=\"mi\">4</span><span class=\"p\">],</span> <span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">,</span><span class=\"mi\">4</span><span class=\"p\">]]),</span> <span class=\"p\">[[</span><span class=\"mi\">0</span><span class=\"p\">,</span><span class=\"mi\">4</span><span class=\"p\">]])</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">([[</span><span class=\"mi\">1</span><span class=\"p\">,</span><span class=\"mi\">4</span><span class=\"p\">],</span> <span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">,</span><span class=\"mi\">0</span><span class=\"p\">]]),</span> <span class=\"p\">[[</span><span class=\"mi\">0</span><span class=\"p\">,</span><span class=\"mi\">0</span><span class=\"p\">],</span> <span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">,</span><span class=\"mi\">4</span><span class=\"p\">]])</span></code></pre></figure><blockquote> <p>Runtime: 204 ms, faster than 65.06% of Python3 online submissions for Merge Intervals. Memory Usage: 18 MB, less than 85.11% of Python3 online submissions for Merge Intervals.</p></blockquote>", "date_published": "2022-10-11T20:00:00+00:00" }, { "id": "https://fewald.net/leetcode/2022/10/10/leetcode-remove-nth-node-from-end-of-list.html", "url": "https://fewald.net/leetcode/2022/10/10/leetcode-remove-nth-node-from-end-of-list.html", "title": "Leetcode: Remove nth node from end of list", "content_html": "<p>Given the <code class=\"language-plaintext highlighter-rouge\">head</code> of a linked list, remove the <code class=\"language-plaintext highlighter-rouge\">nth</code> element from the <strong>end</strong> of the list and return the head of the list. As a follow-up, this should be done with one iteration.</p><p>The most obvious solution is to count the number of elements in the list in one iteration. This is necessary, because we don’t know initially how long the list is. Then iterate over the list again and once the index is reached, set <code class=\"language-plaintext highlighter-rouge\">pointer = pointer.next</code>. This way the <code class=\"language-plaintext highlighter-rouge\">nth</code> element is skipped.</p><p>However, there is a more elegant way to achieve this.</p><!--more--><p>We can set up two pointers, both at the <code class=\"language-plaintext highlighter-rouge\">head</code> of the list. We move the first pointer and increment a counter. When the counter reaches <code class=\"language-plaintext highlighter-rouge\">n</code>, we start moving the second pointer as well. Once the first pointer reaches the end of the list we simply set the second pointer to the next position and we’re done.</p><p>There is one special case: When the element that should be removed is the first element. Because we have a pointer to <code class=\"language-plaintext highlighter-rouge\">head</code> and return <code class=\"language-plaintext highlighter-rouge\">head</code> in the end, this would be discarded. A quick solution is to create a temporary node and point it to the <code class=\"language-plaintext highlighter-rouge\">head</code>. Then do the operation as described above. In the end return <code class=\"language-plaintext highlighter-rouge\">pre_head.next</code> which points to the new (or old) head.</p><p>The <code class=\"language-plaintext highlighter-rouge\">__str__</code> and <code class=\"language-plaintext highlighter-rouge\">__repr__</code> methods are small helper methods that I added for easier debugging.</p><figure class=\"highlight\"><pre><code class=\"language-python\" data-lang=\"python\"><span class=\"kn\">from</span> <span class=\"n\">typing</span> <span class=\"kn\">import</span> <span class=\"n\">List</span><span class=\"p\">,</span> <span class=\"n\">Optional</span><span class=\"c1\"># Definition for singly-linked list.</span><span class=\"k\">class</span> <span class=\"nc\">ListNode</span><span class=\"p\">:</span> <span class=\"k\">def</span> <span class=\"nf\">__init__</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">val</span><span class=\"o\">=</span><span class=\"mi\">0</span><span class=\"p\">,</span> <span class=\"nb\">next</span><span class=\"o\">=</span><span class=\"bp\">None</span><span class=\"p\">):</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">val</span> <span class=\"o\">=</span> <span class=\"n\">val</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"nb\">next</span> <span class=\"o\">=</span> <span class=\"nb\">next</span> <span class=\"k\">def</span> <span class=\"nf\">__str__</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">)</span> <span class=\"o\">-></span> <span class=\"nb\">str</span><span class=\"p\">:</span> <span class=\"sh\">\"\"\"</span><span class=\"s\"> Helper to print results to command line. </span><span class=\"sh\">\"\"\"</span> <span class=\"n\">s</span> <span class=\"o\">=</span> <span class=\"sa\">f</span><span class=\"sh\">\"</span><span class=\"si\">{</span><span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">val</span><span class=\"si\">}</span><span class=\"sh\">\"</span> <span class=\"k\">if</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"nb\">next</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"bp\">None</span><span class=\"p\">:</span> <span class=\"n\">s</span> <span class=\"o\">+=</span> <span class=\"sa\">f</span><span class=\"sh\">\"</span><span class=\"s\">, </span><span class=\"si\">{</span><span class=\"n\">self</span><span class=\"p\">.</span><span class=\"nb\">next</span><span class=\"si\">}</span><span class=\"sh\">\"</span> <span class=\"k\">return</span> <span class=\"n\">s</span> <span class=\"k\">def</span> <span class=\"nf\">__repr__</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">)</span> <span class=\"o\">-></span> <span class=\"nb\">str</span><span class=\"p\">:</span> <span class=\"sh\">\"\"\"</span><span class=\"s\"> Helper for debugging </span><span class=\"sh\">\"\"\"</span> <span class=\"k\">return</span> <span class=\"sa\">f</span><span class=\"sh\">\"</span><span class=\"s\"><</span><span class=\"si\">{</span><span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">val</span><span class=\"si\">}</span><span class=\"s\">></span><span class=\"sh\">\"</span><span class=\"k\">class</span> <span class=\"nc\">Solution</span><span class=\"p\">:</span> <span class=\"k\">def</span> <span class=\"nf\">removeNthFromEnd</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">head</span><span class=\"p\">:</span> <span class=\"n\">Optional</span><span class=\"p\">[</span><span class=\"n\">ListNode</span><span class=\"p\">],</span> <span class=\"n\">n</span><span class=\"p\">:</span> <span class=\"nb\">int</span><span class=\"p\">)</span> <span class=\"o\">-></span> <span class=\"n\">Optional</span><span class=\"p\">[</span><span class=\"n\">ListNode</span><span class=\"p\">]:</span> <span class=\"c1\"># Insert dummy element in front of the head so that we can refer to it later</span> <span class=\"n\">pre_head</span> <span class=\"o\">=</span> <span class=\"nc\">ListNode</span><span class=\"p\">(</span><span class=\"o\">-</span><span class=\"mi\">999</span><span class=\"p\">,</span> <span class=\"n\">head</span><span class=\"p\">)</span> <span class=\"n\">curr</span> <span class=\"o\">=</span> <span class=\"n\">pre_head</span> <span class=\"n\">ptr</span> <span class=\"o\">=</span> <span class=\"n\">pre_head</span> <span class=\"n\">dist</span> <span class=\"o\">=</span> <span class=\"mi\">0</span> <span class=\"k\">while</span> <span class=\"n\">curr</span><span class=\"p\">.</span><span class=\"nb\">next</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"bp\">None</span><span class=\"p\">:</span> <span class=\"k\">if</span> <span class=\"n\">dist</span> <span class=\"o\">==</span> <span class=\"n\">n</span><span class=\"p\">:</span> <span class=\"n\">ptr</span> <span class=\"o\">=</span> <span class=\"n\">ptr</span><span class=\"p\">.</span><span class=\"nb\">next</span> <span class=\"k\">else</span><span class=\"p\">:</span> <span class=\"n\">dist</span> <span class=\"o\">+=</span> <span class=\"mi\">1</span> <span class=\"n\">curr</span> <span class=\"o\">=</span> <span class=\"n\">curr</span><span class=\"p\">.</span><span class=\"nb\">next</span> <span class=\"n\">ptr</span><span class=\"p\">.</span><span class=\"nb\">next</span> <span class=\"o\">=</span> <span class=\"n\">ptr</span><span class=\"p\">.</span><span class=\"nb\">next</span><span class=\"p\">.</span><span class=\"nb\">next</span> <span class=\"k\">return</span> <span class=\"n\">pre_head</span><span class=\"p\">.</span><span class=\"nb\">next</span><span class=\"k\">if</span> <span class=\"n\">__name__</span> <span class=\"o\">==</span> <span class=\"sh\">'</span><span class=\"s\">__main__</span><span class=\"sh\">'</span><span class=\"p\">:</span> <span class=\"n\">s</span> <span class=\"o\">=</span> <span class=\"nc\">Solution</span><span class=\"p\">().</span><span class=\"n\">removeNthFromEnd</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">(</span><span class=\"nc\">ListNode</span><span class=\"p\">(</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"nc\">ListNode</span><span class=\"p\">(</span><span class=\"mi\">2</span><span class=\"p\">,</span> <span class=\"nc\">ListNode</span><span class=\"p\">(</span><span class=\"mi\">3</span><span class=\"p\">,</span> <span class=\"nc\">ListNode</span><span class=\"p\">(</span><span class=\"mi\">4</span><span class=\"p\">,</span> <span class=\"nc\">ListNode</span><span class=\"p\">(</span><span class=\"mi\">5</span><span class=\"p\">))))),</span> <span class=\"mi\">2</span><span class=\"p\">),</span> <span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">,</span><span class=\"mi\">2</span><span class=\"p\">,</span><span class=\"mi\">3</span><span class=\"p\">,</span><span class=\"mi\">5</span><span class=\"p\">])</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">(</span><span class=\"nc\">ListNode</span><span class=\"p\">(</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"nc\">ListNode</span><span class=\"p\">(</span><span class=\"mi\">2</span><span class=\"p\">)),</span> <span class=\"mi\">1</span><span class=\"p\">),</span> <span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">])</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">(</span><span class=\"nc\">ListNode</span><span class=\"p\">(</span><span class=\"mi\">1</span><span class=\"p\">),</span> <span class=\"mi\">1</span><span class=\"p\">),</span> <span class=\"p\">[])</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">(</span><span class=\"nc\">ListNode</span><span class=\"p\">(</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"nc\">ListNode</span><span class=\"p\">(</span><span class=\"mi\">2</span><span class=\"p\">)),</span> <span class=\"mi\">1</span><span class=\"p\">),</span> <span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">])</span></code></pre></figure><blockquote> <p>Runtime: 37 ms, faster than 88.56% of Python3 online submissions for Remove Nth Node From End of List. Memory Usage: 13.9 MB, less than 20.39% of Python3 online submissions for Remove Nth Node From End of List.</p></blockquote>", "date_published": "2022-10-10T20:00:00+00:00" }, { "id": "https://fewald.net/leetcode/2022/10/09/leetcode-sort-colors.html", "url": "https://fewald.net/leetcode/2022/10/09/leetcode-sort-colors.html", "title": "Leetcode: Sort colors", "content_html": "<p>Given an array <code class=\"language-plaintext highlighter-rouge\">nums</code> with <code class=\"language-plaintext highlighter-rouge\">n</code> colored objects, sort the array <strong>in place</strong> so that the colors are orders. The colors are represented by the numbers <code class=\"language-plaintext highlighter-rouge\">0</code>, <code class=\"language-plaintext highlighter-rouge\">1</code>, and <code class=\"language-plaintext highlighter-rouge\">2</code>.</p><p>The easiest way to achieve this is via quicksort in <code class=\"language-plaintext highlighter-rouge\">O(n*log n)</code>.</p><!--more--><figure class=\"highlight\"><pre><code class=\"language-python\" data-lang=\"python\"><span class=\"kn\">from</span> <span class=\"n\">typing</span> <span class=\"kn\">import</span> <span class=\"n\">List</span><span class=\"p\">,</span> <span class=\"n\">Optional</span><span class=\"k\">class</span> <span class=\"nc\">Solution</span><span class=\"p\">:</span> <span class=\"k\">def</span> <span class=\"nf\">sortColors</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">nums</span><span class=\"p\">:</span> <span class=\"n\">List</span><span class=\"p\">[</span><span class=\"nb\">int</span><span class=\"p\">])</span> <span class=\"o\">-></span> <span class=\"bp\">None</span><span class=\"p\">:</span> <span class=\"sh\">\"\"\"</span><span class=\"s\"> Do not return anything, modify nums in-place instead. </span><span class=\"sh\">\"\"\"</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"nf\">quicksort</span><span class=\"p\">(</span><span class=\"n\">nums</span><span class=\"p\">,</span> <span class=\"mi\">0</span><span class=\"p\">,</span> <span class=\"nf\">len</span><span class=\"p\">(</span><span class=\"n\">nums</span><span class=\"p\">)</span> <span class=\"o\">-</span> <span class=\"mi\">1</span><span class=\"p\">)</span> <span class=\"k\">def</span> <span class=\"nf\">quicksort</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">arr</span><span class=\"p\">,</span> <span class=\"n\">left</span><span class=\"p\">,</span> <span class=\"n\">right</span><span class=\"p\">):</span> <span class=\"k\">if</span> <span class=\"n\">left</span> <span class=\"o\"><</span> <span class=\"n\">right</span><span class=\"p\">:</span> <span class=\"n\">partition_pos</span> <span class=\"o\">=</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"nf\">partition</span><span class=\"p\">(</span><span class=\"n\">arr</span><span class=\"p\">,</span> <span class=\"n\">left</span><span class=\"p\">,</span> <span class=\"n\">right</span><span class=\"p\">)</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"nf\">quicksort</span><span class=\"p\">(</span><span class=\"n\">arr</span><span class=\"p\">,</span> <span class=\"n\">left</span><span class=\"p\">,</span> <span class=\"n\">partition_pos</span> <span class=\"o\">-</span> <span class=\"mi\">1</span><span class=\"p\">)</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"nf\">quicksort</span><span class=\"p\">(</span><span class=\"n\">arr</span><span class=\"p\">,</span> <span class=\"n\">partition_pos</span> <span class=\"o\">+</span> <span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"n\">right</span><span class=\"p\">)</span> <span class=\"k\">def</span> <span class=\"nf\">partition</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">arr</span><span class=\"p\">,</span> <span class=\"n\">left</span><span class=\"p\">,</span> <span class=\"n\">right</span><span class=\"p\">):</span> <span class=\"n\">i</span> <span class=\"o\">=</span> <span class=\"n\">left</span> <span class=\"n\">j</span> <span class=\"o\">=</span> <span class=\"n\">right</span> <span class=\"o\">-</span> <span class=\"mi\">1</span> <span class=\"n\">pivot</span> <span class=\"o\">=</span> <span class=\"n\">arr</span><span class=\"p\">[</span><span class=\"n\">right</span><span class=\"p\">]</span> <span class=\"k\">while</span> <span class=\"n\">i</span> <span class=\"o\"><</span> <span class=\"n\">j</span><span class=\"p\">:</span> <span class=\"k\">while</span> <span class=\"n\">i</span> <span class=\"o\"><</span> <span class=\"n\">right</span> <span class=\"ow\">and</span> <span class=\"n\">arr</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">]</span> <span class=\"o\"><</span> <span class=\"n\">pivot</span><span class=\"p\">:</span> <span class=\"n\">i</span> <span class=\"o\">+=</span> <span class=\"mi\">1</span> <span class=\"k\">while</span> <span class=\"n\">j</span> <span class=\"o\">></span> <span class=\"n\">left</span> <span class=\"ow\">and</span> <span class=\"n\">arr</span><span class=\"p\">[</span><span class=\"n\">j</span><span class=\"p\">]</span> <span class=\"o\">>=</span> <span class=\"n\">pivot</span><span class=\"p\">:</span> <span class=\"n\">j</span> <span class=\"o\">-=</span> <span class=\"mi\">1</span> <span class=\"k\">if</span> <span class=\"n\">i</span> <span class=\"o\"><</span> <span class=\"n\">j</span><span class=\"p\">:</span> <span class=\"n\">arr</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">],</span> <span class=\"n\">arr</span><span class=\"p\">[</span><span class=\"n\">j</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">arr</span><span class=\"p\">[</span><span class=\"n\">j</span><span class=\"p\">],</span> <span class=\"n\">arr</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">]</span> <span class=\"k\">if</span> <span class=\"n\">arr</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">]</span> <span class=\"o\">></span> <span class=\"n\">pivot</span><span class=\"p\">:</span> <span class=\"n\">arr</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">],</span> <span class=\"n\">arr</span><span class=\"p\">[</span><span class=\"n\">right</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">arr</span><span class=\"p\">[</span><span class=\"n\">right</span><span class=\"p\">],</span> <span class=\"n\">arr</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">]</span> <span class=\"k\">return</span> <span class=\"n\">i</span><span class=\"k\">if</span> <span class=\"n\">__name__</span> <span class=\"o\">==</span> <span class=\"sh\">'</span><span class=\"s\">__main__</span><span class=\"sh\">'</span><span class=\"p\">:</span> <span class=\"n\">s</span> <span class=\"o\">=</span> <span class=\"nc\">Solution</span><span class=\"p\">().</span><span class=\"n\">sortColors</span> <span class=\"c1\"># print(s([2,0,2,1,1,0]), [0,0,1,1,2,2])</span> <span class=\"n\">l</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"mi\">2</span><span class=\"p\">,</span><span class=\"mi\">0</span><span class=\"p\">,</span><span class=\"mi\">1</span><span class=\"p\">]</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">(</span><span class=\"n\">l</span><span class=\"p\">),</span> <span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">,</span><span class=\"mi\">1</span><span class=\"p\">,</span><span class=\"mi\">2</span><span class=\"p\">])</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"n\">l</span><span class=\"p\">)</span></code></pre></figure><p>Runtime: 70 ms, faster than 12.05% of Python3 online submissions for Sort Colors. Memory Usage: 13.8 MB, less than 64.59% of Python3 online submissions for Sort Colors.</p>", "date_published": "2022-10-09T20:00:00+00:00" }, { "id": "https://fewald.net/leetcode/2022/10/08/leetcode-find-first-and-last-position-of-element-in-sorted-arrays.html", "url": "https://fewald.net/leetcode/2022/10/08/leetcode-find-first-and-last-position-of-element-in-sorted-arrays.html", "title": "Leetcode: Find first and last position of element in sorted arrays", "content_html": "<p>Given a list of ascending sorted numbers, find the first and last occurrence of a <code class=\"language-plaintext highlighter-rouge\">target</code> number. For example for the list <code class=\"language-plaintext highlighter-rouge\">[1,2,2,3,4]</code> and <code class=\"language-plaintext highlighter-rouge\">target = 2</code>, the result would be <code class=\"language-plaintext highlighter-rouge\">[1,2]</code>. If the <code class=\"language-plaintext highlighter-rouge\">target</code> number is not in the array, return <code class=\"language-plaintext highlighter-rouge\">[-1,-1]</code>.</p><!--more--><p>We can solve this problem by using two binary searches. The first search finds the beginning and the second binary search finds the end of the <code class=\"language-plaintext highlighter-rouge\">target</code> number. The default binary search algorithm is slightly modified. If the <code class=\"language-plaintext highlighter-rouge\">target</code> element is found, the <code class=\"language-plaintext highlighter-rouge\">high</code> position gets lowered to the current target <code class=\"language-plaintext highlighter-rouge\">mid - 1</code> position. Then the new comparison is made between half the new <code class=\"language-plaintext highlighter-rouge\">mid</code> position which is between <code class=\"language-plaintext highlighter-rouge\">low</code> and <code class=\"language-plaintext highlighter-rouge\">high</code>.</p><p>For the second loop, this comparison is turned around and the <code class=\"language-plaintext highlighter-rouge\">low</code> point is set to <code class=\"language-plaintext highlighter-rouge\">mid + 1</code> until the end of the chain is found.</p><figure class=\"highlight\"><pre><code class=\"language-python\" data-lang=\"python\"><span class=\"kn\">from</span> <span class=\"n\">typing</span> <span class=\"kn\">import</span> <span class=\"n\">List</span><span class=\"k\">class</span> <span class=\"nc\">Solution</span><span class=\"p\">:</span> <span class=\"k\">def</span> <span class=\"nf\">searchRange</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">nums</span><span class=\"p\">:</span> <span class=\"n\">List</span><span class=\"p\">[</span><span class=\"nb\">int</span><span class=\"p\">],</span> <span class=\"n\">target</span><span class=\"p\">:</span> <span class=\"nb\">int</span><span class=\"p\">)</span> <span class=\"o\">-></span> <span class=\"n\">List</span><span class=\"p\">[</span><span class=\"nb\">int</span><span class=\"p\">]:</span> <span class=\"n\">res</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">]</span> <span class=\"n\">low</span> <span class=\"o\">=</span> <span class=\"mi\">0</span> <span class=\"n\">mid</span> <span class=\"o\">=</span> <span class=\"mi\">0</span> <span class=\"n\">high</span> <span class=\"o\">=</span> <span class=\"nf\">len</span><span class=\"p\">(</span><span class=\"n\">nums</span><span class=\"p\">)</span> <span class=\"o\">-</span> <span class=\"mi\">1</span> <span class=\"k\">while</span> <span class=\"n\">low</span> <span class=\"o\"><=</span> <span class=\"n\">high</span><span class=\"p\">:</span> <span class=\"n\">mid</span> <span class=\"o\">=</span> <span class=\"p\">(</span><span class=\"n\">high</span> <span class=\"o\">+</span> <span class=\"n\">low</span><span class=\"p\">)</span> <span class=\"o\">//</span> <span class=\"mi\">2</span> <span class=\"c1\"># Integer floor division</span> <span class=\"k\">if</span> <span class=\"n\">nums</span><span class=\"p\">[</span><span class=\"n\">mid</span><span class=\"p\">]</span> <span class=\"o\">==</span> <span class=\"n\">target</span><span class=\"p\">:</span> <span class=\"n\">high</span> <span class=\"o\">=</span> <span class=\"n\">mid</span> <span class=\"o\">-</span> <span class=\"mi\">1</span> <span class=\"n\">res</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">mid</span> <span class=\"k\">elif</span> <span class=\"n\">nums</span><span class=\"p\">[</span><span class=\"n\">mid</span><span class=\"p\">]</span> <span class=\"o\"><</span> <span class=\"n\">target</span><span class=\"p\">:</span> <span class=\"n\">low</span> <span class=\"o\">=</span> <span class=\"n\">mid</span> <span class=\"o\">+</span> <span class=\"mi\">1</span> <span class=\"k\">else</span><span class=\"p\">:</span> <span class=\"n\">high</span> <span class=\"o\">=</span> <span class=\"n\">mid</span> <span class=\"o\">-</span> <span class=\"mi\">1</span> <span class=\"n\">low</span> <span class=\"o\">=</span> <span class=\"mi\">0</span> <span class=\"n\">high</span> <span class=\"o\">=</span> <span class=\"nf\">len</span><span class=\"p\">(</span><span class=\"n\">nums</span><span class=\"p\">)</span> <span class=\"o\">-</span> <span class=\"mi\">1</span> <span class=\"n\">mid</span> <span class=\"o\">=</span> <span class=\"mi\">0</span> <span class=\"k\">while</span> <span class=\"n\">low</span> <span class=\"o\"><=</span> <span class=\"n\">high</span><span class=\"p\">:</span> <span class=\"n\">mid</span> <span class=\"o\">=</span> <span class=\"p\">(</span><span class=\"n\">low</span> <span class=\"o\">+</span> <span class=\"n\">high</span><span class=\"p\">)</span> <span class=\"o\">//</span> <span class=\"mi\">2</span> <span class=\"c1\"># Integer floor division</span> <span class=\"k\">if</span> <span class=\"n\">nums</span><span class=\"p\">[</span><span class=\"n\">mid</span><span class=\"p\">]</span> <span class=\"o\">==</span> <span class=\"n\">target</span><span class=\"p\">:</span> <span class=\"n\">low</span> <span class=\"o\">=</span> <span class=\"n\">mid</span> <span class=\"o\">+</span> <span class=\"mi\">1</span> <span class=\"n\">res</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">mid</span> <span class=\"k\">elif</span> <span class=\"n\">nums</span><span class=\"p\">[</span><span class=\"n\">mid</span><span class=\"p\">]</span> <span class=\"o\"><</span> <span class=\"n\">target</span><span class=\"p\">:</span> <span class=\"n\">low</span> <span class=\"o\">=</span> <span class=\"n\">mid</span> <span class=\"o\">+</span> <span class=\"mi\">1</span> <span class=\"k\">else</span><span class=\"p\">:</span> <span class=\"n\">high</span> <span class=\"o\">=</span> <span class=\"n\">mid</span> <span class=\"o\">-</span> <span class=\"mi\">1</span> <span class=\"k\">return</span> <span class=\"n\">res</span><span class=\"k\">if</span> <span class=\"n\">__name__</span> <span class=\"o\">==</span> <span class=\"sh\">'</span><span class=\"s\">__main__</span><span class=\"sh\">'</span><span class=\"p\">:</span> <span class=\"n\">s</span> <span class=\"o\">=</span> <span class=\"nc\">Solution</span><span class=\"p\">().</span><span class=\"n\">searchRange</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">([</span><span class=\"mi\">5</span><span class=\"p\">,</span><span class=\"mi\">7</span><span class=\"p\">,</span><span class=\"mi\">7</span><span class=\"p\">,</span><span class=\"mi\">8</span><span class=\"p\">,</span><span class=\"mi\">8</span><span class=\"p\">,</span><span class=\"mi\">10</span><span class=\"p\">],</span> <span class=\"mi\">8</span><span class=\"p\">),</span> <span class=\"p\">[</span><span class=\"mi\">3</span><span class=\"p\">,</span><span class=\"mi\">4</span><span class=\"p\">])</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">([</span><span class=\"mi\">5</span><span class=\"p\">,</span><span class=\"mi\">6</span><span class=\"p\">,</span><span class=\"mi\">7</span><span class=\"p\">,</span><span class=\"mi\">7</span><span class=\"p\">,</span><span class=\"mi\">8</span><span class=\"p\">,</span><span class=\"mi\">8</span><span class=\"p\">,</span><span class=\"mi\">10</span><span class=\"p\">],</span> <span class=\"mi\">8</span><span class=\"p\">),</span> <span class=\"p\">[</span><span class=\"mi\">4</span><span class=\"p\">,</span><span class=\"mi\">5</span><span class=\"p\">])</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">([</span><span class=\"mi\">5</span><span class=\"p\">,</span><span class=\"mi\">6</span><span class=\"p\">,</span><span class=\"mi\">7</span><span class=\"p\">,</span><span class=\"mi\">7</span><span class=\"p\">,</span><span class=\"mi\">8</span><span class=\"p\">,</span><span class=\"mi\">8</span><span class=\"p\">,</span><span class=\"mi\">10</span><span class=\"p\">,</span><span class=\"mi\">11</span><span class=\"p\">],</span> <span class=\"mi\">8</span><span class=\"p\">),</span> <span class=\"p\">[</span><span class=\"mi\">4</span><span class=\"p\">,</span><span class=\"mi\">5</span><span class=\"p\">])</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">([</span><span class=\"mi\">5</span><span class=\"p\">,</span><span class=\"mi\">7</span><span class=\"p\">,</span><span class=\"mi\">7</span><span class=\"p\">,</span><span class=\"mi\">8</span><span class=\"p\">,</span><span class=\"mi\">8</span><span class=\"p\">,</span><span class=\"mi\">10</span><span class=\"p\">],</span> <span class=\"mi\">6</span><span class=\"p\">),</span> <span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">,</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">])</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">([</span><span class=\"mi\">1</span><span class=\"p\">,</span><span class=\"mi\">2</span><span class=\"p\">,</span><span class=\"mi\">3</span><span class=\"p\">,</span><span class=\"mi\">4</span><span class=\"p\">],</span> <span class=\"mi\">1</span><span class=\"p\">),</span> <span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">,</span><span class=\"mi\">0</span><span class=\"p\">])</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">([</span><span class=\"mi\">1</span><span class=\"p\">,</span><span class=\"mi\">2</span><span class=\"p\">,</span><span class=\"mi\">2</span><span class=\"p\">,</span><span class=\"mi\">3</span><span class=\"p\">,</span><span class=\"mi\">4</span><span class=\"p\">],</span> <span class=\"mi\">2</span><span class=\"p\">),</span> <span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">,</span><span class=\"mi\">2</span><span class=\"p\">])</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">([</span><span class=\"mi\">1</span><span class=\"p\">,</span><span class=\"mi\">2</span><span class=\"p\">,</span><span class=\"mi\">3</span><span class=\"p\">,</span><span class=\"mi\">4</span><span class=\"p\">],</span> <span class=\"mi\">0</span><span class=\"p\">),</span> <span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">,</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">])</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">([],</span> <span class=\"mi\">1</span><span class=\"p\">),</span> <span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">,</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">])</span></code></pre></figure><blockquote> <p>Runtime: 185 ms, faster than 7.30% of Python3 online submissions for Find First and Last Position of Element in Sorted Array. Memory Usage: 15.5 MB, less than 48.10% of Python3 online submissions for Find First and Last Position of Element in Sorted Array.</p></blockquote><p>If the standard library of Python can be utilized, the whole solution becomes a lot simpler. Using <code class=\"language-plaintext highlighter-rouge\">bisect</code> allows us to perform binary search by passing the sorted array and the target. It is important to note that <code class=\"language-plaintext highlighter-rouge\">bisect_right</code> returns one position to the right of the candidate and not the target itself. We can decrement the number by <code class=\"language-plaintext highlighter-rouge\">1</code> to get the actual index. This is safe because we made sure that the number exists by first calling <code class=\"language-plaintext highlighter-rouge\">bisect_left</code>. This method returns the position of the index if it’s in the array. There are two special cases that need to be handled.</p><ol> <li>If all numbers are smaller, then the index is the <code class=\"language-plaintext highlighter-rouge\">len(nums)</code>. In this case we immediately know that the number is not part of the array and can return <code class=\"language-plaintext highlighter-rouge\">[-1, -1]</code>.</li> <li>If the resulting number is <code class=\"language-plaintext highlighter-rouge\">0</code>, we need to check if the number at this position is equal to the number that we are looking for. If that is not the case, we can also immediately return <code class=\"language-plaintext highlighter-rouge\">[-1, -1]</code>.</li></ol><figure class=\"highlight\"><pre><code class=\"language-python\" data-lang=\"python\"><span class=\"kn\">from</span> <span class=\"n\">typing</span> <span class=\"kn\">import</span> <span class=\"n\">List</span><span class=\"kn\">import</span> <span class=\"n\">bisect</span><span class=\"k\">class</span> <span class=\"nc\">Solution</span><span class=\"p\">:</span> <span class=\"k\">def</span> <span class=\"nf\">searchRange</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">nums</span><span class=\"p\">:</span> <span class=\"n\">List</span><span class=\"p\">[</span><span class=\"nb\">int</span><span class=\"p\">],</span> <span class=\"n\">target</span><span class=\"p\">:</span> <span class=\"nb\">int</span><span class=\"p\">)</span> <span class=\"o\">-></span> <span class=\"n\">List</span><span class=\"p\">[</span><span class=\"nb\">int</span><span class=\"p\">]:</span> <span class=\"n\">pos_l</span> <span class=\"o\">=</span> <span class=\"n\">bisect</span><span class=\"p\">.</span><span class=\"nf\">bisect_left</span><span class=\"p\">(</span><span class=\"n\">nums</span><span class=\"p\">,</span> <span class=\"n\">target</span><span class=\"p\">)</span> <span class=\"k\">if</span> <span class=\"n\">pos_l</span> <span class=\"o\">==</span> <span class=\"nf\">len</span><span class=\"p\">(</span><span class=\"n\">nums</span><span class=\"p\">)</span> <span class=\"ow\">or</span> <span class=\"n\">nums</span><span class=\"p\">[</span><span class=\"n\">pos_l</span><span class=\"p\">]</span> <span class=\"o\">!=</span> <span class=\"n\">target</span><span class=\"p\">:</span> <span class=\"k\">return</span> <span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">]</span> <span class=\"n\">pos_r</span> <span class=\"o\">=</span> <span class=\"n\">bisect</span><span class=\"p\">.</span><span class=\"nf\">bisect_right</span><span class=\"p\">(</span><span class=\"n\">nums</span><span class=\"p\">,</span> <span class=\"n\">target</span><span class=\"p\">)</span> <span class=\"k\">return</span> <span class=\"p\">[</span><span class=\"n\">pos_l</span><span class=\"p\">,</span> <span class=\"n\">pos_r</span> <span class=\"o\">-</span> <span class=\"mi\">1</span><span class=\"p\">]</span><span class=\"k\">if</span> <span class=\"n\">__name__</span> <span class=\"o\">==</span> <span class=\"sh\">'</span><span class=\"s\">__main__</span><span class=\"sh\">'</span><span class=\"p\">:</span> <span class=\"n\">s</span> <span class=\"o\">=</span> <span class=\"nc\">Solution</span><span class=\"p\">().</span><span class=\"n\">searchRange</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">([</span><span class=\"mi\">5</span><span class=\"p\">,</span><span class=\"mi\">7</span><span class=\"p\">,</span><span class=\"mi\">7</span><span class=\"p\">,</span><span class=\"mi\">8</span><span class=\"p\">,</span><span class=\"mi\">8</span><span class=\"p\">,</span><span class=\"mi\">10</span><span class=\"p\">],</span> <span class=\"mi\">8</span><span class=\"p\">),</span> <span class=\"p\">[</span><span class=\"mi\">3</span><span class=\"p\">,</span><span class=\"mi\">4</span><span class=\"p\">])</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">([</span><span class=\"mi\">5</span><span class=\"p\">,</span><span class=\"mi\">7</span><span class=\"p\">,</span><span class=\"mi\">7</span><span class=\"p\">,</span><span class=\"mi\">8</span><span class=\"p\">,</span><span class=\"mi\">8</span><span class=\"p\">,</span><span class=\"mi\">10</span><span class=\"p\">],</span> <span class=\"mi\">6</span><span class=\"p\">),</span> <span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">,</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">])</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">([</span><span class=\"mi\">1</span><span class=\"p\">,</span><span class=\"mi\">2</span><span class=\"p\">,</span><span class=\"mi\">3</span><span class=\"p\">,</span><span class=\"mi\">4</span><span class=\"p\">],</span> <span class=\"mi\">1</span><span class=\"p\">),</span> <span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">,</span><span class=\"mi\">0</span><span class=\"p\">])</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">([</span><span class=\"mi\">1</span><span class=\"p\">,</span><span class=\"mi\">2</span><span class=\"p\">,</span><span class=\"mi\">2</span><span class=\"p\">,</span><span class=\"mi\">3</span><span class=\"p\">,</span><span class=\"mi\">4</span><span class=\"p\">],</span> <span class=\"mi\">2</span><span class=\"p\">),</span> <span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">,</span><span class=\"mi\">2</span><span class=\"p\">])</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">([</span><span class=\"mi\">1</span><span class=\"p\">,</span><span class=\"mi\">2</span><span class=\"p\">,</span><span class=\"mi\">3</span><span class=\"p\">,</span><span class=\"mi\">4</span><span class=\"p\">],</span> <span class=\"mi\">0</span><span class=\"p\">),</span> <span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">,</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">])</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">([],</span> <span class=\"mi\">1</span><span class=\"p\">),</span> <span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">,</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">])</span> </code></pre></figure><blockquote> <p>Runtime: 156 ms, faster than 28.55% of Python3 online submissions for Find First and Last Position of Element in Sorted Array. Memory Usage: 15.5 MB, less than 9.48% of Python3 online submissions for Find First and Last Position of Element in Sorted Array.</p></blockquote>", "date_published": "2022-10-08T20:00:00+00:00" }, { "id": "https://fewald.net/leetcode/2022/10/07/leetcode-three-sum.html", "url": "https://fewald.net/leetcode/2022/10/07/leetcode-three-sum.html", "title": "Leetcode: Three sum", "content_html": "<p>Given a list of integers, add three integers at the same time so that the sum of those integers is <code class=\"language-plaintext highlighter-rouge\">0</code>. There should be no repetition of integers, for example <code class=\"language-plaintext highlighter-rouge\">[-1, 0, 1]</code> is equivalent to <code class=\"language-plaintext highlighter-rouge\">[-1, 1, 0]</code>.</p><!--more--><p>The solution makes use of the fact that duplicate numbers can be ignored. To do this, the numbers need to be sorted first. Then, if the next number is the same as the previous, it can be skipped. This does not affect the number of the other pointers, thus there can be the same number in different pointers.</p><p>In total there are two loops needed. The outer loop iterates from the smallest to the third-largest number. For every iteration, a pointer <code class=\"language-plaintext highlighter-rouge\">p2</code> and <code class=\"language-plaintext highlighter-rouge\">p3</code> are defined. The pointer <code class=\"language-plaintext highlighter-rouge\">p2</code> starts directly one position right of <code class=\"language-plaintext highlighter-rouge\">p1</code> while <code class=\"language-plaintext highlighter-rouge\">p3</code> starts at the end of the list.</p><p>We then need to distinguish three cases. If the sum is exactly <code class=\"language-plaintext highlighter-rouge\">0</code>, we can add the item to the results. If it is greater than <code class=\"language-plaintext highlighter-rouge\">0</code>, we move the pointer <code class=\"language-plaintext highlighter-rouge\">p3</code> to the left which makes the number smaller. If it is less than <code class=\"language-plaintext highlighter-rouge\">0</code>, we move <code class=\"language-plaintext highlighter-rouge\">p2</code> to the right which increases the total sum. We continue this approach until <code class=\"language-plaintext highlighter-rouge\">p2</code> and <code class=\"language-plaintext highlighter-rouge\">p3</code> meet, then continue with the outer iteration. Additionally, there is some logic to deal with duplicates.</p><figure class=\"highlight\"><pre><code class=\"language-python\" data-lang=\"python\"><span class=\"kn\">from</span> <span class=\"n\">typing</span> <span class=\"kn\">import</span> <span class=\"n\">List</span><span class=\"k\">class</span> <span class=\"nc\">Solution</span><span class=\"p\">:</span> <span class=\"k\">def</span> <span class=\"nf\">threeSum</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">nums</span><span class=\"p\">:</span> <span class=\"n\">List</span><span class=\"p\">[</span><span class=\"nb\">int</span><span class=\"p\">])</span> <span class=\"o\">-></span> <span class=\"n\">List</span><span class=\"p\">[</span><span class=\"n\">List</span><span class=\"p\">[</span><span class=\"nb\">int</span><span class=\"p\">]]:</span> <span class=\"c1\"># Sort in place</span> <span class=\"n\">nums</span><span class=\"p\">.</span><span class=\"nf\">sort</span><span class=\"p\">()</span> <span class=\"n\">result</span> <span class=\"o\">=</span> <span class=\"p\">[]</span> <span class=\"k\">for</span> <span class=\"n\">p1</span> <span class=\"ow\">in</span> <span class=\"nf\">range</span><span class=\"p\">(</span><span class=\"nf\">len</span><span class=\"p\">(</span><span class=\"n\">nums</span><span class=\"p\">)</span> <span class=\"o\">-</span> <span class=\"mi\">2</span><span class=\"p\">):</span> <span class=\"k\">if</span> <span class=\"n\">p1</span> <span class=\"o\">></span> <span class=\"mi\">0</span> <span class=\"ow\">and</span> <span class=\"n\">nums</span><span class=\"p\">[</span><span class=\"n\">p1</span><span class=\"p\">]</span> <span class=\"o\">==</span> <span class=\"n\">nums</span><span class=\"p\">[</span><span class=\"n\">p1</span> <span class=\"o\">-</span> <span class=\"mi\">1</span><span class=\"p\">]:</span> <span class=\"k\">continue</span> <span class=\"n\">p2</span> <span class=\"o\">=</span> <span class=\"n\">p1</span> <span class=\"o\">+</span> <span class=\"mi\">1</span> <span class=\"n\">p3</span> <span class=\"o\">=</span> <span class=\"nf\">len</span><span class=\"p\">(</span><span class=\"n\">nums</span><span class=\"p\">)</span> <span class=\"o\">-</span> <span class=\"mi\">1</span> <span class=\"k\">while</span> <span class=\"n\">p2</span> <span class=\"o\"><</span> <span class=\"n\">p3</span><span class=\"p\">:</span> <span class=\"n\">s</span> <span class=\"o\">=</span> <span class=\"n\">nums</span><span class=\"p\">[</span><span class=\"n\">p1</span><span class=\"p\">]</span> <span class=\"o\">+</span> <span class=\"n\">nums</span><span class=\"p\">[</span><span class=\"n\">p2</span><span class=\"p\">]</span> <span class=\"o\">+</span> <span class=\"n\">nums</span><span class=\"p\">[</span><span class=\"n\">p3</span><span class=\"p\">]</span> <span class=\"k\">if</span> <span class=\"n\">s</span> <span class=\"o\">==</span> <span class=\"mi\">0</span><span class=\"p\">:</span> <span class=\"n\">result</span> <span class=\"o\">+=</span> <span class=\"p\">[[</span><span class=\"n\">nums</span><span class=\"p\">[</span><span class=\"n\">p1</span><span class=\"p\">],</span> <span class=\"n\">nums</span><span class=\"p\">[</span><span class=\"n\">p2</span><span class=\"p\">],</span> <span class=\"n\">nums</span><span class=\"p\">[</span><span class=\"n\">p3</span><span class=\"p\">]]]</span> <span class=\"n\">p3</span> <span class=\"o\">-=</span> <span class=\"mi\">1</span> <span class=\"k\">while</span> <span class=\"n\">p2</span> <span class=\"o\"><</span> <span class=\"n\">p3</span> <span class=\"ow\">and</span> <span class=\"n\">nums</span><span class=\"p\">[</span><span class=\"n\">p3</span><span class=\"p\">]</span> <span class=\"o\">==</span> <span class=\"n\">nums</span><span class=\"p\">[</span><span class=\"n\">p3</span> <span class=\"o\">+</span> <span class=\"mi\">1</span><span class=\"p\">]:</span> <span class=\"n\">p3</span> <span class=\"o\">-=</span> <span class=\"mi\">1</span> <span class=\"k\">elif</span> <span class=\"n\">s</span> <span class=\"o\">></span> <span class=\"mi\">0</span><span class=\"p\">:</span> <span class=\"n\">p3</span> <span class=\"o\">-=</span> <span class=\"mi\">1</span> <span class=\"k\">else</span><span class=\"p\">:</span> <span class=\"n\">p2</span> <span class=\"o\">+=</span> <span class=\"mi\">1</span> <span class=\"k\">return</span> <span class=\"n\">result</span><span class=\"k\">if</span> <span class=\"n\">__name__</span> <span class=\"o\">==</span> <span class=\"sh\">'</span><span class=\"s\">__main__</span><span class=\"sh\">'</span><span class=\"p\">:</span> <span class=\"n\">s</span> <span class=\"o\">=</span> <span class=\"nc\">Solution</span><span class=\"p\">().</span><span class=\"n\">threeSum</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">([</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">,</span><span class=\"mi\">0</span><span class=\"p\">,</span><span class=\"mi\">1</span><span class=\"p\">,</span><span class=\"mi\">2</span><span class=\"p\">,</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">,</span><span class=\"o\">-</span><span class=\"mi\">4</span><span class=\"p\">]),</span> <span class=\"p\">[[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">,</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">,</span><span class=\"mi\">2</span><span class=\"p\">],[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">,</span><span class=\"mi\">0</span><span class=\"p\">,</span><span class=\"mi\">1</span><span class=\"p\">]])</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">([</span><span class=\"o\">-</span><span class=\"mi\">4</span><span class=\"p\">,</span><span class=\"o\">-</span><span class=\"mi\">2</span><span class=\"p\">,</span><span class=\"o\">-</span><span class=\"mi\">2</span><span class=\"p\">,</span><span class=\"o\">-</span><span class=\"mi\">2</span><span class=\"p\">,</span><span class=\"mi\">0</span><span class=\"p\">,</span><span class=\"mi\">1</span><span class=\"p\">,</span><span class=\"mi\">2</span><span class=\"p\">,</span><span class=\"mi\">2</span><span class=\"p\">,</span><span class=\"mi\">2</span><span class=\"p\">,</span><span class=\"mi\">3</span><span class=\"p\">,</span><span class=\"mi\">3</span><span class=\"p\">,</span><span class=\"mi\">4</span><span class=\"p\">,</span><span class=\"mi\">4</span><span class=\"p\">,</span><span class=\"mi\">6</span><span class=\"p\">,</span><span class=\"mi\">6</span><span class=\"p\">]),</span> <span class=\"p\">[[</span><span class=\"o\">-</span><span class=\"mi\">4</span><span class=\"p\">,</span> <span class=\"o\">-</span><span class=\"mi\">2</span><span class=\"p\">,</span> <span class=\"mi\">6</span><span class=\"p\">],</span> <span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">4</span><span class=\"p\">,</span> <span class=\"mi\">0</span><span class=\"p\">,</span> <span class=\"mi\">4</span><span class=\"p\">],</span> <span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">4</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">3</span><span class=\"p\">],</span> <span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">4</span><span class=\"p\">,</span> <span class=\"mi\">2</span><span class=\"p\">,</span> <span class=\"mi\">2</span><span class=\"p\">],</span> <span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">2</span><span class=\"p\">,</span> <span class=\"o\">-</span><span class=\"mi\">2</span><span class=\"p\">,</span> <span class=\"mi\">4</span><span class=\"p\">],</span> <span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">2</span><span class=\"p\">,</span> <span class=\"mi\">0</span><span class=\"p\">,</span> <span class=\"mi\">2</span><span class=\"p\">]])</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">([</span><span class=\"o\">-</span><span class=\"mi\">2</span><span class=\"p\">,</span><span class=\"mi\">0</span><span class=\"p\">,</span><span class=\"mi\">1</span><span class=\"p\">,</span><span class=\"mi\">1</span><span class=\"p\">,</span><span class=\"mi\">2</span><span class=\"p\">]),</span> <span class=\"p\">[[</span><span class=\"o\">-</span><span class=\"mi\">2</span><span class=\"p\">,</span><span class=\"mi\">0</span><span class=\"p\">,</span><span class=\"mi\">2</span><span class=\"p\">],[</span><span class=\"o\">-</span><span class=\"mi\">2</span><span class=\"p\">,</span><span class=\"mi\">1</span><span class=\"p\">,</span><span class=\"mi\">1</span><span class=\"p\">]])</span></code></pre></figure><p>Runtime: 1340 ms, faster than 50.64% of Python3 online submissions for 3Sum. Memory Usage: 18.2 MB, less than 39.78% of Python3 online submissions for 3Sum.</p>", "date_published": "2022-10-07T20:00:00+00:00" }, { "id": "https://fewald.net/leetcode/2022/10/06/leetcode-longest-consecutive-sequence.html", "url": "https://fewald.net/leetcode/2022/10/06/leetcode-longest-consecutive-sequence.html", "title": "Leetcode: Longest Consecutive Sequence", "content_html": "<p>From an unsorted array <code class=\"language-plaintext highlighter-rouge\">nums</code>, return the length of the longest consecutive sequence of numbers as an integer. For example, the list <code class=\"language-plaintext highlighter-rouge\">[100, 4, 200, 1, 3, 2]</code> would return <code class=\"language-plaintext highlighter-rouge\">4</code>, because the longest consecutive sequence is <code class=\"language-plaintext highlighter-rouge\">[1, 2, 3, 4]</code> with a length of <code class=\"language-plaintext highlighter-rouge\">4</code>. The algorithm should perform in <code class=\"language-plaintext highlighter-rouge\">O(n)</code>.</p><p>Not mentioned in the task is that there can be duplicates of numbers. They should be ignored. The main problem when developing this algorithm is for it to perform it in <code class=\"language-plaintext highlighter-rouge\">O(n)</code>. A brute force method is quite easy and works for smaller lists. The pseudo code looks like this:</p><figure class=\"highlight\"><pre><code class=\"language-plain\" data-lang=\"plain\">for every element in list while next element in list take next element increment counter by 1 endwhile return longest counterendfor</code></pre></figure><p>This approach works but is very time consuming with a complexity of <code class=\"language-plaintext highlighter-rouge\">O(n^2)</code>. This is because for every element in the list we need to possibly visit every other element in the list.</p><!--more--><p>A possible solution is listed below. We need to convert the list into a <code class=\"language-plaintext highlighter-rouge\">set</code> for faster access <code class=\"language-plaintext highlighter-rouge\">O(1)</code>. Then iterate over every number <code class=\"language-plaintext highlighter-rouge\">O(n)</code>. If the number is the smallest number in chain, we count up until we reach the end of the chain. With this approach we visit every number in the for loop exactly once and get a total time complexity of <code class=\"language-plaintext highlighter-rouge\">O(2n) -> O(n)</code>. The code below shows this algorithm.</p><figure class=\"highlight\"><pre><code class=\"language-python\" data-lang=\"python\"><span class=\"kn\">from</span> <span class=\"n\">typing</span> <span class=\"kn\">import</span> <span class=\"n\">List</span><span class=\"p\">,</span> <span class=\"n\">Optional</span><span class=\"k\">class</span> <span class=\"nc\">Solution</span><span class=\"p\">:</span> <span class=\"k\">def</span> <span class=\"nf\">longestConsecutive</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">nums</span><span class=\"p\">:</span> <span class=\"n\">List</span><span class=\"p\">[</span><span class=\"nb\">int</span><span class=\"p\">])</span> <span class=\"o\">-></span> <span class=\"nb\">int</span><span class=\"p\">:</span> <span class=\"c1\"># Copy all numbers to a set for O(1) access.</span> <span class=\"n\">m</span> <span class=\"o\">=</span> <span class=\"nf\">set</span><span class=\"p\">()</span> <span class=\"n\">longest</span> <span class=\"o\">=</span> <span class=\"mi\">0</span> <span class=\"k\">for</span> <span class=\"n\">n</span> <span class=\"ow\">in</span> <span class=\"n\">nums</span><span class=\"p\">:</span> <span class=\"n\">m</span><span class=\"p\">.</span><span class=\"nf\">add</span><span class=\"p\">(</span><span class=\"n\">n</span><span class=\"p\">)</span> <span class=\"k\">for</span> <span class=\"n\">n</span> <span class=\"ow\">in</span> <span class=\"n\">m</span><span class=\"p\">:</span> <span class=\"c1\"># Only iterate if the element is the smallest of the particular chain</span> <span class=\"k\">if</span> <span class=\"n\">n</span> <span class=\"o\">-</span> <span class=\"mi\">1</span> <span class=\"ow\">not</span> <span class=\"ow\">in</span> <span class=\"n\">m</span><span class=\"p\">:</span> <span class=\"c1\"># Initialize counter</span> <span class=\"n\">current</span> <span class=\"o\">=</span> <span class=\"mi\">0</span> <span class=\"k\">while</span> <span class=\"n\">n</span> <span class=\"o\">+</span> <span class=\"n\">current</span> <span class=\"ow\">in</span> <span class=\"n\">m</span><span class=\"p\">:</span> <span class=\"n\">current</span> <span class=\"o\">+=</span> <span class=\"mi\">1</span> <span class=\"n\">longest</span> <span class=\"o\">=</span> <span class=\"nf\">max</span><span class=\"p\">(</span><span class=\"n\">longest</span><span class=\"p\">,</span> <span class=\"n\">current</span><span class=\"p\">)</span> <span class=\"k\">return</span> <span class=\"n\">longest</span><span class=\"k\">if</span> <span class=\"n\">__name__</span> <span class=\"o\">==</span> <span class=\"sh\">'</span><span class=\"s\">__main__</span><span class=\"sh\">'</span><span class=\"p\">:</span> <span class=\"n\">s</span> <span class=\"o\">=</span> <span class=\"nc\">Solution</span><span class=\"p\">().</span><span class=\"n\">longestConsecutive</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">([</span><span class=\"mi\">100</span><span class=\"p\">,</span><span class=\"mi\">4</span><span class=\"p\">,</span> <span class=\"mi\">200</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">3</span><span class=\"p\">,</span> <span class=\"mi\">2</span><span class=\"p\">]),</span> <span class=\"mi\">4</span><span class=\"p\">)</span> <span class=\"c1\"># [1, 2, 3, 4]</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">([</span><span class=\"mi\">1</span><span class=\"p\">]),</span> <span class=\"mi\">1</span><span class=\"p\">)</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">([]),</span> <span class=\"mi\">0</span><span class=\"p\">)</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">([</span><span class=\"mi\">1</span><span class=\"p\">,</span><span class=\"mi\">2</span><span class=\"p\">,</span><span class=\"mi\">3</span><span class=\"p\">,</span><span class=\"mi\">4</span><span class=\"p\">]),</span> <span class=\"mi\">4</span><span class=\"p\">)</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">([</span><span class=\"mi\">1</span><span class=\"p\">,</span><span class=\"mi\">2</span><span class=\"p\">,</span><span class=\"mi\">3</span><span class=\"p\">,</span><span class=\"mi\">4</span><span class=\"p\">,</span><span class=\"mi\">6</span><span class=\"p\">,</span><span class=\"mi\">7</span><span class=\"p\">,</span><span class=\"mi\">5</span><span class=\"p\">]),</span> <span class=\"mi\">7</span><span class=\"p\">)</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">([</span><span class=\"mi\">4</span><span class=\"p\">,</span><span class=\"mi\">3</span><span class=\"p\">,</span><span class=\"mi\">2</span><span class=\"p\">,</span><span class=\"mi\">1</span><span class=\"p\">]),</span> <span class=\"mi\">4</span><span class=\"p\">)</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">([</span><span class=\"mi\">3</span><span class=\"p\">,</span><span class=\"mi\">4</span><span class=\"p\">,</span><span class=\"mi\">1</span><span class=\"p\">,</span><span class=\"mi\">2</span><span class=\"p\">]),</span> <span class=\"mi\">4</span><span class=\"p\">)</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">([</span><span class=\"mi\">0</span><span class=\"p\">,</span><span class=\"mi\">3</span><span class=\"p\">,</span><span class=\"mi\">7</span><span class=\"p\">,</span><span class=\"mi\">2</span><span class=\"p\">,</span><span class=\"mi\">5</span><span class=\"p\">,</span><span class=\"mi\">8</span><span class=\"p\">,</span><span class=\"mi\">4</span><span class=\"p\">,</span><span class=\"mi\">6</span><span class=\"p\">,</span><span class=\"mi\">0</span><span class=\"p\">,</span><span class=\"mi\">1</span><span class=\"p\">]),</span> <span class=\"mi\">9</span><span class=\"p\">)</span></code></pre></figure><p>Runtime: 632 ms, faster than 50.27% of Python3 online submissions for Longest Consecutive Sequence. Memory Usage: 28.9 MB, less than 39.00% of Python3 online submissions for Longest Consecutive Sequence.</p>", "date_published": "2022-10-06T20:00:00+00:00" }, { "id": "https://fewald.net/leetcode/2022/10/05/leetcode-happy-number.html", "url": "https://fewald.net/leetcode/2022/10/05/leetcode-happy-number.html", "title": "Leetcode: Happy number", "content_html": "<blockquote> <p>Write an algorithm to determine if a number <code class=\"language-plaintext highlighter-rouge\">n</code> is happy.</p> <p>A happy number is a number defined by the following process:</p> <p>Starting with any positive integer, replace the number by the sum of the squares of its digits. Repeat the process until the number equals 1 (where it will stay), or it loops endlessly in a cycle which does not include 1. Those numbers for which this process ends in 1 are happy.</p> <p>Return <code class=\"language-plaintext highlighter-rouge\">true</code> if <code class=\"language-plaintext highlighter-rouge\">n</code> is a happy number, and <code class=\"language-plaintext highlighter-rouge\">false</code> if not.</p></blockquote><p>For example, the number <code class=\"language-plaintext highlighter-rouge\">19</code> is divided into <code class=\"language-plaintext highlighter-rouge\">1^2</code> and <code class=\"language-plaintext highlighter-rouge\">9^2</code>, then added together as <code class=\"language-plaintext highlighter-rouge\">82</code>, then divided again, etc. After some iterations this reaches <code class=\"language-plaintext highlighter-rouge\">100</code> which is <code class=\"language-plaintext highlighter-rouge\">1^2 + 0^2 + 0^2 = 1</code>. On the other hand, <code class=\"language-plaintext highlighter-rouge\">2</code> keeps ever incremententing.</p><p>The programming aspect is relatively easy to solve in Python when converting the types to a string and then converting the string to a list.</p><!--more--><p>When solving this problem I recommend to first focus on the loop that eventually reaches to <code class=\"language-plaintext highlighter-rouge\">100</code> and implement the valid case. Once this is done, one can print out the numbers that get visited when using the same algorithm with <code class=\"language-plaintext highlighter-rouge\">2</code>. It becomes obvious that the chain of visited numbers looks something like this: <code class=\"language-plaintext highlighter-rouge\">2 -> 4 -> ... -> 4</code>.</p><p>With this observation we know that invalid numbers have loops and we can use a <code class=\"language-plaintext highlighter-rouge\">set</code> to detect if we encounter a loop.</p><figure class=\"highlight\"><pre><code class=\"language-python\" data-lang=\"python\"><span class=\"k\">class</span> <span class=\"nc\">Solution</span><span class=\"p\">:</span> <span class=\"k\">def</span> <span class=\"nf\">isHappy</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">n</span><span class=\"p\">:</span> <span class=\"nb\">int</span><span class=\"p\">)</span> <span class=\"o\">-></span> <span class=\"nb\">bool</span><span class=\"p\">:</span> <span class=\"n\">seen</span> <span class=\"o\">=</span> <span class=\"nf\">set</span><span class=\"p\">()</span> <span class=\"n\">n</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"o\">*</span><span class=\"nf\">str</span><span class=\"p\">(</span><span class=\"n\">n</span><span class=\"p\">)]</span> <span class=\"k\">while</span> <span class=\"n\">n</span> <span class=\"o\">!=</span> <span class=\"p\">[</span><span class=\"sh\">'</span><span class=\"s\">1</span><span class=\"sh\">'</span><span class=\"p\">]:</span> <span class=\"n\">s</span> <span class=\"o\">=</span> <span class=\"mi\">0</span> <span class=\"k\">for</span> <span class=\"n\">i</span> <span class=\"ow\">in</span> <span class=\"n\">n</span><span class=\"p\">:</span> <span class=\"n\">s</span> <span class=\"o\">+=</span> <span class=\"nf\">int</span><span class=\"p\">(</span><span class=\"n\">i</span><span class=\"p\">)</span> <span class=\"o\">**</span> <span class=\"mi\">2</span> <span class=\"k\">if</span> <span class=\"n\">s</span> <span class=\"ow\">in</span> <span class=\"n\">seen</span><span class=\"p\">:</span> <span class=\"k\">return</span> <span class=\"bp\">False</span> <span class=\"n\">seen</span><span class=\"p\">.</span><span class=\"nf\">add</span><span class=\"p\">(</span><span class=\"n\">s</span><span class=\"p\">)</span> <span class=\"n\">n</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"o\">*</span><span class=\"nf\">str</span><span class=\"p\">(</span><span class=\"n\">s</span><span class=\"p\">)]</span> <span class=\"k\">return</span> <span class=\"bp\">True</span><span class=\"k\">if</span> <span class=\"n\">__name__</span> <span class=\"o\">==</span> <span class=\"sh\">'</span><span class=\"s\">__main__</span><span class=\"sh\">'</span><span class=\"p\">:</span> <span class=\"n\">s</span> <span class=\"o\">=</span> <span class=\"nc\">Solution</span><span class=\"p\">().</span><span class=\"n\">isHappy</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">(</span><span class=\"mi\">19</span><span class=\"p\">),</span> <span class=\"bp\">True</span><span class=\"p\">)</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">(</span><span class=\"mi\">2</span><span class=\"p\">),</span> <span class=\"bp\">False</span><span class=\"p\">)</span></code></pre></figure><p>Runtime: 71 ms, faster than 14.54% of Python3 online submissions for Happy Number.Memory Usage: 13.9 MB, less than 14.75% of Python3 online submissions for Happy Number.</p>", "date_published": "2022-10-05T20:00:00+00:00" }, { "id": "https://fewald.net/leetcode/2022/10/04/leetcode-linked-list-cycle.html", "url": "https://fewald.net/leetcode/2022/10/04/leetcode-linked-list-cycle.html", "title": "Leetcode: Linked list cycle", "content_html": "<p>Given the head of a linked list, determine if there is a cycle in the list. A cycle is defined as a chain of arbitrary length that point to the same node. As an added difficulty, the solution should have a space complexity of <code class=\"language-plaintext highlighter-rouge\">O(1)</code>.</p><p>The first observation is that the cycle can be of arbitrary length. Thus, saving the visited nodes in a set would have a space complexity of <code class=\"language-plaintext highlighter-rouge\">O(n)</code>. Secondly, the numbers cannot be compared because numbers might be duplicated throughout the list. Instead, we need to compare the list objects themselves.</p><!--more--><p>The solution involves using two pointers with different step sizes. The first pointer, <code class=\"language-plaintext highlighter-rouge\">p1</code>, has a step size of one and the second pointer, <code class=\"language-plaintext highlighter-rouge\">p2</code>, has a step size of two. Then iterate as long as either one of the pointers (<code class=\"language-plaintext highlighter-rouge\">p2</code>) reaches the end of the list or if both pointers point to the same object, in which case we found a loop.</p><figure class=\"highlight\"><pre><code class=\"language-python\" data-lang=\"python\"><span class=\"kn\">from</span> <span class=\"n\">typing</span> <span class=\"kn\">import</span> <span class=\"n\">Optional</span><span class=\"c1\"># Definition for singly-linked list.</span><span class=\"k\">class</span> <span class=\"nc\">ListNode</span><span class=\"p\">:</span> <span class=\"k\">def</span> <span class=\"nf\">__init__</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">x</span><span class=\"p\">,</span> <span class=\"n\">n</span><span class=\"o\">=</span><span class=\"bp\">None</span><span class=\"p\">):</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">val</span> <span class=\"o\">=</span> <span class=\"n\">x</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"nb\">next</span> <span class=\"o\">=</span> <span class=\"n\">n</span><span class=\"k\">class</span> <span class=\"nc\">Solution</span><span class=\"p\">:</span> <span class=\"k\">def</span> <span class=\"nf\">hasCycle</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">head</span><span class=\"p\">:</span> <span class=\"n\">Optional</span><span class=\"p\">[</span><span class=\"n\">ListNode</span><span class=\"p\">])</span> <span class=\"o\">-></span> <span class=\"nb\">bool</span><span class=\"p\">:</span> <span class=\"k\">if</span> <span class=\"n\">head</span> <span class=\"ow\">is</span> <span class=\"bp\">None</span><span class=\"p\">:</span> <span class=\"k\">return</span> <span class=\"bp\">False</span> <span class=\"n\">p1</span> <span class=\"o\">=</span> <span class=\"n\">head</span> <span class=\"n\">p2</span> <span class=\"o\">=</span> <span class=\"n\">head</span><span class=\"p\">.</span><span class=\"nb\">next</span> <span class=\"k\">while</span> <span class=\"n\">p1</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"bp\">None</span> <span class=\"ow\">and</span> <span class=\"n\">p2</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"bp\">None</span> <span class=\"ow\">and</span> <span class=\"n\">p2</span><span class=\"p\">.</span><span class=\"nb\">next</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"bp\">None</span><span class=\"p\">:</span> <span class=\"k\">if</span> <span class=\"n\">p1</span> <span class=\"o\">==</span> <span class=\"n\">p2</span><span class=\"p\">:</span> <span class=\"k\">return</span> <span class=\"bp\">True</span> <span class=\"n\">p1</span> <span class=\"o\">=</span> <span class=\"n\">p1</span><span class=\"p\">.</span><span class=\"nb\">next</span> <span class=\"n\">p2</span> <span class=\"o\">=</span> <span class=\"n\">p2</span><span class=\"p\">.</span><span class=\"nb\">next</span><span class=\"p\">.</span><span class=\"nb\">next</span> <span class=\"k\">return</span> <span class=\"bp\">False</span><span class=\"k\">if</span> <span class=\"n\">__name__</span> <span class=\"o\">==</span> <span class=\"sh\">'</span><span class=\"s\">__main__</span><span class=\"sh\">'</span><span class=\"p\">:</span> <span class=\"n\">s</span> <span class=\"o\">=</span> <span class=\"nc\">Solution</span><span class=\"p\">().</span><span class=\"n\">hasCycle</span> <span class=\"n\">l</span> <span class=\"o\">=</span> <span class=\"nc\">ListNode</span><span class=\"p\">(</span><span class=\"mi\">2</span><span class=\"p\">,</span> <span class=\"nc\">ListNode</span><span class=\"p\">(</span><span class=\"mi\">0</span><span class=\"p\">,</span> <span class=\"nc\">ListNode</span><span class=\"p\">(</span><span class=\"o\">-</span><span class=\"mi\">4</span><span class=\"p\">)))</span> <span class=\"n\">l</span><span class=\"p\">.</span><span class=\"nb\">next</span><span class=\"p\">.</span><span class=\"nb\">next</span><span class=\"p\">.</span><span class=\"nb\">next</span> <span class=\"o\">=</span> <span class=\"n\">l</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">(</span><span class=\"nc\">ListNode</span><span class=\"p\">(</span><span class=\"mi\">3</span><span class=\"p\">,</span> <span class=\"n\">l</span><span class=\"p\">)),</span> <span class=\"bp\">True</span><span class=\"p\">)</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">(</span><span class=\"nc\">ListNode</span><span class=\"p\">(</span><span class=\"mi\">1</span><span class=\"p\">)),</span> <span class=\"bp\">False</span><span class=\"p\">)</span></code></pre></figure><p>Runtime: 112 ms, faster than 15.44% of Python3 online submissions for Linked List Cycle.Memory Usage: 17.6 MB, less than 67.21% of Python3 online submissions for Linked List Cycle.</p>", "date_published": "2022-10-04T20:00:00+00:00" }, { "id": "https://fewald.net/leetcode/2022/10/03/leetcode-contains-duplicate.html", "url": "https://fewald.net/leetcode/2022/10/03/leetcode-contains-duplicate.html", "title": "Leetcode: Contains duplicate", "content_html": "<p>Given an array of <code class=\"language-plaintext highlighter-rouge\">nums</code>, return <code class=\"language-plaintext highlighter-rouge\">True</code> if there is a duplicated number and <code class=\"language-plaintext highlighter-rouge\">False</code> otherwise.</p><p>The simple most solution I could find was to use a <code class=\"language-plaintext highlighter-rouge\">set</code> and then see for every number if it is already contained in the set. A map would have worked as well. The time complexity for this is <code class=\"language-plaintext highlighter-rouge\">O(n)</code>, assuming that the access to the hash set is <code class=\"language-plaintext highlighter-rouge\">O(1)</code>, it takes only one iteration over the whole list.</p><!--more--><figure class=\"highlight\"><pre><code class=\"language-python\" data-lang=\"python\"><span class=\"kn\">from</span> <span class=\"n\">typing</span> <span class=\"kn\">import</span> <span class=\"n\">List</span><span class=\"p\">,</span> <span class=\"n\">Optional</span><span class=\"k\">class</span> <span class=\"nc\">Solution</span><span class=\"p\">:</span> <span class=\"k\">def</span> <span class=\"nf\">containsDuplicate</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">nums</span><span class=\"p\">:</span> <span class=\"n\">List</span><span class=\"p\">[</span><span class=\"nb\">int</span><span class=\"p\">])</span> <span class=\"o\">-></span> <span class=\"nb\">bool</span><span class=\"p\">:</span> <span class=\"n\">s</span> <span class=\"o\">=</span> <span class=\"nf\">set</span><span class=\"p\">()</span> <span class=\"k\">for</span> <span class=\"n\">n</span> <span class=\"ow\">in</span> <span class=\"n\">nums</span><span class=\"p\">:</span> <span class=\"k\">if</span> <span class=\"n\">n</span> <span class=\"ow\">in</span> <span class=\"n\">s</span><span class=\"p\">:</span> <span class=\"k\">return</span> <span class=\"bp\">True</span> <span class=\"n\">s</span><span class=\"p\">.</span><span class=\"nf\">add</span><span class=\"p\">(</span><span class=\"n\">n</span><span class=\"p\">)</span> <span class=\"k\">return</span> <span class=\"bp\">False</span><span class=\"k\">if</span> <span class=\"n\">__name__</span> <span class=\"o\">==</span> <span class=\"sh\">'</span><span class=\"s\">__main__</span><span class=\"sh\">'</span><span class=\"p\">:</span> <span class=\"n\">s</span> <span class=\"o\">=</span> <span class=\"nc\">Solution</span><span class=\"p\">().</span><span class=\"n\">containsDuplicate</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">([</span><span class=\"mi\">1</span><span class=\"p\">,</span><span class=\"mi\">2</span><span class=\"p\">,</span><span class=\"mi\">3</span><span class=\"p\">,</span><span class=\"mi\">1</span><span class=\"p\">]),</span> <span class=\"bp\">True</span><span class=\"p\">)</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">([</span><span class=\"mi\">1</span><span class=\"p\">,</span><span class=\"mi\">2</span><span class=\"p\">,</span><span class=\"mi\">3</span><span class=\"p\">,</span><span class=\"mi\">4</span><span class=\"p\">]),</span> <span class=\"bp\">False</span><span class=\"p\">)</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">([</span><span class=\"mi\">1</span><span class=\"p\">,</span><span class=\"mi\">1</span><span class=\"p\">,</span><span class=\"mi\">1</span><span class=\"p\">,</span><span class=\"mi\">3</span><span class=\"p\">,</span><span class=\"mi\">3</span><span class=\"p\">,</span><span class=\"mi\">4</span><span class=\"p\">,</span><span class=\"mi\">3</span><span class=\"p\">,</span><span class=\"mi\">2</span><span class=\"p\">,</span><span class=\"mi\">4</span><span class=\"p\">,</span><span class=\"mi\">2</span><span class=\"p\">]),</span> <span class=\"bp\">True</span><span class=\"p\">)</span></code></pre></figure><p>Runtime: 439 ms, faster than 99.61% of Python3 online submissions for Contains Duplicate.</p><p>Memory Usage: 26 MB, less than 71.55% of Python3 online submissions for Contains Duplicate.</p>", "date_published": "2022-10-03T20:00:00+00:00" }, { "id": "https://fewald.net/leetcode/2022/10/02/leetcode-move-zeros.html", "url": "https://fewald.net/leetcode/2022/10/02/leetcode-move-zeros.html", "title": "Leetcode: Move zeros", "content_html": "<p>The task is as follows: Given an integer array <code class=\"language-plaintext highlighter-rouge\">nums</code>, move all 0’s to the end of it while maintaining the relative order of the non-zero elements.</p><p>Note that you must do this in-place without making a copy of the array.</p><p>The last note is actually the important part. Without this, it would be easy to just use array splitting in Python and add a zero. This would look similar to this:</p><figure class=\"highlight\"><pre><code class=\"language-python\" data-lang=\"python\"><span class=\"k\">if</span> <span class=\"n\">nums</span><span class=\"p\">[</span><span class=\"n\">pos</span><span class=\"p\">]</span> <span class=\"o\">==</span> <span class=\"mi\">0</span><span class=\"p\">:</span> <span class=\"n\">nums</span> <span class=\"o\">=</span> <span class=\"n\">nums</span><span class=\"p\">[:</span><span class=\"n\">pos</span><span class=\"p\">]</span> <span class=\"o\">+</span> <span class=\"n\">nums</span><span class=\"p\">[</span><span class=\"n\">pos</span><span class=\"o\">+</span><span class=\"mi\">1</span><span class=\"p\">:]</span> <span class=\"o\">+</span> <span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span></code></pre></figure><p>This obviously overrides <code class=\"language-plaintext highlighter-rouge\">nums</code> and the change is no longer in place. The next best solution that I found was to delete the items at position I from the list and then add a zero to the end. It is important to note, that the index needs to be decremented by one in case a <code class=\"language-plaintext highlighter-rouge\">0</code> is found to account for double <code class=\"language-plaintext highlighter-rouge\">0</code>. The number of steps needs to always be increased.</p><!--more--><figure class=\"highlight\"><pre><code class=\"language-python\" data-lang=\"python\"><span class=\"kn\">from</span> <span class=\"n\">typing</span> <span class=\"kn\">import</span> <span class=\"n\">List</span><span class=\"p\">,</span> <span class=\"n\">Optional</span><span class=\"k\">class</span> <span class=\"nc\">Solution</span><span class=\"p\">:</span> <span class=\"k\">def</span> <span class=\"nf\">moveZeroes</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">nums</span><span class=\"p\">:</span> <span class=\"n\">List</span><span class=\"p\">[</span><span class=\"nb\">int</span><span class=\"p\">])</span> <span class=\"o\">-></span> <span class=\"bp\">None</span><span class=\"p\">:</span> <span class=\"sh\">\"\"\"</span><span class=\"s\"> Do not return anything, modify nums in-place instead. </span><span class=\"sh\">\"\"\"</span> <span class=\"n\">pos</span> <span class=\"o\">=</span> <span class=\"mi\">0</span> <span class=\"n\">steps</span> <span class=\"o\">=</span> <span class=\"mi\">0</span> <span class=\"k\">while</span> <span class=\"n\">steps</span> <span class=\"o\"><</span> <span class=\"nf\">len</span><span class=\"p\">(</span><span class=\"n\">nums</span><span class=\"p\">):</span> <span class=\"k\">if</span> <span class=\"n\">nums</span><span class=\"p\">[</span><span class=\"n\">pos</span><span class=\"p\">]</span> <span class=\"o\">==</span> <span class=\"mi\">0</span><span class=\"p\">:</span> <span class=\"k\">del</span> <span class=\"n\">nums</span><span class=\"p\">[</span><span class=\"n\">pos</span><span class=\"p\">]</span> <span class=\"n\">nums</span><span class=\"p\">.</span><span class=\"nf\">append</span><span class=\"p\">(</span><span class=\"mi\">0</span><span class=\"p\">)</span> <span class=\"n\">pos</span> <span class=\"o\">-=</span> <span class=\"mi\">1</span> <span class=\"n\">pos</span> <span class=\"o\">+=</span> <span class=\"mi\">1</span> <span class=\"n\">steps</span> <span class=\"o\">+=</span> <span class=\"mi\">1</span><span class=\"k\">if</span> <span class=\"n\">__name__</span> <span class=\"o\">==</span> <span class=\"sh\">'</span><span class=\"s\">__main__</span><span class=\"sh\">'</span><span class=\"p\">:</span> <span class=\"n\">s</span> <span class=\"o\">=</span> <span class=\"nc\">Solution</span><span class=\"p\">().</span><span class=\"n\">moveZeroes</span> <span class=\"n\">l</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">,</span><span class=\"mi\">1</span><span class=\"p\">,</span><span class=\"mi\">0</span><span class=\"p\">,</span><span class=\"mi\">3</span><span class=\"p\">,</span><span class=\"mi\">12</span><span class=\"p\">]</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">(</span><span class=\"n\">l</span><span class=\"p\">),</span> <span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">,</span><span class=\"mi\">3</span><span class=\"p\">,</span><span class=\"mi\">12</span><span class=\"p\">,</span><span class=\"mi\">0</span><span class=\"p\">,</span><span class=\"mi\">0</span><span class=\"p\">])</span> <span class=\"n\">l</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">(</span><span class=\"n\">l</span><span class=\"p\">),</span> <span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">])</span> <span class=\"n\">l</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">,</span><span class=\"mi\">0</span><span class=\"p\">,</span><span class=\"mi\">1</span><span class=\"p\">]</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">(</span><span class=\"n\">l</span><span class=\"p\">),</span> <span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">,</span><span class=\"mi\">0</span><span class=\"p\">,</span><span class=\"mi\">0</span><span class=\"p\">])</span></code></pre></figure><p>Runtime: 189 ms, faster than 84.86% of Python3 online submissions for Move Zeroes.</p><p>Memory Usage: 15.6 MB, less than 17.32% of Python3 online submissions for Move Zeroes.</p>", "date_published": "2022-10-02T20:00:00+00:00" }, { "id": "https://fewald.net/leetcode/2022/10/01/leetcode-reverse-string.html", "url": "https://fewald.net/leetcode/2022/10/01/leetcode-reverse-string.html", "title": "Leetcode: Reverse string", "content_html": "<p>Reverse a string and only use one extra variable. The solution is straightforward with two pointers, <code class=\"language-plaintext highlighter-rouge\">p1</code> and <code class=\"language-plaintext highlighter-rouge\">p2</code>. THe idea here is to start from both ends and increment <code class=\"language-plaintext highlighter-rouge\">p1</code> and decrement <code class=\"language-plaintext highlighter-rouge\">p2</code> until both of them meet in the middle. To switch the values of variables without assigning a temporary variable, the notation of <code class=\"language-plaintext highlighter-rouge\">a, b = b, a</code> can be used. To convert a string into a list of characters, surroung the string with <code class=\"language-plaintext highlighter-rouge\">[*s]</code>.</p><!--more--><figure class=\"highlight\"><pre><code class=\"language-python\" data-lang=\"python\"><span class=\"kn\">from</span> <span class=\"n\">typing</span> <span class=\"kn\">import</span> <span class=\"n\">List</span><span class=\"p\">,</span> <span class=\"n\">Optional</span><span class=\"k\">class</span> <span class=\"nc\">Solution</span><span class=\"p\">:</span> <span class=\"k\">def</span> <span class=\"nf\">reverseString</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">s</span><span class=\"p\">:</span> <span class=\"n\">List</span><span class=\"p\">[</span><span class=\"nb\">str</span><span class=\"p\">])</span> <span class=\"o\">-></span> <span class=\"bp\">None</span><span class=\"p\">:</span> <span class=\"sh\">\"\"\"</span><span class=\"s\"> Do not return anything, modify s in-place instead. </span><span class=\"sh\">\"\"\"</span> <span class=\"n\">p1</span> <span class=\"o\">=</span> <span class=\"mi\">0</span> <span class=\"n\">p2</span> <span class=\"o\">=</span> <span class=\"nf\">len</span><span class=\"p\">(</span><span class=\"n\">s</span><span class=\"p\">)</span> <span class=\"o\">-</span> <span class=\"mi\">1</span> <span class=\"k\">while</span> <span class=\"n\">p1</span> <span class=\"o\"><</span> <span class=\"n\">p2</span><span class=\"p\">:</span> <span class=\"n\">s</span><span class=\"p\">[</span><span class=\"n\">p1</span><span class=\"p\">],</span> <span class=\"n\">s</span><span class=\"p\">[</span><span class=\"n\">p2</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">s</span><span class=\"p\">[</span><span class=\"n\">p2</span><span class=\"p\">],</span> <span class=\"n\">s</span><span class=\"p\">[</span><span class=\"n\">p1</span><span class=\"p\">]</span> <span class=\"n\">p1</span> <span class=\"o\">+=</span> <span class=\"mi\">1</span> <span class=\"n\">p2</span> <span class=\"o\">-=</span> <span class=\"mi\">1</span> <span class=\"k\">if</span> <span class=\"n\">__name__</span> <span class=\"o\">==</span> <span class=\"sh\">'</span><span class=\"s\">__main__</span><span class=\"sh\">'</span><span class=\"p\">:</span> <span class=\"n\">s</span> <span class=\"o\">=</span> <span class=\"nc\">Solution</span><span class=\"p\">().</span><span class=\"n\">reverseString</span> <span class=\"n\">t</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"o\">*</span><span class=\"sh\">'</span><span class=\"s\">Hello world</span><span class=\"sh\">'</span><span class=\"p\">]</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">(</span><span class=\"n\">t</span><span class=\"p\">),</span> <span class=\"n\">t</span><span class=\"p\">)</span> <span class=\"n\">t</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"o\">*</span><span class=\"sh\">'</span><span class=\"s\">AB</span><span class=\"sh\">'</span><span class=\"p\">]</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">(</span><span class=\"n\">t</span><span class=\"p\">),</span> <span class=\"n\">t</span><span class=\"p\">)</span></code></pre></figure><p>Runtime: 377 ms, faster than 22.88% of Python3 online submissions for Reverse String.</p><p>Memory Usage: 18.4 MB, less than 45.70% of Python3 online submissions for Reverse String.</p>", "date_published": "2022-10-01T20:00:00+00:00" }, { "id": "https://fewald.net/leetcode/2022/09/30/leetcode-majority-number.html", "url": "https://fewald.net/leetcode/2022/09/30/leetcode-majority-number.html", "title": "Leetcode: Majority number", "content_html": "<p>Given an array nums of size <code class=\"language-plaintext highlighter-rouge\">n</code>, return the majority element. The majority element is the element that appears more than <code class=\"language-plaintext highlighter-rouge\">⌊n / 2⌋</code> times. You may assume that the majority element always exists in the array.</p><p>Unfortunately, it is not clear from the description whether there are only two different numbers or multiple ones. Some of the solutions seem to suggest that there are only two different ones. The solution that I will show has a time complexity of <code class=\"language-plaintext highlighter-rouge\">O(n)</code> and a space complexity of <code class=\"language-plaintext highlighter-rouge\">O(n)</code> in the worst case, that is, if all the numbers appear exactly once.</p><!--more--><figure class=\"highlight\"><pre><code class=\"language-python\" data-lang=\"python\"><span class=\"kn\">from</span> <span class=\"n\">typing</span> <span class=\"kn\">import</span> <span class=\"n\">List</span><span class=\"p\">,</span> <span class=\"n\">Optional</span><span class=\"k\">class</span> <span class=\"nc\">Solution</span><span class=\"p\">:</span> <span class=\"k\">def</span> <span class=\"nf\">majorityElement</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">nums</span><span class=\"p\">:</span> <span class=\"n\">List</span><span class=\"p\">[</span><span class=\"nb\">int</span><span class=\"p\">])</span> <span class=\"o\">-></span> <span class=\"nb\">int</span><span class=\"p\">:</span> <span class=\"n\">m</span> <span class=\"o\">=</span> <span class=\"p\">{}</span> <span class=\"n\">max_n</span> <span class=\"o\">=</span> <span class=\"n\">nums</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span> <span class=\"n\">count_n</span> <span class=\"o\">=</span> <span class=\"mi\">1</span> <span class=\"k\">for</span> <span class=\"n\">n</span> <span class=\"ow\">in</span> <span class=\"n\">nums</span><span class=\"p\">:</span> <span class=\"k\">if</span> <span class=\"n\">n</span> <span class=\"ow\">not</span> <span class=\"ow\">in</span> <span class=\"n\">m</span><span class=\"p\">:</span> <span class=\"n\">m</span><span class=\"p\">[</span><span class=\"n\">n</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"mi\">0</span> <span class=\"n\">m</span><span class=\"p\">[</span><span class=\"n\">n</span><span class=\"p\">]</span> <span class=\"o\">+=</span> <span class=\"mi\">1</span> <span class=\"k\">if</span> <span class=\"n\">m</span><span class=\"p\">[</span><span class=\"n\">n</span><span class=\"p\">]</span> <span class=\"o\">></span> <span class=\"n\">count_n</span><span class=\"p\">:</span> <span class=\"n\">max_n</span> <span class=\"o\">=</span> <span class=\"n\">n</span> <span class=\"n\">count_n</span> <span class=\"o\">=</span> <span class=\"n\">m</span><span class=\"p\">[</span><span class=\"n\">n</span><span class=\"p\">]</span> <span class=\"k\">return</span> <span class=\"n\">max_n</span><span class=\"k\">if</span> <span class=\"n\">__name__</span> <span class=\"o\">==</span> <span class=\"sh\">'</span><span class=\"s\">__main__</span><span class=\"sh\">'</span><span class=\"p\">:</span> <span class=\"n\">s</span> <span class=\"o\">=</span> <span class=\"nc\">Solution</span><span class=\"p\">().</span><span class=\"n\">majorityElement</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">([</span><span class=\"mi\">3</span><span class=\"p\">,</span><span class=\"mi\">2</span><span class=\"p\">,</span><span class=\"mi\">3</span><span class=\"p\">]),</span> <span class=\"mi\">3</span><span class=\"p\">)</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">([</span><span class=\"mi\">2</span><span class=\"p\">,</span><span class=\"mi\">2</span><span class=\"p\">,</span><span class=\"mi\">1</span><span class=\"p\">,</span><span class=\"mi\">1</span><span class=\"p\">,</span><span class=\"mi\">1</span><span class=\"p\">,</span><span class=\"mi\">2</span><span class=\"p\">,</span><span class=\"mi\">2</span><span class=\"p\">]),</span> <span class=\"mi\">2</span><span class=\"p\">)</span></code></pre></figure><p>A temporary map is used to count elements. If the elemented appeared more than the max element, it will be the new most frequent element. A possible optimization is to stop once the count reaches <code class=\"language-plaintext highlighter-rouge\">> n/2</code>.</p>", "date_published": "2022-09-30T20:00:00+00:00" }, { "id": "https://fewald.net/leetcode/2022/09/29/leetcode-single-number.html", "url": "https://fewald.net/leetcode/2022/09/29/leetcode-single-number.html", "title": "Leetcode: Single number", "content_html": "<p>Given a list of integers <code class=\"language-plaintext highlighter-rouge\">[1,1,2]</code>, there is only one number which is not repeated. The numbers can be in any order. The minimum length of the array is <code class=\"language-plaintext highlighter-rouge\">1</code>. Numbers can be negative or positive. The algorithm should have a time complexity of <code class=\"language-plaintext highlighter-rouge\">O(n)</code> and a space complexity should be constant <code class=\"language-plaintext highlighter-rouge\">O(1)</code>.</p><p>Given this information, we can use the properties of a <code class=\"language-plaintext highlighter-rouge\">set</code> or a <code class=\"language-plaintext highlighter-rouge\">map</code>.</p><!--more--><figure class=\"highlight\"><pre><code class=\"language-python\" data-lang=\"python\"><span class=\"kn\">from</span> <span class=\"n\">typing</span> <span class=\"kn\">import</span> <span class=\"n\">List</span><span class=\"p\">,</span> <span class=\"n\">Optional</span><span class=\"k\">class</span> <span class=\"nc\">Solution</span><span class=\"p\">:</span> <span class=\"k\">def</span> <span class=\"nf\">singleNumber</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">nums</span><span class=\"p\">:</span> <span class=\"n\">List</span><span class=\"p\">[</span><span class=\"nb\">int</span><span class=\"p\">])</span> <span class=\"o\">-></span> <span class=\"nb\">int</span><span class=\"p\">:</span> <span class=\"n\">s</span> <span class=\"o\">=</span> <span class=\"nf\">set</span><span class=\"p\">()</span> <span class=\"k\">for</span> <span class=\"n\">n</span> <span class=\"ow\">in</span> <span class=\"n\">nums</span><span class=\"p\">:</span> <span class=\"k\">if</span> <span class=\"n\">n</span> <span class=\"ow\">in</span> <span class=\"n\">s</span><span class=\"p\">:</span> <span class=\"n\">s</span><span class=\"p\">.</span><span class=\"nf\">remove</span><span class=\"p\">(</span><span class=\"n\">n</span><span class=\"p\">)</span> <span class=\"k\">else</span><span class=\"p\">:</span> <span class=\"n\">s</span><span class=\"p\">.</span><span class=\"nf\">add</span><span class=\"p\">(</span><span class=\"n\">n</span><span class=\"p\">)</span> <span class=\"k\">return</span> <span class=\"n\">s</span><span class=\"p\">.</span><span class=\"nf\">pop</span><span class=\"p\">()</span><span class=\"k\">if</span> <span class=\"n\">__name__</span> <span class=\"o\">==</span> <span class=\"sh\">'</span><span class=\"s\">__main__</span><span class=\"sh\">'</span><span class=\"p\">:</span> <span class=\"n\">s</span> <span class=\"o\">=</span> <span class=\"nc\">Solution</span><span class=\"p\">().</span><span class=\"n\">singleNumber</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">([</span><span class=\"mi\">1</span><span class=\"p\">,</span><span class=\"mi\">2</span><span class=\"p\">,</span><span class=\"mi\">1</span><span class=\"p\">,</span><span class=\"mi\">2</span><span class=\"p\">,</span><span class=\"mi\">3</span><span class=\"p\">]),</span> <span class=\"mi\">3</span><span class=\"p\">)</span></code></pre></figure><p>In the worst case this <code class=\"language-plaintext highlighter-rouge\">set</code> uses the space <code class=\"language-plaintext highlighter-rouge\">O(n/2)</code> which seems to be accepted according to the comments in the question.</p>", "date_published": "2022-09-29T20:00:00+00:00" }, { "id": "https://fewald.net/leetcode/2022/09/28/leetcode-first-unique-character-in-string.html", "url": "https://fewald.net/leetcode/2022/09/28/leetcode-first-unique-character-in-string.html", "title": "Leetcode: First unique character in string", "content_html": "<p>Given a string <code class=\"language-plaintext highlighter-rouge\">s</code>, find the first non-repeating character in it and return its index. If it does not exist, return <code class=\"language-plaintext highlighter-rouge\">-1</code>. An example is the word <code class=\"language-plaintext highlighter-rouge\">leetcode</code> where the <code class=\"language-plaintext highlighter-rouge\">l</code> only appears once, therefore returning <code class=\"language-plaintext highlighter-rouge\">0</code> as result.</p><p>The obvious, but very slow, solution is to iterate over the string and then for ever character, check the whole string if the character appears again. This has a time complexity of <code class=\"language-plaintext highlighter-rouge\">O(n^2)</code>.</p><p>A better solution is to write all characters in a map and count the number of occurrences. This way, we can iterate again and simply look at the counter in the map. This yields a time complexity of <code class=\"language-plaintext highlighter-rouge\">O(2n)</code>.</p><!--more--><figure class=\"highlight\"><pre><code class=\"language-python\" data-lang=\"python\"><span class=\"k\">class</span> <span class=\"nc\">Solution</span><span class=\"p\">:</span> <span class=\"k\">def</span> <span class=\"nf\">firstUniqChar</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">s</span><span class=\"p\">:</span> <span class=\"nb\">str</span><span class=\"p\">)</span> <span class=\"o\">-></span> <span class=\"nb\">int</span><span class=\"p\">:</span> <span class=\"n\">c</span> <span class=\"o\">=</span> <span class=\"p\">{}</span> <span class=\"k\">for</span> <span class=\"n\">char</span> <span class=\"ow\">in</span> <span class=\"n\">s</span><span class=\"p\">:</span> <span class=\"k\">if</span> <span class=\"n\">char</span> <span class=\"ow\">not</span> <span class=\"ow\">in</span> <span class=\"n\">c</span><span class=\"p\">:</span> <span class=\"n\">c</span><span class=\"p\">[</span><span class=\"n\">char</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"mi\">0</span> <span class=\"n\">c</span><span class=\"p\">[</span><span class=\"n\">char</span><span class=\"p\">]</span> <span class=\"o\">+=</span> <span class=\"mi\">1</span> <span class=\"k\">for</span> <span class=\"n\">idx</span> <span class=\"ow\">in</span> <span class=\"nf\">range</span><span class=\"p\">(</span><span class=\"nf\">len</span><span class=\"p\">(</span><span class=\"n\">s</span><span class=\"p\">)):</span> <span class=\"k\">if</span> <span class=\"n\">c</span><span class=\"p\">[</span><span class=\"n\">s</span><span class=\"p\">[</span><span class=\"n\">idx</span><span class=\"p\">]]</span> <span class=\"o\">==</span> <span class=\"mi\">1</span><span class=\"p\">:</span> <span class=\"k\">return</span> <span class=\"n\">idx</span> <span class=\"k\">return</span> <span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"k\">if</span> <span class=\"n\">__name__</span> <span class=\"o\">==</span> <span class=\"sh\">'</span><span class=\"s\">__main__</span><span class=\"sh\">'</span><span class=\"p\">:</span> <span class=\"n\">s</span> <span class=\"o\">=</span> <span class=\"nc\">Solution</span><span class=\"p\">().</span><span class=\"n\">firstUniqChar</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">(</span><span class=\"sh\">'</span><span class=\"s\">leetcode</span><span class=\"sh\">'</span><span class=\"p\">),</span> <span class=\"mi\">0</span><span class=\"p\">)</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">(</span><span class=\"sh\">'</span><span class=\"s\">loveleetcode</span><span class=\"sh\">'</span><span class=\"p\">),</span> <span class=\"mi\">2</span><span class=\"p\">)</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">(</span><span class=\"sh\">'</span><span class=\"s\">aabb</span><span class=\"sh\">'</span><span class=\"p\">),</span> <span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">)</span></code></pre></figure>", "date_published": "2022-09-28T20:00:00+00:00" }, { "id": "https://fewald.net/leetcode/2022/09/27/leetcode-symmetric-tree.html", "url": "https://fewald.net/leetcode/2022/09/27/leetcode-symmetric-tree.html", "title": "Leetcode: Symmetric tree", "content_html": "<p>The task is to determine if a tree is symmetric, meaning mirrored along the <code class=\"language-plaintext highlighter-rouge\">root</code> node. The usual tree structure is given in form of a <code class=\"language-plaintext highlighter-rouge\">TreeNode</code>.</p><figure class=\"highlight\"><pre><code class=\"language-python\" data-lang=\"python\"><span class=\"k\">class</span> <span class=\"nc\">TreeNode</span><span class=\"p\">:</span> <span class=\"k\">def</span> <span class=\"nf\">__init__</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">val</span><span class=\"o\">=</span><span class=\"mi\">0</span><span class=\"p\">,</span> <span class=\"n\">left</span><span class=\"o\">=</span><span class=\"bp\">None</span><span class=\"p\">,</span> <span class=\"n\">right</span><span class=\"o\">=</span><span class=\"bp\">None</span><span class=\"p\">):</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">val</span> <span class=\"o\">=</span> <span class=\"n\">val</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">left</span> <span class=\"o\">=</span> <span class=\"n\">left</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">right</span> <span class=\"o\">=</span> <span class=\"n\">right</span></code></pre></figure><figure class=\"highlight\"><pre><code class=\"language-plain\" data-lang=\"plain\">A symmetric tree looks like this:Note that the 3 and 4 are flipped in the left vs. right branch. 1 / \\ 2 2 / \\ / \\ 3 4 4 3An asymmetric tree looks like this:Note that the 3 would need to be on the other side of either branch to make this tree symmetric. 1 / \\ 2 2 / / 3 3</code></pre></figure><p>The logic itself is quite straightforward look at two nodes and compare the values. If their respective values are the same look at both of their children and compare them. Repeat this process until every node is visited.</p><p>There are some special cases here that need to be handled. The left child can be <code class=\"language-plaintext highlighter-rouge\">None</code> while the right child is not and vice versa. If both children are <code class=\"language-plaintext highlighter-rouge\">None</code>, return <code class=\"language-plaintext highlighter-rouge\">True</code> and do not proceed because this means we reached a leaf node.</p><!--more--><p>The recursive solution looks like this.</p><figure class=\"highlight\"><pre><code class=\"language-python\" data-lang=\"python\"><span class=\"k\">class</span> <span class=\"nc\">Solution</span><span class=\"p\">:</span> <span class=\"k\">def</span> <span class=\"nf\">isSymmetric</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">root</span><span class=\"p\">:</span> <span class=\"n\">Optional</span><span class=\"p\">[</span><span class=\"n\">TreeNode</span><span class=\"p\">])</span> <span class=\"o\">-></span> <span class=\"nb\">bool</span><span class=\"p\">:</span> <span class=\"k\">if</span> <span class=\"n\">root</span> <span class=\"ow\">is</span> <span class=\"bp\">None</span><span class=\"p\">:</span> <span class=\"k\">return</span> <span class=\"bp\">True</span> <span class=\"k\">return</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"nf\">inner</span><span class=\"p\">(</span><span class=\"n\">root</span><span class=\"p\">.</span><span class=\"n\">left</span><span class=\"p\">,</span> <span class=\"n\">root</span><span class=\"p\">.</span><span class=\"n\">right</span><span class=\"p\">)</span> <span class=\"k\">def</span> <span class=\"nf\">inner</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">left</span><span class=\"p\">,</span> <span class=\"n\">right</span><span class=\"p\">)</span> <span class=\"o\">-></span> <span class=\"nb\">bool</span><span class=\"p\">:</span> <span class=\"k\">if</span> <span class=\"n\">left</span> <span class=\"ow\">is</span> <span class=\"bp\">None</span> <span class=\"ow\">and</span> <span class=\"n\">right</span> <span class=\"ow\">is</span> <span class=\"bp\">None</span><span class=\"p\">:</span> <span class=\"k\">return</span> <span class=\"bp\">True</span> <span class=\"k\">if</span> <span class=\"n\">left</span> <span class=\"ow\">is</span> <span class=\"bp\">None</span> <span class=\"ow\">and</span> <span class=\"n\">right</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"bp\">None</span><span class=\"p\">:</span> <span class=\"k\">return</span> <span class=\"bp\">False</span> <span class=\"k\">if</span> <span class=\"n\">left</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"bp\">None</span> <span class=\"ow\">and</span> <span class=\"n\">right</span> <span class=\"ow\">is</span> <span class=\"bp\">None</span><span class=\"p\">:</span> <span class=\"k\">return</span> <span class=\"bp\">False</span> <span class=\"n\">l</span> <span class=\"o\">=</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"nf\">inner</span><span class=\"p\">(</span><span class=\"n\">left</span><span class=\"p\">.</span><span class=\"n\">left</span><span class=\"p\">,</span> <span class=\"n\">right</span><span class=\"p\">.</span><span class=\"n\">right</span><span class=\"p\">)</span> <span class=\"n\">r</span> <span class=\"o\">=</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"nf\">inner</span><span class=\"p\">(</span><span class=\"n\">left</span><span class=\"p\">.</span><span class=\"n\">right</span><span class=\"p\">,</span> <span class=\"n\">right</span><span class=\"p\">.</span><span class=\"n\">left</span><span class=\"p\">)</span> <span class=\"k\">return</span> <span class=\"n\">left</span><span class=\"p\">.</span><span class=\"n\">val</span> <span class=\"o\">==</span> <span class=\"n\">right</span><span class=\"p\">.</span><span class=\"n\">val</span> <span class=\"ow\">and</span> <span class=\"n\">l</span> <span class=\"ow\">and</span> <span class=\"n\">r</span></code></pre></figure><p>And the iterative solution looks like this.</p><figure class=\"highlight\"><pre><code class=\"language-python\" data-lang=\"python\"><span class=\"k\">class</span> <span class=\"nc\">Solution</span><span class=\"p\">:</span> <span class=\"k\">def</span> <span class=\"nf\">isSymmetric</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">root</span><span class=\"p\">:</span> <span class=\"n\">Optional</span><span class=\"p\">[</span><span class=\"n\">TreeNode</span><span class=\"p\">])</span> <span class=\"o\">-></span> <span class=\"nb\">bool</span><span class=\"p\">:</span> <span class=\"k\">if</span> <span class=\"n\">root</span> <span class=\"ow\">is</span> <span class=\"bp\">None</span><span class=\"p\">:</span> <span class=\"k\">return</span> <span class=\"bp\">True</span> <span class=\"c1\"># Create stack and initialize with immediate successors</span> <span class=\"n\">stack</span> <span class=\"o\">=</span> <span class=\"p\">[(</span><span class=\"n\">root</span><span class=\"p\">.</span><span class=\"n\">left</span><span class=\"p\">,</span> <span class=\"n\">root</span><span class=\"p\">.</span><span class=\"n\">right</span><span class=\"p\">)]</span> <span class=\"k\">while</span> <span class=\"nf\">len</span><span class=\"p\">(</span><span class=\"n\">stack</span><span class=\"p\">)</span> <span class=\"o\">></span> <span class=\"mi\">0</span><span class=\"p\">:</span> <span class=\"n\">n</span> <span class=\"o\">=</span> <span class=\"n\">stack</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span> <span class=\"n\">stack</span> <span class=\"o\">=</span> <span class=\"n\">stack</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">:]</span> <span class=\"k\">if</span> <span class=\"n\">n</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span> <span class=\"ow\">is</span> <span class=\"bp\">None</span> <span class=\"ow\">and</span> <span class=\"n\">n</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">]</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"bp\">None</span><span class=\"p\">:</span> <span class=\"k\">return</span> <span class=\"bp\">False</span> <span class=\"k\">if</span> <span class=\"n\">n</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"bp\">None</span> <span class=\"ow\">and</span> <span class=\"n\">n</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">]</span> <span class=\"ow\">is</span> <span class=\"bp\">None</span><span class=\"p\">:</span> <span class=\"k\">return</span> <span class=\"bp\">False</span> <span class=\"k\">if</span> <span class=\"n\">n</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span> <span class=\"ow\">is</span> <span class=\"bp\">None</span> <span class=\"ow\">and</span> <span class=\"n\">n</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">]</span> <span class=\"ow\">is</span> <span class=\"bp\">None</span><span class=\"p\">:</span> <span class=\"k\">continue</span> <span class=\"k\">if</span> <span class=\"n\">n</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">].</span><span class=\"n\">val</span> <span class=\"o\">!=</span> <span class=\"n\">n</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">].</span><span class=\"n\">val</span><span class=\"p\">:</span> <span class=\"k\">return</span> <span class=\"bp\">False</span> <span class=\"n\">stack</span><span class=\"p\">.</span><span class=\"nf\">append</span><span class=\"p\">((</span><span class=\"n\">n</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">].</span><span class=\"n\">left</span><span class=\"p\">,</span> <span class=\"n\">n</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">].</span><span class=\"n\">right</span><span class=\"p\">))</span> <span class=\"n\">stack</span><span class=\"p\">.</span><span class=\"nf\">append</span><span class=\"p\">((</span><span class=\"n\">n</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">].</span><span class=\"n\">right</span><span class=\"p\">,</span> <span class=\"n\">n</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">].</span><span class=\"n\">left</span><span class=\"p\">))</span> <span class=\"k\">return</span> <span class=\"bp\">True</span></code></pre></figure><p>Test both solutions with the following code:</p><figure class=\"highlight\"><pre><code class=\"language-python\" data-lang=\"python\"><span class=\"k\">if</span> <span class=\"n\">__name__</span> <span class=\"o\">==</span> <span class=\"sh\">'</span><span class=\"s\">__main__</span><span class=\"sh\">'</span><span class=\"p\">:</span> <span class=\"n\">s</span> <span class=\"o\">=</span> <span class=\"nc\">Solution</span><span class=\"p\">().</span><span class=\"n\">isSymmetric</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">(</span><span class=\"nc\">TreeNode</span><span class=\"p\">(</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"nc\">TreeNode</span><span class=\"p\">(</span><span class=\"mi\">2</span><span class=\"p\">,</span> <span class=\"nc\">TreeNode</span><span class=\"p\">(</span><span class=\"mi\">3</span><span class=\"p\">),</span> <span class=\"nc\">TreeNode</span><span class=\"p\">(</span><span class=\"mi\">4</span><span class=\"p\">)),</span> <span class=\"nc\">TreeNode</span><span class=\"p\">(</span><span class=\"mi\">2</span><span class=\"p\">,</span> <span class=\"nc\">TreeNode</span><span class=\"p\">(</span><span class=\"mi\">4</span><span class=\"p\">),</span> <span class=\"nc\">TreeNode</span><span class=\"p\">(</span><span class=\"mi\">3</span><span class=\"p\">)))),</span> <span class=\"bp\">True</span><span class=\"p\">)</span></code></pre></figure>", "date_published": "2022-09-27T20:00:00+00:00" }, { "id": "https://fewald.net/leetcode/2022/09/26/leetcode-binary-tree-inorder-traversal.html", "url": "https://fewald.net/leetcode/2022/09/26/leetcode-binary-tree-inorder-traversal.html", "title": "Leetcode: Binary tree inorder traversal", "content_html": "<p>The task is to traverse a binary tree inorder. This means, that starting from the root node, nodes should be visited in the following order: left, self, right. With this knowledge it is easy to come up with a recursive algorithm.</p><p>The only special case that needs to be handled are the leaf nodes that don’t have any children. By still visiting the non-existing children and then returning an empty list (<code class=\"language-plaintext highlighter-rouge\">[]</code>) when a <code class=\"language-plaintext highlighter-rouge\">None</code> is encountered, the whole algorithm fits into two lines.</p><figure class=\"highlight\"><pre><code class=\"language-python\" data-lang=\"python\"><span class=\"k\">class</span> <span class=\"nc\">TreeNode</span><span class=\"p\">:</span> <span class=\"k\">def</span> <span class=\"nf\">__init__</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">val</span><span class=\"o\">=</span><span class=\"mi\">0</span><span class=\"p\">,</span> <span class=\"n\">left</span><span class=\"o\">=</span><span class=\"bp\">None</span><span class=\"p\">,</span> <span class=\"n\">right</span><span class=\"o\">=</span><span class=\"bp\">None</span><span class=\"p\">):</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">val</span> <span class=\"o\">=</span> <span class=\"n\">val</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">left</span> <span class=\"o\">=</span> <span class=\"n\">left</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"n\">right</span> <span class=\"o\">=</span> <span class=\"n\">right</span><span class=\"k\">class</span> <span class=\"nc\">Solution</span><span class=\"p\">:</span> <span class=\"k\">def</span> <span class=\"nf\">inorderTraversal</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">root</span><span class=\"p\">:</span> <span class=\"n\">Optional</span><span class=\"p\">[</span><span class=\"n\">TreeNode</span><span class=\"p\">])</span> <span class=\"o\">-></span> <span class=\"n\">List</span><span class=\"p\">[</span><span class=\"nb\">int</span><span class=\"p\">]:</span> <span class=\"c1\"># Handle non-existing leaf-nodes (including empty root)</span> <span class=\"k\">if</span> <span class=\"n\">root</span> <span class=\"ow\">is</span> <span class=\"bp\">None</span><span class=\"p\">:</span> <span class=\"k\">return</span> <span class=\"p\">[]</span> <span class=\"c1\"># Visit left - current - right</span> <span class=\"k\">return</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"nf\">inorderTraversal</span><span class=\"p\">(</span><span class=\"n\">root</span><span class=\"p\">.</span><span class=\"n\">left</span><span class=\"p\">)</span> <span class=\"o\">+</span> <span class=\"p\">[</span><span class=\"n\">root</span><span class=\"p\">.</span><span class=\"n\">val</span><span class=\"p\">]</span> <span class=\"o\">+</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"nf\">inorderTraversal</span><span class=\"p\">(</span><span class=\"n\">root</span><span class=\"p\">.</span><span class=\"n\">right</span><span class=\"p\">)</span><span class=\"k\">if</span> <span class=\"n\">__name__</span> <span class=\"o\">==</span> <span class=\"sh\">'</span><span class=\"s\">__main__</span><span class=\"sh\">'</span><span class=\"p\">:</span> <span class=\"n\">s</span> <span class=\"o\">=</span> <span class=\"nc\">Solution</span><span class=\"p\">().</span><span class=\"n\">inorderTraversal</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">(</span><span class=\"nc\">TreeNode</span><span class=\"p\">(</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"bp\">None</span><span class=\"p\">,</span> <span class=\"nc\">TreeNode</span><span class=\"p\">(</span><span class=\"mi\">2</span><span class=\"p\">,</span> <span class=\"nc\">TreeNode</span><span class=\"p\">(</span><span class=\"mi\">3</span><span class=\"p\">),</span> <span class=\"bp\">None</span><span class=\"p\">))),</span> <span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">,</span><span class=\"mi\">3</span><span class=\"p\">,</span><span class=\"mi\">2</span><span class=\"p\">])</span></code></pre></figure><p>Runtime: 41 ms, faster than 70.32% of Python3 online submissions for Binary Tree Inorder Traversal.</p><p>Memory Usage: 13.8 MB, less than 60.08% of Python3 online submissions for Binary Tree Inorder Traversal.</p>", "date_published": "2022-09-26T20:00:00+00:00" }, { "id": "https://fewald.net/leetcode/2022/09/25/leetcode-square-root-of-x.html", "url": "https://fewald.net/leetcode/2022/09/25/leetcode-square-root-of-x.html", "title": "Leetcode: Square root of x", "content_html": "<p>The task is to implement a square root method without using <code class=\"language-plaintext highlighter-rouge\">math.sqrt</code> or <code class=\"language-plaintext highlighter-rouge\">**</code> or <code class=\"language-plaintext highlighter-rouge\">pow</code> or any similar function. Any digits after the decimal point do not to be returned. This is effectively the <code class=\"language-plaintext highlighter-rouge\">floor(sqrt(n))</code> function.</p><p>The first idea is to simply try out every number and multiply it with itself until the square root is found. If the next number is greater than <code class=\"language-plaintext highlighter-rouge\">n</code>, return the previous number. This is however not very efficient as it has a time complexity of <code class=\"language-plaintext highlighter-rouge\">O(sqrt(n))</code> in every case.</p><p>To speed this process up, we can use binary search. The idea is to always double the size of the steps until we reach the target number or overshoot. If we overshoot, take half of the number and start at <code class=\"language-plaintext highlighter-rouge\">1</code> again, then double, and so on.</p><!--more--><p>The solution then looks as follows.</p><figure class=\"highlight\"><pre><code class=\"language-python\" data-lang=\"python\"><span class=\"k\">class</span> <span class=\"nc\">Solution</span><span class=\"p\">:</span> <span class=\"k\">def</span> <span class=\"nf\">mySqrt</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">x</span><span class=\"p\">:</span> <span class=\"nb\">int</span><span class=\"p\">)</span> <span class=\"o\">-></span> <span class=\"nb\">int</span><span class=\"p\">:</span> <span class=\"n\">prefix</span> <span class=\"o\">=</span> <span class=\"mi\">0</span> <span class=\"k\">while</span> <span class=\"bp\">True</span><span class=\"p\">:</span> <span class=\"n\">i</span> <span class=\"o\">=</span> <span class=\"mi\">1</span> <span class=\"nf\">while </span><span class=\"p\">((</span><span class=\"n\">prefix</span> <span class=\"o\">+</span> <span class=\"n\">i</span><span class=\"p\">)</span> <span class=\"o\">*</span> <span class=\"p\">(</span><span class=\"n\">prefix</span> <span class=\"o\">+</span> <span class=\"n\">i</span><span class=\"p\">))</span> <span class=\"o\"><=</span> <span class=\"n\">x</span><span class=\"p\">:</span> <span class=\"n\">i</span> <span class=\"o\"><<=</span> <span class=\"mi\">1</span> <span class=\"n\">prefix</span> <span class=\"o\">+=</span> <span class=\"n\">i</span> <span class=\"o\">>></span> <span class=\"mi\">1</span> <span class=\"k\">if</span> <span class=\"n\">prefix</span><span class=\"o\">*</span><span class=\"n\">prefix</span> <span class=\"o\"><=</span> <span class=\"n\">x</span> <span class=\"ow\">and</span> <span class=\"p\">(</span><span class=\"n\">prefix</span><span class=\"o\">+</span><span class=\"mi\">1</span><span class=\"p\">)</span><span class=\"o\">*</span><span class=\"p\">(</span><span class=\"n\">prefix</span><span class=\"o\">+</span><span class=\"mi\">1</span><span class=\"p\">)</span> <span class=\"o\">></span> <span class=\"n\">x</span><span class=\"p\">:</span> <span class=\"k\">return</span> <span class=\"n\">prefix</span><span class=\"k\">if</span> <span class=\"n\">__name__</span> <span class=\"o\">==</span> <span class=\"sh\">'</span><span class=\"s\">__main__</span><span class=\"sh\">'</span><span class=\"p\">:</span> <span class=\"n\">s</span> <span class=\"o\">=</span> <span class=\"nc\">Solution</span><span class=\"p\">().</span><span class=\"n\">mySqrt</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">(</span><span class=\"mi\">125</span><span class=\"p\">),</span> <span class=\"mi\">11</span><span class=\"p\">)</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">(</span><span class=\"mi\">0</span><span class=\"p\">),</span> <span class=\"mi\">0</span><span class=\"p\">)</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">(</span><span class=\"mi\">4</span><span class=\"p\">),</span> <span class=\"mi\">2</span><span class=\"p\">)</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">(</span><span class=\"mi\">16</span><span class=\"p\">),</span> <span class=\"mi\">4</span><span class=\"p\">)</span></code></pre></figure><p>Runtime: 84 ms, faster than 28.09% of Python3 online submissions for Sqrt(x).</p><p>Memory Usage: 13.8 MB, less than 56.92% of Python3 online submissions for Sqrt(x).</p>", "date_published": "2022-09-25T20:00:00+00:00" }, { "id": "https://fewald.net/leetcode/2022/09/24/leetcode-add-binary.html", "url": "https://fewald.net/leetcode/2022/09/24/leetcode-add-binary.html", "title": "Leetcode: Add binary", "content_html": "<p>The task is to add two binary numbers of various length. There is more than one possible solution. First, the basic solution which doesn’t use too many builtin Python functions works as follows: Reverse the strings containing the numbers. Then Iterate in a loop as long as we didn’t reach the end of both strings. Write the current position to a temporary variable if it’s still in the boundaries of the string. Then add a potential overflow and handle it if the sum of <code class=\"language-plaintext highlighter-rouge\">a + b + overflow > 1</code>. Finally, check for the overflow at the end and add a <code class=\"language-plaintext highlighter-rouge\">1</code> and reverse the string again before returning it.</p><p>This can be solved much simpler with builtin Python functions.</p><!--more--><p>First, the manual solution that can be transferred in any programming language.</p><figure class=\"highlight\"><pre><code class=\"language-python\" data-lang=\"python\"><span class=\"k\">class</span> <span class=\"nc\">Solution</span><span class=\"p\">:</span> <span class=\"k\">def</span> <span class=\"nf\">addBinary</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">a</span><span class=\"p\">:</span> <span class=\"nb\">str</span><span class=\"p\">,</span> <span class=\"n\">b</span><span class=\"p\">:</span> <span class=\"nb\">str</span><span class=\"p\">)</span> <span class=\"o\">-></span> <span class=\"nb\">str</span><span class=\"p\">:</span> <span class=\"c1\"># Reverse strings</span> <span class=\"n\">a</span> <span class=\"o\">=</span> <span class=\"n\">a</span><span class=\"p\">[::</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">]</span> <span class=\"n\">b</span> <span class=\"o\">=</span> <span class=\"n\">b</span><span class=\"p\">[::</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">]</span> <span class=\"c1\"># Prepare output</span> <span class=\"n\">out</span> <span class=\"o\">=</span> <span class=\"sh\">''</span> <span class=\"n\">i</span> <span class=\"o\">=</span> <span class=\"mi\">0</span> <span class=\"n\">overflow</span> <span class=\"o\">=</span> <span class=\"mi\">0</span> <span class=\"k\">while</span> <span class=\"n\">i</span> <span class=\"o\"><</span> <span class=\"nf\">len</span><span class=\"p\">(</span><span class=\"n\">a</span><span class=\"p\">)</span> <span class=\"ow\">or</span> <span class=\"n\">i</span> <span class=\"o\"><</span> <span class=\"nf\">len</span><span class=\"p\">(</span><span class=\"n\">b</span><span class=\"p\">):</span> <span class=\"n\">aa</span><span class=\"p\">,</span> <span class=\"n\">bb</span> <span class=\"o\">=</span> <span class=\"mi\">0</span><span class=\"p\">,</span> <span class=\"mi\">0</span> <span class=\"k\">if</span> <span class=\"n\">i</span> <span class=\"o\"><</span> <span class=\"nf\">len</span><span class=\"p\">(</span><span class=\"n\">a</span><span class=\"p\">):</span> <span class=\"n\">aa</span> <span class=\"o\">=</span> <span class=\"n\">a</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">]</span> <span class=\"k\">if</span> <span class=\"n\">i</span> <span class=\"o\"><</span> <span class=\"nf\">len</span><span class=\"p\">(</span><span class=\"n\">b</span><span class=\"p\">):</span> <span class=\"n\">bb</span> <span class=\"o\">=</span> <span class=\"n\">b</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">]</span> <span class=\"n\">s</span> <span class=\"o\">=</span> <span class=\"nf\">int</span><span class=\"p\">(</span><span class=\"n\">aa</span><span class=\"p\">)</span> <span class=\"o\">+</span> <span class=\"nf\">int</span><span class=\"p\">(</span><span class=\"n\">bb</span><span class=\"p\">)</span> <span class=\"o\">+</span> <span class=\"n\">overflow</span> <span class=\"n\">out</span> <span class=\"o\">+=</span> <span class=\"nf\">str</span><span class=\"p\">(</span><span class=\"n\">s</span><span class=\"o\">%</span><span class=\"mi\">2</span><span class=\"p\">)</span> <span class=\"k\">if</span> <span class=\"n\">s</span> <span class=\"o\">></span> <span class=\"mi\">1</span><span class=\"p\">:</span> <span class=\"n\">overflow</span> <span class=\"o\">=</span> <span class=\"mi\">1</span> <span class=\"k\">else</span><span class=\"p\">:</span> <span class=\"n\">overflow</span> <span class=\"o\">=</span> <span class=\"mi\">0</span> <span class=\"n\">i</span> <span class=\"o\">+=</span> <span class=\"mi\">1</span> <span class=\"k\">if</span> <span class=\"n\">overflow</span> <span class=\"o\">></span> <span class=\"mi\">0</span><span class=\"p\">:</span> <span class=\"n\">out</span> <span class=\"o\">+=</span> <span class=\"nf\">str</span><span class=\"p\">(</span><span class=\"n\">overflow</span><span class=\"p\">)</span> <span class=\"k\">return</span> <span class=\"n\">out</span><span class=\"p\">[::</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">]</span> <span class=\"k\">if</span> <span class=\"n\">__name__</span> <span class=\"o\">==</span> <span class=\"sh\">'</span><span class=\"s\">__main__</span><span class=\"sh\">'</span><span class=\"p\">:</span> <span class=\"n\">s</span> <span class=\"o\">=</span> <span class=\"nc\">Solution</span><span class=\"p\">().</span><span class=\"n\">addBinary</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">(</span><span class=\"sh\">'</span><span class=\"s\">11</span><span class=\"sh\">'</span><span class=\"p\">,</span> <span class=\"sh\">'</span><span class=\"s\">1</span><span class=\"sh\">'</span><span class=\"p\">),</span> <span class=\"sh\">'</span><span class=\"s\">100</span><span class=\"sh\">'</span><span class=\"p\">)</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">(</span><span class=\"sh\">'</span><span class=\"s\">1010</span><span class=\"sh\">'</span><span class=\"p\">,</span> <span class=\"sh\">'</span><span class=\"s\">1011</span><span class=\"sh\">'</span><span class=\"p\">),</span> <span class=\"sh\">'</span><span class=\"s\">10101</span><span class=\"sh\">'</span><span class=\"p\">)</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">(</span><span class=\"sh\">'</span><span class=\"s\">0</span><span class=\"sh\">'</span><span class=\"p\">,</span> <span class=\"sh\">'</span><span class=\"s\">0</span><span class=\"sh\">'</span><span class=\"p\">),</span> <span class=\"sh\">'</span><span class=\"s\">0</span><span class=\"sh\">'</span><span class=\"p\">)</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">(</span><span class=\"sh\">'</span><span class=\"s\">0</span><span class=\"sh\">'</span><span class=\"p\">,</span> <span class=\"sh\">'</span><span class=\"s\">1</span><span class=\"sh\">'</span><span class=\"p\">),</span> <span class=\"sh\">'</span><span class=\"s\">1</span><span class=\"sh\">'</span><span class=\"p\">)</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">(</span><span class=\"sh\">'</span><span class=\"s\">100</span><span class=\"sh\">'</span><span class=\"p\">,</span> <span class=\"sh\">'</span><span class=\"s\">0</span><span class=\"sh\">'</span><span class=\"p\">),</span> <span class=\"sh\">'</span><span class=\"s\">100</span><span class=\"sh\">'</span><span class=\"p\">)</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">(</span><span class=\"sh\">'</span><span class=\"s\">100</span><span class=\"sh\">'</span><span class=\"p\">,</span> <span class=\"sh\">'</span><span class=\"s\">100</span><span class=\"sh\">'</span><span class=\"p\">),</span> <span class=\"sh\">'</span><span class=\"s\">1000</span><span class=\"sh\">'</span><span class=\"p\">)</span></code></pre></figure><p>Runtime: 67 ms, faster than 19.66% of Python3 online submissions for Add Binary.</p><p>Memory Usage: 13.9 MB, less than 25.21% of Python3 online submissions for Add Binary.</p><p>Now the solution that uses builtin Python functions.</p><figure class=\"highlight\"><pre><code class=\"language-python\" data-lang=\"python\"><span class=\"k\">class</span> <span class=\"nc\">Solution</span><span class=\"p\">:</span> <span class=\"k\">def</span> <span class=\"nf\">addBinary</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">a</span><span class=\"p\">:</span> <span class=\"nb\">str</span><span class=\"p\">,</span> <span class=\"n\">b</span><span class=\"p\">:</span> <span class=\"nb\">str</span><span class=\"p\">)</span> <span class=\"o\">-></span> <span class=\"nb\">str</span><span class=\"p\">:</span> <span class=\"c1\"># Convert to integer using base 2</span> <span class=\"n\">a</span> <span class=\"o\">=</span> <span class=\"nf\">int</span><span class=\"p\">(</span><span class=\"n\">a</span><span class=\"p\">,</span> <span class=\"n\">base</span><span class=\"o\">=</span><span class=\"mi\">2</span><span class=\"p\">)</span> <span class=\"n\">b</span> <span class=\"o\">=</span> <span class=\"nf\">int</span><span class=\"p\">(</span><span class=\"n\">b</span><span class=\"p\">,</span> <span class=\"n\">base</span><span class=\"o\">=</span><span class=\"mi\">2</span><span class=\"p\">)</span> <span class=\"c1\"># Convert back to binary and skip the `0b` prefix</span> <span class=\"k\">return</span> <span class=\"nf\">bin</span><span class=\"p\">(</span><span class=\"n\">a</span><span class=\"o\">+</span><span class=\"n\">b</span><span class=\"p\">)[</span><span class=\"mi\">2</span><span class=\"p\">:]</span></code></pre></figure><p>The runtime of both approaches is about the same.</p>", "date_published": "2022-09-24T20:00:00+00:00" }, { "id": "https://fewald.net/leetcode/2022/09/23/leetcode-plus-one.html", "url": "https://fewald.net/leetcode/2022/09/23/leetcode-plus-one.html", "title": "Leetcode: Plus one", "content_html": "<p>A decimal number is given as a list of integers. The number should be incremented by <code class=\"language-plaintext highlighter-rouge\">1</code>. The idea here is to iterate backwards through the list and start with the smallest digit. This way, this challenge can be solved in <code class=\"language-plaintext highlighter-rouge\">O(n)</code>. If after adding <code class=\"language-plaintext highlighter-rouge\">1</code>, the <code class=\"language-plaintext highlighter-rouge\">mod(10)</code> is <code class=\"language-plaintext highlighter-rouge\">0</code> it means we had an overflow and need to add one. If we didn’t we’re done and can break the loop. As a final check we need to make sure that there is no overflow in the end which would cause us to prepend the list.</p><!--more--><figure class=\"highlight\"><pre><code class=\"language-python\" data-lang=\"python\"><span class=\"kn\">from</span> <span class=\"n\">typing</span> <span class=\"kn\">import</span> <span class=\"n\">List</span><span class=\"k\">class</span> <span class=\"nc\">Solution</span><span class=\"p\">:</span> <span class=\"k\">def</span> <span class=\"nf\">plusOne</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">digits</span><span class=\"p\">:</span> <span class=\"n\">List</span><span class=\"p\">[</span><span class=\"nb\">int</span><span class=\"p\">])</span> <span class=\"o\">-></span> <span class=\"n\">List</span><span class=\"p\">[</span><span class=\"nb\">int</span><span class=\"p\">]:</span> <span class=\"k\">for</span> <span class=\"n\">pos</span> <span class=\"ow\">in</span> <span class=\"nf\">range</span><span class=\"p\">(</span><span class=\"nf\">len</span><span class=\"p\">(</span><span class=\"n\">digits</span><span class=\"p\">)</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">):</span> <span class=\"n\">remainder</span> <span class=\"o\">=</span> <span class=\"mi\">0</span> <span class=\"n\">digits</span><span class=\"p\">[</span><span class=\"n\">pos</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"p\">(</span><span class=\"n\">digits</span><span class=\"p\">[</span><span class=\"n\">pos</span><span class=\"p\">]</span> <span class=\"o\">+</span> <span class=\"mi\">1</span><span class=\"p\">)</span> <span class=\"o\">%</span> <span class=\"mi\">10</span> <span class=\"k\">if</span> <span class=\"n\">digits</span><span class=\"p\">[</span><span class=\"n\">pos</span><span class=\"p\">]</span> <span class=\"o\">==</span> <span class=\"mi\">0</span><span class=\"p\">:</span> <span class=\"n\">remainder</span> <span class=\"o\">=</span> <span class=\"mi\">1</span> <span class=\"k\">continue</span> <span class=\"k\">else</span><span class=\"p\">:</span> <span class=\"n\">remainder</span> <span class=\"o\">=</span> <span class=\"mi\">0</span> <span class=\"k\">break</span> <span class=\"k\">if</span> <span class=\"n\">remainder</span> <span class=\"o\">==</span> <span class=\"mi\">1</span><span class=\"p\">:</span> <span class=\"n\">digits</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">]</span> <span class=\"o\">+</span> <span class=\"n\">digits</span> <span class=\"k\">return</span> <span class=\"n\">digits</span><span class=\"k\">if</span> <span class=\"n\">__name__</span> <span class=\"o\">==</span> <span class=\"sh\">'</span><span class=\"s\">__main__</span><span class=\"sh\">'</span><span class=\"p\">:</span> <span class=\"n\">s</span> <span class=\"o\">=</span> <span class=\"nc\">Solution</span><span class=\"p\">().</span><span class=\"n\">plusOne</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">([</span><span class=\"mi\">1</span><span class=\"p\">,</span><span class=\"mi\">2</span><span class=\"p\">,</span><span class=\"mi\">3</span><span class=\"p\">]),</span> <span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">,</span><span class=\"mi\">2</span><span class=\"p\">,</span><span class=\"mi\">4</span><span class=\"p\">])</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">([</span><span class=\"mi\">4</span><span class=\"p\">,</span><span class=\"mi\">3</span><span class=\"p\">,</span><span class=\"mi\">2</span><span class=\"p\">,</span><span class=\"mi\">1</span><span class=\"p\">]),</span> <span class=\"p\">[</span><span class=\"mi\">4</span><span class=\"p\">,</span><span class=\"mi\">3</span><span class=\"p\">,</span><span class=\"mi\">2</span><span class=\"p\">,</span><span class=\"mi\">2</span><span class=\"p\">])</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">s</span><span class=\"p\">([</span><span class=\"mi\">9</span><span class=\"p\">]),</span> <span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">,</span><span class=\"mi\">0</span><span class=\"p\">])</span></code></pre></figure><p>Runtime: 67 ms, faster than 12.59% of Python3 online submissions for Plus One.</p><p>Memory Usage: 13.9 MB, less than 59.15% of Python3 online submissions for Plus One.</p>", "date_published": "2022-09-23T20:00:00+00:00" }, { "id": "https://fewald.net/leetcode/2022/09/22/leetcode-climbing-stairs.html", "url": "https://fewald.net/leetcode/2022/09/22/leetcode-climbing-stairs.html", "title": "Leetcode: Climbing stairs", "content_html": "<p>There is a given number of stairs <code class=\"language-plaintext highlighter-rouge\">n</code>. Stairs can be either taken two steps at a time or one step at a time. For a height of <code class=\"language-plaintext highlighter-rouge\">1</code>, there is only one possible solution: <code class=\"language-plaintext highlighter-rouge\">1</code>. For a height of <code class=\"language-plaintext highlighter-rouge\">2</code>, there are two solutions: <code class=\"language-plaintext highlighter-rouge\">1-1</code> or <code class=\"language-plaintext highlighter-rouge\">2</code>.</p><!--more--><p>The main trick in this task is to discover that this is a fibonacci-like sequence. Every next step depends on the steps before. Once this is discovered, the code is straightforward. First, cover the base cases, <code class=\"language-plaintext highlighter-rouge\">1</code> and <code class=\"language-plaintext highlighter-rouge\">2</code>. For the rest, append the sum of the first digits to a list and then pop the first element off the beginning. Finally, return the last digit.</p><figure class=\"highlight\"><pre><code class=\"language-python\" data-lang=\"python\"><span class=\"k\">class</span> <span class=\"nc\">Solution</span><span class=\"p\">:</span> <span class=\"k\">def</span> <span class=\"nf\">climbStairs</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">n</span><span class=\"p\">:</span> <span class=\"nb\">int</span><span class=\"p\">)</span> <span class=\"o\">-></span> <span class=\"nb\">int</span><span class=\"p\">:</span> <span class=\"k\">if</span> <span class=\"n\">n</span> <span class=\"o\"><=</span> <span class=\"mi\">2</span><span class=\"p\">:</span> <span class=\"k\">return</span> <span class=\"n\">n</span> <span class=\"n\">l</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">2</span><span class=\"p\">]</span> <span class=\"n\">n</span> <span class=\"o\">-=</span> <span class=\"mi\">2</span> <span class=\"k\">while</span> <span class=\"n\">n</span> <span class=\"o\">></span> <span class=\"mi\">0</span><span class=\"p\">:</span> <span class=\"n\">l</span><span class=\"p\">.</span><span class=\"nf\">append</span><span class=\"p\">(</span><span class=\"n\">l</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span><span class=\"o\">+</span><span class=\"n\">l</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">])</span> <span class=\"n\">l</span><span class=\"o\">=</span><span class=\"n\">l</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">:]</span> <span class=\"n\">n</span> <span class=\"o\">-=</span> <span class=\"mi\">1</span> <span class=\"k\">return</span> <span class=\"n\">l</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">]</span></code></pre></figure><p>Runtime: 41 ms, faster than 66.93% of Python3 online submissions for Climbing Stairs.</p><p>Memory Usage: 13.9 MB, less than 11.90% of Python3 online submissions for Climbing Stairs.</p>", "date_published": "2022-09-22T20:00:00+00:00" }, { "id": "https://fewald.net/leetcode/2022/09/21/leetcode-best-time-to-buy-and-sell-stock.html", "url": "https://fewald.net/leetcode/2022/09/21/leetcode-best-time-to-buy-and-sell-stock.html", "title": "Leetcode: Best time to buy and sell stock", "content_html": "<p>The task is to find out of a series of stock prices the best time to buy and sell the stock. Only one stock can be owned at the time and it can be sold and bought at the same time.</p><!--more--><p>The Python solution looks like this. It’s not entirely optimal because technically we could sell stock at every transaction, which simplifies the code as shown below.</p><figure class=\"highlight\"><pre><code class=\"language-python\" data-lang=\"python\"><span class=\"kn\">from</span> <span class=\"n\">typing</span> <span class=\"kn\">import</span> <span class=\"n\">List</span><span class=\"k\">class</span> <span class=\"nc\">Solution</span><span class=\"p\">:</span> <span class=\"k\">def</span> <span class=\"nf\">maxProfit</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">prices</span><span class=\"p\">:</span> <span class=\"n\">List</span><span class=\"p\">[</span><span class=\"nb\">int</span><span class=\"p\">])</span> <span class=\"o\">-></span> <span class=\"nb\">int</span><span class=\"p\">:</span> <span class=\"n\">profit</span> <span class=\"o\">=</span> <span class=\"mi\">0</span> <span class=\"n\">buy</span> <span class=\"o\">=</span> <span class=\"o\">-</span><span class=\"mi\">1</span> <span class=\"k\">for</span> <span class=\"n\">i</span> <span class=\"ow\">in</span> <span class=\"nf\">range</span><span class=\"p\">(</span><span class=\"nf\">len</span><span class=\"p\">(</span><span class=\"n\">prices</span><span class=\"p\">)</span> <span class=\"o\">-</span> <span class=\"mi\">1</span><span class=\"p\">):</span> <span class=\"k\">if</span> <span class=\"n\">buy</span> <span class=\"o\">==</span> <span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">:</span> <span class=\"k\">if</span> <span class=\"n\">prices</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">]</span> <span class=\"o\"><</span> <span class=\"n\">prices</span><span class=\"p\">[</span><span class=\"n\">i</span> <span class=\"o\">+</span> <span class=\"mi\">1</span><span class=\"p\">]:</span> <span class=\"n\">buy</span> <span class=\"o\">=</span> <span class=\"n\">prices</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">]</span> <span class=\"k\">else</span><span class=\"p\">:</span> <span class=\"k\">if</span> <span class=\"n\">prices</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">]</span> <span class=\"o\">></span> <span class=\"n\">prices</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"o\">+</span><span class=\"mi\">1</span><span class=\"p\">]:</span> <span class=\"n\">profit</span> <span class=\"o\">+=</span> <span class=\"p\">(</span><span class=\"n\">prices</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">]</span> <span class=\"o\">-</span> <span class=\"n\">buy</span><span class=\"p\">)</span> <span class=\"n\">buy</span> <span class=\"o\">=</span> <span class=\"o\">-</span><span class=\"mi\">1</span> <span class=\"k\">if</span> <span class=\"n\">buy</span> <span class=\"o\">></span> <span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">:</span> <span class=\"n\">profit</span> <span class=\"o\">+=</span> <span class=\"n\">prices</span><span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">]</span> <span class=\"o\">-</span> <span class=\"n\">buy</span> <span class=\"k\">return</span> <span class=\"n\">profit</span><span class=\"k\">if</span> <span class=\"n\">__name__</span> <span class=\"o\">==</span> <span class=\"sh\">'</span><span class=\"s\">__main__</span><span class=\"sh\">'</span><span class=\"p\">:</span> <span class=\"n\">r</span> <span class=\"o\">=</span> <span class=\"nc\">Solution</span><span class=\"p\">().</span><span class=\"n\">maxProfit</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">r</span><span class=\"p\">([</span><span class=\"mi\">7</span><span class=\"p\">,</span><span class=\"mi\">1</span><span class=\"p\">,</span><span class=\"mi\">5</span><span class=\"p\">,</span><span class=\"mi\">3</span><span class=\"p\">,</span><span class=\"mi\">6</span><span class=\"p\">,</span><span class=\"mi\">4</span><span class=\"p\">]),</span> <span class=\"mi\">7</span><span class=\"p\">)</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">r</span><span class=\"p\">([</span><span class=\"mi\">1</span><span class=\"p\">,</span><span class=\"mi\">2</span><span class=\"p\">,</span><span class=\"mi\">3</span><span class=\"p\">,</span><span class=\"mi\">4</span><span class=\"p\">,</span><span class=\"mi\">5</span><span class=\"p\">]),</span> <span class=\"mi\">4</span><span class=\"p\">)</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">r</span><span class=\"p\">([</span><span class=\"mi\">7</span><span class=\"p\">,</span><span class=\"mi\">6</span><span class=\"p\">,</span><span class=\"mi\">4</span><span class=\"p\">,</span><span class=\"mi\">3</span><span class=\"p\">,</span><span class=\"mi\">1</span><span class=\"p\">]),</span> <span class=\"mi\">0</span><span class=\"p\">)</span></code></pre></figure><p>Now the same code in Python but always sell:</p><figure class=\"highlight\"><pre><code class=\"language-python\" data-lang=\"python\"><span class=\"k\">class</span> <span class=\"nc\">Solution</span><span class=\"p\">:</span> <span class=\"k\">def</span> <span class=\"nf\">maxProfit</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">prices</span><span class=\"p\">:</span> <span class=\"n\">List</span><span class=\"p\">[</span><span class=\"nb\">int</span><span class=\"p\">])</span> <span class=\"o\">-></span> <span class=\"nb\">int</span><span class=\"p\">:</span> <span class=\"n\">profit</span> <span class=\"o\">=</span> <span class=\"mi\">0</span> <span class=\"n\">buy</span> <span class=\"o\">=</span> <span class=\"o\">-</span><span class=\"mi\">1</span> <span class=\"k\">for</span> <span class=\"n\">i</span> <span class=\"ow\">in</span> <span class=\"nf\">range</span><span class=\"p\">(</span><span class=\"nf\">len</span><span class=\"p\">(</span><span class=\"n\">prices</span><span class=\"p\">)</span> <span class=\"o\">-</span> <span class=\"mi\">1</span><span class=\"p\">):</span> <span class=\"c1\"># See if I can sell</span> <span class=\"k\">if</span> <span class=\"n\">buy</span> <span class=\"o\">></span> <span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">:</span> <span class=\"n\">profit</span> <span class=\"o\">+=</span> <span class=\"p\">(</span><span class=\"n\">prices</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">]</span> <span class=\"o\">-</span> <span class=\"n\">buy</span><span class=\"p\">)</span> <span class=\"n\">buy</span> <span class=\"o\">=</span> <span class=\"o\">-</span><span class=\"mi\">1</span> <span class=\"c1\"># See if I should buy again</span> <span class=\"k\">if</span> <span class=\"n\">prices</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">]</span> <span class=\"o\"><</span> <span class=\"n\">prices</span><span class=\"p\">[</span><span class=\"n\">i</span> <span class=\"o\">+</span> <span class=\"mi\">1</span><span class=\"p\">]:</span> <span class=\"n\">buy</span> <span class=\"o\">=</span> <span class=\"n\">prices</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">]</span> <span class=\"k\">if</span> <span class=\"n\">buy</span> <span class=\"o\">></span> <span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">:</span> <span class=\"n\">profit</span> <span class=\"o\">+=</span> <span class=\"n\">prices</span><span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">]</span> <span class=\"o\">-</span> <span class=\"n\">buy</span> <span class=\"k\">return</span> <span class=\"n\">profit</span></code></pre></figure><p>And the same in Go, solved some years ago.</p><figure class=\"highlight\"><pre><code class=\"language-go\" data-lang=\"go\"><span class=\"k\">func</span> <span class=\"n\">maxProfit</span><span class=\"p\">(</span><span class=\"n\">prices</span> <span class=\"p\">[]</span><span class=\"kt\">int</span><span class=\"p\">)</span> <span class=\"kt\">int</span> <span class=\"p\">{</span> <span class=\"n\">profit</span> <span class=\"o\">:=</span> <span class=\"m\">0</span> <span class=\"n\">ownStock</span> <span class=\"o\">:=</span> <span class=\"no\">false</span> <span class=\"n\">lastPrice</span> <span class=\"o\">:=</span> <span class=\"n\">prices</span><span class=\"p\">[</span><span class=\"m\">0</span><span class=\"p\">]</span> <span class=\"n\">boughtAt</span> <span class=\"o\">:=</span> <span class=\"m\">0</span> <span class=\"k\">for</span> <span class=\"n\">i</span> <span class=\"o\">:=</span> <span class=\"m\">1</span><span class=\"p\">;</span> <span class=\"n\">i</span> <span class=\"o\"><</span> <span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">prices</span><span class=\"p\">);</span> <span class=\"n\">i</span><span class=\"o\">++</span> <span class=\"p\">{</span> <span class=\"n\">currPrice</span> <span class=\"o\">:=</span> <span class=\"n\">prices</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">]</span> <span class=\"k\">if</span> <span class=\"n\">ownStock</span> <span class=\"p\">{</span> <span class=\"c\">// Check if should sell</span> <span class=\"k\">if</span> <span class=\"n\">currPrice</span> <span class=\"o\"><</span> <span class=\"n\">lastPrice</span> <span class=\"p\">{</span> <span class=\"n\">profit</span> <span class=\"o\">+=</span> <span class=\"n\">lastPrice</span> <span class=\"o\">-</span> <span class=\"n\">boughtAt</span> <span class=\"n\">ownStock</span> <span class=\"o\">=</span> <span class=\"no\">false</span> <span class=\"p\">}</span> <span class=\"p\">}</span> <span class=\"k\">else</span> <span class=\"p\">{</span> <span class=\"c\">// Check if should buy</span> <span class=\"k\">if</span> <span class=\"n\">currPrice</span> <span class=\"o\">></span> <span class=\"n\">lastPrice</span> <span class=\"p\">{</span> <span class=\"n\">boughtAt</span> <span class=\"o\">=</span> <span class=\"n\">lastPrice</span> <span class=\"n\">ownStock</span> <span class=\"o\">=</span> <span class=\"no\">true</span> <span class=\"p\">}</span> <span class=\"p\">}</span> <span class=\"n\">lastPrice</span> <span class=\"o\">=</span> <span class=\"n\">currPrice</span> <span class=\"p\">}</span> <span class=\"c\">// Sell at the end</span> <span class=\"k\">if</span> <span class=\"n\">ownStock</span> <span class=\"p\">{</span> <span class=\"n\">profit</span> <span class=\"o\">+=</span> <span class=\"n\">prices</span><span class=\"p\">[</span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">prices</span><span class=\"p\">)</span><span class=\"o\">-</span><span class=\"m\">1</span><span class=\"p\">]</span> <span class=\"o\">-</span> <span class=\"n\">boughtAt</span> <span class=\"p\">}</span> <span class=\"k\">return</span> <span class=\"n\">profit</span><span class=\"p\">}</span></code></pre></figure><p>The code itself is not that interesting once the idea is understood. What I found remarkable however, is the speed at which the code gets executed. The Go solution is by far the fastest, taking only 4ms. The second fastest solution is the first (and less clean) solution to keep the stock as long as possible with 88ms runtime. The slowest solution is the Python solution that sells the stock immediately with 115ms.</p>", "date_published": "2022-09-21T20:00:00+00:00" }, { "id": "https://fewald.net/leetcode/2022/09/20/leetcode-repeated-substring-pattern.html", "url": "https://fewald.net/leetcode/2022/09/20/leetcode-repeated-substring-pattern.html", "title": "Leetcode: Repeated substring pattern", "content_html": "<p>The task is to find out if a given string is comprised of multiple identical substrings. The first observation is that the substring cannot be longer than half of the length of the original string. The second observation is that the length of the total string has to be a multiple of the string that is tested, if it is not it can be discarded right away. Lastly, a string with the length of one can be discarded immediately.</p><!--more--><p>The main idea is to try out every string from size <code class=\"language-plaintext highlighter-rouge\">1</code> to <code class=\"language-plaintext highlighter-rouge\">n/2+1</code> and <code class=\"language-plaintext highlighter-rouge\">break</code> immediately of the next character is not the expected one. As an additional optimization, substrings whose length do not fit into the whole string can be discarded immediately.</p><figure class=\"highlight\"><pre><code class=\"language-python\" data-lang=\"python\"><span class=\"k\">class</span> <span class=\"nc\">Solution</span><span class=\"p\">:</span> <span class=\"k\">def</span> <span class=\"nf\">repeatedSubstringPattern</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">s</span><span class=\"p\">:</span> <span class=\"nb\">str</span><span class=\"p\">)</span> <span class=\"o\">-></span> <span class=\"nb\">bool</span><span class=\"p\">:</span> <span class=\"k\">for</span> <span class=\"n\">length</span> <span class=\"ow\">in</span> <span class=\"nf\">range</span><span class=\"p\">(</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"nf\">int</span><span class=\"p\">(</span><span class=\"nf\">len</span><span class=\"p\">(</span><span class=\"n\">s</span><span class=\"p\">)</span><span class=\"o\">/</span><span class=\"mi\">2</span><span class=\"p\">)</span><span class=\"o\">+</span><span class=\"mi\">1</span><span class=\"p\">):</span> <span class=\"c1\"># Discard strings with invalid length</span> <span class=\"k\">if</span> <span class=\"nf\">len</span><span class=\"p\">(</span><span class=\"n\">s</span><span class=\"p\">)</span><span class=\"o\">%</span><span class=\"n\">length</span> <span class=\"o\">!=</span> <span class=\"mi\">0</span><span class=\"p\">:</span> <span class=\"k\">continue</span> <span class=\"n\">ok</span> <span class=\"o\">=</span> <span class=\"bp\">True</span> <span class=\"c1\"># Create substring to test</span> <span class=\"n\">curr</span> <span class=\"o\">=</span> <span class=\"n\">s</span><span class=\"p\">[:</span><span class=\"n\">length</span><span class=\"p\">]</span> <span class=\"k\">for</span> <span class=\"n\">char</span> <span class=\"ow\">in</span> <span class=\"nf\">range</span><span class=\"p\">(</span><span class=\"n\">length</span><span class=\"p\">,</span> <span class=\"nf\">len</span><span class=\"p\">(</span><span class=\"n\">s</span><span class=\"p\">)):</span> <span class=\"c1\"># Test character of substring. </span> <span class=\"c1\"># Only continue if character is as expected.</span> <span class=\"k\">if</span> <span class=\"n\">s</span><span class=\"p\">[</span><span class=\"n\">char</span><span class=\"p\">]</span> <span class=\"o\">!=</span> <span class=\"n\">curr</span><span class=\"p\">[</span><span class=\"n\">char</span><span class=\"o\">%</span><span class=\"n\">length</span><span class=\"p\">]:</span> <span class=\"n\">ok</span> <span class=\"o\">=</span> <span class=\"bp\">False</span> <span class=\"k\">break</span> <span class=\"k\">if</span> <span class=\"n\">ok</span><span class=\"p\">:</span> <span class=\"k\">return</span> <span class=\"bp\">True</span> <span class=\"c1\"># No valid substring found</span> <span class=\"k\">return</span> <span class=\"bp\">False</span><span class=\"k\">if</span> <span class=\"n\">__name__</span> <span class=\"o\">==</span> <span class=\"sh\">'</span><span class=\"s\">__main__</span><span class=\"sh\">'</span><span class=\"p\">:</span> <span class=\"n\">r</span> <span class=\"o\">=</span> <span class=\"nc\">Solution</span><span class=\"p\">().</span><span class=\"n\">repeatedSubstringPattern</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">r</span><span class=\"p\">(</span><span class=\"sh\">\"</span><span class=\"s\">aabaaba</span><span class=\"sh\">\"</span><span class=\"p\">),</span> <span class=\"bp\">False</span><span class=\"p\">)</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">r</span><span class=\"p\">(</span><span class=\"sh\">\"</span><span class=\"s\">abcabc</span><span class=\"sh\">\"</span><span class=\"p\">),</span> <span class=\"bp\">True</span><span class=\"p\">)</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">r</span><span class=\"p\">(</span><span class=\"sh\">\"</span><span class=\"s\">ababab</span><span class=\"sh\">\"</span><span class=\"p\">),</span> <span class=\"bp\">True</span><span class=\"p\">)</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">r</span><span class=\"p\">(</span><span class=\"sh\">'</span><span class=\"s\">abcxyz</span><span class=\"sh\">'</span><span class=\"p\">),</span> <span class=\"bp\">False</span><span class=\"p\">)</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">r</span><span class=\"p\">(</span><span class=\"sh\">'</span><span class=\"s\">a</span><span class=\"sh\">'</span><span class=\"p\">),</span> <span class=\"bp\">False</span><span class=\"p\">)</span></code></pre></figure><p>Runtime: 245 ms, faster than 34.66% of Python3 online submissions for Repeated Substring Pattern.Memory Usage: 14 MB, less than 59.35% of Python3 online submissions for Repeated Substring Pattern.</p>", "date_published": "2022-09-20T20:00:00+00:00" }, { "id": "https://fewald.net/leetcode/2022/09/19/leetcode-string-in-string.html", "url": "https://fewald.net/leetcode/2022/09/19/leetcode-string-in-string.html", "title": "Leetcode: String in String", "content_html": "<p>A classic find the <code class=\"language-plaintext highlighter-rouge\">needle</code> in the <code class=\"language-plaintext highlighter-rouge\">haystack</code> problem. The task is to find if a string is contained within another string and return the index of the first position. If the string is not contained return <code class=\"language-plaintext highlighter-rouge\">-1</code> and if the <code class=\"language-plaintext highlighter-rouge\">needle</code> is empty, return <code class=\"language-plaintext highlighter-rouge\">0</code>.</p><!--more--><figure class=\"highlight\"><pre><code class=\"language-python\" data-lang=\"python\"><span class=\"k\">class</span> <span class=\"nc\">Solution</span><span class=\"p\">:</span> <span class=\"k\">def</span> <span class=\"nf\">strStr</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">haystack</span><span class=\"p\">:</span> <span class=\"nb\">str</span><span class=\"p\">,</span> <span class=\"n\">needle</span><span class=\"p\">:</span> <span class=\"nb\">str</span><span class=\"p\">)</span> <span class=\"o\">-></span> <span class=\"nb\">int</span><span class=\"p\">:</span> <span class=\"k\">if</span> <span class=\"n\">needle</span> <span class=\"o\">==</span> <span class=\"sh\">\"\"</span><span class=\"p\">:</span> <span class=\"k\">return</span> <span class=\"mi\">0</span> <span class=\"n\">h</span> <span class=\"o\">=</span> <span class=\"mi\">0</span> <span class=\"n\">n</span> <span class=\"o\">=</span> <span class=\"mi\">0</span> <span class=\"k\">while</span> <span class=\"n\">h</span> <span class=\"o\"><</span> <span class=\"nf\">len</span><span class=\"p\">(</span><span class=\"n\">haystack</span><span class=\"p\">):</span> <span class=\"k\">if</span> <span class=\"n\">haystack</span><span class=\"p\">[</span><span class=\"n\">h</span><span class=\"p\">]</span> <span class=\"o\">==</span> <span class=\"n\">needle</span><span class=\"p\">[</span><span class=\"n\">n</span><span class=\"p\">]:</span> <span class=\"n\">n</span> <span class=\"o\">+=</span> <span class=\"mi\">1</span> <span class=\"k\">else</span><span class=\"p\">:</span> <span class=\"n\">h</span> <span class=\"o\">-=</span> <span class=\"n\">n</span> <span class=\"n\">n</span> <span class=\"o\">=</span> <span class=\"mi\">0</span> <span class=\"n\">h</span> <span class=\"o\">+=</span> <span class=\"mi\">1</span> <span class=\"k\">if</span> <span class=\"n\">n</span> <span class=\"o\">==</span> <span class=\"nf\">len</span><span class=\"p\">(</span><span class=\"n\">needle</span><span class=\"p\">):</span> <span class=\"k\">return</span> <span class=\"n\">h</span> <span class=\"o\">-</span> <span class=\"n\">n</span> <span class=\"k\">return</span> <span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"k\">if</span> <span class=\"n\">__name__</span> <span class=\"o\">==</span> <span class=\"sh\">'</span><span class=\"s\">__main__</span><span class=\"sh\">'</span><span class=\"p\">:</span> <span class=\"n\">r</span> <span class=\"o\">=</span> <span class=\"nc\">Solution</span><span class=\"p\">().</span><span class=\"n\">strStr</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">r</span><span class=\"p\">(</span><span class=\"sh\">\"</span><span class=\"s\">mississippi</span><span class=\"sh\">\"</span><span class=\"p\">,</span> <span class=\"sh\">\"</span><span class=\"s\">issip</span><span class=\"sh\">\"</span><span class=\"p\">),</span> <span class=\"mi\">4</span><span class=\"p\">)</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">r</span><span class=\"p\">(</span><span class=\"sh\">\"</span><span class=\"s\">hello</span><span class=\"sh\">\"</span><span class=\"p\">,</span> <span class=\"sh\">'</span><span class=\"s\">ll</span><span class=\"sh\">'</span><span class=\"p\">),</span> <span class=\"mi\">2</span><span class=\"p\">)</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">r</span><span class=\"p\">(</span><span class=\"sh\">'</span><span class=\"s\">a</span><span class=\"sh\">'</span><span class=\"p\">,</span><span class=\"sh\">'</span><span class=\"s\">a</span><span class=\"sh\">'</span><span class=\"p\">),</span> <span class=\"mi\">0</span><span class=\"p\">)</span></code></pre></figure>", "date_published": "2022-09-19T20:00:00+00:00" }, { "id": "https://fewald.net/leetcode/2022/09/18/leetcode-merge-two-lists.html", "url": "https://fewald.net/leetcode/2022/09/18/leetcode-merge-two-lists.html", "title": "Leetcode: Merge two lists", "content_html": "<figure class=\"highlight\"><pre><code class=\"language-python\" data-lang=\"python\"><span class=\"k\">class</span> <span class=\"nc\">Solution</span><span class=\"p\">:</span> <span class=\"k\">def</span> <span class=\"nf\">mergeTwoLists</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">list1</span><span class=\"p\">:</span> <span class=\"n\">Optional</span><span class=\"p\">[</span><span class=\"n\">ListNode</span><span class=\"p\">],</span> <span class=\"n\">list2</span><span class=\"p\">:</span> <span class=\"n\">Optional</span><span class=\"p\">[</span><span class=\"n\">ListNode</span><span class=\"p\">])</span> <span class=\"o\">-></span> <span class=\"n\">Optional</span><span class=\"p\">[</span><span class=\"n\">ListNode</span><span class=\"p\">]:</span> <span class=\"n\">root</span> <span class=\"o\">=</span> <span class=\"nc\">ListNode</span><span class=\"p\">()</span> <span class=\"n\">current</span> <span class=\"o\">=</span> <span class=\"n\">root</span> <span class=\"k\">while</span> <span class=\"n\">list1</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"bp\">None</span> <span class=\"ow\">and</span> <span class=\"n\">list2</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"bp\">None</span><span class=\"p\">:</span> <span class=\"k\">if</span> <span class=\"n\">list1</span><span class=\"p\">.</span><span class=\"n\">val</span> <span class=\"o\"><</span> <span class=\"n\">list2</span><span class=\"p\">.</span><span class=\"n\">val</span><span class=\"p\">:</span> <span class=\"n\">current</span><span class=\"p\">.</span><span class=\"nb\">next</span> <span class=\"o\">=</span> <span class=\"nc\">ListNode</span><span class=\"p\">(</span><span class=\"n\">list1</span><span class=\"p\">.</span><span class=\"n\">val</span><span class=\"p\">)</span> <span class=\"n\">current</span> <span class=\"o\">=</span> <span class=\"n\">current</span><span class=\"p\">.</span><span class=\"nb\">next</span> <span class=\"n\">list1</span> <span class=\"o\">=</span> <span class=\"n\">list1</span><span class=\"p\">.</span><span class=\"nb\">next</span> <span class=\"k\">else</span><span class=\"p\">:</span> <span class=\"n\">current</span><span class=\"p\">.</span><span class=\"nb\">next</span> <span class=\"o\">=</span> <span class=\"nc\">ListNode</span><span class=\"p\">(</span><span class=\"n\">list2</span><span class=\"p\">.</span><span class=\"n\">val</span><span class=\"p\">)</span> <span class=\"n\">current</span> <span class=\"o\">=</span> <span class=\"n\">current</span><span class=\"p\">.</span><span class=\"nb\">next</span> <span class=\"n\">list2</span> <span class=\"o\">=</span> <span class=\"n\">list2</span><span class=\"p\">.</span><span class=\"nb\">next</span> <span class=\"k\">if</span> <span class=\"n\">list1</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"bp\">None</span><span class=\"p\">:</span> <span class=\"n\">current</span><span class=\"p\">.</span><span class=\"nb\">next</span> <span class=\"o\">=</span> <span class=\"n\">list1</span> <span class=\"k\">if</span> <span class=\"n\">list2</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"bp\">None</span><span class=\"p\">:</span> <span class=\"n\">current</span><span class=\"p\">.</span><span class=\"nb\">next</span> <span class=\"o\">=</span> <span class=\"n\">list2</span> <span class=\"k\">return</span> <span class=\"n\">root</span><span class=\"p\">.</span><span class=\"nb\">next</span></code></pre></figure><h2 id=\"results\">Results</h2><p>Runtime: 34 ms, faster than 97.81% of Python3 online submissions for Merge Two Sorted Lists.</p><p>Memory Usage: 13.9 MB, less than 79.56% of Python3 online submissions for Merge Two Sorted Lists.</p>", "date_published": "2022-09-18T20:00:00+00:00" }, { "id": "https://fewald.net/leetcode/2022/09/17/leetcode-all-possible-subsets.html", "url": "https://fewald.net/leetcode/2022/09/17/leetcode-all-possible-subsets.html", "title": "Leetcode: All possible subsets", "content_html": "<p>A subset of a list with the elements <code class=\"language-plaintext highlighter-rouge\">{a,b,c}</code> is <code class=\"language-plaintext highlighter-rouge\">{a,b}</code>. The task is to find all possible subsets. Sets in programming languages are usually not ordered. Therefore, the set <code class=\"language-plaintext highlighter-rouge\">{a,b,c}</code> is equivalent to <code class=\"language-plaintext highlighter-rouge\">{b,c,a}</code>.</p><p>The idea for the solution is a nested <code class=\"language-plaintext highlighter-rouge\">for</code>-loop that iterates over the results again and again, starting with one empty (<code class=\"language-plaintext highlighter-rouge\">[]</code>) result.</p><!--more--><h2 id=\"solution\">Solution</h2><p>The code to solve this problem is listed here.</p><figure class=\"highlight\"><pre><code class=\"language-python\" data-lang=\"python\"><span class=\"kn\">from</span> <span class=\"n\">typing</span> <span class=\"kn\">import</span> <span class=\"n\">List</span><span class=\"k\">class</span> <span class=\"nc\">Solution</span><span class=\"p\">:</span> <span class=\"k\">def</span> <span class=\"nf\">subsets</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">nums</span><span class=\"p\">:</span> <span class=\"n\">List</span><span class=\"p\">[</span><span class=\"nb\">int</span><span class=\"p\">])</span> <span class=\"o\">-></span> <span class=\"n\">List</span><span class=\"p\">[</span><span class=\"n\">List</span><span class=\"p\">[</span><span class=\"nb\">int</span><span class=\"p\">]]:</span> <span class=\"n\">n</span> <span class=\"o\">=</span> <span class=\"nf\">len</span><span class=\"p\">(</span><span class=\"n\">nums</span><span class=\"p\">)</span> <span class=\"n\">output</span> <span class=\"o\">=</span> <span class=\"p\">[[]]</span> <span class=\"k\">for</span> <span class=\"n\">num</span> <span class=\"ow\">in</span> <span class=\"n\">nums</span><span class=\"p\">:</span> <span class=\"n\">output</span> <span class=\"o\">+=</span> <span class=\"p\">[</span><span class=\"n\">curr</span> <span class=\"o\">+</span> <span class=\"p\">[</span><span class=\"n\">num</span><span class=\"p\">]</span> <span class=\"k\">for</span> <span class=\"n\">curr</span> <span class=\"ow\">in</span> <span class=\"n\">output</span><span class=\"p\">]</span> <span class=\"k\">return</span> <span class=\"n\">output</span></code></pre></figure><h2 id=\"example\">Example</h2><p>Assuming that the input is <code class=\"language-plaintext highlighter-rouge\">[1,2,3]</code>. The execution steps look as follows:</p><figure class=\"highlight\"><pre><code class=\"language-python\" data-lang=\"python\"><span class=\"c1\"># Input</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">2</span><span class=\"p\">,</span> <span class=\"mi\">3</span><span class=\"p\">]</span><span class=\"c1\"># Initialization</span><span class=\"p\">[[]]</span><span class=\"c1\"># First iteration of outer loop</span><span class=\"p\">[[],</span> <span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">]]</span><span class=\"c1\"># Second iteration of outer loop# The previously added elements stay in place</span><span class=\"p\">[[],</span> <span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">],</span> <span class=\"p\">[</span><span class=\"mi\">2</span><span class=\"p\">],</span> <span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">2</span><span class=\"p\">]]</span><span class=\"c1\"># Third and final iteration of outer loop</span><span class=\"p\">[[],</span> <span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">],</span> <span class=\"p\">[</span><span class=\"mi\">2</span><span class=\"p\">],</span> <span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">2</span><span class=\"p\">],</span> <span class=\"p\">[</span><span class=\"mi\">3</span><span class=\"p\">],</span> <span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">3</span><span class=\"p\">],</span> <span class=\"p\">[</span><span class=\"mi\">2</span><span class=\"p\">,</span> <span class=\"mi\">3</span><span class=\"p\">],</span> <span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">2</span><span class=\"p\">,</span> <span class=\"mi\">3</span><span class=\"p\">]]</span></code></pre></figure>", "date_published": "2022-09-17T20:00:00+00:00" }, { "id": "https://fewald.net/leetcode/2022/09/16/leetcode-permutations.html", "url": "https://fewald.net/leetcode/2022/09/16/leetcode-permutations.html", "title": "Leetcode: Permutations", "content_html": "<p>The goal of this task is to find all possible permutations of numbers in a list. For example, <code class=\"language-plaintext highlighter-rouge\">[1,2,3]</code> can become <code class=\"language-plaintext highlighter-rouge\">[[1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], [3,2,1]</code>. Mathematically, the number of possible permutations without using duplicates is <code class=\"language-plaintext highlighter-rouge\">n!</code> where <code class=\"language-plaintext highlighter-rouge\">n</code> is the number of unique elements in the list.</p><p>This problem can best be solved by using backtracing and recursion. The general idea is to put all possible digits in the beginning and then cut off the rest of the list and repeat the first step. Later, the list is assembled. The algorithm stops if there is only one item in the list because the only possible permutation is with itself. The other special case that needs to be handled is the empty list which must return the empty list itself.</p><!--more--><figure class=\"highlight\"><pre><code class=\"language-python\" data-lang=\"python\"><span class=\"k\">class</span> <span class=\"nc\">Solution</span><span class=\"p\">:</span> <span class=\"k\">def</span> <span class=\"nf\">permute</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">nums</span><span class=\"p\">:</span> <span class=\"n\">List</span><span class=\"p\">[</span><span class=\"nb\">int</span><span class=\"p\">])</span> <span class=\"o\">-></span> <span class=\"n\">List</span><span class=\"p\">[</span><span class=\"n\">List</span><span class=\"p\">[</span><span class=\"nb\">int</span><span class=\"p\">]]:</span> <span class=\"c1\"># There are len(nums)! possible permutations</span> <span class=\"n\">res</span> <span class=\"o\">=</span> <span class=\"p\">[]</span> <span class=\"n\">res</span> <span class=\"o\">+=</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"nf\">inner</span><span class=\"p\">(</span><span class=\"n\">nums</span><span class=\"p\">)</span> <span class=\"k\">return</span> <span class=\"n\">res</span> <span class=\"k\">def</span> <span class=\"nf\">inner</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">nums</span><span class=\"p\">):</span> <span class=\"k\">if</span> <span class=\"nf\">len</span><span class=\"p\">(</span><span class=\"n\">nums</span><span class=\"p\">)</span> <span class=\"o\">==</span> <span class=\"mi\">0</span><span class=\"p\">:</span> <span class=\"k\">return</span> <span class=\"p\">[]</span> <span class=\"k\">if</span> <span class=\"nf\">len</span><span class=\"p\">(</span><span class=\"n\">nums</span><span class=\"p\">)</span> <span class=\"o\">==</span> <span class=\"mi\">1</span><span class=\"p\">:</span> <span class=\"k\">return</span> <span class=\"p\">[</span><span class=\"n\">nums</span><span class=\"p\">]</span> <span class=\"n\">res</span> <span class=\"o\">=</span> <span class=\"p\">[]</span> <span class=\"k\">for</span> <span class=\"n\">i</span> <span class=\"ow\">in</span> <span class=\"nf\">range</span><span class=\"p\">(</span><span class=\"nf\">len</span><span class=\"p\">(</span><span class=\"n\">nums</span><span class=\"p\">)):</span> <span class=\"c1\"># Copy the list to avoid changing it in memory</span> <span class=\"n\">t</span> <span class=\"o\">=</span> <span class=\"n\">nums</span><span class=\"p\">.</span><span class=\"nf\">copy</span><span class=\"p\">()</span> <span class=\"c1\"># Swap i-th element with the first, placing every item</span> <span class=\"c1\"># at the front, one at a time</span> <span class=\"n\">t</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">],</span> <span class=\"n\">t</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">t</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">],</span> <span class=\"n\">t</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span> <span class=\"c1\"># The inner function will return a list of lists.</span> <span class=\"c1\"># Iterate over all lists and add them to the first </span> <span class=\"c1\"># element.</span> <span class=\"k\">for</span> <span class=\"n\">perm</span> <span class=\"ow\">in</span> <span class=\"n\">self</span><span class=\"p\">.</span><span class=\"nf\">inner</span><span class=\"p\">(</span><span class=\"n\">t</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">:]):</span> <span class=\"n\">res</span><span class=\"p\">.</span><span class=\"nf\">append</span><span class=\"p\">([</span><span class=\"n\">t</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]]</span> <span class=\"o\">+</span> <span class=\"n\">perm</span><span class=\"p\">)</span> <span class=\"k\">return</span> <span class=\"n\">res</span> <span class=\"k\">if</span> <span class=\"n\">__name__</span> <span class=\"o\">==</span> <span class=\"sh\">'</span><span class=\"s\">__main__</span><span class=\"sh\">'</span><span class=\"p\">:</span> <span class=\"n\">r</span> <span class=\"o\">=</span> <span class=\"nc\">Solution</span><span class=\"p\">().</span><span class=\"n\">permute</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"nf\">r</span><span class=\"p\">([</span><span class=\"mi\">1</span><span class=\"p\">,</span><span class=\"mi\">2</span><span class=\"p\">,</span><span class=\"mi\">3</span><span class=\"p\">]),</span> <span class=\"p\">[[</span><span class=\"mi\">1</span><span class=\"p\">,</span><span class=\"mi\">2</span><span class=\"p\">,</span><span class=\"mi\">3</span><span class=\"p\">],[</span><span class=\"mi\">1</span><span class=\"p\">,</span><span class=\"mi\">3</span><span class=\"p\">,</span><span class=\"mi\">2</span><span class=\"p\">],[</span><span class=\"mi\">2</span><span class=\"p\">,</span><span class=\"mi\">1</span><span class=\"p\">,</span><span class=\"mi\">3</span><span class=\"p\">],[</span><span class=\"mi\">2</span><span class=\"p\">,</span><span class=\"mi\">3</span><span class=\"p\">,</span><span class=\"mi\">1</span><span class=\"p\">],[</span><span class=\"mi\">3</span><span class=\"p\">,</span><span class=\"mi\">1</span><span class=\"p\">,</span><span class=\"mi\">2</span><span class=\"p\">],[</span><span class=\"mi\">3</span><span class=\"p\">,</span><span class=\"mi\">2</span><span class=\"p\">,</span><span class=\"mi\">1</span><span class=\"p\">]])</span></code></pre></figure><p>Runtime: 52 ms, faster than 73.88% of Python3 online submissions for Permutations.</p><p>Memory Usage: 14.1 MB, less than 22.42% of Python3 online submissions for Permutations.</p>", "date_published": "2022-09-16T20:00:00+00:00" }, { "id": "https://fewald.net/ruby/rails/2022/09/15/how-to-add-devise-to-rails.html", "url": "https://fewald.net/ruby/rails/2022/09/15/how-to-add-devise-to-rails.html", "title": "How to add Devise to Rails", "content_html": "<p>Great tutorial how to use Devise with Rails 7 and Turbo: <a href=\"https://www.youtube.com/watch?v=yZDTBItc3ZM\">Youtube</a>.</p>", "date_published": "2022-09-15T22:31:00+00:00" }, { "id": "https://fewald.net/leetcode/2022/09/15/leetcode-letter-case-permutation.html", "url": "https://fewald.net/leetcode/2022/09/15/leetcode-letter-case-permutation.html", "title": "Leetcode: Letter case permutation", "content_html": "<p>The task is to print all case permutations of letters from strings that can include digits and letters. For example, <code class=\"language-plaintext highlighter-rouge\">a1b</code> becomes <code class=\"language-plaintext highlighter-rouge\">a1b, a1B, A1b, A1B</code>.</p><p>The trick here is to realize that there are <code class=\"language-plaintext highlighter-rouge\">2^n</code> possible permutations where <code class=\"language-plaintext highlighter-rouge\">n</code> is the number of characters, excluding digits.</p><!--more--><p>One possible solution is shown below. The main idea is to generate binary numbers and then use the <code class=\"language-plaintext highlighter-rouge\">1</code> and <code class=\"language-plaintext highlighter-rouge\">0</code> in their places to either make the character uppercase or keep it lowercase. For example a decimal number <code class=\"language-plaintext highlighter-rouge\">2</code> is represented by <code class=\"language-plaintext highlighter-rouge\">b10</code> in binary notation. The number <code class=\"language-plaintext highlighter-rouge\">3</code> is represented by <code class=\"language-plaintext highlighter-rouge\">b11</code>, and so on. When left padding - meaning to write a prefix of <code class=\"language-plaintext highlighter-rouge\">0</code>, all possible combinations are found.</p><figure class=\"highlight\"><pre><code class=\"language-python\" data-lang=\"python\"><span class=\"kn\">from</span> <span class=\"n\">typing</span> <span class=\"kn\">import</span> <span class=\"n\">List</span><span class=\"k\">class</span> <span class=\"nc\">Solution</span><span class=\"p\">:</span> <span class=\"k\">def</span> <span class=\"nf\">letterCasePermutation</span><span class=\"p\">(</span><span class=\"n\">self</span><span class=\"p\">,</span> <span class=\"n\">s</span><span class=\"p\">:</span> <span class=\"nb\">str</span><span class=\"p\">)</span> <span class=\"o\">-></span> <span class=\"n\">List</span><span class=\"p\">[</span><span class=\"nb\">str</span><span class=\"p\">]:</span> <span class=\"n\">output</span> <span class=\"o\">=</span> <span class=\"p\">[]</span> <span class=\"n\">s</span> <span class=\"o\">=</span> <span class=\"n\">s</span><span class=\"p\">.</span><span class=\"nf\">lower</span><span class=\"p\">()</span> <span class=\"n\">n</span> <span class=\"o\">=</span> <span class=\"nf\">sum</span><span class=\"p\">([</span><span class=\"mi\">1</span> <span class=\"k\">if</span> <span class=\"n\">c</span><span class=\"p\">.</span><span class=\"nf\">isalpha</span><span class=\"p\">()</span> <span class=\"k\">else</span> <span class=\"mi\">0</span> <span class=\"k\">for</span> <span class=\"n\">c</span> <span class=\"ow\">in</span> <span class=\"n\">s</span><span class=\"p\">])</span> <span class=\"k\">for</span> <span class=\"n\">i</span> <span class=\"ow\">in</span> <span class=\"nf\">range</span><span class=\"p\">(</span><span class=\"mi\">2</span><span class=\"o\">**</span><span class=\"n\">n</span><span class=\"p\">):</span> <span class=\"n\">m</span> <span class=\"o\">=</span> <span class=\"sa\">f</span><span class=\"sh\">'</span><span class=\"si\">{</span><span class=\"nf\">bin</span><span class=\"p\">(</span><span class=\"n\">i</span><span class=\"p\">)[</span><span class=\"mi\">2</span><span class=\"si\">:</span><span class=\"p\">]</span><span class=\"si\">:</span><span class=\"mi\">0</span><span class=\"o\">></span><span class=\"si\">{</span><span class=\"n\">n</span><span class=\"si\">}}</span><span class=\"sh\">'</span> <span class=\"n\">t</span> <span class=\"o\">=</span> <span class=\"sh\">''</span> <span class=\"n\">counter</span> <span class=\"o\">=</span> <span class=\"mi\">0</span> <span class=\"k\">for</span> <span class=\"n\">c</span> <span class=\"ow\">in</span> <span class=\"n\">s</span><span class=\"p\">:</span> <span class=\"k\">if</span> <span class=\"n\">c</span><span class=\"p\">.</span><span class=\"nf\">isalpha</span><span class=\"p\">():</span> <span class=\"n\">t</span> <span class=\"o\">+=</span> <span class=\"n\">c</span><span class=\"p\">.</span><span class=\"nf\">upper</span><span class=\"p\">()</span> <span class=\"k\">if</span> <span class=\"n\">m</span><span class=\"p\">[</span><span class=\"n\">counter</span><span class=\"p\">]</span> <span class=\"o\">==</span> <span class=\"sh\">'</span><span class=\"s\">1</span><span class=\"sh\">'</span> <span class=\"k\">else</span> <span class=\"n\">c</span> <span class=\"n\">counter</span> <span class=\"o\">+=</span> <span class=\"mi\">1</span> <span class=\"k\">else</span><span class=\"p\">:</span> <span class=\"n\">t</span> <span class=\"o\">+=</span> <span class=\"n\">c</span> <span class=\"n\">output</span><span class=\"p\">.</span><span class=\"nf\">append</span><span class=\"p\">(</span><span class=\"n\">t</span><span class=\"p\">)</span> <span class=\"k\">return</span> <span class=\"n\">output</span></code></pre></figure><p>Runtime: 106 ms, faster than 33.96% of Python3 online submissions for Letter Case Permutation.</p><p>Memory Usage: 14.6 MB, less than 81.20% of Python3 online submissions for Letter Case Permutation.</p>", "date_published": "2022-09-15T20:00:00+00:00" }, { "id": "https://fewald.net/2022/09/04/nearest-binary-search.html", "url": "https://fewald.net/2022/09/04/nearest-binary-search.html", "title": "Nearest binary search", "content_html": "<p>To find the exact element or the next element that is greater than the target, use the following code. This algorithm returns an invalid index if the element that is searched for is greater than the greatest element in the array. This needs to be manually checked with <code class=\"language-plaintext highlighter-rouge\">s(items, target) == len(items)</code>.</p><figure class=\"highlight\"><pre><code class=\"language-python\" data-lang=\"python\"><span class=\"k\">def</span> <span class=\"nf\">s</span><span class=\"p\">(</span><span class=\"n\">items</span><span class=\"p\">,</span> <span class=\"n\">target</span><span class=\"p\">):</span> <span class=\"n\">l</span> <span class=\"o\">=</span> <span class=\"mi\">0</span> <span class=\"n\">r</span> <span class=\"o\">=</span> <span class=\"nf\">len</span><span class=\"p\">(</span><span class=\"n\">items</span><span class=\"p\">)</span> <span class=\"n\">m</span> <span class=\"o\">=</span> <span class=\"p\">(</span><span class=\"n\">l</span> <span class=\"o\">+</span> <span class=\"n\">r</span><span class=\"p\">)</span> <span class=\"o\">//</span> <span class=\"mi\">2</span> <span class=\"k\">while</span> <span class=\"n\">l</span> <span class=\"o\"><</span> <span class=\"n\">r</span><span class=\"p\">:</span> <span class=\"k\">if</span> <span class=\"n\">items</span><span class=\"p\">[</span><span class=\"n\">m</span><span class=\"p\">]</span> <span class=\"o\">==</span> <span class=\"n\">target</span><span class=\"p\">:</span> <span class=\"k\">return</span> <span class=\"n\">m</span> <span class=\"k\">elif</span> <span class=\"n\">items</span><span class=\"p\">[</span><span class=\"n\">m</span><span class=\"p\">]</span> <span class=\"o\"><=</span> <span class=\"n\">target</span><span class=\"p\">:</span> <span class=\"n\">l</span> <span class=\"o\">=</span> <span class=\"n\">m</span> <span class=\"o\">+</span> <span class=\"mi\">1</span> <span class=\"k\">elif</span> <span class=\"n\">items</span><span class=\"p\">[</span><span class=\"n\">m</span><span class=\"p\">]</span> <span class=\"o\">></span> <span class=\"n\">target</span><span class=\"p\">:</span> <span class=\"n\">r</span> <span class=\"o\">=</span> <span class=\"n\">m</span> <span class=\"n\">m</span> <span class=\"o\">=</span> <span class=\"p\">(</span><span class=\"n\">l</span> <span class=\"o\">+</span> <span class=\"n\">r</span><span class=\"p\">)</span> <span class=\"o\">//</span> <span class=\"mi\">2</span> <span class=\"k\">return</span> <span class=\"n\">m</span> <span class=\"n\">l</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">,</span><span class=\"mi\">2</span><span class=\"p\">,</span><span class=\"mi\">3</span><span class=\"p\">,</span><span class=\"mi\">5</span><span class=\"p\">,</span><span class=\"mi\">6</span><span class=\"p\">,</span><span class=\"mi\">7</span><span class=\"p\">,</span><span class=\"mi\">8</span><span class=\"p\">,</span><span class=\"mi\">20</span><span class=\"p\">,</span><span class=\"mi\">30</span><span class=\"p\">,</span><span class=\"mi\">40</span><span class=\"p\">,</span><span class=\"mi\">50</span><span class=\"p\">]</span><span class=\"n\">targets</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">,</span> <span class=\"mi\">3</span><span class=\"p\">,</span> <span class=\"mi\">4</span><span class=\"p\">,</span> <span class=\"mi\">11</span><span class=\"p\">,</span> <span class=\"mi\">12</span><span class=\"p\">,</span> <span class=\"mi\">20</span><span class=\"p\">,</span> <span class=\"mi\">30</span><span class=\"p\">,</span> <span class=\"mi\">38</span><span class=\"p\">]</span><span class=\"k\">for</span> <span class=\"n\">target</span> <span class=\"ow\">in</span> <span class=\"n\">targets</span><span class=\"p\">:</span> <span class=\"n\">idx</span> <span class=\"o\">=</span> <span class=\"nf\">s</span><span class=\"p\">(</span><span class=\"n\">l</span><span class=\"p\">,</span> <span class=\"n\">target</span><span class=\"p\">)</span> <span class=\"nf\">print</span><span class=\"p\">(</span><span class=\"sa\">f</span><span class=\"sh\">\"</span><span class=\"s\">[</span><span class=\"si\">{</span><span class=\"n\">target</span><span class=\"si\">:</span><span class=\"mi\">02</span><span class=\"si\">}</span><span class=\"s\">] Index: </span><span class=\"si\">{</span><span class=\"n\">idx</span><span class=\"si\">}</span><span class=\"s\"> => </span><span class=\"si\">{</span><span class=\"n\">l</span><span class=\"p\">[</span><span class=\"n\">idx</span><span class=\"p\">]</span><span class=\"si\">}</span><span class=\"sh\">\"</span><span class=\"p\">)</span></code></pre></figure><p>If you want to find the element which is exactly the element or less than the element, change the return value to <code class=\"language-plaintext highlighter-rouge\">return m - 1</code> instead. In the smallest case this will return <code class=\"language-plaintext highlighter-rouge\">-1</code> which means that the element searched for is smaller than the smallest on in the list. The resulting code looks like this:</p><figure class=\"highlight\"><pre><code class=\"language-python\" data-lang=\"python\"><span class=\"k\">def</span> <span class=\"nf\">s</span><span class=\"p\">(</span><span class=\"n\">items</span><span class=\"p\">,</span> <span class=\"n\">target</span><span class=\"p\">):</span> <span class=\"n\">l</span> <span class=\"o\">=</span> <span class=\"mi\">0</span> <span class=\"n\">r</span> <span class=\"o\">=</span> <span class=\"nf\">len</span><span class=\"p\">(</span><span class=\"n\">items</span><span class=\"p\">)</span> <span class=\"n\">m</span> <span class=\"o\">=</span> <span class=\"p\">(</span><span class=\"n\">l</span><span class=\"o\">+</span><span class=\"n\">r</span><span class=\"p\">)</span> <span class=\"o\">//</span> <span class=\"mi\">2</span> <span class=\"k\">while</span> <span class=\"n\">l</span> <span class=\"o\"><</span> <span class=\"n\">r</span><span class=\"p\">:</span> <span class=\"k\">if</span> <span class=\"n\">items</span><span class=\"p\">[</span><span class=\"n\">m</span><span class=\"p\">]</span> <span class=\"o\">==</span> <span class=\"n\">target</span><span class=\"p\">:</span> <span class=\"k\">return</span> <span class=\"n\">m</span> <span class=\"k\">elif</span> <span class=\"n\">items</span><span class=\"p\">[</span><span class=\"n\">m</span><span class=\"p\">]</span> <span class=\"o\"><=</span> <span class=\"n\">target</span><span class=\"p\">:</span> <span class=\"n\">l</span> <span class=\"o\">=</span> <span class=\"n\">m</span> <span class=\"o\">+</span> <span class=\"mi\">1</span> <span class=\"k\">elif</span> <span class=\"n\">items</span><span class=\"p\">[</span><span class=\"n\">m</span><span class=\"p\">]</span> <span class=\"o\">></span> <span class=\"n\">target</span><span class=\"p\">:</span> <span class=\"n\">r</span> <span class=\"o\">=</span> <span class=\"n\">m</span> <span class=\"n\">m</span> <span class=\"o\">=</span> <span class=\"p\">(</span><span class=\"n\">l</span><span class=\"o\">+</span><span class=\"n\">r</span><span class=\"p\">)</span> <span class=\"o\">//</span> <span class=\"mi\">2</span> <span class=\"k\">return</span> <span class=\"n\">m</span> <span class=\"o\">-</span> <span class=\"mi\">1</span></code></pre></figure>", "date_published": "2022-09-04T16:28:00+00:00" }, { "id": "https://fewald.net/python/2022/09/03/predictable-hash-function.html", "url": "https://fewald.net/python/2022/09/03/predictable-hash-function.html", "title": "Predictable hash function", "content_html": "<p>The <code class=\"language-plaintext highlighter-rouge\">hash</code> method in python produces different results for the same object on each different Python run. This is meant as a security feature to prevent predictable hash values. For testing, this can be disabled by setting the environment variable <code class=\"language-plaintext highlighter-rouge\">PYTHONHASHSEED</code> to <code class=\"language-plaintext highlighter-rouge\">0</code>. The hash value for a given key will then always be the same.</p><figure class=\"highlight\"><pre><code class=\"language-shell\" data-lang=\"shell\"><span class=\"nv\">PYTHONHASHSEED</span><span class=\"o\">=</span>0 python script.py</code></pre></figure>", "date_published": "2022-09-03T20:33:00+00:00" }, { "id": "https://fewald.net/machine-learning/2022/08/22/openai-api-price-reduction.html", "url": "https://fewald.net/machine-learning/2022/08/22/openai-api-price-reduction.html", "title": "OpenAI API price reduction", "content_html": "<p><a href=\"https://openai.com\">OpenAI</a> just reduced their prices, starting September 1 2022 on midnight UTC. For the DaVinci model, the price is cut by around two thirds.</p><table> <thead> <tr> <th>Model</th> <th>Before</th> <th>On Sept 1</th> </tr> </thead> <tbody> <tr> <td>Davinci</td> <td>$0.06 / 1k tokens</td> <td>$0.02 / 1k tokens</td> </tr> <tr> <td>Curie</td> <td>$0.006 / 1k tokens</td> <td>$0.002 / 1k tokens</td> </tr> <tr> <td>Babbage</td> <td>$0.0012 / 1k tokens</td> <td>$0.0005 / 1k tokens</td> </tr> <tr> <td>Ada</td> <td>$0.0008 / 1k tokens</td> <td>$0.0004 / 1k tokens</td> </tr> <tr> <td>Davinci Embeddings</td> <td>$0.6 / 1k tokens</td> <td>$0.2 / 1k tokens</td> </tr> <tr> <td>Curie Embeddings</td> <td>$0.06 / 1k tokens</td> <td>$0.02 / 1k tokens</td> </tr> <tr> <td>Babbage Embeddings</td> <td>$0.012 / 1k tokens</td> <td>$0.005 / 1k tokens</td> </tr> <tr> <td>Ada Embeddings</td> <td>$0.008 / 1k tokens</td> <td>$0.004 / 1k tokens</td> </tr> </tbody></table><p>This is a significant reduction. I am curious if that means that Dall-E 2 will follow this example in the near future.</p>", "date_published": "2022-08-22T17:41:00+00:00" }, { "id": "https://fewald.net/ruby/rails/2022/08/08/secure-sidekiq-with-basicauth.html", "url": "https://fewald.net/ruby/rails/2022/08/08/secure-sidekiq-with-basicauth.html", "title": "Secure Sidekiq with BasicAuth", "content_html": "<p>I am using Sidekiq for background processing for my website Every Podcast. One of the background jobs is <a href=\"https://everypodcast.page/episodes\">loading new episodes</a> from known feeds. Because this relies on external resources, many things that are out of my control can go wrong. To isolate the individual fetch and potential errors, I automatically create a job for every single podcast update. This obviously leads to a lot of jobs. Sidekiq comes with a UI that allows me to monitor the job queue, find dead jobs and see the throughput.</p><!--more--><p>While looking on how to secure the backend interface I found many <a href=\"https://stackoverflow.com/a/46891659/636676\">articles</a>, also from the developers themselves, that recommend using the authentication framework Devise. I didn’t want to introduce a whole framework for a single use case, especially considering that there are currently no user accounts supported. Instead, something like <strong>Basic Auth</strong> is enough for my use case.</p><p>I came across this <a href=\"https://stackoverflow.com/a/13409418/636676\">Stackoverflow post</a> which suggested a solution similar to the one shown below. I added a default username and password if they’re not set to allow for easier local testing. In a production environment those values are coming from environment variables.</p><figure class=\"highlight\"><pre><code class=\"language-ruby\" data-lang=\"ruby\"><span class=\"no\">Sidekiq</span><span class=\"o\">::</span><span class=\"no\">Web</span><span class=\"p\">.</span><span class=\"nf\">use</span><span class=\"p\">(</span><span class=\"no\">Rack</span><span class=\"o\">::</span><span class=\"no\">Auth</span><span class=\"o\">::</span><span class=\"no\">Basic</span><span class=\"p\">)</span> <span class=\"k\">do</span> <span class=\"o\">|</span><span class=\"n\">user</span><span class=\"p\">,</span> <span class=\"n\">password</span><span class=\"o\">|</span> <span class=\"c1\"># Protect against timing attacks:</span> <span class=\"c1\"># - See https://codahale.com/a-lesson-in-timing-attacks/</span> <span class=\"c1\"># - See https://thisdata.com/blog/timing-attacks-against-string-comparison/</span> <span class=\"c1\"># - Use & (do not use &&) so that it doesn't short circuit.</span> <span class=\"c1\"># - Use digests to stop length information leaking</span> <span class=\"no\">Rack</span><span class=\"o\">::</span><span class=\"no\">Utils</span><span class=\"p\">.</span><span class=\"nf\">secure_compare</span><span class=\"p\">(</span><span class=\"o\">::</span><span class=\"no\">Digest</span><span class=\"o\">::</span><span class=\"no\">SHA256</span><span class=\"p\">.</span><span class=\"nf\">hexdigest</span><span class=\"p\">(</span><span class=\"n\">user</span><span class=\"p\">),</span> <span class=\"o\">::</span><span class=\"no\">Digest</span><span class=\"o\">::</span><span class=\"no\">SHA256</span><span class=\"p\">.</span><span class=\"nf\">hexdigest</span><span class=\"p\">(</span><span class=\"no\">ENV</span><span class=\"p\">[</span><span class=\"s1\">'SIDEKIQ_USER'</span><span class=\"p\">]</span> <span class=\"o\">||</span> <span class=\"s1\">'admin'</span><span class=\"p\">))</span> <span class=\"o\">&</span> <span class=\"no\">Rack</span><span class=\"o\">::</span><span class=\"no\">Utils</span><span class=\"p\">.</span><span class=\"nf\">secure_compare</span><span class=\"p\">(</span><span class=\"o\">::</span><span class=\"no\">Digest</span><span class=\"o\">::</span><span class=\"no\">SHA256</span><span class=\"p\">.</span><span class=\"nf\">hexdigest</span><span class=\"p\">(</span><span class=\"n\">password</span><span class=\"p\">),</span> <span class=\"o\">::</span><span class=\"no\">Digest</span><span class=\"o\">::</span><span class=\"no\">SHA256</span><span class=\"p\">.</span><span class=\"nf\">hexdigest</span><span class=\"p\">(</span><span class=\"no\">ENV</span><span class=\"p\">[</span><span class=\"s1\">'SIDEKIQ_PASSWORD'</span><span class=\"p\">]</span> <span class=\"o\">||</span> <span class=\"s1\">'password'</span><span class=\"p\">))</span><span class=\"k\">end</span></code></pre></figure>", "date_published": "2022-08-08T23:30:00+00:00" }, { "id": "https://fewald.net/links/2022/07/30/aaron-koblin.html", "url": "https://fewald.net/links/2022/07/30/aaron-koblin.html", "title": "Visualizations by Aaron Koblin", "content_html": "<p>Beautiful visualizations and projects by <a href=\"http://www.aaronkoblin.com\">Aaron Koblin</a>. Through this I discovered the flight patterns, generated with the <a href=\"https://processing.org/\">processing framework</a> which is now on my list to try out.</p><p>I meant to post this some time ago and recently found it in my “drafts” folder.</p>", "date_published": "2022-07-30T05:00:00+00:00" }, { "id": "https://fewald.net/ruby/rails/2022/07/28/fast-feed-processing-in-ruby.html", "url": "https://fewald.net/ruby/rails/2022/07/28/fast-feed-processing-in-ruby.html", "title": "Fast feed processing in Ruby and Rails", "content_html": "<p>While working on my current project, <a href=\"https://everypodcast.page\">everypodcast</a>, I needed to implement an RSS feed parser, mostly for iTunes RSS feeds. Initially I went with the builtin <code class=\"language-plaintext highlighter-rouge\">RSS</code> package from the standard library. When reading a lot of large XML feeds, I noticed that parsing those feeds takes anywhere from 0.5 to over 30 seconds. At the same time the process was using a 100% CPU.</p><p>After some searching I found <a href=\"https://github.com/feedjira/feedjira\">Feedjira</a>. With this, it now takes on average 0.5 seconds and at most 1.5 seconds to parse even the longest feeds. Furthermore it has dedicated support for different types of RSS feeds, I highly recommend it.</p><!--more--><p>Installation via <code class=\"language-plaintext highlighter-rouge\">Gemfile</code>:</p><figure class=\"highlight\"><pre><code class=\"language-ruby\" data-lang=\"ruby\"><span class=\"n\">gem</span> <span class=\"s1\">'feedjira'</span><span class=\"p\">,</span> <span class=\"s1\">'~> 3.2'</span></code></pre></figure><p>Parsing feeds is as simple as this:</p><figure class=\"highlight\"><pre><code class=\"language-ruby\" data-lang=\"ruby\"><span class=\"no\">URI</span><span class=\"p\">.</span><span class=\"nf\">parse</span><span class=\"p\">(</span><span class=\"n\">url</span><span class=\"p\">).</span><span class=\"nf\">open</span><span class=\"p\">(</span><span class=\"ss\">read_timeout: </span><span class=\"mi\">10</span><span class=\"p\">)</span> <span class=\"k\">do</span> <span class=\"o\">|</span><span class=\"n\">rss</span><span class=\"o\">|</span> <span class=\"n\">feed</span> <span class=\"o\">=</span> <span class=\"no\">Feedjira</span><span class=\"p\">.</span><span class=\"nf\">parse</span><span class=\"p\">(</span><span class=\"n\">rss</span><span class=\"p\">.</span><span class=\"nf\">read</span><span class=\"p\">)</span> <span class=\"c1\"># Feed attributes can be accessed as follows</span> <span class=\"n\">feed</span><span class=\"p\">.</span><span class=\"nf\">language</span> <span class=\"c1\">#=> 'en'</span><span class=\"k\">end</span></code></pre></figure>", "date_published": "2022-07-28T16:56:00+00:00" }, { "id": "https://fewald.net/ruby/rails/2022/07/18/rails-testing-with-static-server.html", "url": "https://fewald.net/ruby/rails/2022/07/18/rails-testing-with-static-server.html", "title": "Rails testing with static server", "content_html": "<p>I wanted to test some part of my application that performs HTTP requests against a different website. Now, for testing, I didn’t want to perform actual outside HTTP calls because they tend to become flaky if the internnet becomes unstable or when the remote resource is not available. Another reason, why I didn’t want to use the rails server and their static files, is that I didn’t want to serve those files in production. So I decided to write my own static file server.</p><!--more--><h2 id=\"requirements\">Requirements</h2><p>The requirements are quite simple. I wanted something that I can spin up from Ruby in the current process and that is able to serve static files from a predefined folder. For this purpose, I created a <code class=\"language-plaintext highlighter-rouge\">files</code> folder under <code class=\"language-plaintext highlighter-rouge\">fixtures</code>. The other requirement is that I did not want it to clash with any other server that might be running on the target system. The reason is that I am planning to run this on my CI pipeline and I have very little control over what runs there. Furthermore, if tests run in parallel I didn’t want to spend much time on synchronization, instead spin up a temporary server for each test and shut it down immediately afterwards.</p><h2 id=\"solution\">Solution</h2><p>I came up with two methods that I added to the <code class=\"language-plaintext highlighter-rouge\">test_helper.rb</code> in my Rails application: <code class=\"language-plaintext highlighter-rouge\">fixture_server</code> and <code class=\"language-plaintext highlighter-rouge\">replace_port!</code>. The former starts a server and returns the instance of the server itself, giving full control over the server process, including shutdown. This is intended if the server should run for a whole suite instead of for a single test. The block mode allows to start a server inline, and end it immediately. This mode is intended for cases when only a single tests uses the server. See the following example for example usage.</p><figure class=\"highlight\"><pre><code class=\"language-ruby\" data-lang=\"ruby\"><span class=\"k\">def</span> <span class=\"nf\">demo_explicit_shutdown</span> <span class=\"n\">server</span> <span class=\"o\">=</span> <span class=\"n\">fixture_server</span> <span class=\"n\">port</span> <span class=\"o\">=</span> <span class=\"n\">server</span><span class=\"p\">.</span><span class=\"nf\">config</span><span class=\"p\">[</span><span class=\"ss\">:Port</span><span class=\"p\">]</span> <span class=\"c1\"># Do something with the server</span> <span class=\"c1\"># ...</span> <span class=\"c1\"># Stop server</span> <span class=\"n\">server</span><span class=\"p\">.</span><span class=\"nf\">shutdown</span><span class=\"k\">end</span><span class=\"k\">def</span> <span class=\"nf\">demo_block_mode</span> <span class=\"n\">fixture_server</span> <span class=\"k\">do</span> <span class=\"o\">|</span><span class=\"n\">server</span><span class=\"p\">,</span> <span class=\"n\">port</span><span class=\"o\">|</span> <span class=\"c1\"># Do something with server and port</span> <span class=\"c1\"># ...</span> <span class=\"c1\"># No need to shutdown server</span> <span class=\"k\">end</span><span class=\"k\">end</span></code></pre></figure><p>As the port number is dynamic, the HTTP calls also need to be constructed dynamically. I found that it is relatively easy to write <code class=\"language-plaintext highlighter-rouge\"><PORT></code> in my URLs and then use the small helper method <code class=\"language-plaintext highlighter-rouge\">replace_port!</code> to replace the port via regular expression inline.</p><p>The complete code for the methods <code class=\"language-plaintext highlighter-rouge\">fixture_server</code> and <code class=\"language-plaintext highlighter-rouge\">replace_port!</code> is listed below. The dynamic port number is achieved by passing <code class=\"language-plaintext highlighter-rouge\">0</code>. This tells the system to use the first available port. The server is started in a different thread to be non-blocking and automatically shuts down upon receiving a <code class=\"language-plaintext highlighter-rouge\">SIGINT</code> signal.</p><figure class=\"highlight\"><pre><code class=\"language-ruby\" data-lang=\"ruby\"><span class=\"c1\"># Start a temporary server for fixtures which gets automatically shut down.</span><span class=\"c1\"># The port number is returned</span><span class=\"k\">def</span> <span class=\"nf\">fixture_server</span> <span class=\"n\">root</span> <span class=\"o\">=</span> <span class=\"no\">Rails</span><span class=\"p\">.</span><span class=\"nf\">root</span><span class=\"p\">.</span><span class=\"nf\">join</span><span class=\"p\">(</span><span class=\"s1\">'test'</span><span class=\"p\">,</span> <span class=\"s1\">'fixtures'</span><span class=\"p\">,</span> <span class=\"s1\">'files'</span><span class=\"p\">)</span> <span class=\"n\">server</span> <span class=\"o\">=</span> <span class=\"no\">WEBrick</span><span class=\"o\">::</span><span class=\"no\">HTTPServer</span><span class=\"p\">.</span><span class=\"nf\">new</span> <span class=\"ss\">:Port</span> <span class=\"o\">=></span> <span class=\"mi\">0</span><span class=\"p\">,</span> <span class=\"ss\">:DocumentRoot</span> <span class=\"o\">=></span> <span class=\"n\">root</span> <span class=\"nb\">trap</span> <span class=\"s1\">'INT'</span> <span class=\"k\">do</span> <span class=\"n\">server</span><span class=\"p\">.</span><span class=\"nf\">shutdown</span> <span class=\"k\">end</span> <span class=\"no\">Thread</span><span class=\"p\">.</span><span class=\"nf\">new</span> <span class=\"k\">do</span> <span class=\"n\">server</span><span class=\"p\">.</span><span class=\"nf\">start</span> <span class=\"k\">end</span> <span class=\"k\">if</span> <span class=\"nb\">block_given?</span> <span class=\"k\">yield</span><span class=\"p\">(</span><span class=\"n\">server</span><span class=\"p\">,</span> <span class=\"n\">server</span><span class=\"p\">.</span><span class=\"nf\">config</span><span class=\"p\">[</span><span class=\"ss\">:Port</span><span class=\"p\">])</span> <span class=\"n\">server</span><span class=\"p\">.</span><span class=\"nf\">stop</span> <span class=\"k\">end</span> <span class=\"n\">server</span><span class=\"k\">end</span><span class=\"c1\"># Replace port placeholder <PORT> with real port</span><span class=\"k\">def</span> <span class=\"nf\">replace_port!</span><span class=\"p\">(</span><span class=\"n\">s</span><span class=\"p\">,</span> <span class=\"n\">port</span><span class=\"p\">)</span> <span class=\"n\">s</span><span class=\"p\">.</span><span class=\"nf\">gsub!</span> <span class=\"sr\">/<PORT>/</span><span class=\"p\">,</span> <span class=\"n\">port</span><span class=\"p\">.</span><span class=\"nf\">to_s</span><span class=\"k\">end</span></code></pre></figure><p>Besides the installation of the <code class=\"language-plaintext highlighter-rouge\">webrick</code> gem, that is all that is needed to serve static files during tests in Rails from the <code class=\"language-plaintext highlighter-rouge\">fixtures/files</code> folder.</p>", "date_published": "2022-07-18T04:33:00+00:00" }, { "id": "https://fewald.net/2022/07/17/new-york-times-story-portrait.html", "url": "https://fewald.net/2022/07/17/new-york-times-story-portrait.html", "title": "New York Times Story Portrait", "content_html": "<p><a href=\"/assets/images/story-portrait.jpeg\"><picture><source srcset=\"/generated/assets/images/story-portrait-200-04d658255.avif 200w, /generated/assets/images/story-portrait-400-04d658255.avif 400w, /generated/assets/images/story-portrait-800-04d658255.avif 800w, /generated/assets/images/story-portrait-1200-04d658255.avif 1200w\" type=\"image/avif\"><source srcset=\"/generated/assets/images/story-portrait-200-e498de1f6.webp 200w, /generated/assets/images/story-portrait-400-e498de1f6.webp 400w, /generated/assets/images/story-portrait-800-e498de1f6.webp 800w, /generated/assets/images/story-portrait-1200-e498de1f6.webp 1200w\" type=\"image/webp\"><source srcset=\"/generated/assets/images/story-portrait-200-9b7030554.jpeg 200w, /generated/assets/images/story-portrait-400-9b7030554.jpeg 400w, /generated/assets/images/story-portrait-800-9b7030554.jpeg 800w, /generated/assets/images/story-portrait-1200-9b7030554.jpeg 1200w\" type=\"image/jpeg\"><img src=\"/generated/assets/images/story-portrait-800-9b7030554.jpeg\" alt=\"New York Time Story Portrait\" width=\"2160\" height=\"2700\"></picture></a></p><p>Really clever from the New York Times. You can create your own <a href=\"http://nytimes.com/storyportrait\">here</a>.</p>", "date_published": "2022-07-17T03:06:00+00:00" }, { "id": "https://fewald.net/seo/2022/07/08/improving-search-engine-optimization.html", "url": "https://fewald.net/seo/2022/07/08/improving-search-engine-optimization.html", "title": "Improving Search Engine Optimization", "content_html": "<p>As the final step in this very small series I tried improving the SEO (search engine optimization) score for my start page. I started out with a good score of 92. As usual, my goal was 100.</p><p><a href=\"/assets/images/lighthouse-seo-start-fewald.png\"><picture><source srcset=\"/generated/assets/images/lighthouse-seo-start-fewald-200-1cd893131.avif 200w, /generated/assets/images/lighthouse-seo-start-fewald-400-1cd893131.avif 400w, /generated/assets/images/lighthouse-seo-start-fewald-800-1cd893131.avif 800w, /generated/assets/images/lighthouse-seo-start-fewald-828-1cd893131.avif 828w\" type=\"image/avif\"><source srcset=\"/generated/assets/images/lighthouse-seo-start-fewald-200-8f272ea12.webp 200w, /generated/assets/images/lighthouse-seo-start-fewald-400-8f272ea12.webp 400w, /generated/assets/images/lighthouse-seo-start-fewald-800-8f272ea12.webp 800w, /generated/assets/images/lighthouse-seo-start-fewald-828-8f272ea12.webp 828w\" type=\"image/webp\"><source srcset=\"/generated/assets/images/lighthouse-seo-start-fewald-200-80af4b92d.png 200w, /generated/assets/images/lighthouse-seo-start-fewald-400-80af4b92d.png 400w, /generated/assets/images/lighthouse-seo-start-fewald-800-80af4b92d.png 800w, /generated/assets/images/lighthouse-seo-start-fewald-828-80af4b92d.png 828w\" type=\"image/png\"><img src=\"/generated/assets/images/lighthouse-seo-start-fewald-800-80af4b92d.png\" alt=\"Lighthouse score of 92 for fewald.net\" width=\"828\" height=\"436\"></picture></a></p><!--more--><h2 id=\"links\">Links</h2><p>As a first step I had to fix a broken link in one of my articles. One forgotten <code class=\"language-plaintext highlighter-rouge\">href</code> in a post needed to be fixed. Fixing this issue did not change the score.</p><h2 id=\"meta-description\">Meta description</h2><p>The start page didn’t have an HTML meta description, so I added one. I followed the best practices outlined <a href=\"https://web.dev/meta-description/\">here</a>.</p><ul> <li>Use a unique description for each page</li> <li>Clear and concise descriptions</li> <li>Avoid keyword stuffing</li> <li>No complete sentences needed, can be structured data</li></ul><p>Furthermore descriptions should be less than 160 characters to appear completely in search results.</p><figure class=\"highlight\"><pre><code class=\"language-html\" data-lang=\"html\"><span class=\"nt\"><meta</span> <span class=\"na\">name=</span><span class=\"s\">\"description\"</span> <span class=\"na\">content=</span><span class=\"s\">\"...\"</span><span class=\"nt\">></span></code></pre></figure><p>For the home page I chose a static description whereas for each individual post I wanted to either use the first 160 characters or, if provided, use an individual meta description. I achieved this with the following code in the templates.</p><figure class=\"highlight\"><pre><code class=\"language-liquid\" data-lang=\"liquid\"><span class=\"cp\">{%</span><span class=\"w\"> </span><span class=\"nt\">case</span><span class=\"w\"> </span><span class=\"nv\">page</span><span class=\"p\">.</span><span class=\"nv\">layout</span><span class=\"w\"> </span><span class=\"cp\">%}</span><span class=\"cp\">{%</span><span class=\"w\"> </span><span class=\"nt\">when</span><span class=\"w\"> </span><span class=\"s2\">\"post\"</span><span class=\"w\"> </span><span class=\"cp\">%}</span><span class=\"cp\">{%</span><span class=\"w\"> </span><span class=\"nt\">if</span><span class=\"w\"> </span><span class=\"nv\">page</span><span class=\"p\">.</span><span class=\"nv\">meta_description</span><span class=\"w\"> </span><span class=\"o\">==</span><span class=\"w\"> </span><span class=\"kc\">nil</span><span class=\"w\"> </span><span class=\"cp\">%}</span> <span class=\"cp\">{%</span><span class=\"w\"> </span><span class=\"nt\">assign</span><span class=\"w\"> </span><span class=\"nv\">meta_description</span><span class=\"w\"> </span><span class=\"o\">=</span><span class=\"w\"> </span><span class=\"nv\">page</span><span class=\"p\">.</span><span class=\"nv\">excerpt</span><span class=\"w\"> </span><span class=\"p\">|</span><span class=\"w\"> </span><span class=\"nf\">strip_html</span><span class=\"w\"> </span><span class=\"p\">|</span><span class=\"w\"> </span><span class=\"nf\">strip_newlines</span><span class=\"w\"> </span><span class=\"p\">|</span><span class=\"w\"> </span><span class=\"nf\">truncate</span><span class=\"p\">:</span><span class=\"w\"> </span><span class=\"mi\">160</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"s2\">\"... read more\"</span><span class=\"w\"> </span><span class=\"cp\">%}</span><span class=\"cp\">{%</span><span class=\"w\"> </span><span class=\"nt\">else</span><span class=\"w\"> </span><span class=\"cp\">%}</span> <span class=\"cp\">{%</span><span class=\"w\"> </span><span class=\"nt\">assign</span><span class=\"w\"> </span><span class=\"nv\">meta_description</span><span class=\"w\"> </span><span class=\"o\">=</span><span class=\"w\"> </span><span class=\"nv\">page</span><span class=\"p\">.</span><span class=\"nv\">meta_description</span><span class=\"w\"> </span><span class=\"cp\">%}</span><span class=\"cp\">{%</span><span class=\"w\"> </span><span class=\"nt\">endif</span><span class=\"w\"> </span><span class=\"cp\">%}</span><span class=\"cp\">{%</span><span class=\"w\"> </span><span class=\"nt\">when</span><span class=\"w\"> </span><span class=\"s2\">\"page\"</span><span class=\"w\"> </span><span class=\"cp\">%}</span><span class=\"cp\">{%</span><span class=\"w\"> </span><span class=\"nt\">unless</span><span class=\"w\"> </span><span class=\"nv\">page</span><span class=\"p\">.</span><span class=\"nv\">meta_description</span><span class=\"w\"> </span><span class=\"o\">==</span><span class=\"w\"> </span><span class=\"kc\">nil</span><span class=\"w\"> </span><span class=\"cp\">%}</span> <span class=\"cp\">{%</span><span class=\"w\"> </span><span class=\"nt\">assign</span><span class=\"w\"> </span><span class=\"nv\">meta_description</span><span class=\"w\"> </span><span class=\"o\">=</span><span class=\"w\"> </span><span class=\"nv\">page</span><span class=\"p\">.</span><span class=\"nv\">meta_description</span><span class=\"w\"> </span><span class=\"cp\">%}</span><span class=\"cp\">{%</span><span class=\"w\"> </span><span class=\"nt\">endunless</span><span class=\"w\"> </span><span class=\"cp\">%}</span><span class=\"cp\">{%</span><span class=\"w\"> </span><span class=\"nt\">else</span><span class=\"w\"> </span><span class=\"cp\">%}</span><span class=\"cp\">{%</span><span class=\"w\"> </span><span class=\"nt\">assign</span><span class=\"w\"> </span><span class=\"nv\">meta_description</span><span class=\"w\"> </span><span class=\"o\">=</span><span class=\"w\"> </span><span class=\"nv\">site</span><span class=\"p\">.</span><span class=\"nv\">meta_description</span><span class=\"w\"> </span><span class=\"cp\">%}</span><span class=\"cp\">{%</span><span class=\"w\"> </span><span class=\"nt\">endcase</span><span class=\"w\"> </span><span class=\"cp\">-%}</span><span class=\"cp\">{%</span><span class=\"w\"> </span><span class=\"nt\">unless</span><span class=\"w\"> </span><span class=\"nv\">meta_description</span><span class=\"w\"> </span><span class=\"o\">==</span><span class=\"w\"> </span><span class=\"kc\">nil</span><span class=\"w\"> </span><span class=\"cp\">%}</span><meta name=\"description\" content=\"<span class=\"cp\">{{</span><span class=\"w\"> </span><span class=\"nv\">meta_description</span><span class=\"w\"> </span><span class=\"cp\">}}</span>\"><span class=\"cp\">{%</span><span class=\"w\"> </span><span class=\"nt\">endunless</span><span class=\"w\"> </span><span class=\"cp\">-%}</span></code></pre></figure><p>This change brought the score to 100 and concluded my improvements for now.</p><p><a href=\"/assets/images/lighthouse-seo-100-fewald.png\"><picture><source srcset=\"/generated/assets/images/lighthouse-seo-100-fewald-200-769de143f.avif 200w, /generated/assets/images/lighthouse-seo-100-fewald-400-769de143f.avif 400w, /generated/assets/images/lighthouse-seo-100-fewald-800-769de143f.avif 800w, /generated/assets/images/lighthouse-seo-100-fewald-886-769de143f.avif 886w\" type=\"image/avif\"><source srcset=\"/generated/assets/images/lighthouse-seo-100-fewald-200-a1c570f19.webp 200w, /generated/assets/images/lighthouse-seo-100-fewald-400-a1c570f19.webp 400w, /generated/assets/images/lighthouse-seo-100-fewald-800-a1c570f19.webp 800w, /generated/assets/images/lighthouse-seo-100-fewald-886-a1c570f19.webp 886w\" type=\"image/webp\"><source srcset=\"/generated/assets/images/lighthouse-seo-100-fewald-200-45b3d0010.png 200w, /generated/assets/images/lighthouse-seo-100-fewald-400-45b3d0010.png 400w, /generated/assets/images/lighthouse-seo-100-fewald-800-45b3d0010.png 800w, /generated/assets/images/lighthouse-seo-100-fewald-886-45b3d0010.png 886w\" type=\"image/png\"><img src=\"/generated/assets/images/lighthouse-seo-100-fewald-800-45b3d0010.png\" alt=\"Lighthouse score of 100 for blog at fewald.net\" width=\"886\" height=\"464\"></picture></a></p>", "date_published": "2022-07-08T06:22:00+00:00" }, { "id": "https://fewald.net/2022/07/08/improving-website-accessibility.html", "url": "https://fewald.net/2022/07/08/improving-website-accessibility.html", "title": "Improving Website Accessibility", "content_html": "<p>Continuing from before, I wanted to improve the accessibility on this website as much as possible. The initial Lighthouse run gave me a score of around 82, which is not too bad, but I definitely wanted to improve it.</p><!--more--><h2 id=\"background-and-foreground-colors-do-not-have-a-sufficient-contrast-ratio\">Background and foreground colors do not have a sufficient contrast ratio</h2><p>The first thing I did was to increase the contrast on the site. Several elements had a too low contrast against their background. Google <a href=\"https://web.dev/color-contrast/\">recommends</a> a contrast of 4.5:1 for text less than 18px and 3:1 for text equal or greater than 18px.</p><p>Luckily there is an easy way to achieve this via the Chrome dev tools. Simply select an element that violates this rule and click on the “fix” button, then copy the new color code into the CSS. After repeating this multiple times, I reran the test and everything in regards to the contrast was fixed.</p><p><a href=\"/assets/images/lighthouse-contrast-ratio.png\"><picture><source srcset=\"/generated/assets/images/lighthouse-contrast-ratio-200-370092959.avif 200w, /generated/assets/images/lighthouse-contrast-ratio-400-370092959.avif 400w, /generated/assets/images/lighthouse-contrast-ratio-582-370092959.avif 582w\" type=\"image/avif\"><source srcset=\"/generated/assets/images/lighthouse-contrast-ratio-200-a8f01ef5e.webp 200w, /generated/assets/images/lighthouse-contrast-ratio-400-a8f01ef5e.webp 400w, /generated/assets/images/lighthouse-contrast-ratio-582-a8f01ef5e.webp 582w\" type=\"image/webp\"><source srcset=\"/generated/assets/images/lighthouse-contrast-ratio-200-b1576a3c1.png 200w, /generated/assets/images/lighthouse-contrast-ratio-400-b1576a3c1.png 400w, /generated/assets/images/lighthouse-contrast-ratio-582-b1576a3c1.png 582w\" type=\"image/png\"><img src=\"/generated/assets/images/lighthouse-contrast-ratio-582-b1576a3c1.png\" alt=\"Google Chrome warning about too low contrast ration in developer tools\" width=\"582\" height=\"327\"></picture></a></p><h2 id=\"form-elements-do-not-have-associated-labels\">Form elements do not have associated labels</h2><p>Another easy fix with <code class=\"language-plaintext highlighter-rouge\">aria-label</code>. The checkbox that Lighthouse complained about is used to keep the state of the side menu.</p><figure class=\"highlight\"><pre><code class=\"language-html\" data-lang=\"html\"><span class=\"nt\"><input</span> <span class=\"na\">aria-label=</span><span class=\"s\">\"Sidebar\"</span> <span class=\"na\">type=</span><span class=\"s\">\"checkbox\"</span> <span class=\"na\">class=</span><span class=\"s\">\"sidebar-checkbox\"</span> <span class=\"na\">id=</span><span class=\"s\">\"sidebar-checkbox\"</span><span class=\"nt\">></span></code></pre></figure><h2 id=\"user-scalable\">User scalable</h2><p>As a last step it was recommended that I change the maximum viewport scale level to 5. All I had to change was one line.</p><figure class=\"highlight\"><pre><code class=\"language-html\" data-lang=\"html\"><span class=\"nt\"><meta</span> <span class=\"na\">name=</span><span class=\"s\">\"viewport\"</span> <span class=\"na\">content=</span><span class=\"s\">\"width=device-width, initial-scale=1.0, maximum-scale=5\"</span><span class=\"nt\">></span></code></pre></figure><h2 id=\"results\">Results</h2><p>After these three relatively minor tweaks, I was able to reach an accessibility level of <strong>100</strong>.</p><p><a href=\"/assets/images/lighthouse-accessibility-100-fewald.png\"><picture><source srcset=\"/generated/assets/images/lighthouse-accessibility-100-fewald-200-1fe4771f2.avif 200w, /generated/assets/images/lighthouse-accessibility-100-fewald-400-1fe4771f2.avif 400w, /generated/assets/images/lighthouse-accessibility-100-fewald-800-1fe4771f2.avif 800w, /generated/assets/images/lighthouse-accessibility-100-fewald-802-1fe4771f2.avif 802w\" type=\"image/avif\"><source srcset=\"/generated/assets/images/lighthouse-accessibility-100-fewald-200-a7a61bd92.webp 200w, /generated/assets/images/lighthouse-accessibility-100-fewald-400-a7a61bd92.webp 400w, /generated/assets/images/lighthouse-accessibility-100-fewald-800-a7a61bd92.webp 800w, /generated/assets/images/lighthouse-accessibility-100-fewald-802-a7a61bd92.webp 802w\" type=\"image/webp\"><source srcset=\"/generated/assets/images/lighthouse-accessibility-100-fewald-200-fc82b1784.png 200w, /generated/assets/images/lighthouse-accessibility-100-fewald-400-fc82b1784.png 400w, /generated/assets/images/lighthouse-accessibility-100-fewald-800-fc82b1784.png 800w, /generated/assets/images/lighthouse-accessibility-100-fewald-802-fc82b1784.png 802w\" type=\"image/png\"><img src=\"/generated/assets/images/lighthouse-accessibility-100-fewald-800-fc82b1784.png\" alt=\"Lighthouse showing score of 100 for Accessibility\" width=\"802\" height=\"398\"></picture></a></p>", "date_published": "2022-07-08T06:14:00+00:00" }, { "id": "https://fewald.net/2022/07/06/improving-page-speed.html", "url": "https://fewald.net/2022/07/06/improving-page-speed.html", "title": "Improving Page Speed", "content_html": "<p>One important thing for a good user experience is a fast website. Google offers the free tool <a href=\"https://pagespeed.web.dev/\">Page Speed Insights</a>. Running it initially on my website I already have a score of 99, which is pretty good. In the past I already spent a fair amount of time optimizing the bigger problems.</p><p><a href=\"/assets/images/page-speed-score-fewald.png\"><picture><source srcset=\"/generated/assets/images/page-speed-score-fewald-200-1e6abbe1f.avif 200w, /generated/assets/images/page-speed-score-fewald-400-1e6abbe1f.avif 400w, /generated/assets/images/page-speed-score-fewald-800-1e6abbe1f.avif 800w, /generated/assets/images/page-speed-score-fewald-1200-1e6abbe1f.avif 1200w\" type=\"image/avif\"><source srcset=\"/generated/assets/images/page-speed-score-fewald-200-4f1148a9f.webp 200w, /generated/assets/images/page-speed-score-fewald-400-4f1148a9f.webp 400w, /generated/assets/images/page-speed-score-fewald-800-4f1148a9f.webp 800w, /generated/assets/images/page-speed-score-fewald-1200-4f1148a9f.webp 1200w\" type=\"image/webp\"><source srcset=\"/generated/assets/images/page-speed-score-fewald-200-a6c2438e5.png 200w, /generated/assets/images/page-speed-score-fewald-400-a6c2438e5.png 400w, /generated/assets/images/page-speed-score-fewald-800-a6c2438e5.png 800w, /generated/assets/images/page-speed-score-fewald-1200-a6c2438e5.png 1200w\" type=\"image/png\"><img src=\"/generated/assets/images/page-speed-score-fewald-800-a6c2438e5.png\" alt=\"Google Page Speed score of 99\" width=\"2004\" height=\"946\"></picture></a></p><p>I looked at the tips to improve the page speed even further. There are four things that Google considers currently in need of improvement on this page.</p><!--more--><ul> <li>Ensure text remains visible during webfont load</li> <li>Image elements do not have explicit width and height</li> <li>Serve static assets with an efficient cache policy</li> <li>First Contentful Paint (3G)</li></ul><p><a href=\"/assets/images/page-speed-fewald-tips.png\"><picture><source srcset=\"/generated/assets/images/page-speed-fewald-tips-200-3d5e13c1e.avif 200w, /generated/assets/images/page-speed-fewald-tips-400-3d5e13c1e.avif 400w, /generated/assets/images/page-speed-fewald-tips-800-3d5e13c1e.avif 800w, /generated/assets/images/page-speed-fewald-tips-1200-3d5e13c1e.avif 1200w\" type=\"image/avif\"><source srcset=\"/generated/assets/images/page-speed-fewald-tips-200-4d2be39fd.webp 200w, /generated/assets/images/page-speed-fewald-tips-400-4d2be39fd.webp 400w, /generated/assets/images/page-speed-fewald-tips-800-4d2be39fd.webp 800w, /generated/assets/images/page-speed-fewald-tips-1200-4d2be39fd.webp 1200w\" type=\"image/webp\"><source srcset=\"/generated/assets/images/page-speed-fewald-tips-200-f78142f78.png 200w, /generated/assets/images/page-speed-fewald-tips-400-f78142f78.png 400w, /generated/assets/images/page-speed-fewald-tips-800-f78142f78.png 800w, /generated/assets/images/page-speed-fewald-tips-1200-f78142f78.png 1200w\" type=\"image/png\"><img src=\"/generated/assets/images/page-speed-fewald-tips-800-f78142f78.png\" alt=\"Google Page Speed recommendations to improve website speed\" width=\"1954\" height=\"434\"></picture></a></p><p>As a first step I made sure that the text remains visible during webfont load. It is recommended to add <code class=\"language-plaintext highlighter-rouge\">font-face: swap;</code> to the <code class=\"language-plaintext highlighter-rouge\">@font-face</code> CSS definition whenever a custom font is loaded that the browser has to fetch over the network. I am using the webfontloader library on my page. To change this, I had to slightly modify my Javascript code to the following. Note the <code class=\"language-plaintext highlighter-rouge\">&display=swap</code> in the end.</p><figure class=\"highlight\"><pre><code class=\"language-javascript\" data-lang=\"javascript\"><span class=\"nx\">WebFont</span><span class=\"p\">.</span><span class=\"nf\">load</span><span class=\"p\">({</span> <span class=\"na\">google</span><span class=\"p\">:</span> <span class=\"p\">{</span> <span class=\"na\">families</span><span class=\"p\">:</span> <span class=\"p\">[</span><span class=\"dl\">'</span><span class=\"s1\">PT Sans:400</span><span class=\"dl\">'</span><span class=\"p\">,</span> <span class=\"dl\">'</span><span class=\"s1\">PT Serif:400&display=swap</span><span class=\"dl\">'</span><span class=\"p\">]</span> <span class=\"p\">}</span><span class=\"p\">});</span></code></pre></figure><p>After this, the largest contentful paint dropped from 3 seconds to 2.6 seconds. The score remained unchanged.</p><p>The next step was the caching of static resources. Since I am using cloudflare to serve and cache my content, it was as easy as setting the cache time to 1 year. After this, I reran the tests: Interestingly, the score for mobile dropped to 86 while the desktop score increased to 100.</p><p>The remaining issue is setting the explicit width and height for images and using next-gen formats for images. Google prefers <a href=\"https://developers.google.com/speed/webp\">webp</a>. Luckily, there is a Jekyll plugin for this purpose which does a great job: <a href=\"https://github.com/rbuchberger/jekyll_picture_tag\">jekyll_picture_tag</a>. This gem requires <code class=\"language-plaintext highlighter-rouge\">vips</code> to be installed locally as well as in the CI pipeline. I was able to do it on my Mac via <code class=\"language-plaintext highlighter-rouge\">brew install vips</code>. As a CI pipeline I use bitbucket</p><p>To automatically generate different versions of the same image, I had to place the following code in my post:</p><figure class=\"highlight\"><pre><code class=\"language-plain\" data-lang=\"plain\">{% picture jpt-webp /assets/images/page-speed-score-fewald.png --alt Google Page Speed score of 99 %}</code></pre></figure><p>This creates the following HTML of which the browser picks the best version to display:</p><figure class=\"highlight\"><pre><code class=\"language-html\" data-lang=\"html\"><span class=\"nt\"><picture></span> <span class=\"nt\"><source</span> <span class=\"na\">srcset=</span><span class=\"s\">\"/generated/assets/images/page-speed-score-fewald-400-4f1148a9f.webp 400w, /generated/assets/images/page-speed-score-fewald-600-4f1148a9f.webp 600w, /generated/assets/images/page-speed-score-fewald-800-4f1148a9f.webp 800w, /generated/assets/images/page-speed-score-fewald-1000-4f1148a9f.webp 1000w\"</span> <span class=\"na\">type=</span><span class=\"s\">\"image/webp\"</span><span class=\"nt\">></span> <span class=\"nt\"></source></span> <span class=\"nt\"><source</span> <span class=\"na\">srcset=</span><span class=\"s\">\"/generated/assets/images/page-speed-score-fewald-400-a6c2438e5.png 400w, /generated/assets/images/page-speed-score-fewald-600-a6c2438e5.png 600w, /generated/assets/images/page-speed-score-fewald-800-a6c2438e5.png 800w, /generated/assets/images/page-speed-score-fewald-1000-a6c2438e5.png 1000w\"</span> <span class=\"na\">type=</span><span class=\"s\">\"image/png\"</span><span class=\"nt\">></span> <span class=\"nt\"></source></span> <span class=\"nt\"><img</span> <span class=\"na\">src=</span><span class=\"s\">\"/generated/assets/images/page-speed-score-fewald-800-a6c2438e5.png\"</span> <span class=\"na\">alt=</span><span class=\"s\">\"Google Page Speed score of 99\"</span> <span class=\"na\">loading=</span><span class=\"s\">\"lazy\"</span><span class=\"nt\">></span><span class=\"nt\"></picture></span></code></pre></figure><p>Serving webp images made the responses much smaller but didn’t have any significant effect on the score. The main issue remained still the first contentful paint. I <a href=\"https://github.com/typekit/webfontloader/issues/429#issuecomment-619632202\">read a tip</a> to prefetch fonts by adding the following lines to the <code class=\"language-plaintext highlighter-rouge\"><head></code> section.</p><figure class=\"highlight\"><pre><code class=\"language-html\" data-lang=\"html\"><span class=\"nt\"><link</span> <span class=\"na\">rel=</span><span class=\"s\">\"dns-prefetch\"</span> <span class=\"na\">href=</span><span class=\"s\">\"//fonts.googleapis.com\"</span><span class=\"nt\">></span><span class=\"nt\"><link</span> <span class=\"na\">rel=</span><span class=\"s\">\"preconnect\"</span> <span class=\"na\">href=</span><span class=\"s\">\"https://fonts.gstatic.com\"</span> <span class=\"na\">crossorigin</span><span class=\"nt\">></span></code></pre></figure><p>Finally, I added <code class=\"language-plaintext highlighter-rouge\">widths</code> and <code class=\"language-plaintext highlighter-rouge\">heights</code> to image tags. This is supported directly by jekyll picture tag preset. This has to be saved in <code class=\"language-plaintext highlighter-rouge\">_data/picture.yml</code>, the important part here is <code class=\"language-plaintext highlighter-rouge\">dimension_attributes: true</code>, which is not part of the default settings.</p><figure class=\"highlight\"><pre><code class=\"language-yaml\" data-lang=\"yaml\"><span class=\"na\">presets</span><span class=\"pi\">:</span> <span class=\"na\">default</span><span class=\"pi\">:</span> <span class=\"na\">formats</span><span class=\"pi\">:</span> <span class=\"pi\">[</span><span class=\"nv\">webp</span><span class=\"pi\">,</span> <span class=\"nv\">original</span><span class=\"pi\">]</span> <span class=\"na\">widths</span><span class=\"pi\">:</span> <span class=\"pi\">[</span><span class=\"nv\">200</span><span class=\"pi\">,</span> <span class=\"nv\">400</span><span class=\"pi\">,</span> <span class=\"nv\">800</span><span class=\"pi\">,</span> <span class=\"nv\">1200</span><span class=\"pi\">]</span> <span class=\"na\">link_source</span><span class=\"pi\">:</span> <span class=\"kc\">true</span> <span class=\"na\">dimension_attributes</span><span class=\"pi\">:</span> <span class=\"kc\">true</span></code></pre></figure><p>To avoid distortion of the images I had to add CSS similar to the following:</p><figure class=\"highlight\"><pre><code class=\"language-css\" data-lang=\"css\"><span class=\"nt\">img</span> <span class=\"p\">{</span> <span class=\"nl\">width</span><span class=\"p\">:</span> <span class=\"m\">100%</span><span class=\"p\">;</span> <span class=\"nl\">height</span><span class=\"p\">:</span> <span class=\"nb\">auto</span><span class=\"p\">;</span><span class=\"p\">}</span></code></pre></figure><p>With those improvements, I was able to reach a <strong>Google Page Speed 100</strong> with only one warning. As the next step I am planning to clean up the HTML for better accessibility (currently 62) and SEO (currently around 80).</p><p><a href=\"/assets/images/page-speed-performance-100-fewald.png\"><picture><source srcset=\"/generated/assets/images/page-speed-performance-100-fewald-200-f5eaffe94.avif 200w, /generated/assets/images/page-speed-performance-100-fewald-400-f5eaffe94.avif 400w, /generated/assets/images/page-speed-performance-100-fewald-774-f5eaffe94.avif 774w\" type=\"image/avif\"><source srcset=\"/generated/assets/images/page-speed-performance-100-fewald-200-f045618e7.webp 200w, /generated/assets/images/page-speed-performance-100-fewald-400-f045618e7.webp 400w, /generated/assets/images/page-speed-performance-100-fewald-774-f045618e7.webp 774w\" type=\"image/webp\"><source srcset=\"/generated/assets/images/page-speed-performance-100-fewald-200-4d120c6da.png 200w, /generated/assets/images/page-speed-performance-100-fewald-400-4d120c6da.png 400w, /generated/assets/images/page-speed-performance-100-fewald-774-4d120c6da.png 774w\" type=\"image/png\"><img src=\"/generated/assets/images/page-speed-performance-100-fewald-774-4d120c6da.png\" alt=\"Lighthouse report showing 100 performance for fewald.net\" width=\"774\" height=\"616\"></picture></a></p><p><strong>Update 2022-07-10</strong>: I read further on image formats and also enabled avif, which is an open standard and results in even smaller images. The browser now tries the images in the following order: AVIF, WebP, JPG/PNG.</p>", "date_published": "2022-07-06T22:24:00+00:00" }, { "id": "https://fewald.net/ruby-on-rails/2022/07/06/ruby-on-rails-nil-check.html", "url": "https://fewald.net/ruby-on-rails/2022/07/06/ruby-on-rails-nil-check.html", "title": "Ruby on Rails nil check", "content_html": "<p>Rails provides a great way to check for <code class=\"language-plaintext highlighter-rouge\">nil</code> and empty variables in the same call: <code class=\"language-plaintext highlighter-rouge\">blank?</code>. This is especially helpful in ERB templates where a variable can be either nil or empty, depending on the object. Without it, the check would look similar to this:</p><figure class=\"highlight\"><pre><code class=\"language-ruby\" data-lang=\"ruby\"><span class=\"o\"><</span><span class=\"sx\">% unless </span><span class=\"n\">obj</span><span class=\"p\">.</span><span class=\"nf\">nil?</span> <span class=\"ow\">and</span> <span class=\"n\">obj</span> <span class=\"o\">!=</span> <span class=\"s2\">\"\"</span> <span class=\"o\">%></span> <span class=\"o\"><</span><span class=\"sx\">%= obj %><% end %></span></code></pre></figure><p>This is quite cumbersome and easy to forget. With <code class=\"language-plaintext highlighter-rouge\">blank?</code>, this can be simplified to:</p><figure class=\"highlight\"><pre><code class=\"language-ruby\" data-lang=\"ruby\"><span class=\"o\"><</span><span class=\"sx\">% unless </span><span class=\"n\">obj</span><span class=\"p\">.</span><span class=\"nf\">blank?</span> <span class=\"sx\">%> <%= obj %></span><span class=\"o\"><</span><span class=\"sx\">% end </span><span class=\"o\">%></span></code></pre></figure><p>For the following values <code class=\"language-plaintext highlighter-rouge\">blank?</code> returns <code class=\"language-plaintext highlighter-rouge\">true</code> and <code class=\"language-plaintext highlighter-rouge\">false</code> respectively:</p><figure class=\"highlight\"><pre><code class=\"language-ruby\" data-lang=\"ruby\"><span class=\"s2\">\"\"</span><span class=\"p\">.</span><span class=\"nf\">blank?</span><span class=\"o\">=></span> <span class=\"kp\">true</span><span class=\"kp\">nil</span><span class=\"p\">.</span><span class=\"nf\">blank?</span><span class=\"o\">=></span> <span class=\"kp\">true</span><span class=\"s2\">\"hello\"</span><span class=\"p\">.</span><span class=\"nf\">blank?</span><span class=\"o\">=></span> <span class=\"kp\">false</span><span class=\"mi\">5</span><span class=\"p\">.</span><span class=\"nf\">blank?</span><span class=\"o\">=></span> <span class=\"kp\">false</span><span class=\"no\">AnyClass</span><span class=\"p\">.</span><span class=\"nf\">blank?</span><span class=\"o\">=></span> <span class=\"kp\">false</span></code></pre></figure>", "date_published": "2022-07-06T16:57:00+00:00" } ] }