<?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>similar Archives - Huahua&#039;s Tech Road</title>
	<atom:link href="https://zxi.mytechroad.com/blog/tag/similar/feed/" rel="self" type="application/rss+xml" />
	<link>https://zxi.mytechroad.com/blog/tag/similar/</link>
	<description></description>
	<lastBuildDate>Thu, 19 Apr 2018 15:30:59 +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>similar Archives - Huahua&#039;s Tech Road</title>
	<link>https://zxi.mytechroad.com/blog/tag/similar/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>花花酱 LeetCode 737. Sentence Similarity II</title>
		<link>https://zxi.mytechroad.com/blog/hashtable/leetcode-737-sentence-similarity-ii/</link>
					<comments>https://zxi.mytechroad.com/blog/hashtable/leetcode-737-sentence-similarity-ii/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Tue, 28 Nov 2017 23:04:19 +0000</pubDate>
				<category><![CDATA[Hashtable]]></category>
		<category><![CDATA[Medium]]></category>
		<category><![CDATA[similar]]></category>
		<category><![CDATA[union find]]></category>
		<guid isPermaLink="false">http://zxi.mytechroad.com/blog/?p=1013</guid>

					<description><![CDATA[<p>Problem: Given two sentences words1, words2 (each represented as an array of strings), and a list of similar word pairs pairs, determine if two sentences are similar. For&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/hashtable/leetcode-737-sentence-similarity-ii/">花花酱 LeetCode 737. Sentence Similarity II</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/0rZUi3kZGLI?feature=oembed" frameborder="0" gesture="media" allow="encrypted-media" allowfullscreen></iframe></p>
<p><strong>Problem:</strong></p>
<p>Given two sentences <code>words1, words2</code> (each represented as an array of strings), and a list of similar word pairs <code>pairs</code>, determine if two sentences are similar.</p>
<p>For example, <code>words1 = ["great", "acting", "skills"]</code> and <code>words2 = ["fine", "drama", "talent"]</code> are similar, if the similar word pairs are <code>pairs = [["great", "good"], ["fine", "good"], ["acting","drama"], ["skills","talent"]]</code>.</p>
<p>Note that the similarity relation <b>is</b> transitive. For example, if &#8220;great&#8221; and &#8220;good&#8221; are similar, and &#8220;fine&#8221; and &#8220;good&#8221; are similar, then &#8220;great&#8221; and &#8220;fine&#8221; <b>are similar</b>.</p>
<p>Similarity is also symmetric. For example, &#8220;great&#8221; and &#8220;fine&#8221; being similar is the same as &#8220;fine&#8221; and &#8220;great&#8221; being similar.</p>
<p>Also, a word is always similar with itself. For example, the sentences <code>words1 = ["great"], words2 = ["great"], pairs = []</code> are similar, even though there are no specified similar word pairs.</p>
<p>Finally, sentences can only be similar if they have the same number of words. So a sentence like <code>words1 = ["great"]</code> can never be similar to <code>words2 = ["doubleplus","good"]</code>.</p>
<p><b>Note:</b></p>
<ul>
<li>The length of <code>words1</code> and <code>words2</code> will not exceed <code>1000</code>.</li>
<li>The length of <code>pairs</code> will not exceed <code>2000</code>.</li>
<li>The length of each <code>pairs[i]</code> will be <code>2</code>.</li>
<li>The length of each <code>words[i]</code> and <code>pairs[i][j]</code> will be in the range <code>[1, 20]</code>.</li>
</ul>
<p><ins class="adsbygoogle" style="display: block; text-align: center;" data-ad-layout="in-article" data-ad-format="fluid" data-ad-client="ca-pub-2404451723245401" data-ad-slot="7983117522"></ins><br />
<script>
     (adsbygoogle = window.adsbygoogle || []).push({});
</script></p>
<p>题目大意：</p>
<p>给你两个句子（由单词数组表示）和一些近义词对，问你这两个句子是否相似，即每组相对应的单词都要相似。</p>
<p>注意相似性可以传递，比如只给你&#8221;great&#8221;和&#8221;fine&#8221;相似、&#8221;fine&#8221;和&#8221;good&#8221;相似，能推断&#8221;great&#8221;和&#8221;good&#8221;也相似。</p>
<p><strong>Idea:</strong></p>
<p>DFS / Union Find</p>
<p><a href="http://zxi.mytechroad.com/blog/wp-content/uploads/2017/11/737-ep118.png"><img class="alignnone size-full wp-image-1034" src="http://zxi.mytechroad.com/blog/wp-content/uploads/2017/11/737-ep118.png" alt="" width="960" height="540" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2017/11/737-ep118.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/11/737-ep118-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/11/737-ep118-768x432.png 768w" sizes="(max-width: 960px) 100vw, 960px" /></a></p>
<p><strong>Solution1:</strong></p>
<p>Time complexity: O(|Pairs| * |words1|)</p>
<p>Space complexity: O(|Pairs|)</p>
<p>C++ / DFS</p><pre class="crayon-plain-tag">// Author: Huahua
// Runtime: 346 ms
class Solution {
public:
    bool areSentencesSimilarTwo(vector&lt;string&gt;&amp; words1, vector&lt;string&gt;&amp; words2, vector&lt;pair&lt;string, string&gt;&gt;&amp; pairs) {
        if (words1.size() != words2.size()) return false;
        
        g_.clear();
        
        for (const auto&amp; p : pairs) {
            g_[p.first].insert(p.second);
            g_[p.second].insert(p.first);
        }
        
        unordered_set&lt;string&gt; visited;
        
        for (int i = 0; i &lt; words1.size(); ++i) {
            visited.clear();
            if (!dfs(words1[i], words2[i], visited)) return false;
        }
        
        return true;
    }
private:
    bool dfs(const string&amp; src, const string&amp; dst, unordered_set&lt;string&gt;&amp; visited) {
        if (src == dst) return true;
        visited.insert(src);
        for (const auto&amp; next : g_[src]) {
            if (visited.count(next)) continue;
            if (dfs(next, dst, visited)) return true;
        }
        return false;
    }
    unordered_map&lt;string, unordered_set&lt;string&gt;&gt; g_;
};</pre><p>Time complexity: O(|Pairs| + |words1|)</p>
<p>Space complexity: O(|Pairs|)</p>
<p>C++ / DFS Optimized</p><pre class="crayon-plain-tag">// Author: Huahua
// Runtime 229 ms
class Solution {
public:
    bool areSentencesSimilarTwo(vector&lt;string&gt;&amp; words1, vector&lt;string&gt;&amp; words2, vector&lt;pair&lt;string, string&gt;&gt;&amp; pairs) {
        if (words1.size() != words2.size()) return false;
        
        g_.clear();
        ids_.clear();
        
        for (const auto&amp; p : pairs) {
            g_[p.first].insert(p.second);
            g_[p.second].insert(p.first);
        }        
        
        int id = 0;
        
        for (const auto&amp; p : pairs) {
            if(!ids_.count(p.first)) dfs(p.first, ++id);
            if(!ids_.count(p.second)) dfs(p.second, ++id);
        }
        
        for (int i = 0; i &lt; words1.size(); ++i) {
            if (words1[i] == words2[i]) continue;
            auto it1 = ids_.find(words1[i]);
            auto it2 = ids_.find(words2[i]);
            if (it1 == ids_.end() || it2 == ids_.end()) return false;
            if (it1-&gt;second != it2-&gt;second) return false;
        }
        
        return true;
    }
private:
    bool dfs(const string&amp; curr, int id) {
        ids_[curr] = id;        
        for (const auto&amp; next : g_[curr]) {
            if (ids_.count(next)) continue;
            if (dfs(next, id)) return true;
        }
        return false;
    }
    
    unordered_map&lt;string, int&gt; ids_;
    unordered_map&lt;string, unordered_set&lt;string&gt;&gt; g_;
};</pre><p>&nbsp;</p>
<p><strong>Solution2:</strong></p>
<p>Time complexity: O(|Pairs| + |words1|)</p>
<p>Space complexity: O(|Pairs|)</p>
<p>C++ / Union Find</p><pre class="crayon-plain-tag">// Author: Huahua
// Runtime: 219 ms
class UnionFindSet {
public:
    bool Union(const string&amp; word1, const string&amp; word2) {
        const string&amp; p1 = Find(word1, true);
        const string&amp; p2 = Find(word2, true);
        if (p1 == p2) return false;        
        parents_[p1] = p2;
        return true;
    }
    
    const string&amp; Find(const string&amp; word, bool create = false) {
        if (!parents_.count(word)) {
            if (!create) return word;
            return parents_[word] = word;
        }
        
        string w = word;
        while (w != parents_[w]) {
            parents_[w] = parents_[parents_[w]];
            w = parents_[w];
        }
        
        return parents_[w];
    }
private:
    unordered_map&lt;string, string&gt; parents_;
};

class Solution {
public:
    bool areSentencesSimilarTwo(vector&lt;string&gt;&amp; words1, vector&lt;string&gt;&amp; words2, vector&lt;pair&lt;string, string&gt;&gt;&amp; pairs) {
        if (words1.size() != words2.size()) return false;
        
        UnionFindSet s;
        for (const auto&amp; pair : pairs)
            s.Union(pair.first, pair.second);
        
        for (int i = 0; i &lt; words1.size(); ++i) 
            if (s.Find(words1[i]) != s.Find(words2[i])) return false;
        
        return true;
    }
};</pre><p>&nbsp;</p>
<p>C++ / Union Find, Optimized</p><pre class="crayon-plain-tag">// Author: Huahua
// Runtime: 175 ms (&lt; 98.45%)
class UnionFindSet {
public:
    UnionFindSet(int n) {
        parents_ = vector&lt;int&gt;(n + 1, 0);
        ranks_ = vector&lt;int&gt;(n + 1, 0);
        
        for (int i = 0; i &lt; parents_.size(); ++i)
            parents_[i] = i;
    }
    
    bool Union(int u, int v) {
        int pu = Find(u);
        int pv = Find(v);
        if (pu == pv) return false;
        
        if (ranks_[pu] &gt; ranks_[pv]) {
            parents_[pv] = pu;
        } else if (ranks_[pv] &gt; ranks_[pu]) {
            parents_[pu] = pv;
        } else {
            parents_[pu] = pv;
            ++ranks_[pv];
        }

        return true;
    }
    
    int Find(int id) {        
        if (id != parents_[id])
            parents_[id] = Find(parents_[id]);        
        return parents_[id];
    }
    
private:
    vector&lt;int&gt; parents_;
    vector&lt;int&gt; ranks_;
};

class Solution {
public:
    bool areSentencesSimilarTwo(vector&lt;string&gt;&amp; words1, vector&lt;string&gt;&amp; words2, vector&lt;pair&lt;string, string&gt;&gt;&amp; pairs) {
        if (words1.size() != words2.size()) return false;
        
        UnionFindSet s(pairs.size() * 2);
        
        unordered_map&lt;string, int&gt; indies; // word to index
        
        for (const auto&amp; pair : pairs) {
            int u = getIndex(pair.first, indies, true);
            int v = getIndex(pair.second, indies, true);
            s.Union(u, v);
        }
        
        for (int i = 0; i &lt; words1.size(); ++i) {
            if (words1[i] == words2[i]) continue;
            int u = getIndex(words1[i], indies);
            int v = getIndex(words2[i], indies);
            if (u &lt; 0 || v &lt; 0) return false;
            if (s.Find(u) != s.Find(v)) return false;
        }
        
        return true;
    }
private:
    int getIndex(const string&amp; word, unordered_map&lt;string, int&gt;&amp; indies, bool create = false) {
        auto it = indies.find(word);
        if (it == indies.end()) {
            if (!create) return INT_MIN;
            int index = indies.size();
            indies.emplace(word, index);
            return index;
        }
        
        return it-&gt;second;
    }
};</pre><p><strong>Related Problems:</strong></p>
<ul>
<li><a href="http://zxi.mytechroad.com/blog/hashtable/leetcode-734-sentence-similarity/">[解题报告] LeetCode 734. Sentence Similarity</a></li>
<li><a href="http://zxi.mytechroad.com/blog/tree/leetcode-684-redundant-connection/">[解题报告] LeetCode 684. Redundant Connection</a></li>
<li><a href="http://zxi.mytechroad.com/blog/graph/leetcode-685-redundant-connection-ii/">[解题报告] LeetCode 685. Redundant Connection II</a></li>
</ul>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/hashtable/leetcode-737-sentence-similarity-ii/">花花酱 LeetCode 737. Sentence Similarity II</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/hashtable/leetcode-737-sentence-similarity-ii/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
