<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Not To Work Lab</title><link>https://ntwlab.com/</link><description>Recent content on Not To Work Lab</description><generator>Hugo -- 0.146.3</generator><language>en</language><lastBuildDate>Sun, 04 May 2025 12:34:56 +0800</lastBuildDate><atom:link href="https://ntwlab.com/index.xml" rel="self" type="application/rss+xml"/><item><title>Combination Sum</title><link>https://ntwlab.com/posts/algorithm/39/</link><pubDate>Sun, 04 May 2025 12:34:56 +0800</pubDate><guid>https://ntwlab.com/posts/algorithm/39/</guid><description>&lt;h1 id="problem">Problem&lt;/h1>
&lt;p>&lt;a href="https://leetcode.com/problems/combination-sum">https://leetcode.com/problems/combination-sum&lt;/a>&lt;/p>
&lt;h1 id="what-is-the-problem">What is the Problem?&lt;/h1>
&lt;ol>
&lt;li>You are given a list of integers &lt;code>candidates&lt;/code>.&lt;/li>
&lt;li>You are also given an integer &lt;code>target&lt;/code>.&lt;/li>
&lt;li>Each number in &lt;code>candidates&lt;/code> can be reused any number of times.&lt;/li>
&lt;li>Return all unique combinations of numbers that sum up to &lt;code>target&lt;/code>.&lt;/li>
&lt;/ol>
&lt;h1 id="approach">Approach&lt;/h1>
&lt;ol>
&lt;li>Use a recursive approach with backtracking (similar to BFS) to explore all possible combinations.&lt;/li>
&lt;li>The base case of the recursion is when the sum of the current combination equals the &lt;code>target&lt;/code>.&lt;/li>
&lt;li>To avoid redundant computations and duplicate combinations, sort the list first and only consider the current or later candidates in recursive calls.&lt;/li>
&lt;/ol>
&lt;h1 id="solution">Solution&lt;/h1>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-py" data-lang="py">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">def&lt;/span> &lt;span style="color:#a6e22e">combinationSum&lt;/span>(candidates: List[int], target: int) &lt;span style="color:#f92672">-&amp;gt;&lt;/span> List[List[int]]:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> combinations &lt;span style="color:#f92672">=&lt;/span> []
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">def&lt;/span> &lt;span style="color:#a6e22e">helper&lt;/span>(index, target, selected):
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">if&lt;/span> target &lt;span style="color:#f92672">==&lt;/span> &lt;span style="color:#ae81ff">0&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span> selected
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">for&lt;/span> idx &lt;span style="color:#f92672">in&lt;/span> range(index, len(candidates)):
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> candidate &lt;span style="color:#f92672">=&lt;/span> candidates[idx]
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">if&lt;/span> target &lt;span style="color:#f92672">-&lt;/span> candidate &lt;span style="color:#f92672">&amp;gt;=&lt;/span> &lt;span style="color:#ae81ff">0&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> combination &lt;span style="color:#f92672">=&lt;/span> helper(idx, target &lt;span style="color:#f92672">-&lt;/span> candidate, selected &lt;span style="color:#f92672">+&lt;/span> [candidate])
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">if&lt;/span> combination &lt;span style="color:#f92672">and&lt;/span> combination &lt;span style="color:#f92672">not&lt;/span> &lt;span style="color:#f92672">in&lt;/span> combinations:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> combinations&lt;span style="color:#f92672">.&lt;/span>append(combination)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> helper(&lt;span style="color:#ae81ff">0&lt;/span>, target, [])
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span> combinations
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">assert&lt;/span> combinationSum([&lt;span style="color:#ae81ff">2&lt;/span>,&lt;span style="color:#ae81ff">3&lt;/span>,&lt;span style="color:#ae81ff">6&lt;/span>,&lt;span style="color:#ae81ff">7&lt;/span>], &lt;span style="color:#ae81ff">7&lt;/span>) &lt;span style="color:#f92672">==&lt;/span> [[&lt;span style="color:#ae81ff">2&lt;/span>,&lt;span style="color:#ae81ff">2&lt;/span>,&lt;span style="color:#ae81ff">3&lt;/span>],[&lt;span style="color:#ae81ff">7&lt;/span>]]
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h1 id="key-concepts">Key Concepts&lt;/h1>
&lt;ul>
&lt;li>Recursive exploration: We explore all paths by repeatedly subtracting from the target.&lt;/li>
&lt;li>Backtracking: We track the current path (selected) and backtrack when necessary.&lt;/li>
&lt;li>Avoiding duplicates: By always iterating from the current index (index), we prevent combinations with the same elements in different orders.&lt;/li>
&lt;/ul>
&lt;h1 id="time-complexity">Time Complexity&lt;/h1>
&lt;p>Let &lt;code>T&lt;/code> be the target and &lt;code>N&lt;/code> be the number of candidates. In the worst case, the time complexity is exponential, approximately &lt;code>O(N^T)&lt;/code>, due to the branching factor of the recursive calls.
Sorting the candidates first and pruning paths early can significantly reduce redundant computations.&lt;/p></description></item><item><title>Make a Test Framework [1/1]</title><link>https://ntwlab.com/posts/qa/auto/make-a-test-framework-1/</link><pubDate>Thu, 01 May 2025 12:34:56 +0800</pubDate><guid>https://ntwlab.com/posts/qa/auto/make-a-test-framework-1/</guid><description>&lt;h1 id="background">Background&lt;/h1>
&lt;p>There was a side project within our team focused on designing a new test framework that would allow others to easily add new test cases without needing to understand the underlying workings of the framework. The framework was also intended to be deployable across various platforms without requiring any toolchain setup in advance.&lt;/p>
&lt;p>Some compiled languages came to mind—Go in particular. Thanks to its static compilation and straightforward build process, we could deploy binaries to almost any platform in our company. It also happened to be my first project using Go, which made the experience even more exciting.&lt;/p></description></item></channel></rss>