<?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>graph Archives - Huahua&#039;s Tech Road</title>
	<atom:link href="https://zxi.mytechroad.com/blog/tag/graph/feed/" rel="self" type="application/rss+xml" />
	<link>https://zxi.mytechroad.com/blog/tag/graph/</link>
	<description></description>
	<lastBuildDate>Mon, 08 Jan 2024 14:01:52 +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>graph Archives - Huahua&#039;s Tech Road</title>
	<link>https://zxi.mytechroad.com/blog/tag/graph/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>花花酱 LeetCode 2976. Minimum Cost to Convert String I</title>
		<link>https://zxi.mytechroad.com/blog/graph/leetcode-2976-minimum-cost-to-convert-string-i/</link>
					<comments>https://zxi.mytechroad.com/blog/graph/leetcode-2976-minimum-cost-to-convert-string-i/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Mon, 08 Jan 2024 14:01:15 +0000</pubDate>
				<category><![CDATA[Graph]]></category>
		<category><![CDATA[graph]]></category>
		<category><![CDATA[medium]]></category>
		<category><![CDATA[shortest path]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=10100</guid>

					<description><![CDATA[<p>You are given two&#160;0-indexed&#160;strings&#160;source&#160;and&#160;target, both of length&#160;n&#160;and consisting of&#160;lowercase&#160;English letters. You are also given two&#160;0-indexed&#160;character arrays&#160;original&#160;and&#160;changed, and an integer array&#160;cost, where&#160;cost[i]&#160;represents the cost of changing&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/graph/leetcode-2976-minimum-cost-to-convert-string-i/">花花酱 LeetCode 2976. Minimum Cost to Convert String I</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>You are given two&nbsp;<strong>0-indexed</strong>&nbsp;strings&nbsp;<code>source</code>&nbsp;and&nbsp;<code>target</code>, both of length&nbsp;<code>n</code>&nbsp;and consisting of&nbsp;<strong>lowercase</strong>&nbsp;English letters. You are also given two&nbsp;<strong>0-indexed</strong>&nbsp;character arrays&nbsp;<code>original</code>&nbsp;and&nbsp;<code>changed</code>, and an integer array&nbsp;<code>cost</code>, where&nbsp;<code>cost[i]</code>&nbsp;represents the cost of changing the character&nbsp;<code>original[i]</code>&nbsp;to the character&nbsp;<code>changed[i]</code>.</p>



<p>You start with the string&nbsp;<code>source</code>. In one operation, you can pick a character&nbsp;<code>x</code>&nbsp;from the string and change it to the character&nbsp;<code>y</code>&nbsp;at a cost of&nbsp;<code>z</code>&nbsp;<strong>if</strong>&nbsp;there exists&nbsp;<strong>any</strong>&nbsp;index&nbsp;<code>j</code>&nbsp;such that&nbsp;<code>cost[j] == z</code>,&nbsp;<code>original[j] == x</code>, and&nbsp;<code>changed[j] == y</code>.</p>



<p>Return&nbsp;<em>the&nbsp;<strong>minimum</strong>&nbsp;cost to convert the string&nbsp;</em><code>source</code><em>&nbsp;to the string&nbsp;</em><code>target</code><em>&nbsp;using&nbsp;<strong>any</strong>&nbsp;number of operations. If it is impossible to convert</em>&nbsp;<code>source</code>&nbsp;<em>to</em>&nbsp;<code>target</code>,&nbsp;<em>return</em>&nbsp;<code>-1</code>.</p>



<p><strong>Note</strong>&nbsp;that there may exist indices&nbsp;<code>i</code>,&nbsp;<code>j</code>&nbsp;such that&nbsp;<code>original[j] == original[i]</code>&nbsp;and&nbsp;<code>changed[j] == changed[i]</code>.</p>



<p><strong>Example 1:</strong></p>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> source = "abcd", target = "acbe", original = ["a","b","c","c","e","d"], changed = ["b","c","b","e","b","e"], cost = [2,5,5,1,2,20]
<strong>Output:</strong> 28
<strong>Explanation:</strong> To convert the string "abcd" to string "acbe":
- Change value at index 1 from 'b' to 'c' at a cost of 5.
- Change value at index 2 from 'c' to 'e' at a cost of 1.
- Change value at index 2 from 'e' to 'b' at a cost of 2.
- Change value at index 3 from 'd' to 'e' at a cost of 20.
The total cost incurred is 5 + 1 + 2 + 20 = 28.
It can be shown that this is the minimum possible cost.
</pre>



<p><strong>Example 2:</strong></p>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> source = "aaaa", target = "bbbb", original = ["a","c"], changed = ["c","b"], cost = [1,2]
<strong>Output:</strong> 12
<strong>Explanation:</strong> To change the character 'a' to 'b' change the character 'a' to 'c' at a cost of 1, followed by changing the character 'c' to 'b' at a cost of 2, for a total cost of 1 + 2 = 3. To change all occurrences of 'a' to 'b', a total cost of 3 * 4 = 12 is incurred.
</pre>



<p><strong>Example 3:</strong></p>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> source = "abcd", target = "abce", original = ["a"], changed = ["e"], cost = [10000]
<strong>Output:</strong> -1
<strong>Explanation:</strong> It is impossible to convert source to target because the value at index 3 cannot be changed from 'd' to 'e'.
</pre>



<p><strong>Constraints:</strong></p>



<ul><li><code>1 &lt;= source.length == target.length &lt;= 10<sup>5</sup></code></li><li><code>source</code>,&nbsp;<code>target</code>&nbsp;consist of lowercase English letters.</li><li><code>1 &lt;= cost.length == original.length == changed.length &lt;= 2000</code></li><li><code>original[i]</code>,&nbsp;<code>changed[i]</code>&nbsp;are lowercase English letters.</li><li><code>1 &lt;= cost[i] &lt;= 10<sup>6</sup></code></li><li><code>original[i] != changed[i]</code></li></ul>



<h2><strong>Solution: All pairs shortest path</strong></h2>



<p>Compute the shortest path (min cost) for any given letter pairs.</p>



<p>Time complexity: O(26^3 + m + n)<br>Space complexity: O(26^2)</p>



<div class="responsive-tabs">
<h2 class="tabtitle">C++</h2>
<div class="tabcontent">

<pre class="crayon-plain-tag">class Solution {
public:
    long long minimumCost(string s, string t, vector&lt;char&gt;&amp; o, vector&lt;char&gt;&amp; c, vector&lt;int&gt;&amp; cost) {
    const int n = c.size();
    vector&lt;vector&lt;int&gt;&gt; d(26, vector&lt;int&gt;(26, 1e9));
    for (int i = 0; i &lt; 26; ++i)
      d[i][i] = 0;
    for (int i = 0; i &lt; n; ++i)
      d[o[i] - 'a'][c[i] - 'a'] = min(d[o[i] - 'a'][c[i] - 'a'], cost[i]);
    for (int k = 0; k &lt; 26; ++k)
      for (int i = 0; i &lt; 26;++i)
        for (int j = 0; j &lt; 26; ++j)
          if (d[i][k] + d[k][j] &lt; d[i][j])
            d[i][j] = d[i][k] + d[k][j];
    long ans = 0;
    for (int i = 0; i &lt; s.size(); ++i) {
      if (d[s[i] - 'a'][t[i] - 'a'] &gt;= 1e9) return -1; 
      ans += d[s[i] - 'a'][t[i] - 'a'];
    }
    return ans;
  }
};</pre>
</div></div>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/graph/leetcode-2976-minimum-cost-to-convert-string-i/">花花酱 LeetCode 2976. Minimum Cost to Convert String I</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/graph/leetcode-2976-minimum-cost-to-convert-string-i/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 2662. Minimum Cost of a Path With Special Roads</title>
		<link>https://zxi.mytechroad.com/blog/graph/leetcode-2662-minimum-cost-of-a-path-with-special-roads/</link>
					<comments>https://zxi.mytechroad.com/blog/graph/leetcode-2662-minimum-cost-of-a-path-with-special-roads/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sun, 30 Apr 2023 18:03:03 +0000</pubDate>
				<category><![CDATA[Graph]]></category>
		<category><![CDATA[dijkstra]]></category>
		<category><![CDATA[graph]]></category>
		<category><![CDATA[medium]]></category>
		<category><![CDATA[shortest path]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=10044</guid>

					<description><![CDATA[<p>You are given an array&#160;start&#160;where&#160;start = [startX, startY]&#160;represents your initial position&#160;(startX, startY)&#160;in a 2D space. You are also given the array&#160;target&#160;where&#160;target = [targetX, targetY]&#160;represents your&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/graph/leetcode-2662-minimum-cost-of-a-path-with-special-roads/">花花酱 LeetCode 2662. Minimum Cost of a Path With Special Roads</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe title="花花酱 LeetCode 2662. Minimum Cost of a Path With Special Roads - 刷题找工作 EP411" width="500" height="281" src="https://www.youtube.com/embed/oBtS4aAJDaA?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>
</div></figure>



<p>You are given an array&nbsp;<code>start</code>&nbsp;where&nbsp;<code>start = [startX, startY]</code>&nbsp;represents your initial position&nbsp;<code>(startX, startY)</code>&nbsp;in a 2D space. You are also given the array&nbsp;<code>target</code>&nbsp;where&nbsp;<code>target = [targetX, targetY]</code>&nbsp;represents your target position&nbsp;<code>(targetX, targetY)</code>.</p>



<p>The cost of going from a position&nbsp;<code>(x1, y1)</code>&nbsp;to any other position in the space&nbsp;<code>(x2, y2)</code>&nbsp;is&nbsp;<code>|x2 - x1| + |y2 - y1|</code>.</p>



<p>There are also some special roads. You are given a 2D array&nbsp;<code>specialRoads</code>&nbsp;where&nbsp;<code>specialRoads[i] = [x1<sub>i</sub>, y1<sub>i</sub>, x2<sub>i</sub>, y2<sub>i</sub>, cost<sub>i</sub>]</code>&nbsp;indicates that the&nbsp;<code>i<sup>th</sup></code>&nbsp;special road can take you from&nbsp;<code>(x1<sub>i</sub>, y1<sub>i</sub>)</code>&nbsp;to&nbsp;<code>(x2<sub>i</sub>, y2<sub>i</sub>)</code>&nbsp;with a cost equal to&nbsp;<code>cost<sub>i</sub></code>. You can use each special road any number of times.</p>



<p>Return&nbsp;<em>the minimum cost required to go from</em>&nbsp;<code>(startX, startY)</code>&nbsp;to&nbsp;<code>(targetX, targetY)</code>.</p>



<p><strong>Example 1:</strong></p>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> start = [1,1], target = [4,5], specialRoads = [[1,2,3,3,2],[3,4,4,5,1]]
<strong>Output:</strong> 5
<strong>Explanation:</strong> The optimal path from (1,1) to (4,5) is the following:
- (1,1) -&gt; (1,2). This move has a cost of |1 - 1| + |2 - 1| = 1.
- (1,2) -&gt; (3,3). This move uses the first special edge, the cost is 2.
- (3,3) -&gt; (3,4). This move has a cost of |3 - 3| + |4 - 3| = 1.
- (3,4) -&gt; (4,5). This move uses the second special edge, the cost is 1.
So the total cost is 1 + 2 + 1 + 1 = 5.
It can be shown that we cannot achieve a smaller total cost than 5.
</pre>



<p><strong>Example 2:</strong></p>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> start = [3,2], target = [5,7], specialRoads = [[3,2,3,4,4],[3,3,5,5,5],[3,4,5,6,6]]
<strong>Output:</strong> 7
<strong>Explanation:</strong> It is optimal to not use any special edges and go directly from the starting to the ending position with a cost |5 - 3| + |7 - 2| = 7.
</pre>



<p><strong>Constraints:</strong></p>



<ul><li><code>start.length == target.length == 2</code></li><li><code>1 &lt;= startX &lt;= targetX &lt;= 10<sup>5</sup></code></li><li><code>1 &lt;= startY &lt;= targetY &lt;= 10<sup>5</sup></code></li><li><code>1 &lt;= specialRoads.length &lt;= 200</code></li><li><code>specialRoads[i].length == 5</code></li><li><code>startX &lt;= x1<sub>i</sub>, x2<sub>i</sub> &lt;= targetX</code></li><li><code>startY &lt;= y1<sub>i</sub>, y2<sub>i</sub> &lt;= targetY</code></li><li><code>1 &lt;= cost<sub>i</sub> &lt;= 10<sup>5</sup></code></li></ul>



<h2><strong>Solution: Dijkstra</strong></h2>



<ol><li>Create a node for each point in special edges as well as start and target. </li><li>Add edges for special roads (note it&#8217;s directional)</li><li>Add edges for each pair of node with default cost, i.e. |x1-x2| + |y1-y2|</li><li>Run Dijkstra&#8217;s algorithm</li></ol>



<p>Time complexity: O(n<sup>2</sup>logn)<br>Space complexity: O(n<sup>2</sup>)</p>



<div class="responsive-tabs">
<h2 class="tabtitle">C++</h2>
<div class="tabcontent">

<pre class="crayon-plain-tag">// Author: Huahua
class Solution {
public:
  int minimumCost(vector&lt;int&gt;&amp; start, vector&lt;int&gt;&amp; target, vector&lt;vector&lt;int&gt;&gt;&amp; specialRoads) {
    unordered_map&lt;long, int&gt; ids;
    vector&lt;pair&lt;int, int&gt;&gt; pos;
    
    auto getId = [&amp;](int x, int y) {
      const auto key = ((unsigned long)x &lt;&lt; 32) | y;
      if (ids.count(key)) return ids[key];
      const int id = ids.size();      
      ids[key] = id;
      pos.emplace_back(x, y);
      return id;
    };
    const int s = getId(start[0], start[1]);
    const int t = getId(target[0], target[1]);
    vector&lt;vector&lt;pair&lt;int, int&gt;&gt;&gt; g;
    auto addEdge = [&amp;](int x1, int y1, int x2, int y2, int c = INT_MAX) {      
      int n1 = getId(x1, y1);
      int n2 = getId(x2, y2);
      if (n1 == n2) return;
      while (g.size() &lt;= max(n1, n2)) g.push_back({});      
      int cost = min(c, abs(x1 - x2) + abs(y1 - y2));
      g[n1].emplace_back(cost, n2);
      // directional for special edge
      if (c == INT_MAX) g[n2].emplace_back(cost, n1);
    };
    for (const auto&amp; r : specialRoads)
      addEdge(r[0], r[1], r[2], r[3], r[4]);    
    for (int i = 0; i &lt; pos.size(); ++i)
      for (int j = i + 1; j &lt; pos.size(); ++j)
        addEdge(pos[i].first, pos[i].second, 
                pos[j].first, pos[j].second);
    vector&lt;int&gt; dist(ids.size(), INT_MAX);
    dist[s] = 0;
    priority_queue&lt;pair&lt;int, int&gt;, vector&lt;pair&lt;int, int&gt;&gt;, greater&lt;&gt;&gt; q;
    q.emplace(0, s);    
    while (!q.empty()) {
      auto [d, u] = q.top(); q.pop();
      if (d &gt; dist[u]) continue;
      if (u == t) return d;
      for (auto [c, v] : g[u])
        if (d + c &lt; dist[v])
          q.emplace(dist[v] = d + c, v);
    }
    return -1;
  }
};</pre>
</div></div>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/graph/leetcode-2662-minimum-cost-of-a-path-with-special-roads/">花花酱 LeetCode 2662. Minimum Cost of a Path With Special Roads</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/graph/leetcode-2662-minimum-cost-of-a-path-with-special-roads/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 2658. Maximum Number of Fish in a Grid</title>
		<link>https://zxi.mytechroad.com/blog/graph/leetcode-2658-maximum-number-of-fish-in-a-grid/</link>
					<comments>https://zxi.mytechroad.com/blog/graph/leetcode-2658-maximum-number-of-fish-in-a-grid/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sun, 30 Apr 2023 15:30:49 +0000</pubDate>
				<category><![CDATA[Graph]]></category>
		<category><![CDATA[connected components]]></category>
		<category><![CDATA[DFS]]></category>
		<category><![CDATA[graph]]></category>
		<category><![CDATA[medium]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=10032</guid>

					<description><![CDATA[<p>You are given a&#160;0-indexed&#160;2D matrix&#160;grid&#160;of size&#160;m x n, where&#160;(r, c)&#160;represents: A&#160;land&#160;cell if&#160;grid[r][c] = 0, or A&#160;water&#160;cell containing&#160;grid[r][c]&#160;fish, if&#160;grid[r][c] &#62; 0. A fisher can start at&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/graph/leetcode-2658-maximum-number-of-fish-in-a-grid/">花花酱 LeetCode 2658. Maximum Number of Fish in a Grid</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>You are given a&nbsp;<strong>0-indexed</strong>&nbsp;2D matrix&nbsp;<code>grid</code>&nbsp;of size&nbsp;<code>m x n</code>, where&nbsp;<code>(r, c)</code>&nbsp;represents:</p>



<ul><li>A&nbsp;<strong>land</strong>&nbsp;cell if&nbsp;<code>grid[r][c] = 0</code>, or</li><li>A&nbsp;<strong>water</strong>&nbsp;cell containing&nbsp;<code>grid[r][c]</code>&nbsp;fish, if&nbsp;<code>grid[r][c] &gt; 0</code>.</li></ul>



<p>A fisher can start at any&nbsp;<strong>water</strong>&nbsp;cell&nbsp;<code>(r, c)</code>&nbsp;and can do the following operations any number of times:</p>



<ul><li>Catch all the fish at cell&nbsp;<code>(r, c)</code>, or</li><li>Move to any adjacent&nbsp;<strong>water</strong>&nbsp;cell.</li></ul>



<p>Return&nbsp;<em>the&nbsp;<strong>maximum</strong>&nbsp;number of fish the fisher can catch if he chooses his starting cell optimally, or&nbsp;</em><code>0</code>&nbsp;if no water cell exists.</p>



<p>An&nbsp;<strong>adjacent</strong>&nbsp;cell of the cell&nbsp;<code>(r, c)</code>, is one of the cells&nbsp;<code>(r, c + 1)</code>,&nbsp;<code>(r, c - 1)</code>,&nbsp;<code>(r + 1, c)</code>&nbsp;or&nbsp;<code>(r - 1, c)</code>&nbsp;if it exists.</p>



<p><strong>Example 1:</strong></p>



<figure class="wp-block-image"><img src="https://assets.leetcode.com/uploads/2023/03/29/example.png" alt=""/></figure>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> grid = [[0,2,1,0],[4,0,0,3],[1,0,0,4],[0,3,2,0]]
<strong>Output:</strong> 7
<strong>Explanation:</strong> The fisher can start at cell <code>(1,3)</code> and collect 3 fish, then move to cell <code>(2,3)</code>&nbsp;and collect 4 fish.
</pre>



<p><strong>Example 2:</strong></p>



<figure class="wp-block-image"><img src="https://assets.leetcode.com/uploads/2023/03/29/example2.png" alt=""/></figure>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> grid = [[1,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,1]]
<strong>Output:</strong> 1
<strong>Explanation:</strong> The fisher can start at cells (0,0) or (3,3) and collect a single fish. 
</pre>



<p><strong>Constraints:</strong></p>



<ul><li><code>m == grid.length</code></li><li><code>n == grid[i].length</code></li><li><code>1 &lt;= m, n &lt;= 10</code></li><li><code>0 &lt;= grid[i][j] &lt;= 10</code></li></ul>



<h2><strong>Solution: Connected Component</strong></h2>



<p>Similar to <a href="https://zxi.mytechroad.com/blog/graph/leetcode-695-max-area-of-island/">花花酱 LeetCode 695. Max Area of Island</a></p>



<p>Find the connected component that has the max sum.</p>



<p>Time complexity: O(mn)<br>Space complexity: O(mn)</p>



<div class="responsive-tabs">
<h2 class="tabtitle">C++</h2>
<div class="tabcontent">

<pre class="crayon-plain-tag">// Author: Huahua
class Solution {
public:
  int findMaxFish(vector&lt;vector&lt;int&gt;&gt;&amp; grid) {
    const int m = grid.size();
    const int n = grid[0].size();
    function&lt;int(int, int)&gt; dfs = [&amp;](int r, int c) {
      if (r &lt; 0 || r &gt;= m || c &lt; 0 || c &gt;= n || !grid[r][c]) return 0;      
      return exchange(grid[r][c], 0) 
        + dfs(r - 1, c) + dfs(r, c - 1) + dfs(r + 1, c) + dfs(r, c + 1);
    };
    int ans = 0;
    for (int r = 0; r &lt; m; ++r)
      for (int c = 0; c &lt; n; ++c)
        ans = max(ans, dfs(r, c));
    return ans;
  }
};</pre>
</div></div>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/graph/leetcode-2658-maximum-number-of-fish-in-a-grid/">花花酱 LeetCode 2658. Maximum Number of Fish in a Grid</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/graph/leetcode-2658-maximum-number-of-fish-in-a-grid/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 2642. Design Graph With Shortest Path Calculator</title>
		<link>https://zxi.mytechroad.com/blog/graph/leetcode-2642-design-graph-with-shortest-path-calculator/</link>
					<comments>https://zxi.mytechroad.com/blog/graph/leetcode-2642-design-graph-with-shortest-path-calculator/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sat, 29 Apr 2023 19:16:35 +0000</pubDate>
				<category><![CDATA[Graph]]></category>
		<category><![CDATA[dijkstra]]></category>
		<category><![CDATA[floyd-warshall]]></category>
		<category><![CDATA[graph]]></category>
		<category><![CDATA[hard]]></category>
		<category><![CDATA[shortest path]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=10015</guid>

					<description><![CDATA[<p>There is a&#160;directed weighted&#160;graph that consists of&#160;n&#160;nodes numbered from&#160;0&#160;to&#160;n - 1. The edges of the graph are initially represented by the given array&#160;edges&#160;where&#160;edges[i] = [fromi,&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/graph/leetcode-2642-design-graph-with-shortest-path-calculator/">花花酱 LeetCode 2642. Design Graph With Shortest Path Calculator</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>There is a&nbsp;<strong>directed weighted</strong>&nbsp;graph that consists of&nbsp;<code>n</code>&nbsp;nodes numbered from&nbsp;<code>0</code>&nbsp;to&nbsp;<code>n - 1</code>. The edges of the graph are initially represented by the given array&nbsp;<code>edges</code>&nbsp;where&nbsp;<code>edges[i] = [from<sub>i</sub>, to<sub>i</sub>, edgeCost<sub>i</sub>]</code>&nbsp;meaning that there is an edge from&nbsp;<code>from<sub>i</sub></code>&nbsp;to&nbsp;<code>to<sub>i</sub></code>&nbsp;with the cost&nbsp;<code>edgeCost<sub>i</sub></code>.</p>



<p>Implement the&nbsp;<code>Graph</code>&nbsp;class:</p>



<ul><li><code>Graph(int n, int[][] edges)</code>&nbsp;initializes the object with&nbsp;<code>n</code>&nbsp;nodes and the given edges.</li><li><code>addEdge(int[] edge)</code>&nbsp;adds an edge to the list of edges where&nbsp;<code>edge = [from, to, edgeCost]</code>. It is guaranteed that there is no edge between the two nodes before adding this one.</li><li><code>int shortestPath(int node1, int node2)</code>&nbsp;returns the&nbsp;<strong>minimum</strong>&nbsp;cost of a path from&nbsp;<code>node1</code>&nbsp;to&nbsp;<code>node2</code>. If no path exists, return&nbsp;<code>-1</code>. The cost of a path is the sum of the costs of the edges in the path.</li></ul>



<p><strong>Example 1:</strong></p>



<figure class="wp-block-image"><img src="https://assets.leetcode.com/uploads/2023/01/11/graph3drawio-2.png" alt=""/></figure>



<pre class="wp-block-preformatted;crayon:false"><strong>Input</strong>
["Graph", "shortestPath", "shortestPath", "addEdge", "shortestPath"]
[[4, [[0, 2, 5], [0, 1, 2], [1, 2, 1], [3, 0, 3]]], [3, 2], [0, 3], [[1, 3, 4]], [0, 3]]
<strong>Output</strong>
[null, 6, -1, null, 6]
</pre>



<p><strong>Explanation</strong> </p>



<pre class="wp-block-preformatted;crayon:false">Graph g = new Graph(4, [[0, 2, 5], [0, 1, 2], [1, 2, 1], [3, 0, 3]]); g.shortestPath(3, 2); // return 6. The shortest path from 3 to 2 in the first diagram above is 3 -> 0 -> 1 -> 2 with a total cost of 3 + 2 + 1 = 6.
g.shortestPath(0, 3); // return -1. There is no path from 0 to 3. 
g.addEdge([1, 3, 4]); // We add an edge from node 1 to node 3, and we get the second diagram above. 
g.shortestPath(0, 3); // return 6. The shortest path from 0 to 3 now is 0 -> 1 -> 3 with a total cost of 2 + 4 = 6.</pre>



<p><strong>Constraints:</strong></p>



<ul><li><code>1 &lt;= n &lt;= 100</code></li><li><code>0 &lt;= edges.length &lt;= n * (n - 1)</code></li><li><code>edges[i].length == edge.length == 3</code></li><li><code>0 &lt;= from<sub>i</sub>, to<sub>i</sub>, from, to, node1, node2 &lt;= n - 1</code></li><li><code>1 &lt;= edgeCost<sub>i</sub>, edgeCost &lt;= 10<sup>6</sup></code></li><li>There are no repeated edges and no self-loops in the graph at any point.</li><li>At most&nbsp;<code>100</code>&nbsp;calls will be made for&nbsp;<code>addEdge</code>.</li><li>At most&nbsp;<code>100</code>&nbsp;calls will be made for&nbsp;<code>shortestPath</code>.</li></ul>



<h2><strong>Solution 1: Floyd-Washall</strong></h2>



<p>Time complexity:<br>Init O(n<sup>3</sup>)<br>addEdge O(n<sup>2</sup>)<br>shortestPath O(1)</p>



<p>Space complexity: O(1)</p>



<div class="responsive-tabs">
<h2 class="tabtitle">C++</h2>
<div class="tabcontent">

<pre class="crayon-plain-tag">// Author: Huahua
class Graph {
public:
  Graph(int n, vector&lt;vector&lt;int&gt;&gt;&amp; edges):
  n_(n),
  d_(n, vector&lt;long&gt;(n, 1e18)) {
    for (int i = 0; i &lt; n; ++i)
      d_[i][i] = 0;
    for (const vector&lt;int&gt;&amp; e : edges)
      d_[e[0]][e[1]] = e[2];    
    for (int k = 0; k &lt; n; ++k)
      for (int i = 0; i &lt; n; ++i)
        for (int j = 0; j &lt; n; ++j)
          d_[i][j] = min(d_[i][j], d_[i][k] + d_[k][j]);
  }
  
  void addEdge(vector&lt;int&gt; edge) {    
    for (int i = 0; i &lt; n_; ++i)
      for (int j = 0; j &lt; n_; ++j)
        d_[i][j] = min(d_[i][j], d_[i][edge[0]] + edge[2] + d_[edge[1]][j]);
  }
  
  int shortestPath(int node1, int node2) {
    return d_[node1][node2] &gt;= 1e18 ? -1 : d_[node1][node2];
  }
private:
  int n_;
  vector&lt;vector&lt;long&gt;&gt; d_;
};</pre>
</div></div>



<h2><strong>Solution 2: Dijkstra</strong></h2>



<p>Time complexity: <br>Init: O(|E|) ~ O(n<sup>2</sup>)<br>AddEdge: O(1)<br>ShortestPath: O(|V|*log(|E|)) ~ O(n*logn)</p>



<p>Space complexity: O(E|) ~ O(n<sup>2</sup>)</p>



<div class="responsive-tabs">
<h2 class="tabtitle">C++</h2>
<div class="tabcontent">

<pre class="crayon-plain-tag">// Author: Huahua
class Graph {
public:
    Graph(int n, vector&lt;vector&lt;int&gt;&gt;&amp; edges): n_(n), g_(n) {
      for (const auto&amp; e : edges)
        g_[e[0]].emplace_back(e[1], e[2]);
    }
    
    void addEdge(vector&lt;int&gt; edge) {
      g_[edge[0]].emplace_back(edge[1], edge[2]);
    }
    
    int shortestPath(int node1, int node2) {
      vector&lt;int&gt; dist(n_, INT_MAX);
      dist[node1] = 0;
      priority_queue&lt;pair&lt;int, int&gt;, vector&lt;pair&lt;int, int&gt;&gt;, greater&lt;&gt;&gt; q;
      q.emplace(0, node1);
      while (!q.empty()) {
        const auto [d, u] = q.top(); q.pop();        
        if (u == node2) return d;
        for (const auto&amp; [v, c] : g_[u])
          if (dist[u] + c &lt; dist[v]) {
            dist[v] = dist[u] + c;
            q.emplace(dist[v], v);
          }
      }
      return -1;
    }
private:
  int n_;
  vector&lt;vector&lt;pair&lt;int, int&gt;&gt;&gt; g_;
};</pre>
</div></div>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/graph/leetcode-2642-design-graph-with-shortest-path-calculator/">花花酱 LeetCode 2642. Design Graph With Shortest Path Calculator</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/graph/leetcode-2642-design-graph-with-shortest-path-calculator/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 1061. Lexicographically Smallest Equivalent String</title>
		<link>https://zxi.mytechroad.com/blog/graph/leetcode-1061-lexicographically-smallest-equivalent-string/</link>
					<comments>https://zxi.mytechroad.com/blog/graph/leetcode-1061-lexicographically-smallest-equivalent-string/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sat, 14 Jan 2023 20:24:29 +0000</pubDate>
				<category><![CDATA[Graph]]></category>
		<category><![CDATA[graph]]></category>
		<category><![CDATA[medium]]></category>
		<category><![CDATA[union find]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=9916</guid>

					<description><![CDATA[<p>You are given two strings of the same length&#160;s1&#160;and&#160;s2&#160;and a string&#160;baseStr. We say&#160;s1[i]&#160;and&#160;s2[i]&#160;are equivalent characters. For example, if&#160;s1 = "abc"&#160;and&#160;s2 = "cde", then we have&#160;'a'&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/graph/leetcode-1061-lexicographically-smallest-equivalent-string/">花花酱 LeetCode 1061. Lexicographically Smallest Equivalent String</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>You are given two strings of the same length&nbsp;<code>s1</code>&nbsp;and&nbsp;<code>s2</code>&nbsp;and a string&nbsp;<code>baseStr</code>.</p>



<p>We say&nbsp;<code>s1[i]</code>&nbsp;and&nbsp;<code>s2[i]</code>&nbsp;are equivalent characters.</p>



<ul><li>For example, if&nbsp;<code>s1 = "abc"</code>&nbsp;and&nbsp;<code>s2 = "cde"</code>, then we have&nbsp;<code>'a' == 'c'</code>,&nbsp;<code>'b' == 'd'</code>, and&nbsp;<code>'c' == 'e'</code>.</li></ul>



<p>Equivalent characters follow the usual rules of any equivalence relation:</p>



<ul><li><strong>Reflexivity:</strong>&nbsp;<code>'a' == 'a'</code>.</li><li><strong>Symmetry:</strong>&nbsp;<code>'a' == 'b'</code>&nbsp;implies&nbsp;<code>'b' == 'a'</code>.</li><li><strong>Transitivity:</strong>&nbsp;<code>'a' == 'b'</code>&nbsp;and&nbsp;<code>'b' == 'c'</code>&nbsp;implies&nbsp;<code>'a' == 'c'</code>.</li></ul>



<p>For example, given the equivalency information from&nbsp;<code>s1 = "abc"</code>&nbsp;and&nbsp;<code>s2 = "cde"</code>,&nbsp;<code>"acd"</code>&nbsp;and&nbsp;<code>"aab"</code>&nbsp;are equivalent strings of&nbsp;<code>baseStr = "eed"</code>, and&nbsp;<code>"aab"</code>&nbsp;is the lexicographically smallest equivalent string of&nbsp;<code>baseStr</code>.</p>



<p>Return&nbsp;<em>the lexicographically smallest equivalent string of&nbsp;</em><code>baseStr</code><em>&nbsp;by using the equivalency information from&nbsp;</em><code>s1</code><em>&nbsp;and&nbsp;</em><code>s2</code>.</p>



<p><strong>Example 1:</strong></p>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> s1 = "parker", s2 = "morris", baseStr = "parser"
<strong>Output:</strong> "makkek"
<strong>Explanation:</strong> Based on the equivalency information in s1 and s2, we can group their characters as [m,p], [a,o], [k,r,s], [e,i].
The characters in each group are equivalent and sorted in lexicographical order.
So the answer is "makkek".
</pre>



<p><strong>Example 2:</strong></p>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> s1 = "hello", s2 = "world", baseStr = "hold"
<strong>Output:</strong> "hdld"
<strong>Explanation: </strong>Based on the equivalency information in s1 and s2, we can group their characters as [h,w], [d,e,o], [l,r].
So only the second letter 'o' in baseStr is changed to 'd', the answer is "hdld".
</pre>



<p><strong>Example 3:</strong></p>



<pre class="crayon-plain-tag">&lt;strong&gt;Input:&lt;/strong&gt; s1 = &quot;leetcode&quot;, s2 = &quot;programs&quot;, baseStr = &quot;sourcecode&quot;
&lt;strong&gt;Output:&lt;/strong&gt; &quot;aauaaaaada&quot;
&lt;strong&gt;Explanation:&lt;/strong&gt; We group the equivalent characters in s1 and s2 as [a,o,e,r,s,c], [l,p], [g,t] and [d,m], thus all letters in baseStr except 'u' and 'd' are transformed to 'a', the answer is &quot;aauaaaaada&quot;.</pre>



<p><strong>Constraints:</strong></p>



<ul><li><code>1 &lt;= s1.length, s2.length, baseStr &lt;= 1000</code></li><li><code>s1.length == s2.length</code></li><li><code>s1</code>,&nbsp;<code>s2</code>, and&nbsp;<code>baseStr</code>&nbsp;consist of lowercase English letters.</li></ul>



<h2><strong>Solution: Union Find</strong></h2>



<figure class="wp-block-image size-full"><a href="https://zxi.mytechroad.com/blog/wp-content/uploads/2023/01/1061-s1.png"><img width="960" height="540" src="https://zxi.mytechroad.com/blog/wp-content/uploads/2023/01/1061-s1.png" alt="" class="wp-image-9918" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2023/01/1061-s1.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2023/01/1061-s1-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2023/01/1061-s1-768x432.png 768w" sizes="(max-width: 960px) 100vw, 960px" /></a></figure>



<p>Time complexity: O(n + m)<br>Space complexity: O(1)</p>



<div class="responsive-tabs">
<h2 class="tabtitle">C++</h2>
<div class="tabcontent">

<pre class="crayon-plain-tag">// Author: Huahua
class Solution {
public:
  string smallestEquivalentString(string s1, string s2, string baseStr) {
    vector&lt;int&gt; p(26);
    iota(begin(p), end(p), 0);
    function&lt;int(int)&gt; find = [&amp;](int x) {
      return p[x] == x ? x : p[x] = find(p[x]);
    };
    for (int i = 0; i &lt; s1.length(); ++i) {
      int r1 = find(s1[i] - 'a');
      int r2 = find(s2[i] - 'a');
      if (r2 &lt; r1) swap(r1, r2);
      p[r2] = r1;
    }
    
    string ans(baseStr);
    for (int i = 0; i &lt; baseStr.length(); ++i) {
      ans[i] = find(baseStr[i] - 'a') + 'a';
    }
    return ans;
  }
};</pre>
</div></div>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/graph/leetcode-1061-lexicographically-smallest-equivalent-string/">花花酱 LeetCode 1061. Lexicographically Smallest Equivalent String</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/graph/leetcode-1061-lexicographically-smallest-equivalent-string/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 2477. Minimum Fuel Cost to Report to the Capital</title>
		<link>https://zxi.mytechroad.com/blog/graph/leetcode-2477-minimum-fuel-cost-to-report-to-the-capital/</link>
					<comments>https://zxi.mytechroad.com/blog/graph/leetcode-2477-minimum-fuel-cost-to-report-to-the-capital/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sat, 26 Nov 2022 16:41:02 +0000</pubDate>
				<category><![CDATA[Graph]]></category>
		<category><![CDATA[DFS]]></category>
		<category><![CDATA[graph]]></category>
		<category><![CDATA[greedy]]></category>
		<category><![CDATA[medium]]></category>
		<category><![CDATA[tree]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=9905</guid>

					<description><![CDATA[<p>There is a tree (i.e., a connected, undirected graph with no cycles) structure country network consisting of&#160;n&#160;cities numbered from&#160;0&#160;to&#160;n - 1&#160;and exactly&#160;n - 1&#160;roads. The&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/graph/leetcode-2477-minimum-fuel-cost-to-report-to-the-capital/">花花酱 LeetCode 2477. Minimum Fuel Cost to Report to the Capital</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>There is a tree (i.e., a connected, undirected graph with no cycles) structure country network consisting of&nbsp;<code>n</code>&nbsp;cities numbered from&nbsp;<code>0</code>&nbsp;to&nbsp;<code>n - 1</code>&nbsp;and exactly&nbsp;<code>n - 1</code>&nbsp;roads. The capital city is city&nbsp;<code>0</code>. You are given a 2D integer array&nbsp;<code>roads</code>&nbsp;where&nbsp;<code>roads[i] = [a<sub>i</sub>, b<sub>i</sub>]</code>&nbsp;denotes that there exists a&nbsp;<strong>bidirectional road</strong>&nbsp;connecting cities&nbsp;<code>a<sub>i</sub></code>&nbsp;and&nbsp;<code>b<sub>i</sub></code>.</p>



<p>There is a meeting for the representatives of each city. The meeting is in the capital city.</p>



<p>There is a car in each city. You are given an integer&nbsp;<code>seats</code>&nbsp;that indicates the number of seats in each car.</p>



<p>A representative can use the car in their city to travel or change the car and ride with another representative. The cost of traveling between two cities is one liter of fuel.</p>



<p>Return&nbsp;<em>the minimum number of liters of fuel to reach the capital city</em>.</p>



<p><strong>Example 1:</strong></p>



<figure class="wp-block-image"><img src="https://assets.leetcode.com/uploads/2022/09/22/a4c380025e3ff0c379525e96a7d63a3.png" alt=""/></figure>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> roads = [[0,1],[0,2],[0,3]], seats = 5
<strong>Output:</strong> 3
<strong>Explanation:</strong> 
- Representative<sub>1</sub> goes directly to the capital with 1 liter of fuel.
- Representative<sub>2</sub> goes directly to the capital with 1 liter of fuel.
- Representative<sub>3</sub> goes directly to the capital with 1 liter of fuel.
It costs 3 liters of fuel at minimum. 
It can be proven that 3 is the minimum number of liters of fuel needed.
</pre>



<p><strong>Example 2:</strong></p>



<figure class="wp-block-image"><img src="https://assets.leetcode.com/uploads/2022/11/16/2.png" alt=""/></figure>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> roads = [[3,1],[3,2],[1,0],[0,4],[0,5],[4,6]], seats = 2
<strong>Output:</strong> 7
<strong>Explanation:</strong> 
- Representative<sub>2</sub> goes directly to city 3 with 1 liter of fuel.
- Representative<sub>2</sub> and representative<sub>3</sub> go together to city 1 with 1 liter of fuel.
- Representative<sub>2</sub> and representative<sub>3</sub> go together to the capital with 1 liter of fuel.
- Representative<sub>1</sub> goes directly to the capital with 1 liter of fuel.
- Representative<sub>5</sub> goes directly to the capital with 1 liter of fuel.
- Representative<sub>6</sub> goes directly to city 4 with 1 liter of fuel.
- Representative<sub>4</sub> and representative<sub>6</sub> go together to the capital with 1 liter of fuel.
It costs 7 liters of fuel at minimum. 
It can be proven that 7 is the minimum number of liters of fuel needed.
</pre>



<p><strong>Example 3:</strong></p>



<figure class="wp-block-image"><img src="https://assets.leetcode.com/uploads/2022/09/27/efcf7f7be6830b8763639cfd01b690a.png" alt=""/></figure>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> roads = [], seats = 1
<strong>Output:</strong> 0
<strong>Explanation:</strong> No representatives need to travel to the capital city.
</pre>



<p><strong>Constraints:</strong></p>



<ul><li><code>1 &lt;= n &lt;= 10<sup>5</sup></code></li><li><code>roads.length == n - 1</code></li><li><code>roads[i].length == 2</code></li><li><code>0 &lt;= a<sub>i</sub>, b<sub>i</sub>&nbsp;&lt; n</code></li><li><code>a<sub>i</sub>&nbsp;!= b<sub>i</sub></code></li><li><code>roads</code>&nbsp;represents a valid tree.</li><li><code>1 &lt;= seats &lt;= 10<sup>5</sup></code></li></ul>



<h2><strong>Solution: Greedy + DFS</strong></h2>



<p>To reach the minimum cost, we must share cars if possible, say X reps from children nodes to an intermediate node u on the way towards capital 0.  Then they all changes cars at node u, and we need (X + 1) // seats cars/fuel from u to 0.</p>



<p>We use DFS to count # of reps at each node u while accumulating the total cost.</p>



<p>Time complexity: O(n)<br>Space complexity: O(n)</p>



<div class="responsive-tabs">
<h2 class="tabtitle">C++</h2>
<div class="tabcontent">

<pre class="crayon-plain-tag">// Author: Huahua
class Solution {
public:
  long long minimumFuelCost(vector&lt;vector&lt;int&gt;&gt;&amp; roads, int seats) {
    long long ans = 0;
    vector&lt;vector&lt;int&gt;&gt; g(roads.size() + 1);
    for (const vector&lt;int&gt;&amp; r : roads) {
      g[r[0]].push_back(r[1]);
      g[r[1]].push_back(r[0]);
    }
    // Returns total # of children of u.
    function&lt;int(int, int)&gt; dfs = [&amp;](int u, int p, int rep = 1) {      
      for (int v : g[u])
        if (v != p) rep += dfs(v, u);
      if (u) ans += (rep + seats - 1) / seats;
      return rep;
    };
    dfs(0, -1);
    return ans;
  }
};</pre>
</div></div>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/graph/leetcode-2477-minimum-fuel-cost-to-report-to-the-capital/">花花酱 LeetCode 2477. Minimum Fuel Cost to Report to the Capital</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/graph/leetcode-2477-minimum-fuel-cost-to-report-to-the-capital/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 2374. Node With Highest Edge Score</title>
		<link>https://zxi.mytechroad.com/blog/graph/leetcode-2374-node-with-highest-edge-score/</link>
					<comments>https://zxi.mytechroad.com/blog/graph/leetcode-2374-node-with-highest-edge-score/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Mon, 15 Aug 2022 04:36:05 +0000</pubDate>
				<category><![CDATA[Graph]]></category>
		<category><![CDATA[array]]></category>
		<category><![CDATA[graph]]></category>
		<category><![CDATA[medium]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=9787</guid>

					<description><![CDATA[<p>You are given a directed graph with&#160;n&#160;nodes labeled from&#160;0&#160;to&#160;n - 1, where each node has&#160;exactly one&#160;outgoing edge. The graph is represented by a given&#160;0-indexed&#160;integer array&#160;edges&#160;of&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/graph/leetcode-2374-node-with-highest-edge-score/">花花酱 LeetCode 2374. Node With Highest Edge Score</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>You are given a directed graph with&nbsp;<code>n</code>&nbsp;nodes labeled from&nbsp;<code>0</code>&nbsp;to&nbsp;<code>n - 1</code>, where each node has&nbsp;<strong>exactly one</strong>&nbsp;outgoing edge.</p>



<p>The graph is represented by a given&nbsp;<strong>0-indexed</strong>&nbsp;integer array&nbsp;<code>edges</code>&nbsp;of length&nbsp;<code>n</code>, where&nbsp;<code>edges[i]</code>&nbsp;indicates that there is a&nbsp;<strong>directed</strong>&nbsp;edge from node&nbsp;<code>i</code>&nbsp;to node&nbsp;<code>edges[i]</code>.</p>



<p>The&nbsp;<strong>edge score</strong>&nbsp;of a node&nbsp;<code>i</code>&nbsp;is defined as the sum of the&nbsp;<strong>labels</strong>&nbsp;of all the nodes that have an edge pointing to&nbsp;<code>i</code>.</p>



<p>Return&nbsp;<em>the node with the highest&nbsp;<strong>edge score</strong></em>. If multiple nodes have the same&nbsp;<strong>edge score</strong>, return the node with the&nbsp;<strong>smallest</strong>&nbsp;index.</p>



<p><strong>Example 1:</strong></p>



<figure class="wp-block-image"><img src="https://assets.leetcode.com/uploads/2022/06/20/image-20220620195403-1.png" alt=""/></figure>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> edges = [1,0,0,0,0,7,7,5]
<strong>Output:</strong> 7
<strong>Explanation:</strong>
- The nodes 1, 2, 3 and 4 have an edge pointing to node 0. The edge score of node 0 is 1 + 2 + 3 + 4 = 10.
- The node 0 has an edge pointing to node 1. The edge score of node 1 is 0.
- The node 7 has an edge pointing to node 5. The edge score of node 5 is 7.
- The nodes 5 and 6 have an edge pointing to node 7. The edge score of node 7 is 5 + 6 = 11.
Node 7 has the highest edge score so return 7.
</pre>



<p><strong>Example 2:</strong></p>



<figure class="wp-block-image"><img src="https://assets.leetcode.com/uploads/2022/06/20/image-20220620200212-3.png" alt=""/></figure>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> edges = [2,0,0,2]
<strong>Output:</strong> 0
<strong>Explanation:</strong>
- The nodes 1 and 2 have an edge pointing to node 0. The edge score of node 0 is 1 + 2 = 3.
- The nodes 0 and 3 have an edge pointing to node 2. The edge score of node 2 is 0 + 3 = 3.
Nodes 0 and 2 both have an edge score of 3. Since node 0 has a smaller index, we return 0.
</pre>



<p><strong>Constraints:</strong></p>



<ul><li><code>n == edges.length</code></li><li><code>2 &lt;= n &lt;= 10<sup>5</sup></code></li><li><code>0 &lt;= edges[i] &lt; n</code></li><li><code>edges[i] != i</code></li></ul>



<h2><strong>Solution: </strong></h2>



<p>Use an array to store the score of each node.</p>



<p>Time complexity: O(n)<br>Space complexity: O(n)</p>



<p>use <a href="https://en.cppreference.com/w/cpp/algorithm/max_element">max_element</a> to find the largest element.</p>



<div class="responsive-tabs">
<h2 class="tabtitle">C++</h2>
<div class="tabcontent">

<pre class="crayon-plain-tag">// Author: Huahua
class Solution {
public:
  int edgeScore(vector&lt;int&gt;&amp; edges) {
    const int n = edges.size();
    vector&lt;long&gt; s(n);
    for (int i = 0; i &lt; n; ++i)
      s[edges[i]] += i;
    return max_element(begin(s), end(s)) - begin(s);
  }
};</pre>
</div></div>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/graph/leetcode-2374-node-with-highest-edge-score/">花花酱 LeetCode 2374. Node With Highest Edge Score</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/graph/leetcode-2374-node-with-highest-edge-score/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 133. Clone Graph</title>
		<link>https://zxi.mytechroad.com/blog/graph/leetcode-133-clone-graph-2/</link>
					<comments>https://zxi.mytechroad.com/blog/graph/leetcode-133-clone-graph-2/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sun, 14 Aug 2022 16:33:26 +0000</pubDate>
				<category><![CDATA[Graph]]></category>
		<category><![CDATA[clone]]></category>
		<category><![CDATA[graph]]></category>
		<category><![CDATA[medium]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=9775</guid>

					<description><![CDATA[<p>Given a reference of a node in a connected undirected graph. Return a&#160;deep copy&#160;(clone) of the graph. Each node in the graph contains a value (int) and&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/graph/leetcode-133-clone-graph-2/">花花酱 LeetCode 133. Clone Graph</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe title="花花酱 LeetCode 133. Clone Graph - 刷题找工作 EP400" width="500" height="281" src="https://www.youtube.com/embed/NCQMg-WMRZc?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
</div></figure>



<p>Given a reference of a node in a <strong><a rel="noreferrer noopener" href="https://en.wikipedia.org/wiki/Connectivity_(graph_theory)#Connected_graph" target="_blank">connected</a></strong> undirected graph.</p>



<p>Return a&nbsp;<a href="https://en.wikipedia.org/wiki/Object_copying#Deep_copy" target="_blank" rel="noreferrer noopener"><strong>deep copy</strong></a>&nbsp;(clone) of the graph.</p>



<p>Each node in the graph contains a value (<code>int</code>) and a list (<code>List[Node]</code>) of its neighbors.</p>



<pre class="wp-block-preformatted;crayon:false">class Node {
    public int val;
    public List<Node> neighbors;
}
</pre>



<p><strong>Test case format:</strong></p>



<p>For simplicity, each node&#8217;s value is the same as the node&#8217;s index (1-indexed). For example, the first node with&nbsp;<code>val == 1</code>, the second node with&nbsp;<code>val == 2</code>, and so on. The graph is represented in the test case using an adjacency list.</p>



<p><strong>An adjacency list</strong>&nbsp;is a collection of unordered&nbsp;<strong>lists</strong>&nbsp;used to represent a finite graph. Each list describes the set of neighbors of a node in the graph.</p>



<p>The given node will always be the first node with&nbsp;<code>val = 1</code>. You must return the&nbsp;<strong>copy of the given node</strong>&nbsp;as a reference to the cloned graph.</p>



<p><strong>Example 1:</strong></p>



<figure class="wp-block-image"><img src="https://assets.leetcode.com/uploads/2019/11/04/133_clone_graph_question.png" alt=""/></figure>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> adjList = [[2,4],[1,3],[2,4],[1,3]]
<strong>Output:</strong> [[2,4],[1,3],[2,4],[1,3]]
<strong>Explanation:</strong> There are 4 nodes in the graph.
1st node (val = 1)'s neighbors are 2nd node (val = 2) and 4th node (val = 4).
2nd node (val = 2)'s neighbors are 1st node (val = 1) and 3rd node (val = 3).
3rd node (val = 3)'s neighbors are 2nd node (val = 2) and 4th node (val = 4).
4th node (val = 4)'s neighbors are 1st node (val = 1) and 3rd node (val = 3).
</pre>



<p><strong>Example 2:</strong></p>



<figure class="wp-block-image"><img src="https://assets.leetcode.com/uploads/2020/01/07/graph.png" alt=""/></figure>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> adjList = [[]]
<strong>Output:</strong> [[]]
<strong>Explanation:</strong> Note that the input contains one empty list. The graph consists of only one node with val = 1 and it does not have any neighbors.
</pre>



<p><strong>Example 3:</strong></p>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> adjList = []
<strong>Output:</strong> []
<strong>Explanation:</strong> This an empty graph, it does not have any nodes.
</pre>



<p><strong>Constraints:</strong></p>



<ul><li>The number of nodes in the graph is in the range&nbsp;<code>[0, 100]</code>.</li><li><code>1 &lt;= Node.val &lt;= 100</code></li><li><code>Node.val</code>&nbsp;is unique for each node.</li><li>There are no repeated edges and no self-loops in the graph.</li><li>The Graph is connected and all nodes can be visited starting from the given node.</li></ul>



<h2><strong>Solution: DFS + Hashtable</strong></h2>



<figure class="wp-block-image size-full"><a href="https://zxi.mytechroad.com/blog/wp-content/uploads/2022/08/133-ep400-1.png"><img width="960" height="540" src="https://zxi.mytechroad.com/blog/wp-content/uploads/2022/08/133-ep400-1.png" alt="" class="wp-image-9776" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2022/08/133-ep400-1.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2022/08/133-ep400-1-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2022/08/133-ep400-1-768x432.png 768w" sizes="(max-width: 960px) 100vw, 960px" /></a></figure>



<figure class="wp-block-image size-full"><a href="https://zxi.mytechroad.com/blog/wp-content/uploads/2022/08/133-ep400-2.png"><img width="960" height="540" src="https://zxi.mytechroad.com/blog/wp-content/uploads/2022/08/133-ep400-2.png" alt="" class="wp-image-9777" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2022/08/133-ep400-2.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2022/08/133-ep400-2-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2022/08/133-ep400-2-768x432.png 768w" sizes="(max-width: 960px) 100vw, 960px" /></a></figure>



<figure class="wp-block-image size-full"><a href="https://zxi.mytechroad.com/blog/wp-content/uploads/2022/08/133-ep400-3.png"><img width="960" height="540" src="https://zxi.mytechroad.com/blog/wp-content/uploads/2022/08/133-ep400-3.png" alt="" class="wp-image-9778" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2022/08/133-ep400-3.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2022/08/133-ep400-3-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2022/08/133-ep400-3-768x432.png 768w" sizes="(max-width: 960px) 100vw, 960px" /></a></figure>



<p>Time complexity: O(V+E)<br>Space complexity: O(V+E)</p>



<div class="responsive-tabs">
<h2 class="tabtitle">C++</h2>
<div class="tabcontent">

<pre class="crayon-plain-tag">// Author: Huahua
class Solution {
public:
  Node* cloneGraph(Node* node) {
    if (!node) return nullptr;
    unordered_map&lt;Node*, Node*&gt; m;
    function&lt;void(Node*)&gt; dfs = [&amp;](Node* u) {
      m[u] = new Node(u-&gt;val);
      for (Node* v : u-&gt;neighbors) {
        if (!m.count(v)) dfs(v);
        m[u]-&gt;neighbors.push_back(m[v]);
      }
    };
    dfs(node);
    return m[node];
  }
};</pre>
</div></div>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/graph/leetcode-133-clone-graph-2/">花花酱 LeetCode 133. Clone Graph</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/graph/leetcode-133-clone-graph-2/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 2316. Count Unreachable Pairs of Nodes in an Undirected Graph</title>
		<link>https://zxi.mytechroad.com/blog/graph/leetcode-2316-count-unreachable-pairs-of-nodes-in-an-undirected-graph/</link>
					<comments>https://zxi.mytechroad.com/blog/graph/leetcode-2316-count-unreachable-pairs-of-nodes-in-an-undirected-graph/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sat, 25 Jun 2022 23:07:42 +0000</pubDate>
				<category><![CDATA[Graph]]></category>
		<category><![CDATA[DFS]]></category>
		<category><![CDATA[graph]]></category>
		<category><![CDATA[medium]]></category>
		<category><![CDATA[union find]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=9761</guid>

					<description><![CDATA[<p>You are given an integer n. There is an undirected graph with n nodes, numbered from 0 to n - 1. You are given a 2D integer array edges where edges[i] = [ai, bi] denotes that there&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/graph/leetcode-2316-count-unreachable-pairs-of-nodes-in-an-undirected-graph/">花花酱 LeetCode 2316. Count Unreachable Pairs of Nodes in an Undirected Graph</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe title="花花酱 LeetCode 2316. Count Unreachable Pairs of Nodes in an Undirected Graph - 刷题找工作 EP397" width="500" height="281" src="https://www.youtube.com/embed/vH9CLfE82Rk?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
</div></figure>



<p>You are given an integer <code>n</code>. There is an <strong>undirected</strong> graph with <code>n</code> nodes, numbered from <code>0</code> to <code>n - 1</code>. You are given a 2D integer array <code>edges</code> where <code>edges[i] = [a<sub>i</sub>, b<sub>i</sub>]</code> denotes that there exists an <strong>undirected</strong> edge connecting nodes <code>a<sub>i</sub></code> and <code>b<sub>i</sub></code>.</p>



<p>Return&nbsp;<em>the&nbsp;<strong>number of pairs</strong>&nbsp;of different nodes that are&nbsp;<strong>unreachable</strong>&nbsp;from each other</em>.</p>



<p><strong>Example 1:</strong></p>



<figure class="wp-block-image"><img src="https://assets.leetcode.com/uploads/2022/05/05/tc-3.png" alt=""/></figure>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> n = 3, edges = [[0,1],[0,2],[1,2]]
<strong>Output:</strong> 0
<strong>Explanation:</strong> There are no pairs of nodes that are unreachable from each other. Therefore, we return 0.
</pre>



<p><strong>Example 2:</strong></p>



<figure class="wp-block-image"><img src="https://assets.leetcode.com/uploads/2022/05/05/tc-2.png" alt=""/></figure>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> n = 7, edges = [[0,2],[0,5],[2,4],[1,6],[5,4]]
<strong>Output:</strong> 14
<strong>Explanation:</strong> There are 14 pairs of nodes that are unreachable from each other:
[[0,1],[0,3],[0,6],[1,2],[1,3],[1,4],[1,5],[2,3],[2,6],[3,4],[3,5],[3,6],[4,6],[5,6]].
Therefore, we return 14.
</pre>



<p><strong>Constraints:</strong></p>



<ul><li><code>1 &lt;= n &lt;= 10<sup>5</sup></code></li><li><code>0 &lt;= edges.length &lt;= 2 * 10<sup>5</sup></code></li><li><code>edges[i].length == 2</code></li><li><code>0 &lt;= a<sub>i</sub>, b<sub>i</sub>&nbsp;&lt; n</code></li><li><code>a<sub>i</sub>&nbsp;!= b<sub>i</sub></code></li><li>There are no repeated edges.</li></ul>



<h2><strong>Solution 1: DFS</strong></h2>



<p>Use DFS to find all CCs</p>



<p>Time complexity: O(V+E)<br>Space complexity: O(V+E)</p>



<div class="responsive-tabs">
<h2 class="tabtitle">C++</h2>
<div class="tabcontent">

<pre class="crayon-plain-tag">// Author: Huahua
// Author: Huahua, 791ms, 136 MB
class Solution {
public:
  long long countPairs(int n, vector&lt;vector&lt;int&gt;&gt;&amp; edges) {
    vector&lt;vector&lt;int&gt;&gt; g(n);
    for (const auto&amp; e : edges) {
      g[e[0]].push_back(e[1]);
      g[e[1]].push_back(e[0]);
    }
    vector&lt;int&gt; seen(n);
    long long cur = 0;
    
    function&lt;void(int)&gt; dfs = [&amp;](int u) {
      ++cur;
      for (int v : g[u])
        if (seen[v]++ == 0) dfs(v);      
    };
    long long ans = 0;    
    for (int i = 0; i &lt; n; ++i) {
      if (seen[i]++) continue;
      cur = 0;
      dfs(i);
      ans += (n - cur) * cur;
    }
    return ans / 2;
  }
};</pre>
</div></div>



<h2><strong>Solution 2: Union Find</strong></h2>



<p>Time complexity: O(V+E)<br>Space complexity: O(V)</p>



<div class="responsive-tabs">
<h2 class="tabtitle">C++</h2>
<div class="tabcontent">

<pre class="crayon-plain-tag">// Author: Huahua
class Solution {
public:
  long long countPairs(int n, vector&lt;vector&lt;int&gt;&gt;&amp; edges) {
    vector&lt;int&gt; parents(n);
    vector&lt;int&gt; counts(n, 1);
    std::iota(begin(parents), end(parents), 0);
    
    function&lt;int(int)&gt; find = [&amp;](int x) {
      if (parents[x] == x) return x;
      return parents[x] = find(parents[x]);
    };
    
    for (const auto&amp; e : edges) {
      int ru = find(e[0]);
      int rv = find(e[1]);
      if (ru != rv) {
        parents[rv] = ru;
        counts[ru] += counts[rv];        
      }
    }
    long long ans = 0;    
    for (int i = 0; i &lt; n; ++i)      
      ans += n - counts[find(i)];
    return ans / 2;
  }
};</pre>
</div></div>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/graph/leetcode-2316-count-unreachable-pairs-of-nodes-in-an-undirected-graph/">花花酱 LeetCode 2316. Count Unreachable Pairs of Nodes in an Undirected Graph</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/graph/leetcode-2316-count-unreachable-pairs-of-nodes-in-an-undirected-graph/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 2242. Maximum Score of a Node Sequence</title>
		<link>https://zxi.mytechroad.com/blog/greedy/leetcode-2242-maximum-score-of-a-node-sequence/</link>
					<comments>https://zxi.mytechroad.com/blog/greedy/leetcode-2242-maximum-score-of-a-node-sequence/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sun, 17 Apr 2022 06:16:40 +0000</pubDate>
				<category><![CDATA[Greedy]]></category>
		<category><![CDATA[graph]]></category>
		<category><![CDATA[greedy]]></category>
		<category><![CDATA[hard]]></category>
		<category><![CDATA[heap]]></category>
		<category><![CDATA[set]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=9662</guid>

					<description><![CDATA[<p>There is an&#160;undirected&#160;graph with&#160;n&#160;nodes, numbered from&#160;0&#160;to&#160;n - 1. You are given a&#160;0-indexed&#160;integer array&#160;scores&#160;of length&#160;n&#160;where&#160;scores[i]&#160;denotes the score of node&#160;i. You are also given a 2D integer&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/greedy/leetcode-2242-maximum-score-of-a-node-sequence/">花花酱 LeetCode 2242. Maximum Score of a Node Sequence</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>There is an&nbsp;<strong>undirected</strong>&nbsp;graph with&nbsp;<code>n</code>&nbsp;nodes, numbered from&nbsp;<code>0</code>&nbsp;to&nbsp;<code>n - 1</code>.</p>



<p>You are given a&nbsp;<strong>0-indexed</strong>&nbsp;integer array&nbsp;<code>scores</code>&nbsp;of length&nbsp;<code>n</code>&nbsp;where&nbsp;<code>scores[i]</code>&nbsp;denotes the score of node&nbsp;<code>i</code>. You are also given a 2D integer array&nbsp;<code>edges</code>&nbsp;where&nbsp;<code>edges[i] = [a<sub>i</sub>, b<sub>i</sub>]</code>&nbsp;denotes that there exists an&nbsp;<strong>undirected</strong>&nbsp;edge connecting nodes&nbsp;<code>a<sub>i</sub></code>&nbsp;and&nbsp;<code>b<sub>i</sub></code>.</p>



<p>A node sequence is&nbsp;<strong>valid</strong>&nbsp;if it meets the following conditions:</p>



<ul><li>There is an edge connecting every pair of&nbsp;<strong>adjacent</strong>&nbsp;nodes in the sequence.</li><li>No node appears more than once in the sequence.</li></ul>



<p>The score of a node sequence is defined as the&nbsp;<strong>sum</strong>&nbsp;of the scores of the nodes in the sequence.</p>



<p>Return&nbsp;<em>the&nbsp;<strong>maximum score</strong>&nbsp;of a valid node sequence with a length of&nbsp;</em><code>4</code><em>.&nbsp;</em>If no such sequence exists, return<em>&nbsp;</em><code>-1</code>.</p>



<p><strong>Example 1:</strong></p>



<figure class="wp-block-image"><img src="https://assets.leetcode.com/uploads/2022/04/15/ex1new3.png" alt=""/></figure>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> scores = [5,2,9,8,4], edges = [[0,1],[1,2],[2,3],[0,2],[1,3],[2,4]]
<strong>Output:</strong> 24
<strong>Explanation:</strong> The figure above shows the graph and the chosen node sequence [0,1,2,3].
The score of the node sequence is 5 + 2 + 9 + 8 = 24.
It can be shown that no other node sequence has a score of more than 24.
Note that the sequences [3,1,2,0] and [1,0,2,3] are also valid and have a score of 24.
The sequence [0,3,2,4] is not valid since no edge connects nodes 0 and 3.
</pre>



<p><strong>Example 2:</strong></p>



<figure class="wp-block-image"><img src="https://assets.leetcode.com/uploads/2022/03/17/ex2.png" alt=""/></figure>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> scores = [9,20,6,4,11,12], edges = [[0,3],[5,3],[2,4],[1,3]]
<strong>Output:</strong> -1
<strong>Explanation:</strong> The figure above shows the graph.
There are no valid node sequences of length 4, so we return -1.
</pre>



<p><strong>Constraints:</strong></p>



<ul><li><code>n == scores.length</code></li><li><code>4 &lt;= n &lt;= 5 * 10<sup>4</sup></code></li><li><code>1 &lt;= scores[i] &lt;= 10<sup>8</sup></code></li><li><code>0 &lt;= edges.length &lt;= 5 * 10<sup>4</sup></code></li><li><code>edges[i].length == 2</code></li><li><code>0 &lt;= a<sub>i</sub>, b<sub>i</sub>&nbsp;&lt;= n - 1</code></li><li><code>a<sub>i</sub>&nbsp;!= b<sub>i</sub></code></li><li>There are no duplicate edges.</li></ul>



<h2><strong>Solution: Greedy / Top3 neighbors</strong></h2>



<figure class="wp-block-image size-full"><a href="https://zxi.mytechroad.com/blog/wp-content/uploads/2022/04/lc2242-ep396-1.png"><img width="960" height="540" src="https://zxi.mytechroad.com/blog/wp-content/uploads/2022/04/lc2242-ep396-1.png" alt="" class="wp-image-9667" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2022/04/lc2242-ep396-1.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2022/04/lc2242-ep396-1-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2022/04/lc2242-ep396-1-768x432.png 768w" sizes="(max-width: 960px) 100vw, 960px" /></a></figure>



<figure class="wp-block-image size-full"><a href="https://zxi.mytechroad.com/blog/wp-content/uploads/2022/04/lc2242-ep396-2.png"><img width="960" height="540" src="https://zxi.mytechroad.com/blog/wp-content/uploads/2022/04/lc2242-ep396-2.png" alt="" class="wp-image-9668" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2022/04/lc2242-ep396-2.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2022/04/lc2242-ep396-2-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2022/04/lc2242-ep396-2-768x432.png 768w" sizes="(max-width: 960px) 100vw, 960px" /></a></figure>



<figure class="wp-block-image size-full"><a href="https://zxi.mytechroad.com/blog/wp-content/uploads/2022/04/lc2242-ep396-3.png"><img width="960" height="540" src="https://zxi.mytechroad.com/blog/wp-content/uploads/2022/04/lc2242-ep396-3.png" alt="" class="wp-image-9669" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2022/04/lc2242-ep396-3.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2022/04/lc2242-ep396-3-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2022/04/lc2242-ep396-3-768x432.png 768w" sizes="(max-width: 960px) 100vw, 960px" /></a></figure>



<figure class="wp-block-image size-full"><a href="https://zxi.mytechroad.com/blog/wp-content/uploads/2022/04/lc2242-ep396-4.png"><img width="960" height="540" src="https://zxi.mytechroad.com/blog/wp-content/uploads/2022/04/lc2242-ep396-4.png" alt="" class="wp-image-9671" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2022/04/lc2242-ep396-4.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2022/04/lc2242-ep396-4-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2022/04/lc2242-ep396-4-768x432.png 768w" sizes="(max-width: 960px) 100vw, 960px" /></a></figure>



<figure class="wp-block-image size-full"><a href="https://zxi.mytechroad.com/blog/wp-content/uploads/2022/04/lc2242-ep396-5.png"><img width="960" height="540" src="https://zxi.mytechroad.com/blog/wp-content/uploads/2022/04/lc2242-ep396-5.png" alt="" class="wp-image-9673" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2022/04/lc2242-ep396-5.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2022/04/lc2242-ep396-5-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2022/04/lc2242-ep396-5-768x432.png 768w" sizes="(max-width: 960px) 100vw, 960px" /></a></figure>



<p>Since |E| is already 5*10<sup>4</sup>, we can&#8217;t enumerate all possible sequences. We must do in O(|E|) or O(|E|log|E|).</p>



<p>Enumerate all the edges, we have a pair of node a, b. To get the optimal answer, we just need to find the largest neighbor of a and b, which we call c, d respectively. Just need to make sure a, b, c, d are unique. i.e. c != d, c != b and d != a. Since the a&#8217;s largest neighbor can be either b or d. We can&#8217;t just store the largest neighbor, but top 3 instead for each node to avoid duplications.</p>



<p>Time complexity: O(|E|*9)<br>Space complexity: O(|V|*3)</p>



<div class="responsive-tabs">
<h2 class="tabtitle">C++</h2>
<div class="tabcontent">

<pre class="crayon-plain-tag">// Author: Huahua
class Solution {
public:
  int maximumScore(vector&lt;int&gt;&amp; scores, vector&lt;vector&lt;int&gt;&gt;&amp; edges) {
    const int n = scores.size();
    vector&lt;set&lt;pair&lt;int, int&gt;&gt;&gt; top3(n);
    for (const auto&amp; e : edges) {      
      top3[e[0]].emplace(scores[e[1]], e[1]);
      top3[e[1]].emplace(scores[e[0]], e[0]);
      if (top3[e[0]].size() &gt; 3) top3[e[0]].erase(begin(top3[e[0]]));
      if (top3[e[1]].size() &gt; 3) top3[e[1]].erase(begin(top3[e[1]]));
    }
    int ans = -1;
    for (const auto&amp; e : edges) {
      const int a = e[0], b = e[1], sa = scores[a], sb = scores[b];
      for (const auto&amp; [sc, c] : top3[a])
        for (const auto&amp; [sd, d] : top3[b])          
          if (sa + sb + sc + sd &gt; ans &amp;&amp; c != b &amp;&amp; c != d &amp;&amp; d != a)
            ans = sa + sb + sc + sd;
    }
    return ans;
  }
};</pre>
</div></div>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/greedy/leetcode-2242-maximum-score-of-a-node-sequence/">花花酱 LeetCode 2242. Maximum Score of a Node Sequence</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/greedy/leetcode-2242-maximum-score-of-a-node-sequence/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 2192. All Ancestors of a Node in a Directed Acyclic Graph</title>
		<link>https://zxi.mytechroad.com/blog/graph/leetcode-2192-all-ancestors-of-a-node-in-a-directed-acyclic-graph/</link>
					<comments>https://zxi.mytechroad.com/blog/graph/leetcode-2192-all-ancestors-of-a-node-in-a-directed-acyclic-graph/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sat, 12 Mar 2022 07:14:40 +0000</pubDate>
				<category><![CDATA[Graph]]></category>
		<category><![CDATA[DFS]]></category>
		<category><![CDATA[graph]]></category>
		<category><![CDATA[medium]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=9570</guid>

					<description><![CDATA[<p>You are given a positive integer&#160;n&#160;representing the number of nodes of a&#160;Directed Acyclic Graph&#160;(DAG). The nodes are numbered from&#160;0&#160;to&#160;n - 1&#160;(inclusive). You are also given&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/graph/leetcode-2192-all-ancestors-of-a-node-in-a-directed-acyclic-graph/">花花酱 LeetCode 2192. All Ancestors of a Node in a Directed Acyclic Graph</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>You are given a positive integer&nbsp;<code>n</code>&nbsp;representing the number of nodes of a&nbsp;<strong>Directed Acyclic Graph</strong>&nbsp;(DAG). The nodes are numbered from&nbsp;<code>0</code>&nbsp;to&nbsp;<code>n - 1</code>&nbsp;(<strong>inclusive</strong>).</p>



<p>You are also given a 2D integer array&nbsp;<code>edges</code>, where&nbsp;<code>edges[i] = [from<sub>i</sub>, to<sub>i</sub>]</code>&nbsp;denotes that there is a&nbsp;<strong>unidirectional</strong>&nbsp;edge from&nbsp;<code>from<sub>i</sub></code>&nbsp;to&nbsp;<code>to<sub>i</sub></code>&nbsp;in the graph.</p>



<p>Return&nbsp;<em>a list</em>&nbsp;<code>answer</code><em>, where&nbsp;</em><code>answer[i]</code><em>&nbsp;is the&nbsp;<strong>list of ancestors</strong>&nbsp;of the</em>&nbsp;<code>i<sup>th</sup></code>&nbsp;<em>node, sorted in&nbsp;<strong>ascending order</strong></em>.</p>



<p>A node&nbsp;<code>u</code>&nbsp;is an&nbsp;<strong>ancestor</strong>&nbsp;of another node&nbsp;<code>v</code>&nbsp;if&nbsp;<code>u</code>&nbsp;can reach&nbsp;<code>v</code>&nbsp;via a set of edges.</p>



<p><strong>Example 1:</strong></p>



<figure class="wp-block-image"><img src="https://assets.leetcode.com/uploads/2019/12/12/e1.png" alt=""/></figure>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> n = 8, edgeList = [[0,3],[0,4],[1,3],[2,4],[2,7],[3,5],[3,6],[3,7],[4,6]]
<strong>Output:</strong> [[],[],[],[0,1],[0,2],[0,1,3],[0,1,2,3,4],[0,1,2,3]]
<strong>Explanation:</strong>
The above diagram represents the input graph.
- Nodes 0, 1, and 2 do not have any ancestors.
- Node 3 has two ancestors 0 and 1.
- Node 4 has two ancestors 0 and 2.
- Node 5 has three ancestors 0, 1, and 3.
- Node 6 has five ancestors 0, 1, 2, 3, and 4.
- Node 7 has four ancestors 0, 1, 2, and 3.
</pre>



<p><strong>Example 2:</strong></p>



<figure class="wp-block-image"><img src="https://assets.leetcode.com/uploads/2019/12/12/e2.png" alt=""/></figure>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> n = 5, edgeList = [[0,1],[0,2],[0,3],[0,4],[1,2],[1,3],[1,4],[2,3],[2,4],[3,4]]
<strong>Output:</strong> [[],[0],[0,1],[0,1,2],[0,1,2,3]]
<strong>Explanation:</strong>
The above diagram represents the input graph.
- Node 0 does not have any ancestor.
- Node 1 has one ancestor 0.
- Node 2 has two ancestors 0 and 1.
- Node 3 has three ancestors 0, 1, and 2.
- Node 4 has four ancestors 0, 1, 2, and 3.
</pre>



<p><strong>Constraints:</strong></p>



<ul><li><code>1 &lt;= n &lt;= 1000</code></li><li><code>0 &lt;= edges.length &lt;= min(2000, n * (n - 1) / 2)</code></li><li><code>edges[i].length == 2</code></li><li><code>0 &lt;= from<sub>i</sub>, to<sub>i</sub>&nbsp;&lt;= n - 1</code></li><li><code>from<sub>i</sub>&nbsp;!= to<sub>i</sub></code></li><li>There are no duplicate edges.</li><li>The graph is&nbsp;<strong>directed</strong>&nbsp;and&nbsp;<strong>acyclic</strong>.</li></ul>



<h2><strong>Solution: DFS</strong></h2>



<p>For each source node S, add it to all its reachable nodes by traversing the entire graph.<br>In one pass, only traverse each child node at most once.</p>



<p>Time complexity: O(VE)<br>Space complexity: (V+E)</p>



<div class="responsive-tabs">
<h2 class="tabtitle">C++</h2>
<div class="tabcontent">

<pre class="crayon-plain-tag">// Author: Huahua
class Solution {
public:
  vector&lt;vector&lt;int&gt;&gt; getAncestors(int n, vector&lt;vector&lt;int&gt;&gt;&amp; edges) {
    vector&lt;vector&lt;int&gt;&gt; ans(n);
    vector&lt;vector&lt;int&gt;&gt; g(n);
    for (const auto&amp; e : edges)
      g[e[0]].push_back(e[1]);    
    
    function&lt;void(int, int)&gt; dfs = [&amp;](int s, int u) -&gt; void {
      for (int v : g[u]) {
        if (ans[v].empty() || ans[v].back() != s) {
          ans[v].push_back(s);
          dfs(s, v);
        }
      }
    };
    
    for (int i = 0; i &lt; n; ++i)
      dfs(i, i);  
    return ans;
  }
};</pre>
</div></div>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/graph/leetcode-2192-all-ancestors-of-a-node-in-a-directed-acyclic-graph/">花花酱 LeetCode 2192. All Ancestors of a Node in a Directed Acyclic Graph</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/graph/leetcode-2192-all-ancestors-of-a-node-in-a-directed-acyclic-graph/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 2157. Groups of Strings</title>
		<link>https://zxi.mytechroad.com/blog/searching/leetcode-2157-groups-of-strings/</link>
					<comments>https://zxi.mytechroad.com/blog/searching/leetcode-2157-groups-of-strings/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Mon, 07 Feb 2022 01:03:45 +0000</pubDate>
				<category><![CDATA[Search]]></category>
		<category><![CDATA[connected components]]></category>
		<category><![CDATA[graph]]></category>
		<category><![CDATA[search]]></category>
		<category><![CDATA[union find]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=9492</guid>

					<description><![CDATA[<p>You are given a&#160;0-indexed&#160;array of strings&#160;words. Each string consists of&#160;lowercase English letters&#160;only. No letter occurs more than once in any string of&#160;words. Two strings&#160;s1&#160;and&#160;s2&#160;are said&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/searching/leetcode-2157-groups-of-strings/">花花酱 LeetCode 2157. Groups of Strings</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>You are given a&nbsp;<strong>0-indexed</strong>&nbsp;array of strings&nbsp;<code>words</code>. Each string consists of&nbsp;<strong>lowercase English letters</strong>&nbsp;only. No letter occurs more than once in any string of&nbsp;<code>words</code>.</p>



<p>Two strings&nbsp;<code>s1</code>&nbsp;and&nbsp;<code>s2</code>&nbsp;are said to be&nbsp;<strong>connected</strong>&nbsp;if the set of letters of&nbsp;<code>s2</code>&nbsp;can be obtained from the set of letters of&nbsp;<code>s1</code>&nbsp;by any&nbsp;<strong>one</strong>&nbsp;of the following operations:</p>



<ul><li>Adding exactly one letter to the set of the letters of&nbsp;<code>s1</code>.</li><li>Deleting exactly one letter from the set of the letters of&nbsp;<code>s1</code>.</li><li>Replacing exactly one letter from the set of the letters of&nbsp;<code>s1</code>&nbsp;with any letter,&nbsp;<strong>including</strong>&nbsp;itself.</li></ul>



<p>The array&nbsp;<code>words</code>&nbsp;can be divided into one or more non-intersecting&nbsp;<strong>groups</strong>. A string belongs to a group if any&nbsp;<strong>one</strong>&nbsp;of the following is true:</p>



<ul><li>It is connected to&nbsp;<strong>at least one</strong>&nbsp;other string of the group.</li><li>It is the&nbsp;<strong>only</strong>&nbsp;string present in the group.</li></ul>



<p>Note that the strings in&nbsp;<code>words</code>&nbsp;should be grouped in such a manner that a string belonging to a group cannot be connected to a string present in any other group. It can be proved that such an arrangement is always unique.</p>



<p>Return&nbsp;<em>an array</em>&nbsp;<code>ans</code>&nbsp;<em>of size</em>&nbsp;<code>2</code>&nbsp;<em>where:</em></p>



<ul><li><code>ans[0]</code>&nbsp;<em>is the&nbsp;<strong>total number</strong>&nbsp;of groups</em>&nbsp;<code>words</code>&nbsp;<em>can be divided into, and</em></li><li><code>ans[1]</code>&nbsp;<em>is the&nbsp;<strong>size of the largest</strong>&nbsp;group</em>.</li></ul>



<p><strong>Example 1:</strong></p>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> words = ["a","b","ab","cde"]
<strong>Output:</strong> [2,3]
<strong>Explanation:</strong>
- words[0] can be used to obtain words[1] (by replacing 'a' with 'b'), and words[2] (by adding 'b'). So words[0] is connected to words[1] and words[2].
- words[1] can be used to obtain words[0] (by replacing 'b' with 'a'), and words[2] (by adding 'a'). So words[1] is connected to words[0] and words[2].
- words[2] can be used to obtain words[0] (by deleting 'b'), and words[1] (by deleting 'a'). So words[2] is connected to words[0] and words[1].
- words[3] is not connected to any string in words.
Thus, words can be divided into 2 groups ["a","b","ab"] and ["cde"]. The size of the largest group is 3.  
</pre>



<p><strong>Example 2:</strong></p>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> words = ["a","ab","abc"]
<strong>Output:</strong> [1,3]
<strong>Explanation:</strong>
- words[0] is connected to words[1].
- words[1] is connected to words[0] and words[2].
- words[2] is connected to words[1].
Since all strings are connected to each other, they should be grouped together.
Thus, the size of the largest group is 3.
</pre>



<p><strong>Constraints:</strong></p>



<ul><li><code>1 &lt;= words.length &lt;= 2 * 10<sup>4</sup></code></li><li><code>1 &lt;= words[i].length &lt;= 26</code></li><li><code>words[i]</code>&nbsp;consists of lowercase English letters only.</li><li>No letter occurs more than once in&nbsp;<code>words[i]</code>.</li></ul>



<h2><strong>Solution: Bitmask + DFS</strong></h2>



<p>Use a bitmask to represent a string. Use dfs to find connected components.</p>



<p>Time complexity: O(n*26<sup>2</sup>)<br>Space complexity: O(n)</p>



<div class="responsive-tabs">
<h2 class="tabtitle">C++</h2>
<div class="tabcontent">

<pre class="crayon-plain-tag">// Author: Huahua
class Solution {
public:
  vector&lt;int&gt; groupStrings(vector&lt;string&gt;&amp; words) {
    unordered_map&lt;int, int&gt; m;
    for (const string&amp; w : words)
      ++m[accumulate(begin(w), end(w), 0, [](int k, char c){ return k | (1 &lt;&lt; (c - 'a')); })];
    function&lt;int(int)&gt; dfs = [&amp;](int mask) {
      auto it = m.find(mask);
      if (it == end(m)) return 0;
      int ans = it-&gt;second;      
      m.erase(it);
      for (int i = 0; i &lt; 26; ++i) {        
        ans += dfs(mask ^ (1 &lt;&lt; i));
        for (int j = i + 1; j &lt; 26; ++j)
          if ((mask &gt;&gt; i &amp; 1) != (mask &gt;&gt; j &amp; 1))
            ans += dfs(mask ^ (1 &lt;&lt; i) ^ (1 &lt;&lt; j));
      }
      return ans;
    };
    int size = 0;
    int groups = 0;
    while (!m.empty()) {
      size = max(size, dfs(begin(m)-&gt;first));
      ++groups;
    }
    return {groups, size};
  }
};</pre>
</div></div>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/searching/leetcode-2157-groups-of-strings/">花花酱 LeetCode 2157. Groups of Strings</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-2157-groups-of-strings/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 1998. GCD Sort of an Array</title>
		<link>https://zxi.mytechroad.com/blog/graph/leetcode-1998-gcd-sort-of-an-array/</link>
					<comments>https://zxi.mytechroad.com/blog/graph/leetcode-1998-gcd-sort-of-an-array/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sat, 01 Jan 2022 06:49:23 +0000</pubDate>
				<category><![CDATA[Graph]]></category>
		<category><![CDATA[gcd]]></category>
		<category><![CDATA[graph]]></category>
		<category><![CDATA[hard]]></category>
		<category><![CDATA[math]]></category>
		<category><![CDATA[prime]]></category>
		<category><![CDATA[sqrt]]></category>
		<category><![CDATA[union find]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=9383</guid>

					<description><![CDATA[<p>You are given an integer array&#160;nums, and you can perform the following operation&#160;any&#160;number of times on&#160;nums: Swap the positions of two elements&#160;nums[i]&#160;and&#160;nums[j]&#160;if&#160;gcd(nums[i], nums[j]) &#62; 1&#160;where&#160;gcd(nums[i],&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/graph/leetcode-1998-gcd-sort-of-an-array/">花花酱 LeetCode 1998. GCD Sort of an Array</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>You are given an integer array&nbsp;<code>nums</code>, and you can perform the following operation&nbsp;<strong>any</strong>&nbsp;number of times on&nbsp;<code>nums</code>:</p>



<ul><li>Swap the positions of two elements&nbsp;<code>nums[i]</code>&nbsp;and&nbsp;<code>nums[j]</code>&nbsp;if&nbsp;<code>gcd(nums[i], nums[j]) &gt; 1</code>&nbsp;where&nbsp;<code>gcd(nums[i], nums[j])</code>&nbsp;is the&nbsp;<strong>greatest common divisor</strong>&nbsp;of&nbsp;<code>nums[i]</code>&nbsp;and&nbsp;<code>nums[j]</code>.</li></ul>



<p>Return&nbsp;<code>true</code>&nbsp;<em>if it is possible to sort&nbsp;</em><code>nums</code><em>&nbsp;in&nbsp;<strong>non-decreasing</strong>&nbsp;order using the above swap method, or&nbsp;</em><code>false</code><em>&nbsp;otherwise.</em></p>



<p><strong>Example 1:</strong></p>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> nums = [7,21,3]
<strong>Output:</strong> true
<strong>Explanation:</strong> We can sort [7,21,3] by performing the following operations:
- Swap 7 and 21 because gcd(7,21) = 7. nums = [<strong>21</strong>,<strong>7</strong>,3]
- Swap 21 and 3 because gcd(21,3) = 3. nums = [<strong>3</strong>,7,<strong>21</strong>]
</pre>



<p><strong>Example 2:</strong></p>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> nums = [5,2,6,2]
<strong>Output:</strong> false
<strong>Explanation:</strong> It is impossible to sort the array because 5 cannot be swapped with any other element.
</pre>



<p><strong>Example 3:</strong></p>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> nums = [10,5,9,3,15]
<strong>Output:</strong> true
We can sort [10,5,9,3,15] by performing the following operations:
- Swap 10 and 15 because gcd(10,15) = 5. nums = [<strong>15</strong>,5,9,3,<strong>10</strong>]
- Swap 15 and 3 because gcd(15,3) = 3. nums = [<strong>3</strong>,5,9,<strong>15</strong>,10]
- Swap 10 and 15 because gcd(10,15) = 5. nums = [3,5,9,<strong>10</strong>,<strong>15</strong>]
</pre>



<p><strong>Constraints:</strong></p>



<ul><li><code>1 &lt;= nums.length &lt;= 3 * 10<sup>4</sup></code></li><li><code>2 &lt;= nums[i] &lt;= 10<sup>5</sup></code></li></ul>



<h2><strong>Solution: Union-Find</strong></h2>



<p>Let nums[j]&#8217;s target position be i. In order to put nums[j] to pos i by swapping. nums[i] and nums[j] must be in the same connected component. There is an edge between two numbers if they have gcd > 1.</p>



<p>We union two numbers if their have gcd > 1. However, it will be TLE if we do all pairs . Thus, for each number, we union it with its divisors instead.</p>



<p>Time complexity: O(n<sup>2</sup>) TLE -> O(sum(sqrt(nums[i]))) &lt;= O(n*sqrt(m))<br>Space complexity: O(n)</p>



<div class="responsive-tabs">
<h2 class="tabtitle">C++</h2>
<div class="tabcontent">

<pre class="crayon-plain-tag">// Author: Huahua
class Solution {
public:
  bool gcdSort(vector&lt;int&gt;&amp; nums) {
    const int m = *max_element(begin(nums), end(nums));
    const int n = nums.size();
    
    vector&lt;int&gt; p(m + 1);
    iota(begin(p), end(p), 0);
  
    function&lt;int(int)&gt; find = [&amp;](int x) {
      return p[x] == x ? x : (p[x] = find(p[x]));
    };
  
    for (int x : nums)
      for (int d = 2; d &lt;= sqrt(x); ++d)
        if (x % d == 0)
          p[find(x)] = p[find(x / d)] = find(d);

    vector&lt;int&gt; sorted(nums);
    sort(begin(sorted), end(sorted));
    
    for (int i = 0; i &lt; n; ++i)
      if (find(sorted[i]) != find(nums[i])) 
        return false;

    return true;
  }
};</pre>
</div></div>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/graph/leetcode-1998-gcd-sort-of-an-array/">花花酱 LeetCode 1998. GCD Sort of an Array</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/graph/leetcode-1998-gcd-sort-of-an-array/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 2115. Find All Possible Recipes from Given Supplies</title>
		<link>https://zxi.mytechroad.com/blog/hashtable/leetcode-2115-find-all-possible-recipes-from-given-supplies/</link>
					<comments>https://zxi.mytechroad.com/blog/hashtable/leetcode-2115-find-all-possible-recipes-from-given-supplies/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sun, 26 Dec 2021 15:47:05 +0000</pubDate>
				<category><![CDATA[Hashtable]]></category>
		<category><![CDATA[graph]]></category>
		<category><![CDATA[hashtable]]></category>
		<category><![CDATA[medium]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=9264</guid>

					<description><![CDATA[<p>You have information about&#160;n&#160;different recipes. You are given a string array&#160;recipes&#160;and a 2D string array&#160;ingredients. The&#160;ith&#160;recipe has the name&#160;recipes[i], and you can&#160;create&#160;it if you have&#160;all&#160;the&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/hashtable/leetcode-2115-find-all-possible-recipes-from-given-supplies/">花花酱 LeetCode 2115. Find All Possible Recipes from Given Supplies</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>You have information about&nbsp;<code>n</code>&nbsp;different recipes. You are given a string array&nbsp;<code>recipes</code>&nbsp;and a 2D string array&nbsp;<code>ingredients</code>. The&nbsp;<code>i<sup>th</sup></code>&nbsp;recipe has the name&nbsp;<code>recipes[i]</code>, and you can&nbsp;<strong>create</strong>&nbsp;it if you have&nbsp;<strong>all</strong>&nbsp;the needed ingredients from&nbsp;<code>ingredients[i]</code>. Ingredients to a recipe may need to be created from&nbsp;<strong>other&nbsp;</strong>recipes, i.e.,&nbsp;<code>ingredients[i]</code>&nbsp;may contain a string that is in&nbsp;<code>recipes</code>.</p>



<p>You are also given a string array&nbsp;<code>supplies</code>&nbsp;containing all the ingredients that you initially have, and you have an infinite supply of all of them.</p>



<p>Return&nbsp;<em>a list of all the recipes that you can create.&nbsp;</em>You may return the answer in&nbsp;<strong>any order</strong>.</p>



<p>Note that two recipes may contain each other in their ingredients.</p>



<p><strong>Example 1:</strong></p>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> recipes = ["bread"], ingredients = [["yeast","flour"]], supplies = ["yeast","flour","corn"]
<strong>Output:</strong> ["bread"]
<strong>Explanation:</strong>
We can create "bread" since we have the ingredients "yeast" and "flour".
</pre>



<p><strong>Example 2:</strong></p>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> recipes = ["bread","sandwich"], ingredients = [["yeast","flour"],["bread","meat"]], supplies = ["yeast","flour","meat"]
<strong>Output:</strong> ["bread","sandwich"]
<strong>Explanation:</strong>
We can create "bread" since we have the ingredients "yeast" and "flour".
We can create "sandwich" since we have the ingredient "meat" and can create the ingredient "bread".
</pre>



<p><strong>Example 3:</strong></p>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> recipes = ["bread","sandwich","burger"], ingredients = [["yeast","flour"],["bread","meat"],["sandwich","meat","bread"]], supplies = ["yeast","flour","meat"]
<strong>Output:</strong> ["bread","sandwich","burger"]
<strong>Explanation:</strong>
We can create "bread" since we have the ingredients "yeast" and "flour".
We can create "sandwich" since we have the ingredient "meat" and can create the ingredient "bread".
We can create "burger" since we have the ingredient "meat" and can create the ingredients "bread" and "sandwich".
</pre>



<p><strong>Constraints:</strong></p>



<ul><li><code>n == recipes.length == ingredients.length</code></li><li><code>1 &lt;= n &lt;= 100</code></li><li><code>1 &lt;= ingredients[i].length, supplies.length &lt;= 100</code></li><li><code>1 &lt;= recipes[i].length, ingredients[i][j].length, supplies[k].length &lt;= 10</code></li><li><code>recipes[i], ingredients[i][j]</code>, and&nbsp;<code>supplies[k]</code>&nbsp;consist only of lowercase English letters.</li><li>All the values of&nbsp;<code>recipes</code>&nbsp;and&nbsp;<code>supplies</code>&nbsp;combined are unique.</li><li>Each&nbsp;<code>ingredients[i]</code>&nbsp;does not contain any duplicate values.</li></ul>



<h2><strong>Solution: Brute Force</strong></h2>



<div class="responsive-tabs">
<h2 class="tabtitle">C++</h2>
<div class="tabcontent">

<pre class="crayon-plain-tag">// Author: Huahua
class Solution {
public:
  vector&lt;string&gt; findAllRecipes(vector&lt;string&gt;&amp; recipes, vector&lt;vector&lt;string&gt;&gt;&amp; ingredients, vector&lt;string&gt;&amp; supplies) {
    const int n = recipes.size();
    unordered_set&lt;string&gt; s(begin(supplies), end(supplies));
    vector&lt;string&gt; ans;
    vector&lt;int&gt; seen(n);
    while (true) {      
      bool newSupply = false;  
      for (int i = 0; i &lt; n; ++i) {
        if (seen[i]) continue;
        bool hasAll = true;
        for (const string&amp; ingredient : ingredients[i])
          if (!s.count(ingredient)) {
            hasAll = false; 
            break;
          }
        if (!hasAll) continue;
        ans.push_back(recipes[i]);
        seen[i] = 1;
        s.insert(recipes[i]);
        newSupply = true;              
      }
      if (!newSupply) break;
    }
    return ans;
  }
};</pre>
</div></div>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/hashtable/leetcode-2115-find-all-possible-recipes-from-given-supplies/">花花酱 LeetCode 2115. Find All Possible Recipes from Given Supplies</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-2115-find-all-possible-recipes-from-given-supplies/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 2097. Valid Arrangement of Pairs</title>
		<link>https://zxi.mytechroad.com/blog/graph/leetcode-2097-valid-arrangement-of-pairs/</link>
					<comments>https://zxi.mytechroad.com/blog/graph/leetcode-2097-valid-arrangement-of-pairs/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sun, 05 Dec 2021 17:36:35 +0000</pubDate>
				<category><![CDATA[Graph]]></category>
		<category><![CDATA[eulerian]]></category>
		<category><![CDATA[graph]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=9032</guid>

					<description><![CDATA[<p>You are given a&#160;0-indexed&#160;2D integer array&#160;pairs&#160;where&#160;pairs[i] = [starti, endi]. An arrangement of&#160;pairs&#160;is&#160;valid&#160;if for every index&#160;i&#160;where&#160;1 &#60;= i &#60; pairs.length, we have&#160;endi-1&#160;== starti. Return&#160;any&#160;valid arrangement of&#160;pairs.&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/graph/leetcode-2097-valid-arrangement-of-pairs/">花花酱 LeetCode 2097. Valid Arrangement of Pairs</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>You are given a&nbsp;<strong>0-indexed</strong>&nbsp;2D integer array&nbsp;<code>pairs</code>&nbsp;where&nbsp;<code>pairs[i] = [start<sub>i</sub>, end<sub>i</sub>]</code>. An arrangement of&nbsp;<code>pairs</code>&nbsp;is&nbsp;<strong>valid</strong>&nbsp;if for every index&nbsp;<code>i</code>&nbsp;where&nbsp;<code>1 &lt;= i &lt; pairs.length</code>, we have&nbsp;<code>end<sub>i-1</sub>&nbsp;== start<sub>i</sub></code>.</p>



<p>Return&nbsp;<em><strong>any</strong>&nbsp;valid arrangement of&nbsp;</em><code>pairs</code>.</p>



<p><strong>Note:</strong>&nbsp;The inputs will be generated such that there exists a valid arrangement of&nbsp;<code>pairs</code>.</p>



<p><strong>Example 1:</strong></p>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> pairs = [[5,1],[4,5],[11,9],[9,4]]
<strong>Output:</strong> [[11,9],[9,4],[4,5],[5,1]]
<strong>Explanation:
</strong>This is a valid arrangement since end<sub>i-1</sub> always equals start<sub>i</sub>.
end<sub>0</sub> = 9 == 9 = start<sub>1</sub> 
end<sub>1</sub> = 4 == 4 = start<sub>2</sub>
end<sub>2</sub> = 5 == 5 = start<sub>3</sub>
</pre>



<p><strong>Example 2:</strong></p>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> pairs = [[1,3],[3,2],[2,1]]
<strong>Output:</strong> [[1,3],[3,2],[2,1]]
<strong>Explanation:</strong>
This is a valid arrangement since end<sub>i-1</sub> always equals start<sub>i</sub>.
end<sub>0</sub> = 3 == 3 = start<sub>1</sub>
end<sub>1</sub> = 2 == 2 = start<sub>2</sub>
The arrangements [[2,1],[1,3],[3,2]] and [[3,2],[2,1],[1,3]] are also valid.
</pre>



<p><strong>Example 3:</strong></p>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> pairs = [[1,2],[1,3],[2,1]]
<strong>Output:</strong> [[1,2],[2,1],[1,3]]
<strong>Explanation:</strong>
This is a valid arrangement since end<sub>i-1</sub> always equals start<sub>i</sub>.
end<sub>0</sub> = 2 == 2 = start<sub>1</sub>
end<sub>1</sub> = 1 == 1 = start<sub>2</sub>
</pre>



<p><strong>Constraints:</strong></p>



<ul><li><code>1 &lt;= pairs.length &lt;= 10<sup>5</sup></code></li><li><code>pairs[i].length == 2</code></li><li><code>0 &lt;= start<sub>i</sub>, end<sub>i</sub>&nbsp;&lt;= 10<sup>9</sup></code></li><li><code>start<sub>i</sub>&nbsp;!= end<sub>i</sub></code></li><li>No two pairs are exactly the same.</li><li>There&nbsp;<strong>exists</strong>&nbsp;a valid arrangement of&nbsp;<code>pairs</code>.</li></ul>



<h2><strong>Solution: Eulerian trail</strong></h2>



<p>The goal of the problem is to find a Eulerian trail in the graph.</p>



<p>If there is a vertex whose out degree &#8211; in degree == 1 which means it&#8217;s the starting vertex. Otherwise wise, the graph must have a Eulerian circuit thus we can start from any vertex.</p>



<p>We can use Hierholzer&#8217;s algorithm to find it.</p>



<p>Time complexity: O(|V| + |E|)<br>Space complexity: O(|V| + |E|)</p>



<div class="responsive-tabs">
<h2 class="tabtitle">C++</h2>
<div class="tabcontent">

<pre class="crayon-plain-tag">// Author: Huahua
class Solution {
public:
  vector&lt;vector&lt;int&gt;&gt; validArrangement(vector&lt;vector&lt;int&gt;&gt;&amp; pairs) {    
    unordered_map&lt;int, queue&lt;int&gt;&gt; g;
    unordered_map&lt;int, int&gt; degree; // out - in  
    for (const auto&amp; p : pairs) {
      g[p[0]].push(p[1]);
      ++degree[p[0]];
      --degree[p[1]];
    }
    
    int s = pairs[0][0];
    for (const auto&amp; [u, d] : degree)
      if (d == 1) s = u;
    
    vector&lt;vector&lt;int&gt;&gt; ans;
    function&lt;void(int)&gt; dfs = [&amp;](int u) {
      while (!g[u].empty()) {
        int v = g[u].front(); g[u].pop();
        dfs(v);
        ans.push_back({u, v});
      }
    };
    dfs(s);
    return {rbegin(ans), rend(ans)};
  }
};</pre>

</div><h2 class="tabtitle">Python3</h2>
<div class="tabcontent">

<pre class="crayon-plain-tag"># Author: Huahua
class Solution:
  def validArrangement(self, pairs: List[List[int]]) -&gt; List[List[int]]:
    g = defaultdict(list)
    d = defaultdict(int)
    for u, v in pairs:
      g[u].append(v)
      d[u] += 1
      d[v] -= 1
    
    s = pairs[0][0]
    for u in d:
      if d[u] == 1: s = u
    
    ans = []
    def dfs(u: int) -&gt; None:
      while g[u]:
        v = g[u].pop()
        dfs(v)
        ans.append([u, v])

    dfs(s)
    return ans[::-1]</pre>
</div></div>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/graph/leetcode-2097-valid-arrangement-of-pairs/">花花酱 LeetCode 2097. Valid Arrangement of Pairs</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/graph/leetcode-2097-valid-arrangement-of-pairs/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
