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

[Swift]LeetCode399. 除法求值 | Evaluate Division

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

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

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

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

Equations are given in the format A / B = k, where A and B are variables represented as strings, and k is a real number (floating point number). Given some queries, return the answers. If the answer does not exist, return -1.0.

Example:
Given a / b = 2.0, b / c = 3.0. 
queries are: a / c = ?, b / a = ?, a / e = ?, a / a = ?, x / x = ? . 
return [6.0, 0.5, -1.0, 1.0, -1.0 ].

The input is: vector<pair<string, string>> equations, vector<double>& values, vector<pair<string, string>> queries , where equations.size() == values.size(), and the values are positive. This represents the equations. Return vector<double>.

According to the example above:

equations = [ ["a", "b"], ["b", "c"] ],
values = [2.0, 3.0],
queries = [ ["a", "c"], ["b", "a"], ["a", "e"], ["a", "a"], ["x", "x"] ].  

The input is always valid. You may assume that evaluating the queries will result in no division by zero and there is no contradiction.


给出方程式 A / B = k, 其中 A 和 B 均为代表字符串的变量, k 是一个浮点型数字。根据已知方程式求解问题,并返回计算结果。如果结果不存在,则返回 -1.0

示例 :
给定 a / b = 2.0, b / c = 3.0
问题: a / c = ?, b / a = ?, a / e = ?, a / a = ?, x / x = ? 
返回 [6.0, 0.5, -1.0, 1.0, -1.0 ]

输入为: vector<pair<string, string>> equations, vector<double>& values, vector<pair<string, string>> queries(方程式,方程式结果,问题方程式), 其中 equations.size() == values.size(),即方程式的长度与方程式结果长度相等(程式与结果一一对应),并且结果值均为正数。以上为方程式的描述。 返回vector<double>类型。

基于上述例子,输入如下:

equations(方程式) = [ ["a", "b"], ["b", "c"] ],
values(方程式结果) = [2.0, 3.0],
queries(问题方程式) = [ ["a", "c"], ["b", "a"], ["a", "e"], ["a", "a"], ["x", "x"] ]. 

输入总是有效的。你可以假设除法运算中不会出现除数为0的情况,且不存在任何矛盾的结果。


8ms

 1 class Solution {
 2     func calcEquation(_ equations: [[String]], _ values: [Double], _ queries: [[String]]) -> [Double] {
 3         var graph: [String : [(String, Double)]] = [:]
 4         
 5         for i in 0..<equations.count {
 6             let firstVar = equations[i][0]
 7             let secondVar = equations[i][1]
 8             
 9             if graph[firstVar] == nil {
10                 graph[firstVar] = []
11             }
12             
13             if graph[secondVar] == nil {
14                 graph[secondVar] = []
15             }
16             
17             graph[firstVar]!.append((secondVar, values[i]))
18             graph[secondVar]!.append((firstVar, 1 / values[i]))
19         }
20           
21         var result: [Double] = []
22 
23         for querie in queries {
24             result.append(search(graph, querie[0], querie[1], [:], 1))
25         }
26         
27         return result
28     }
29         
30     func search(_ graph: [String : [(String, Double)]], _ currentElement: String, _ element: String, _ searched: [String:Bool], _ sum: Double) -> Double {
31         if currentElement == element, graph[currentElement] != nil {
32             return sum
33         }
34         
35         var updatedSearched = searched
36         updatedSearched[currentElement] = true
37         guard let children = graph[currentElement] else {
38             return -1
39         }
40         
41         for child in children {
42             if updatedSearched[child.0] == nil {
43                 let result = search(graph, child.0, element, updatedSearched, sum * child.1)
44                 
45                 if result != -1 {
46                     return result
47                 } 
48             }
49         }
50         
51         return -1
52     }
53 }

