为有牺牲多壮志,敢教日月换新天。

[Swift]LeetCode207. 课程表 | Course Schedule

★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
➤微信公众号:山青咏芝(shanqingyongzhi)
➤博客园地址:山青咏芝(https://www.cnblogs.com/strengthen/
➤GitHub地址:https://github.com/strengthen/LeetCode
➤原文地址:https://www.cnblogs.com/strengthen/p/10186643.html 
➤如果链接不是山青咏芝的博客园地址,则可能是爬取作者的文章。
➤原文已修改更新!强烈建议点击原文地址阅读!支持作者!支持原创!
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★

热烈欢迎,请直接点击!!!

进入博主App Store主页,下载使用各个作品!!!

注:博主将坚持每月上线一个新app!!!

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 you have to first take course 1, which is expressed as a pair: [0,1]

Given the total number of courses and a list of prerequisite pairs, is it possible for you to finish all courses?

Example 1:

Input: 2, [[1,0]] 
Output: true
Explanation: There are a total of 2 courses to take. 
             To take course 1 you should have finished course 0. So it is possible.

Example 2:

Input: 2, [[1,0],[0,1]]
Output: false
Explanation: 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.

Note:

  1. The input prerequisites is a graph represented by a list of edges, not adjacency matrices. Read more about how a graph is represented.
  2. You may assume that there are no duplicate edges in the input prerequisites.

现在你总共有 n 门课需要选,记为 0 到 n-1

在选修某些课程之前需要一些先修课程。 例如,想要学习课程 0 ,你需要先完成课程 1 ,我们用一个匹配来表示他们: [0,1]

给定课程总量以及它们的先决条件,判断是否可能完成所有课程的学习?

示例 1:

输入: 2, [[1,0]] 
输出: true
解释: 总共有 2 门课程。学习课程 1 之前,你需要完成课程 0。所以这是可能的。

示例 2:

输入: 2, [[1,0],[0,1]]
输出: false
解释: 总共有 2 门课程。学习课程 1 之前,你需要先完成​课程 0;并且学习课程 0 之前,你还应先完成课程 1。这是不可能的。

说明:

  1. 输入的先决条件是由边缘列表表示的图形,而不是邻接矩阵。详情请参见图的表示法
  2. 你可以假定输入的先决条件中没有重复的边。

提示:

  1. 这个问题相当于查找一个循环是否存在于有向图中。如果存在循环,则不存在拓扑排序,因此不可能选取所有课程进行学习。
  2. 通过 DFS 进行拓扑排序 - 一个关于Coursera的精彩视频教程(21分钟),介绍拓扑排序的基本概念。
  3. 拓扑排序也可以通过 BFS 完成。


104ms

 1 class Solution {
 2     func canFinish(_ numCourses: Int, _ prerequisites: [[Int]]) -> Bool {
 3 
 4         var graph = Array(repeating: Array(repeating: 0, count: 0), count: numCourses)
 5         var courses = Array(repeating: 0, count: numCourses)
 6         for a in prerequisites {
 7             graph[a[1]].append(a[0])
 8             courses[a[0]] += 1
 9         }
10         var q = [Int]()
11         for (i, num) in courses.enumerated() {
12             if num == 0 { q.append(i) } 
13         }
14         while !q.isEmpty {
15             var t = q.removeLast()
16             for a in graph[t]{
17                 courses[a] -= 1
18                 if courses[a] == 0 { q.append(a)}
19             }
20         }
21 
22         for a in courses {
23          //   if a != 0 { return false }
24         }
25         return courses.filter{ $0 != 0 }.count == 0
26     }
27 }

108ms

 1 class Solution {
 2     var visited = [Bool]()
 3     var onPath = [Bool]()
 4     var has = false
 5     
 6     func canFinish(_ numCourses: Int, _ prerequisites: [[Int]]) -> Bool {
 7         var g = [Node]()
 8         for i in stride(from: 0, to: numCourses, by: 1) {
 9             g.append(Node(label: i, adj: [Node]()))
10         }
11         
12         for pre in prerequisites {
13             let from = pre[0]
14             let to = pre[1]
15             
16             g[from].adj.append(g[to])
17         }
18         
19         visited = Array(repeating: false, count: g.count) 
20         onPath = Array(repeating: false, count: g.count) 
21         has = false
22         
23         return !hasCycles(g)
24     }
25     
26     
27     func hasCycles(_ g: [Node]) -> Bool {
28         if g.isEmpty {
29             return true
30         }
31         
32         for n in g {
33             if !visited[n.label] && !has {
34                 dfs(n)
35             }
36 
37         }
38         
39         return has
40     }
41     
42     func dfs(_ node: Node) {
43         if has {
44             return        
45         }
46         
47         visited[node.label] = true
48         onPath[node.label] = true
49         
50         for adj in node.adj {
51             if !visited[adj.label] {
52                 dfs(adj)
53             } else {
54                 if onPath[adj.label] {
55                     has = true
56                 }
57             }
58         }
59         
60         onPath[node.label] = false
61     }
62 
63     class Node {
64         let label: Int
65         var adj: [Node]
66     
67         init(label: Int, adj: [Node]) {
68             self.label = label
69             self.adj = adj
70         }
71     }
72 }

116ms

 1 class Solution {
 2     func canFinish(_ total: Int, _ nums: [[Int]]) -> Bool {
 3         var dict: [Int: [Int]] = [:]
 4         var prev: [Int] = Array(repeating: 0, count: total)
 5         for num in nums {
 6             prev[num[0]] += 1
 7             dict[num[1], default: []].append(num[0])
 8         }
 9         var count = 0
10         var queue: [Int] = []
11         for (index, num) in prev.enumerated() {
12             if num == 0 {
13                 queue.append(index)
14             }
15         }
16         while queue.isEmpty == false {
17             let num = queue.removeFirst()
18             count += 1
19             if let courses = dict[num] {
20                 for course in courses {
21                     prev[course] -= 1
22                     if prev[course] == 0 {
23                         queue.append(course)
24                     }
25                 }
26             }
27         }
28         return count == total
29     }
30 }

116ms

 1 class Solution {
 2     func canFinish(_ numCourses: Int, _ prerequisites: [[Int]]) -> Bool {
 3         var graph = [[Int]](repeating: [Int](), count: numCourses)
 4         var indegrees = [Int](repeating: 0, count: numCourses)
 5         for prerequisite in prerequisites {
 6             graph[prerequisite.last!].append(prerequisite.first!)
 7             indegrees[prerequisite.first!] += 1
 8         }
 9         var queue = [Int]()
10         for i in 0..<numCourses {
11             if indegrees[i] == 0 {
12                 queue.append(i)
13             }
14         }
15         var sortedNodes = [Int]()
16         while !queue.isEmpty {
17             let node = queue.removeFirst()
18             sortedNodes.append(node)
19             let followingNodes = graph[node]
20             for followingNode in followingNodes {
21                 indegrees[followingNode] -= 1
22                 if indegrees[followingNode] == 0 {
23                     queue.append(followingNode)
24                 }
25             }
26         }
27         return sortedNodes.count == numCourses
28     }
29 }

132ms

 1 class Solution {
 2     func canFinish(_ total: Int, _ nums: [[Int]]) -> Bool {
 3         var dict: [Int: [Int]] = [:]
 4         var prev: [Int] = Array(repeating: 0, count: total)
 5         for num in nums {
 6             prev[num[0]] += 1
 7             dict[num[1], default: []].append(num[0])
 8         }
 9         var count = 0
10         var queue: [Int] = []
11         for (index, num) in prev.enumerated() {
12             if num == 0 {
13                 queue.append(index)
14             }
15         }
16         while queue.isEmpty == false {
17             let num = queue.removeFirst()
18             count += 1
19             if let courses = dict[num] {
20                 for course in courses {
21                     prev[course] -= 1
22                     if prev[course] == 0 {
23                         queue.append(course)
24                     }
25                 }
26             }
27         }
28         return count == total
29     }
30 }

160ms

 1 class LinkedListNode<Element> {
 2     var val: Element
 3     var next: LinkedListNode?
 4     init(_ val: Element,_ next: LinkedListNode? = nil) {
 5         self.val = val
 6         self.next = next
 7     }
 8 }
 9 
10 public struct LinkedList<Element> {
11     private var head: LinkedListNode<Element>? = nil
12     private var tail: LinkedListNode<Element>? = nil
13     
14     public mutating func append(_ element: Element) {
15         guard head != nil else {
16             head = LinkedListNode(element)
17             tail = head
18             return
19         }
20         tail?.next = LinkedListNode(element)
21         tail = tail?.next
22     }
23     
24     public mutating func popFirst() -> Element? {
25         let popped = head
26         head = head?.next
27         if head == nil {
28             tail = nil
29         }
30         return popped?.val
31     }
32     
33     public var first: Element? {
34         return head?.val
35     }
36 }
37 
38 public struct Queue<Element> {
39     private var linkedList = LinkedList<Element>()
40     public mutating func enqueue(_ element: Element) {
41         linkedList.append(element)
42     }
43     
44     public mutating func dequeue() -> Element? {
45         return linkedList.popFirst()
46     }
47     
48     public var isEmpty: Bool {
49         return linkedList.first == nil
50     }
51 }
52 
53 
54 class Solution {
55     func canFinish(_ numCourses: Int, _ prerequisites: [[Int]]) -> Bool {
56         var iDependOn = Array(repeating: 0, count: numCourses)
57         var dependsOnMe = Array(repeating: [Int](), count: numCourses)
58         for courseDependency in prerequisites {
59             dependsOnMe[courseDependency[1]].append(courseDependency[0])
60             iDependOn[courseDependency[0]] += 1
61         }
62         var q = Queue<Int>()
63         for i in 0..<numCourses {
64             if iDependOn[i] == 0 {
65                 q.enqueue(i)
66             }
67         }
68         while !q.isEmpty {
69             let next = q.dequeue()!
70             for course in dependsOnMe[next] {
71                 if iDependOn[course] == 1 {
72                     q.enqueue(course)
73                 }
74                 iDependOn[course] -= 1
75             }
76         }
77         for i in 0..<numCourses {
78             if iDependOn[i] > 0 {
79                 return false
80             }
81         }
82         return true
83     }
84 }

168ms

 1 class Solution {
 2     func canFinish(_ numCourses: Int, _ prerequisites: [[Int]]) -> Bool {
 3         // number of dependencies the course has
 4         var dependencies: [Int] = [Int](repeating: 0, count: numCourses)
 5         // list of courses dependent on this course
 6         var dependents: [Int: [Int]] = [:]
 7         
 8         // create graph
 9         for prereq in prerequisites {
10             let dep = prereq[0]
11             let course = prereq[1]
12             dependencies[course] += 1
13             if dependents[dep] == nil {
14                 dependents[dep] = []
15             }
16             dependents[dep]!.append(course)
17         }
18         
19         var count = 0
20         var queue: [Int] = []
21         for i in 0..<numCourses {
22             if dependencies[i] == 0 {
23                 queue.append(i)
24             }
25         }
26         
27         while !queue.isEmpty {
28             let course = queue.removeFirst()
29             count += 1
30             if let dependents = dependents[course] {
31                 for dep in dependents {
32                     dependencies[dep] -= 1
33                     if dependencies[dep] == 0 {
34                         queue.append(dep)
35                     }
36                 }
37             }
38         }
39         
40         return count == numCourses
41     }
42 }

212ms

 1 class Solution {
 2     func canFinish(_ numCourses: Int, _ prerequisites: [[Int]]) -> Bool {
 3         guard numCourses > 0 else {
 4             return true
 5         }
 6         guard prerequisites.count > 0 else {
 7             return true
 8         }
 9         
10         var target = numCourses
11         var graph = [Int:[Int]]()
12         
13         for p in prerequisites {
14             graph[p[0]] = graph[p[0], default:[Int]()] + [p[1]]
15         }
16         
17         var visited = [Int: Bool]()
18         
19         func dfs(node: Int, curVisited:[Int: Bool]) -> Bool {
20             guard curVisited[node] == nil else {
21                 return false
22             }
23             guard visited[node] == nil else {
24                 return true
25             }
26             visited[node] = true
27             var curVisited = curVisited
28             curVisited[node] = true
29             guard let neighbors = graph[node] else  {
30                 return true
31             }
32             for n in neighbors {
33                 if dfs(node:n, curVisited:curVisited) == false {
34                     return false
35                 }
36             }
37             return true
38         }
39         for i in 0..<numCourses {
40             if !dfs(node: i, curVisited: [Int:Bool]()) {
41                 return false
42             }
43         }
44         return true
45     }
46 }

1104ms

 1 class Solution {
 2     func canFinish(_ numCourses: Int, _ prerequisites: [[Int]]) -> Bool {
 3         var nodes = prerequisites.reduce(into: [Int: Set<Int>]()) {
 4             $0[$1.first!, default: Set<Int>()].insert($1.last!)
 5             if $0[$1.last!] == nil {
 6                 $0[$1.last!] = Set<Int>()
 7             }
 8         }
 9         var sortedNodes = [Int](), noIncomingNodes = nodes.filter { $0.value.count == 0 }.map { $0.key }
10         while !noIncomingNodes.isEmpty {
11             let sortedNode = noIncomingNodes.removeFirst()
12             nodes.removeValue(forKey: sortedNode)
13             sortedNodes.append(sortedNode)
14             for node in nodes where node.value.contains(sortedNode) {
15                 var prerequisite = node.value
16                 prerequisite.remove(sortedNode)
17                 if prerequisite.isEmpty {
18                     noIncomingNodes.append(node.key)
19                 } else {
20                     nodes[node.key] = prerequisite
21                 }
22             }
23         }
24         return nodes.count == 0
25     }
26 }

 

posted @ 2018-12-27 18:41  为敢技术  阅读(561)  评论(0编辑  收藏  举报