<?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>topological sort Archives - Huahua&#039;s Tech Road</title>
	<atom:link href="https://zxi.mytechroad.com/blog/tag/topological-sort/feed/" rel="self" type="application/rss+xml" />
	<link>https://zxi.mytechroad.com/blog/tag/topological-sort/</link>
	<description></description>
	<lastBuildDate>Fri, 19 Nov 2021 04:00:30 +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>topological sort Archives - Huahua&#039;s Tech Road</title>
	<link>https://zxi.mytechroad.com/blog/tag/topological-sort/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>花花酱 LeetCode 2050. Parallel Courses III</title>
		<link>https://zxi.mytechroad.com/blog/graph/leetcode-2050-parallel-courses-iii/</link>
					<comments>https://zxi.mytechroad.com/blog/graph/leetcode-2050-parallel-courses-iii/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Fri, 19 Nov 2021 03:31:15 +0000</pubDate>
				<category><![CDATA[Graph]]></category>
		<category><![CDATA[graph]]></category>
		<category><![CDATA[hard]]></category>
		<category><![CDATA[topological sort]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=8722</guid>

					<description><![CDATA[<p>You are given an integer&#160;n, which indicates that there are&#160;n&#160;courses labeled from&#160;1&#160;to&#160;n. You are also given a 2D integer array&#160;relations&#160;where&#160;relations[j] = [prevCoursej, nextCoursej]&#160;denotes that course&#160;prevCoursej&#160;has&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/graph/leetcode-2050-parallel-courses-iii/">花花酱 LeetCode 2050. Parallel Courses III</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&nbsp;<code>n</code>, which indicates that there are&nbsp;<code>n</code>&nbsp;courses labeled from&nbsp;<code>1</code>&nbsp;to&nbsp;<code>n</code>. You are also given a 2D integer array&nbsp;<code>relations</code>&nbsp;where&nbsp;<code>relations[j] = [prevCourse<sub>j</sub>, nextCourse<sub>j</sub>]</code>&nbsp;denotes that course&nbsp;<code>prevCourse<sub>j</sub></code>&nbsp;has to be completed&nbsp;<strong>before</strong>&nbsp;course&nbsp;<code>nextCourse<sub>j</sub></code>&nbsp;(prerequisite relationship). Furthermore, you are given a&nbsp;<strong>0-indexed</strong>&nbsp;integer array&nbsp;<code>time</code>&nbsp;where&nbsp;<code>time[i]</code>&nbsp;denotes how many&nbsp;<strong>months</strong>&nbsp;it takes to complete the&nbsp;<code>(i+1)<sup>th</sup></code>&nbsp;course.</p>



<p>You must find the&nbsp;<strong>minimum</strong>&nbsp;number of months needed to complete all the courses following these rules:</p>



<ul><li>You may start taking a course at&nbsp;<strong>any time</strong>&nbsp;if the prerequisites are met.</li><li><strong>Any number of courses</strong>&nbsp;can be taken at the&nbsp;<strong>same time</strong>.</li></ul>



<p>Return&nbsp;<em>the&nbsp;<strong>minimum</strong>&nbsp;number of months needed to complete all the courses</em>.</p>



<p><strong>Note:</strong>&nbsp;The test cases are generated such that it is possible to complete every course (i.e., the graph is a directed acyclic graph).</p>



<p><strong>Example 1:</strong><strong><img alt="" src="https://assets.leetcode.com/uploads/2021/10/07/ex1.png"></strong></p>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> n = 3, relations = [[1,3],[2,3]], time = [3,2,5]
<strong>Output:</strong> 8
<strong>Explanation:</strong> The figure above represents the given graph and the time required to complete each course. 
We start course 1 and course 2 simultaneously at month 0.
Course 1 takes 3 months and course 2 takes 2 months to complete respectively.
Thus, the earliest time we can start course 3 is at month 3, and the total time required is 3 + 5 = 8 months.
</pre>



<p><strong>Example 2:</strong><strong><img alt="" src="https://assets.leetcode.com/uploads/2021/10/07/ex2.png"></strong></p>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> n = 5, relations = [[1,5],[2,5],[3,5],[3,4],[4,5]], time = [1,2,3,4,5]
<strong>Output:</strong> 12
<strong>Explanation:</strong> The figure above represents the given graph and the time required to complete each course.
You can start courses 1, 2, and 3 at month 0.
You can complete them after 1, 2, and 3 months respectively.
Course 4 can be taken only after course 3 is completed, i.e., after 3 months. It is completed after 3 + 4 = 7 months.
Course 5 can be taken only after courses 1, 2, 3, and 4 have been completed, i.e., after max(1,2,3,7) = 7 months.
Thus, the minimum time needed to complete all the courses is 7 + 5 = 12 months.
</pre>



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



<ul><li><code>1 &lt;= n &lt;= 5 * 10<sup>4</sup></code></li><li><code>0 &lt;= relations.length &lt;= min(n * (n - 1) / 2, 5 * 10<sup>4</sup>)</code></li><li><code>relations[j].length == 2</code></li><li><code>1 &lt;= prevCourse<sub>j</sub>, nextCourse<sub>j</sub>&nbsp;&lt;= n</code></li><li><code>prevCourse<sub>j</sub>&nbsp;!= nextCourse<sub>j</sub></code></li><li>All the pairs&nbsp;<code>[prevCourse<sub>j</sub>, nextCourse<sub>j</sub>]</code>&nbsp;are&nbsp;<strong>unique</strong>.</li><li><code>time.length == n</code></li><li><code>1 &lt;= time[i] &lt;= 10<sup>4</sup></code></li><li>The given graph is a directed acyclic graph.</li></ul>



<h2><strong>Solution: Topological Sorting</strong></h2>



<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:
  int minimumTime(int n, vector&lt;vector&lt;int&gt;&gt;&amp; relations, vector&lt;int&gt;&amp; time) {
    vector&lt;vector&lt;int&gt;&gt; g(n);  
    for (const auto&amp; r: relations)
      g[r[0] - 1].push_back(r[1] - 1);    
    vector&lt;int&gt; t(n, -1);
    function&lt;int(int)&gt; dfs = [&amp;](int u) {
      if (t[u] != -1) return t[u];
      t[u] = 0;
      for (int v : g[u])
        t[u] = max(t[u], dfs(v));
      return t[u] += time[u];
    };
    int ans = 0;
    for (int i = 0; i &lt; n; ++i)
      ans = max(ans, dfs(i));
    return ans;
  }
};</pre>

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

<pre class="crayon-plain-tag">class Solution:
  def minimumTime(self, n: int, relations: List[List[int]], time: List[int]) -&gt; int:
    g = [[] for _ in range(n)]
    for u, v in relations: g[u - 1].append(v - 1)
    @cache
    def dfs(u: int) -&gt; int:      
      return max([dfs(v) for v in g[u]] + [0]) + time[u]
    return max(dfs(u) for u in range(n))</pre>
</div></div>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/graph/leetcode-2050-parallel-courses-iii/">花花酱 LeetCode 2050. Parallel Courses III</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-2050-parallel-courses-iii/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 1857. Largest Color Value in a Directed Graph</title>
		<link>https://zxi.mytechroad.com/blog/graph/leetcode-1857-largest-color-value-in-a-directed-graph/</link>
					<comments>https://zxi.mytechroad.com/blog/graph/leetcode-1857-largest-color-value-in-a-directed-graph/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sat, 29 May 2021 22:33:31 +0000</pubDate>
				<category><![CDATA[Graph]]></category>
		<category><![CDATA[graph]]></category>
		<category><![CDATA[hard]]></category>
		<category><![CDATA[topological sort]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=8451</guid>

					<description><![CDATA[<p>There is a&#160;directed graph&#160;of&#160;n&#160;colored nodes and&#160;m&#160;edges. The nodes are numbered from&#160;0&#160;to&#160;n - 1. You are given a string&#160;colors&#160;where&#160;colors[i]&#160;is a lowercase English letter representing the&#160;color&#160;of the&#160;ith&#160;node&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/graph/leetcode-1857-largest-color-value-in-a-directed-graph/">花花酱 LeetCode 1857. Largest Color Value in a Directed 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>There is a&nbsp;<strong>directed graph</strong>&nbsp;of&nbsp;<code>n</code>&nbsp;colored nodes and&nbsp;<code>m</code>&nbsp;edges. The nodes are numbered from&nbsp;<code>0</code>&nbsp;to&nbsp;<code>n - 1</code>.</p>



<p>You are given a string&nbsp;<code>colors</code>&nbsp;where&nbsp;<code>colors[i]</code>&nbsp;is a lowercase English letter representing the&nbsp;<strong>color</strong>&nbsp;of the&nbsp;<code>i<sup>th</sup></code>&nbsp;node in this graph (<strong>0-indexed</strong>). You are also given a 2D array&nbsp;<code>edges</code>&nbsp;where&nbsp;<code>edges[j] = [a<sub>j</sub>, b<sub>j</sub>]</code>&nbsp;indicates that there is a&nbsp;<strong>directed edge</strong>&nbsp;from node&nbsp;<code>a<sub>j</sub></code>&nbsp;to node&nbsp;<code>b<sub>j</sub></code>.</p>



<p>A valid&nbsp;<strong>path</strong>&nbsp;in the graph is a sequence of nodes&nbsp;<code>x<sub>1</sub>&nbsp;-&gt; x<sub>2</sub>&nbsp;-&gt; x<sub>3</sub>&nbsp;-&gt; ... -&gt; x<sub>k</sub></code>&nbsp;such that there is a directed edge from&nbsp;<code>x<sub>i</sub></code>&nbsp;to&nbsp;<code>x<sub>i+1</sub></code>&nbsp;for every&nbsp;<code>1 &lt;= i &lt; k</code>. The&nbsp;<strong>color value</strong>&nbsp;of the path is the number of nodes that are colored the&nbsp;<strong>most frequently</strong>&nbsp;occurring color along that path.</p>



<p>Return&nbsp;<em>the&nbsp;<strong>largest color value</strong>&nbsp;of any valid path in the given graph, or&nbsp;</em><code>-1</code><em>&nbsp;if the graph contains a cycle</em>.</p>



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



<figure class="wp-block-image"><img src="https://assets.leetcode.com/uploads/2021/04/21/leet1.png" alt=""/></figure>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> colors = "abaca", edges = [[0,1],[0,2],[2,3],[3,4]]
<strong>Output:</strong> 3
<strong>Explanation:</strong> The path 0 -&gt; 2 -&gt; 3 -&gt; 4 contains 3 nodes that are colored <code>"a" (red in the above image)</code>.
</pre>



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



<figure class="wp-block-image"><img src="https://assets.leetcode.com/uploads/2021/04/21/leet2.png" alt=""/></figure>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> colors = "a", edges = [[0,0]]
<strong>Output:</strong> -1
<strong>Explanation:</strong> There is a cycle from 0 to 0.
</pre>



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



<ul><li><code>n == colors.length</code></li><li><code>m == edges.length</code></li><li><code>1 &lt;= n &lt;= 10<sup>5</sup></code></li><li><code>0 &lt;= m &lt;= 10<sup>5</sup></code></li><li><code>colors</code>&nbsp;consists of lowercase English letters.</li><li><code>0 &lt;= a<sub>j</sub>, b<sub>j</sub>&nbsp;&lt; n</code></li></ul>



<h2><strong>Solution: Topological Sorting</strong></h2>



<p>freq[n][c] := max freq of color <code>c</code> after visiting node <code>n</code>.</p>



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



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

<pre class="crayon-plain-tag">class Solution:
  def largestPathValue(self, colors: str, edges: List[List[int]]) -&gt; int:
    INF = 1e9
    n = len(colors)
    g = [[] for _ in range(n)]
    for u, v in edges:
      g[u].append(v)    
    visited = [0] * n
    freq = [[0] * 26 for _ in range(n)]
    def dfs(u: int) -&gt; int:
      idx = ord(colors[u]) - ord('a')
      if not visited[u]:
        visited[u] = 1 # visiting
        for v in g[u]:
          if (dfs(v) == INF):
            return INF
          for c in range(26):
            freq[u][c] = max(freq[u][c], freq[v][c])
        freq[u][idx] += 1
        visited[u] = 2 # done
      return freq[u][idx] if visited[u] == 2 else INF
    ans = 0
    for u in range(n):
      ans = max(ans, dfs(u))
      if ans == INF: break
    return -1 if ans == INF else ans</pre>
</div></div>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/graph/leetcode-1857-largest-color-value-in-a-directed-graph/">花花酱 LeetCode 1857. Largest Color Value in a Directed 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-1857-largest-color-value-in-a-directed-graph/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 1591. Strange Printer II</title>
		<link>https://zxi.mytechroad.com/blog/graph/leetcode-1591-strange-printer-ii/</link>
					<comments>https://zxi.mytechroad.com/blog/graph/leetcode-1591-strange-printer-ii/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Mon, 21 Sep 2020 06:12:17 +0000</pubDate>
				<category><![CDATA[Graph]]></category>
		<category><![CDATA[DFS]]></category>
		<category><![CDATA[graph]]></category>
		<category><![CDATA[hard]]></category>
		<category><![CDATA[topological sort]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=7396</guid>

					<description><![CDATA[<p>There is a strange printer with the following two special requirements: On each turn, the printer will print a solid rectangular pattern of a single&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/graph/leetcode-1591-strange-printer-ii/">花花酱 LeetCode 1591. Strange Printer II</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>There is a strange printer with the following two special requirements:</p>



<ul><li>On each turn, the printer will print a solid rectangular pattern of a single color on the grid. This will cover up the existing colors in the rectangle.</li><li>Once the printer has used a color for the above operation,&nbsp;<strong>the same color cannot be used again</strong>.</li></ul>



<p>You are given a&nbsp;<code>m x n</code>&nbsp;matrix&nbsp;<code>targetGrid</code>, where&nbsp;<code>targetGrid[row][col]</code>&nbsp;is the color in the position&nbsp;<code>(row, col)</code>&nbsp;of the grid.</p>



<p>Return&nbsp;<code>true</code><em>&nbsp;if it is possible to print the matrix&nbsp;</em><code>targetGrid</code><em>,</em><em>&nbsp;otherwise, return&nbsp;</em><code>false</code>.</p>



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



<figure class="wp-block-image"><img src="https://assets.leetcode.com/uploads/2020/08/15/sample_1_1929.png" alt=""/></figure>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> targetGrid = [[1,1,1,1],[1,2,2,1],[1,2,2,1],[1,1,1,1]]
<strong>Output:</strong> true
</pre>



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



<figure class="wp-block-image"><img src="https://assets.leetcode.com/uploads/2020/08/15/sample_2_1929.png" alt=""/></figure>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> targetGrid = [[1,1,1,1],[1,1,3,3],[1,1,3,4],[5,5,1,4]]
<strong>Output:</strong> true
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> targetGrid = [[1,2,1],[2,1,2],[1,2,1]]
<strong>Output:</strong> false
<strong>Explanation:</strong> It is impossible to form targetGrid because it is not allowed to print the same color in different turns.</pre>



<p><strong>Example 4:</strong></p>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> targetGrid = [[1,1,1],[3,1,3]]
<strong>Output:</strong> false
</pre>



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



<ul><li><code>m == targetGrid.length</code></li><li><code>n == targetGrid[i].length</code></li><li><code>1 &lt;= m, n &lt;= 60</code></li><li><code>1 &lt;= targetGrid[row][col] &lt;= 60</code></li></ul>



<h2><strong>Solution: Dependency graph</strong></h2>



<p>For each color C find the maximum rectangle to cover it. Any other color C&#8217; in this rectangle is a dependency of C, e.g. C&#8217; must be print first in order to print C.</p>



<p>Then this problem reduced to check if there is any cycle in the dependency graph.</p>



<p>e.g. <br>1 2 1<br>2 1 2<br>1 2 1<br>The maximum rectangle for 1 and 2 are both [0, 0] ~ [2, 2]. 1 depends on 2, and 2 depends on 1. This is a circular reference and no way to print.</p>



<p>Time complexity: O(C*M*N)<br>Space complexity: O(C*C)</p>



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

<pre class="crayon-plain-tag">class Solution {
public:
  bool isPrintable(vector&lt;vector&lt;int&gt;&gt;&amp; targetGrid) {
    constexpr int kMaxC = 60;
    const int m = targetGrid.size();
    const int n = targetGrid[0].size();
    vector&lt;unordered_set&lt;int&gt;&gt; deps(kMaxC + 1);
    for (int c = 1; c &lt;= kMaxC; ++c) {
      int l = n, r = -1, t = m, b = -1;      
      for (int i = 0; i &lt; m; ++i)
        for (int j = 0; j &lt; n; ++j)
          if (targetGrid[i][j] == c)
            l = min(l, j), r = max(r, j), t = min(t, i), b = max(b, i);
      if (l == -1) continue;
      for (int i = t; i &lt;= b; ++i)
        for (int j = l; j &lt;= r; ++j)
          if (targetGrid[i][j] != c) 
            deps[c].insert(targetGrid[i][j]);
    }
    vector&lt;int&gt; seen(kMaxC + 1);
    function&lt;bool(int)&gt; hasCycle = [&amp;](int c) {
      if (seen[c] == 1) return true;
      if (seen[c] == 2) return false;
      seen[c] = 1;
      for (int t : deps[c])
        if (hasCycle(t)) return true;
      seen[c] = 2;
      return false;
    };
    for (int c = 1; c &lt;= kMaxC; ++c)
      if (hasCycle(c)) return false;
    return true;
  }
};</pre>
</div></div>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/graph/leetcode-1591-strange-printer-ii/">花花酱 LeetCode 1591. Strange Printer II</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/graph/leetcode-1591-strange-printer-ii/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 802. Find Eventual Safe States</title>
		<link>https://zxi.mytechroad.com/blog/graph/leetcode-802-find-eventual-safe-states/</link>
					<comments>https://zxi.mytechroad.com/blog/graph/leetcode-802-find-eventual-safe-states/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sun, 18 Mar 2018 06:37:10 +0000</pubDate>
				<category><![CDATA[Graph]]></category>
		<category><![CDATA[cycle]]></category>
		<category><![CDATA[DFS]]></category>
		<category><![CDATA[directed graph]]></category>
		<category><![CDATA[graph]]></category>
		<category><![CDATA[medium]]></category>
		<category><![CDATA[topological sort]]></category>
		<guid isPermaLink="false">http://zxi.mytechroad.com/blog/?p=2196</guid>

					<description><![CDATA[<p>Problem https://leetcode.com/problems/find-eventual-safe-states/description/ 题目大意：给一个有向图，找出所有不可能进入环的节点。 In a directed graph, we start at some node and every turn, walk along a directed edge of the graph.  If we&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/graph/leetcode-802-find-eventual-safe-states/">花花酱 LeetCode 802. Find Eventual Safe States</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p><iframe width="500" height="375" src="https://www.youtube.com/embed/v5Ni_3bHjzk?feature=oembed" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe></p>
<h1>Problem</h1>
<p><a href="https://leetcode.com/problems/find-eventual-safe-states/description/">https://leetcode.com/problems/find-eventual-safe-states/description/</a></p>
<p>题目大意：给一个有向图，找出所有不可能进入环的节点。</p>
<p>In a directed graph, we start at some node and every turn, walk along a directed edge of the graph.  If we reach a node that is terminal (that is, it has no outgoing directed edges), we stop.</p>
<p>Now, say our starting node is <em>eventually safe </em>if and only if we must eventually walk to a terminal node.  More specifically, there exists a natural number <code>K</code> so that for any choice of where to walk, we must have stopped at a terminal node in less than <code>K</code> steps.</p>
<p>Which nodes are eventually safe?  Return them as an array in sorted order.</p>
<p>The directed graph has <code>N</code> nodes with labels <code>0, 1, ..., N-1</code>, where <code>N</code> is the length of <code>graph</code>.  The graph is given in the following form: <code>graph[i]</code> is a list of labels <code>j</code> such that <code>(i, j)</code> is a directed edge of the graph.</p>
<pre class="crayon:false "><strong>Example:</strong>
<strong>Input:</strong> graph = [[1,2],[2,3],[5],[0],[5],[],[]]
<strong>Output:</strong> [2,4,5,6]
Here is a diagram of the above graph.

</pre>
<p><img src="https://s3-lc-upload.s3.amazonaws.com/uploads/2018/03/17/picture1.png" alt="Illustration of graph" /></p>
<p><strong>Note:</strong></p>
<ul>
<li><code>graph</code> will have length at most <code>10000</code>.</li>
<li>The number of edges in the graph will not exceed <code>32000</code>.</li>
<li>Each <code>graph[i]</code> will be a sorted list of different integers, chosen within the range <code>[0, graph.length - 1]</code>.</li>
</ul>
<h1><strong>Idea: Finding Cycles</strong></h1>
<p><img class="alignnone size-full wp-image-2214" src="http://zxi.mytechroad.com/blog/wp-content/uploads/2018/03/802-ep174.png" alt="" width="960" height="540" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2018/03/802-ep174.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2018/03/802-ep174-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2018/03/802-ep174-768x432.png 768w" sizes="(max-width: 960px) 100vw, 960px" /></p>
<h1><strong>Solution 1: DFS</strong></h1>
<p><strong> </strong>A node is safe if and only if: itself and all of its neighbors do not have any cycles.</p>
<p>Time complexity: O(V + E)</p>
<p>Space complexity: O(V + E)</p><pre class="crayon-plain-tag">// Author: Huahua
// Running time: 155 ms
class Solution {
public:
  vector&lt;int&gt; eventualSafeNodes(vector&lt;vector&lt;int&gt;&gt;&amp; graph) {    
    vector&lt;State&gt; states(graph.size(), UNKNOWN);
    vector&lt;int&gt; ans;
    for (int i = 0; i &lt; graph.size(); ++i)      
      if (dfs(graph, i, states) == SAFE)
        ans.push_back(i);
    return ans;
  }
private:
  enum State {UNKNOWN, VISITING, SAFE, UNSAFE};
  State dfs(const vector&lt;vector&lt;int&gt;&gt;&amp; g, int cur, vector&lt;State&gt;&amp; states) {
    if (states[cur] == VISITING)
      return states[cur] = UNSAFE;
    if (states[cur] != UNKNOWN)
      return states[cur];
    states[cur] = VISITING;
    for (int next : g[cur])
      if (dfs(g, next, states) == UNSAFE) 
        return states[cur] = UNSAFE;
    return states[cur] = SAFE;
  }
};</pre><p></p>
<h1><strong>Related Problems</strong></h1>
<ul>
<li><a href="http://zxi.mytechroad.com/blog/graph/leetcode-207-course-schedule/">[解题报告] LeetCode 207. Course Schedule</a></li>
<li><a href="http://zxi.mytechroad.com/blog/graph/leetcode-210-course-schedule-ii/">花花酱 LeetCode 210. Course Schedule II</a></li>
<li><a href="http://zxi.mytechroad.com/blog/tree/leetcode-684-redundant-connection/">[解题报告] LeetCode 684. Redundant Connection 花花酱</a></li>
</ul>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/graph/leetcode-802-find-eventual-safe-states/">花花酱 LeetCode 802. Find Eventual Safe States</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-802-find-eventual-safe-states/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 210. Course Schedule II</title>
		<link>https://zxi.mytechroad.com/blog/graph/leetcode-210-course-schedule-ii/</link>
					<comments>https://zxi.mytechroad.com/blog/graph/leetcode-210-course-schedule-ii/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Thu, 14 Dec 2017 06:35:21 +0000</pubDate>
				<category><![CDATA[Graph]]></category>
		<category><![CDATA[Medium]]></category>
		<category><![CDATA[cycle]]></category>
		<category><![CDATA[directed graph]]></category>
		<category><![CDATA[graph]]></category>
		<category><![CDATA[topological sort]]></category>
		<guid isPermaLink="false">http://zxi.mytechroad.com/blog/?p=1228</guid>

					<description><![CDATA[<p>Problem There are a total of n courses you have to take, labeled from 0 to n - 1. Some courses may have prerequisites, for example to take course 0&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/graph/leetcode-210-course-schedule-ii/">花花酱 LeetCode 210. Course Schedule II</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p><iframe width="500" height="375" src="https://www.youtube.com/embed/Qqgck2ijUjU?feature=oembed" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe></p>
<h1><strong>Problem</strong></h1>
<p>There are a total of <i>n</i> courses you have to take, labeled from <code>0</code> to <code>n - 1</code>.</p>
<p>Some courses may have prerequisites, for example to take course 0 you have to first take course 1, which is expressed as a pair: <code>[0,1]</code></p>
<p>Given the total number of courses and a list of prerequisite <b>pairs</b>, return the ordering of courses you should take to finish all courses.</p>
<p>There may be multiple correct orders, you just need to return one of them. If it is impossible to finish all courses, return an empty array.</p>
<p>For example:</p><pre class="crayon-plain-tag">2, [[1,0]]</pre><p>There are a total of 2 courses to take. To take course 1 you should have finished course 0. So the correct course order is <code>[0,1]</code></p><pre class="crayon-plain-tag">4, [[1,0],[2,0],[3,1],[3,2]]</pre><p>There are a total of 4 courses to take. To take course 3 you should have finished both courses 1 and 2. Both courses 1 and 2 should be taken after you finished course 0. So one correct course order is <code>[0,1,2,3]</code>. Another correct ordering is<code>[0,2,1,3]</code>.</p>
<p><b>Note:</b></p>
<ol>
<li>The input prerequisites is a graph represented by <b>a list of edges</b>, not adjacency matrices. Read more about <a href="https://www.khanacademy.org/computing/computer-science/algorithms/graph-representation/a/representing-graphs" target="_blank" rel="noopener">how a graph is represented</a>.</li>
<li>You may assume that there are no duplicate edges in the input prerequisites.</li>
</ol>
<p><strong>题目大意：</strong></p>
<p>给你一些课程和它的先修课程，让你输出修课顺序。如果无法修完所有课程，返回空数组。</p>
<p><ins class="adsbygoogle" style="display: block; text-align: center;" data-ad-layout="in-article" data-ad-format="fluid" data-ad-client="ca-pub-2404451723245401" data-ad-slot="7983117522"></ins><br />
<script>
     (adsbygoogle = window.adsbygoogle || []).push({});
</script></p>
<p><img class="alignnone size-full wp-image-1252" src="http://zxi.mytechroad.com/blog/wp-content/uploads/2017/12/210-ep133.png" alt="" width="960" height="540" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2017/12/210-ep133.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/12/210-ep133-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/12/210-ep133-768x432.png 768w" sizes="(max-width: 960px) 100vw, 960px" /></p>
<h1><strong>Idea</strong></h1>
<p>Topological sorting</p>
<p>拓扑排序</p>
<h1><strong>Solution 1: Topological Sorting</strong></h1>
<p>Time complexity: O(V+E)</p>
<p>Space complexity: O(V+E)</p>
<p><div class="responsive-tabs">
<h2 class="tabtitle">C++</h2>
<div class="tabcontent">
</p><pre class="crayon-plain-tag">// Author: Huahua
// Runtime: 16 ms
class Solution {
public:
  vector&lt;int&gt; findOrder(int numCourses, vector&lt;pair&lt;int, int&gt;&gt;&amp; prerequisites) {
    vector&lt;vector&lt;int&gt;&gt; graph(numCourses);    
    for(const auto&amp; p : prerequisites)
      graph[p.second].push_back(p.first);

    // states: 0 = unkonwn, 1 == visiting, 2 = visited
    vector&lt;int&gt; v(numCourses, 0);
    vector&lt;int&gt; ans;
    
    for (int i = 0; i &lt; numCourses; ++i)
      if (dfs(i, graph, v, ans)) return {};

    std::reverse(ans.begin(), ans.end());
    return ans;
  }
private:
  bool dfs(int cur, vector&lt;vector&lt;int&gt;&gt;&amp; graph, vector&lt;int&gt;&amp; v, vector&lt;int&gt;&amp; ans) {
    if (v[cur] == 1) return true;
    if (v[cur] == 2) return false;

    v[cur] = 1;
    
    for (const int t : graph[cur])
      if (dfs(t, graph, v, ans)) return true;
    
    v[cur] = 2;
    ans.push_back(cur);

    return false;
  }
};</pre><p></div><h2 class="tabtitle">Java</h2>
<div class="tabcontent">
</p><pre class="crayon-plain-tag">// Author: Huahua
// Runtime: 83 ms
class Solution {
    public int[] findOrder(int numCourses, int[][] prerequisites) {
        ArrayList&lt;ArrayList&lt;Integer&gt;&gt; graph = new ArrayList&lt;&gt;();
        
        for (int i = 0; i &lt; numCourses; ++i)
            graph.add(new ArrayList&lt;Integer&gt;());
        
        for (int i = 0; i &lt; prerequisites.length; ++i) {
            int course = prerequisites[i][0];
            int prerequisite = prerequisites[i][1];            
            graph.get(course).add(prerequisite);
        }
        
        int[] visited = new int[numCourses];
        List&lt;Integer&gt; ans = new ArrayList&lt;Integer&gt;();
        Integer index = numCourses;
        for (int i = 0; i &lt; numCourses; ++i)
            if (dfs(i, graph, visited, ans)) return new int[0];        
        
        return ans.stream().mapToInt(i-&gt;i).toArray();
    }
    
    private boolean dfs(int curr, ArrayList&lt;ArrayList&lt;Integer&gt;&gt; graph, int[] visited, List&lt;Integer&gt; ans) {
        if (visited[curr] == 1) return true;
        if (visited[curr] == 2) return false;
        
        visited[curr] = 1;
        for (int next : graph.get(curr))
            if (dfs(next, graph, visited, ans)) return true;
        
        visited[curr] = 2;
        ans.add(curr);
        
        return false;
    }    
}</pre><p></div></div></p>
<h1><strong>Related Problems:</strong></h1>
<ul>
<li><a href="http://zxi.mytechroad.com/blog/graph/leetcode-207-course-schedule/">[解题报告] LeetCode 207. Course Schedule</a></li>
<li><a href="https://zxi.mytechroad.com/blog/graph/leetcode-802-find-eventual-safe-states/">花花酱 LeetCode 802. Find Eventual Safe States</a></li>
</ul>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/graph/leetcode-210-course-schedule-ii/">花花酱 LeetCode 210. Course Schedule II</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/graph/leetcode-210-course-schedule-ii/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 207. Course Schedule</title>
		<link>https://zxi.mytechroad.com/blog/graph/leetcode-207-course-schedule/</link>
					<comments>https://zxi.mytechroad.com/blog/graph/leetcode-207-course-schedule/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sat, 21 Oct 2017 06:26:36 +0000</pubDate>
				<category><![CDATA[Graph]]></category>
		<category><![CDATA[Medium]]></category>
		<category><![CDATA[cycle]]></category>
		<category><![CDATA[directed graph]]></category>
		<category><![CDATA[graph]]></category>
		<category><![CDATA[medium]]></category>
		<category><![CDATA[topological sort]]></category>
		<guid isPermaLink="false">http://zxi.mytechroad.com/blog/?p=654</guid>

					<description><![CDATA[<p>Problem: There are a total of&#160;n&#160;courses you have to take, labeled from&#160;0&#160;to&#160;n - 1. Some courses may have prerequisites, for example to take course 0&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/graph/leetcode-207-course-schedule/">花花酱 LeetCode 207. Course Schedule</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p><iframe width="500" height="375" src="https://www.youtube.com/embed/M6SBePBMznU?feature=oembed" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe></p>
<p><strong>Problem:</strong></p>
<p>There are a total of&nbsp;<i>n</i>&nbsp;courses you have to take, labeled from&nbsp;<code>0</code>&nbsp;to&nbsp;<code>n - 1</code>.</p>
<p>Some courses may have prerequisites, for example to take course 0 you have to first take course 1, which is expressed as a pair:&nbsp;<code>[0,1]</code></p>
<p>Given the total number of courses and a list of prerequisite&nbsp;<b>pairs</b>, is it possible for you to finish all courses?</p>
<p>For example:</p><pre class="crayon-plain-tag">2, [[1,0]]</pre><p>There are a total of 2 courses to take. To take course 1 you should have finished course 0. So it is possible.</p><pre class="crayon-plain-tag">2, [[1,0],[0,1]]</pre><p>There are a total of 2 courses to take. To take course 1 you should have finished course 0, and to take course 0 you should also have finished course 1. So it is impossible.</p>
<p><script async="" src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script><br />
<ins class="adsbygoogle" style="display: block; text-align: center;" data-ad-layout="in-article" data-ad-format="fluid" data-ad-client="ca-pub-2404451723245401" data-ad-slot="7983117522"></ins><br />
<script><br />
     (adsbygoogle = window.adsbygoogle || []).push({});<br />
</script></p>
<p><strong>Idea:</strong></p>
<p>Finding cycles O(n^2) -&gt; Topological sort O(n)</p>
<p><a href="http://zxi.mytechroad.com/blog/wp-content/uploads/2017/10/207-ep93.png"><img class="alignnone size-full wp-image-659" src="http://zxi.mytechroad.com/blog/wp-content/uploads/2017/10/207-ep93.png" alt="" width="960" height="540" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2017/10/207-ep93.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/10/207-ep93-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/10/207-ep93-768x432.png 768w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/10/207-ep93-624x351.png 624w" sizes="(max-width: 960px) 100vw, 960px" /></a></p>
<p><a href="http://zxi.mytechroad.com/blog/wp-content/uploads/2017/10/207-ep93-1.png"><img class="alignnone size-full wp-image-658" src="http://zxi.mytechroad.com/blog/wp-content/uploads/2017/10/207-ep93-1.png" alt="" width="960" height="540" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2017/10/207-ep93-1.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/10/207-ep93-1-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/10/207-ep93-1-768x432.png 768w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/10/207-ep93-1-624x351.png 624w" sizes="(max-width: 960px) 100vw, 960px" /></a></p>
<h1><strong>Solution 1: Topological Sort</strong></h1>
<p><div class="responsive-tabs">
<h2 class="tabtitle">C++</h2>
<div class="tabcontent">
</p><pre class="crayon-plain-tag">// Author: Huahua
// Time complexity: O(n)
// Runtime: 12 ms
class Solution {
public:
    bool canFinish(int numCourses, vector&lt;pair&lt;int, int&gt;&gt;&amp; prerequisites) {
        
        graph_ = vector&lt;vector&lt;int&gt;&gt;(numCourses);
        
        for(const auto&amp; p : prerequisites)
            graph_[p.first].push_back(p.second);
        
        // states: 0 = unkonwn, 1 == visiting, 2 = visited
        vector&lt;int&gt; v(numCourses, 0);
        
        for(int i = 0; i &lt; numCourses; ++i)
            if(dfs(i, v)) return false;
        
        return true;
    }
    
private:
    vector&lt;vector&lt;int&gt;&gt; graph_;
    bool dfs(int cur, vector&lt;int&gt;&amp; v) {
        if(v[cur] == 1) return true;
        if(v[cur] == 2) return false;
        
        v[cur] = 1;
        
        for(const int t : graph_[cur])
            if(dfs(t, v)) return true;
        
        v[cur] = 2;
        
        return false;
    }
};</pre><p></div><h2 class="tabtitle">Java</h2>
<div class="tabcontent">
</p><pre class="crayon-plain-tag">// Author: Huahua
// Runtime: 6 ms
// HashMap is slower than ArrayList in this problem.
class Solution {    
    public boolean canFinish(int numCourses, int[][] prerequisites) {        
        ArrayList&lt;ArrayList&lt;Integer&gt;&gt; graph = new ArrayList&lt;&gt;();
        
        for (int i = 0; i &lt; numCourses; ++i)
            graph.add(new ArrayList&lt;Integer&gt;());
        
        for (int i = 0; i &lt; prerequisites.length; ++i) {
            int course = prerequisites[i][0];
            int prerequisite = prerequisites[i][1];            
            graph.get(course).add(prerequisite);
        }
        
        int[] visited = new int[numCourses];
        for (int i = 0; i &lt; numCourses; ++i)
            if (dfs(i, graph, visited)) return false;
        
        return true;
    }
    
    private boolean dfs(int curr, ArrayList&lt;ArrayList&lt;Integer&gt;&gt; graph, int[] visited) {
        if (visited[curr] == 1) return true;
        if (visited[curr] == 2) return false;
        
        visited[curr] = 1;
                
        for (int next : graph.get(curr))
            if (dfs(next, graph, visited)) return true;
        
        visited[curr] = 2;
        return false;
    }

}</pre><p></div></div></p>
<p><script async="" src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script><br />
<ins class="adsbygoogle" style="display:block" data-ad-format="fluid" data-ad-layout-key="-fb+5w+4e-db+86" data-ad-client="ca-pub-2404451723245401" data-ad-slot="2162692788"></ins><br />
<script><br />
     (adsbygoogle = window.adsbygoogle || []).push({});<br />
</script></p>
<h1><strong>Solution 2: DFS&nbsp;Finding cycles</strong></h1>
<p>Time complexity: O(n^2)</p>
<p>Space complexity: O(n)</p>
<p><div class="responsive-tabs">
<h2 class="tabtitle">C++</h2>
<div class="tabcontent">
</p><pre class="crayon-plain-tag">// Author: Huahua
// Time complexity: O(n^2)
// Runtime: 179 ms
class Solution {
public:
    bool canFinish(int numCourses, vector&lt;pair&lt;int, int&gt;&gt;&amp; prerequisites) {
        
        graph_.clear();
        
        for(const auto&amp; p : prerequisites)
            graph_[p.first].insert(p.second);
        
        for (int i = 0; i &lt; numCourses; ++i) {
            vector&lt;int&gt; visited(numCourses, 0);
            if (cycle(i, i, visited)) return false;
        }
        
        return true;
    }
    
private:
    unordered_map&lt;int, unordered_set&lt;int&gt;&gt; graph_;
    
    bool cycle(int start, int curr, vector&lt;int&gt;&amp; visited) {        
        if (curr == start &amp;&amp; visited[start]) return true;
        if (!graph_.count(curr)) return false;
        
        for (const int next : graph_.at(curr)) {
            if (visited[next]) continue;
            visited[next] = true;
            if (cycle(start, next, visited)) return true;
        }
        return false;
    }
};</pre><p></div></div></p>
<h1><strong>Related Pr0blems:</strong></h1>
<ul>
<li><a href="http://zxi.mytechroad.com/blog/graph/leetcode-210-course-schedule-ii/">花花酱 LeetCode 210. Course Schedule II</a></li>
<li><a href="https://zxi.mytechroad.com/blog/graph/leetcode-802-find-eventual-safe-states/">花花酱 LeetCode 802. Find Eventual Safe States</a></li>
</ul>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/graph/leetcode-207-course-schedule/">花花酱 LeetCode 207. Course Schedule</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-207-course-schedule/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