12ms

 1 class Solution {
 2     var m:[String:[String:Double]] = [String:[String:Double]]()
 3     func calcEquation(_ equations: [[String]], _ values: [Double], _ queries: [[String]]) -> [Double] {
 4         var res:[Double] = [Double]()        
 5         for i in 0..<equations.count
 6         { 
 7             if m[equations[i][0]] == nil
 8             {
 9                 var item1:[String:Double] = [equations[i][1] : values[i]]
10                 m[equations[i][0]] = item1
11             }
12             else
13             {
14                 m[equations[i][0]]![equations[i][1]] = values[i]
15             }
16             
17             if m[equations[i][1]] == nil
18             {
19                 var item2:[String:Double] = [equations[i][0] : 1.0 / values[i]]
20                 m[equations[i][1]] = item2
21             }
22             else
23             {
24                 m[equations[i][1]]![equations[i][0]] = 1.0 / values[i]
25             }
26             
27         }
28         for query in queries
29         {
30             var visited:Set<String> = Set<String>()
31             var t:Double = helper(query[0], query[1], &visited)
32             if t > 0.0
33             {
34                 res.append(t)
35             }
36             else
37             {
38                 res.append(-1.0)
39             }
40         }
41         return res
42     }
43     
44     func helper(_ up:String,_ down:String,_ visited:inout Set<String>) -> Double
45     {
46         if m[up] == nil
47         {
48             return -1.0
49         }
50         if m[up]![down] != nil
51         {
52             return m[up]![down]!
53         }
54 
55         var dic = m[up]!
56         var arrG = [String](dic.keys)
57         for a in arrG
58         {
59             if visited.contains(a)
60             {
61                 continue
62             }
63             visited.insert(a)
64             var t:Double = helper(a, down, &visited)
65             if t > 0.0
66             {
67                 return t * dic[a]!
68             }
69         }
70         return -1.0
71     }
72 }

12ms

 1 class Solution {
 2     func calcEquation(_ equations: [[String]], _ values: [Double], _ queries: [[String]]) -> [Double] {
 3         
 4         var argumentsSet: Set<String> = Set<String>()
 5         for pair in equations {
 6             for argument in pair {
 7                 argumentsSet.insert(argument)
 8             }
 9         }
10         let argumentsArray = Array(argumentsSet)
11         let amountOfElements = argumentsArray.count
12         var matrix: [[Double?]] = []
13         for i in 0..<amountOfElements {
14             var line: [Double?] = []
15             for j in 0..<amountOfElements {
16                 if let index = equations.firstIndex(of: [argumentsArray[i], argumentsArray[j]]) {
17                     line.append(values[index])
18                 } else if let index = equations.firstIndex(of: [argumentsArray[j], argumentsArray[i]]) {
19                     line.append(1.0/values[index])
20                 } else {
21                     line.append(nil)
22                 }
23             }
24             matrix.append(line)
25         }
26         for i in 0..<amountOfElements {
27             matrix = algorithmFloyd(matrix:matrix)
28         }
29     var resultArray: [Double] = []
30         for pair in queries {
31             guard let index1 = argumentsArray.firstIndex(of:pair[0]),
32             let index2 = argumentsArray.firstIndex(of:pair[1]) else {
33                 resultArray.append(-1)
34                 continue}
35             let element = matrix[index1][index2] ?? -1.0
36             resultArray.append(element)
37         } 
38     return resultArray
39     }
40     
41     func algorithmFloyd(matrix: [[Double?]]) -> [[Double?]] {
42         var resultMatrix:[[Double?]] = []
43         for i in 0..<matrix.count {
44             var line: [Double?] = []
45             for j in 0..<matrix.count {
46                 if let element = matrix[i][j] {
47                     line.append(element)
48                 } else {
49                     var resultElement: Double? = nil
50                     for k in 0..<matrix.count {
51                         if let firstElement = matrix[i][k],
52                         let secondElement = matrix[k][j] {
53                             resultElement = firstElement*secondElement
54                             break;
55                         }
56                     }
57                     line.append(resultElement)
58                 }
59             }
60             resultMatrix.append(line)
61         }
62         return resultMatrix
63     }
64 }

16ms

 1 class Solution {
 2     func calcEquation(_ equations: [[String]], _ values: [Double], _ queries: [[String]]) -> [Double] {
 3         var graph: [String: [(String, Double)]] = [:] // stores key/val
 4         var res: [Double] = []
 5         
 6         for i in 0..<equations.count {
 7             let e = equations[i]
 8             let n1 = e[0], n2 = e[1]
 9             let v = values[i]
10             
11             var l1 = graph[n1] ?? []
12             l1.append((n2, v))
13             graph[n1] = l1
14             var l2 = graph[n2] ?? []
15             l2.append((n1, 1/v))
16             graph[n2] = l2
17         }
18         
19         for q in queries {
20             var visited: Set<String> = Set<String>()
21             // dfs
22             let start = q[0]
23             let end = q[1]
24             let r = self.dfs(start, end, graph, &visited)
25             res.append(r)
26         }
27         return res
28     }
29     
30     private func dfs(_ start: String, _ end: String, _ graph: [String: [(String, Double)]], _ visited: inout Set<String>) -> Double {
31         defer {
32             visited.remove(start)
33         }
34         
35         visited.insert(start)
36         if let l1 = graph[start] {
37             if start == end { return 1 }
38             for e in l1 {
39                 if visited.contains(e.0) { continue }
40                 let val = self.dfs(e.0, end, graph, &visited)
41                 if val != -1 {
42                     return val * e.1
43                 }
44             }
45         }
46         return -1
47     }
48 }

