<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>NPC Archives - Huahua&#039;s Tech Road</title>
	<atom:link href="https://zxi.mytechroad.com/blog/tag/npc/feed/" rel="self" type="application/rss+xml" />
	<link>https://zxi.mytechroad.com/blog/tag/npc/</link>
	<description></description>
	<lastBuildDate>Sat, 18 May 2019 00:07:02 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.0.8</generator>

<image>
	<url>https://zxi.mytechroad.com/blog/wp-content/uploads/2017/09/cropped-photo-32x32.jpg</url>
	<title>NPC Archives - Huahua&#039;s Tech Road</title>
	<link>https://zxi.mytechroad.com/blog/tag/npc/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>花花酱 LeetCode 943. Find the Shortest Superstring</title>
		<link>https://zxi.mytechroad.com/blog/searching/leetcode-943-find-the-shortest-superstring/</link>
					<comments>https://zxi.mytechroad.com/blog/searching/leetcode-943-find-the-shortest-superstring/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sun, 18 Nov 2018 23:10:30 +0000</pubDate>
				<category><![CDATA[Search]]></category>
		<category><![CDATA[dp]]></category>
		<category><![CDATA[Hamiltonian path]]></category>
		<category><![CDATA[hard]]></category>
		<category><![CDATA[NPC]]></category>
		<category><![CDATA[search]]></category>
		<category><![CDATA[TSP]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=4343</guid>

					<description><![CDATA[<p>Problem Given an array A of strings, find any&#160;smallest string that contains each string in&#160;A&#160;as a&#160;substring. We may assume that no string in&#160;A&#160;is substring of&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/searching/leetcode-943-find-the-shortest-superstring/">花花酱 LeetCode 943. Find the Shortest Superstring</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p><iframe width="500" height="375" src="https://www.youtube.com/embed/u_Wc4jwrp3Q?feature=oembed" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe></p>
<h1><strong>Problem</strong></h1>
<p>Given an array A of strings, find any&nbsp;smallest string that contains each string in&nbsp;<code>A</code>&nbsp;as a&nbsp;substring.</p>
<p>We may assume that no string in&nbsp;<code>A</code>&nbsp;is substring of another string in&nbsp;<code>A</code>.</p>
<div>
<p><strong>Example 1:</strong></p>
<pre class="crayon:false"><strong>Input: </strong><span id="example-input-1-1">["alex","loves","leetcode"]</span>
<strong>Output: </strong><span id="example-output-1">"alexlovesleetcode"</span>
<strong>Explanation: </strong>All permutations of "alex","loves","leetcode" would also be accepted.
</pre>
<div>
<p><strong>Example 2:</strong></p>
<pre class="crayon:false"><strong>Input: </strong><span id="example-input-2-1">["catg","ctaagt","gcta","ttca","atgcatc"]</span>
<strong>Output: </strong><span id="example-output-2">"gctaagttcatgcatc"</span></pre>
</div>
</div>
<p><strong>Note:</strong></p>
<ol>
<li><code>1 &lt;= A.length &lt;= 12</code></li>
<li><code>1 &lt;= A[i].length &lt;= 20</code></li>
</ol>
<p><img class="alignnone size-full wp-image-4352" src="https://zxi.mytechroad.com/blog/wp-content/uploads/2018/11/943-ep231.png" alt="" width="960" height="540"></p>
<h1><strong>Solution 1: Search +&nbsp;Pruning</strong></h1>
<p>Try all permutations. Pre-process the cost from word[i] to word[j] and store it in g[i][j].</p>
<p>Time complexity: O(n!)</p>
<p>Space complexity: O(n)</p>
<p><div class="responsive-tabs">
<h2 class="tabtitle">C++</h2>
<div class="tabcontent">
</p><pre class="crayon-plain-tag">// Author: Huahua, running time: 692 ms
class Solution {
public:
  string shortestSuperstring(vector&lt;string&gt;&amp; A) {    
    const int n = A.size();
    g_ = vector&lt;vector&lt;int&gt;&gt;(n, vector&lt;int&gt;(n));
    for (int i = 0; i &lt; n; ++i)
      for (int j = 0; j &lt; n; ++j) {
        g_[i][j] = A[j].length();
        for (int k = 1; k &lt;= min(A[i].length(), A[j].length()); ++k)
          if (A[i].substr(A[i].size() - k) == A[j].substr(0, k))            
            g_[i][j] = A[j].length() - k;
      }
    vector&lt;int&gt; path(n);
    best_len_ = INT_MAX;
    dfs(A, 0, 0, 0, path);    
    string ans = A[best_path_[0]];
    for (int k = 1; k &lt; best_path_.size(); ++k) {
      int i = best_path_[k - 1];
      int j = best_path_[k];
      ans += A[j].substr(A[j].length() - g_[i][j]);
    }
    return ans;
  }
private:
  vector&lt;vector&lt;int&gt;&gt; g_;
  vector&lt;int&gt; best_path_;
  int best_len_;
  void dfs(const vector&lt;string&gt;&amp; A, int d, int used, int cur_len, vector&lt;int&gt;&amp; path) {
    if (cur_len &gt;= best_len_) return;
    if (d == A.size()) {
      best_len_ = cur_len;
      best_path_ = path;
      return;
    }
    
    for (int i = 0; i &lt; A.size(); ++i) {
      if (used &amp; (1 &lt;&lt; i)) continue;      
      path[d] = i;
      dfs(A,
          d + 1, 
          used | (1 &lt;&lt; i),
          d == 0 ? A[i].length() : cur_len + g_[path[d - 1]][i],
          path);
    }
  }
};</pre><p></div><h2 class="tabtitle">Java</h2>
<div class="tabcontent">
</p><pre class="crayon-plain-tag">// Author: Huahua, 439 ms, 35.8MB
class Solution {
  private int n;
  private int[][] g;
  private String[] a;
  private int best_len;
  private int[] path;
  private int[] best_path;
  
  private void dfs(int d, int used, int cur_len) {
    if (cur_len &gt;= best_len) return;
    if (d == n) {
      best_len = cur_len;
      best_path = path.clone();
      return;
    }
    
    for (int i = 0; i &lt; n; ++i) {
      if ((used &amp; (1 &lt;&lt; i)) != 0) continue;
      path[d] = i;
      dfs(d + 1, 
          used | (1 &lt;&lt; i), 
          d == 0 ? a[i].length() : cur_len + g[path[d - 1]][i]);
    }
  }
  
  public String shortestSuperstring(String[] A) {
    n = A.length;
    g = new int[n][n];
    a = A;
    for (int i = 0; i &lt; n; ++i)
      for (int j = 0; j &lt; n; ++j) {
        g[i][j] = A[j].length();
        for (int k = 1; k &lt;= Math.min(A[i].length(), A[j].length()); ++k)
          if (A[i].substring(A[i].length() - k).equals(A[j].substring(0, k)))
            g[i][j] = A[j].length() - k;        
      }
    
    path = new int[n];
    best_len = Integer.MAX_VALUE;
    
    dfs(0, 0, 0);
    
    String ans = A[best_path[0]];
    for (int k = 1; k &lt; n; ++k) {
      int i = best_path[k - 1];
      int j = best_path[k];
      ans += A[j].substring(A[j].length() - g[i][j]);      
    }
    return ans;
  }
}</pre><p></div></div></p>
<h1><strong>Solution 2: DP</strong></h1>
<p>g[i][j] is the cost of appending word[j] after word[i], or weight of edge[i][j].</p>
<p>We would like find the shortest path to visit each node from 0 to n &#8211; 1 once and only once this is called&nbsp;the Travelling sells man&#8217;s problem which is NP-Complete.</p>
<p>We can solve it with DP that uses exponential time.</p>
<p>dp[s][i] := min distance to visit nodes (represented as a binary state s) once and only once and the path ends with node i.</p>
<p>e.g. dp[7][1] is the min distance to visit nodes (0, 1, 2) and ends with node 1, the possible paths could be (0, 2, 1), (2, 0, 1).</p>
<p>Time complexity: O(n^2 * 2^n)</p>
<p>Space complexity: O(n * 2^n)</p>
<p><div class="responsive-tabs">
<h2 class="tabtitle">C++</h2>
<div class="tabcontent">
</p><pre class="crayon-plain-tag">// Author: Huahua, running time: 20 ms
class Solution {
public:
  string shortestSuperstring(vector&lt;string&gt;&amp; A) {        
    const int n = A.size();
    vector&lt;vector&lt;int&gt;&gt; g(n, vector&lt;int&gt;(n));
    for (int i = 0; i &lt; n; ++i)
      for (int j = 0; j &lt; n; ++j) {
        g[i][j] = A[j].length();
        for (int k = 1; k &lt;= min(A[i].length(), A[j].length()); ++k)
          if (A[i].substr(A[i].size() - k) == A[j].substr(0, k)) 
            g[i][j] = A[j].length() - k;
      }
    
    vector&lt;vector&lt;int&gt;&gt; dp(1 &lt;&lt; n, vector&lt;int&gt;(n, INT_MAX / 2));
    vector&lt;vector&lt;int&gt;&gt; parent(1 &lt;&lt; n, vector&lt;int&gt;(n, -1));
    
    for (int i = 0; i &lt; n; ++i) dp[1 &lt;&lt; i][i] = A[i].length();
    
    for (int s = 1; s &lt; (1 &lt;&lt; n); ++s) {
      for (int j = 0; j &lt; n; ++j) {
        if (!(s &amp; (1 &lt;&lt; j))) continue;
        int ps = s &amp; ~(1 &lt;&lt; j);
        for (int i = 0; i &lt; n; ++i) {
          if (dp[ps][i] + g[i][j] &lt; dp[s][j]) {
            dp[s][j] = dp[ps][i] + g[i][j];
            parent[s][j] = i;
          }
        }
      }
    }
    
    auto it = min_element(begin(dp.back()), end(dp.back()));
    int j = it - begin(dp.back());
    int s = (1 &lt;&lt; n) - 1;
    string ans;
    while (s) {
      int i = parent[s][j];
      if (i &lt; 0) ans = A[j] + ans;
      else ans = A[j].substr(A[j].length() - g[i][j]) + ans;
      s &amp;= ~(1 &lt;&lt; j);
      j = i;
    }
    return ans;
  } 
};</pre><p></div></div></p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/searching/leetcode-943-find-the-shortest-superstring/">花花酱 LeetCode 943. Find the Shortest Superstring</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/searching/leetcode-943-find-the-shortest-superstring/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