20ms

  1 class Edge {
  2     var source: Node
  3     var destination: Node
  4     var weight: Double
  5     
  6     init(source: Node, destination: Node, weight: Double) {
  7         self.source = source
  8         self.destination = destination
  9         self.weight = weight
 10     }
 11 }
 12 
 13 class Node {
 14     var value: String
 15     var edges: [Edge]
 16     var visited: Bool
 17     var currentWeight: Double
 18     var currentParent: Node?
 19     
 20     init(value: String) {
 21         self.value = value
 22         self.edges = [Edge]()
 23         self.currentWeight = 0.0
 24         self.visited = false
 25     }
 26 }
 27 
 28 class Solution {
 29     func calcEquation(_ equations: [[String]], _ values: [Double], _ queries: [[String]]) -> [Double] {
 30         //TODO: input validation
 31         
 32         var result = [Double]()
 33         var nodeDict = [String: Node]()
 34         var nodes = [Node]()
 35         
 36         for (index,equation) in equations.enumerated() {
 37             let first = equation[0]
 38             let second = equation[1]
 39             let value = values[index]
 40             
 41             var firstNode = nodeDict[first]
 42             if firstNode == nil {
 43                 firstNode = Node.init(value: first)
 44                 nodeDict[first] = firstNode
 45                 nodes.append(firstNode!)
 46             }
 47             var secondNode = nodeDict[second]
 48             if secondNode == nil {
 49                 secondNode = Node.init(value: second)
 50                 nodeDict[second] = secondNode
 51                 nodes.append(secondNode!)
 52             }
 53             
 54             let firstEdge = Edge.init(source: firstNode!, destination: secondNode!, weight:value)
 55             let secondEdge = Edge.init(source: secondNode!, destination: firstNode!, weight:1.0 / value)
 56             firstNode!.edges.append(firstEdge)
 57             secondNode!.edges.append(secondEdge)
 58         }
 59         
 60         for query in queries {
 61             for node in nodes {
 62                 node.currentParent = nil
 63                 node.currentWeight = 0.0
 64                 node.visited = false
 65             }
 66             let first = query[0]
 67             let second = query[1]
 68             
 69             let firstNode = nodeDict[first]
 70             if firstNode == nil {
 71                 result.append(-1.0)
 72                 continue
 73             }
 74             let secondNode = nodeDict[second]
 75             if secondNode == nil {
 76                 result.append(-1.0)
 77                 continue
 78             }
 79             
 80             if firstNode?.value == secondNode?.value {
 81                 result.append(1.0)
 82                 continue
 83             }
 84             var queue = [Edge]()
 85             for edge in firstNode!.edges {
 86                 edge.destination.currentParent = firstNode!
 87                 edge.destination.currentWeight = edge.weight
 88                 edge.source.visited = true
 89                 queue.append(edge)
 90             }
 91             var found = false
 92             while queue.count > 0 {
 93                 let edge = queue[0]
 94                 queue.remove(at: 0)
 95                 var currentNode = edge.destination
 96                 currentNode.visited = true
 97                 if currentNode.value == secondNode!.value {
 98                     var eq = 1.0
 99                     while currentNode.currentParent != nil {
100                         eq = eq * currentNode.currentWeight
101                         currentNode = currentNode.currentParent!
102                     }
103                     result.append(eq)
104                     found = true
105                     break
106                 }
107                 for subedge in currentNode.edges {
108                     if !subedge.destination.visited {
109                         subedge.destination.currentParent = currentNode
110                         subedge.destination.currentWeight = subedge.weight
111                         queue.append(subedge)
112                     }
113                 }
114             }
115             if !found {
116                 result.append(-1.0)
117             }
118         }
119         
120         return result
121     }
122 }

 

posted @ 2019-01-23 15:03  为敢技术  阅读(481)  评论(0编辑  收藏  举报