zoukankan      html  css  js  c++  java
  • [Swift]LeetCode990. 等式方程的可满足性 | Satisfiability of Equality Equations

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

    Given an array equations of strings that represent relationships between variables, each string equations[i] has length 4and takes one of two different forms: "a==b" or "a!=b".  Here, a and b are lowercase letters (not necessarily different) that represent one-letter variable names.

    Return true if and only if it is possible to assign integers to variable names so as to satisfy all the given equations.

    Example 1:

    Input: ["a==b","b!=a"]
    Output: false
    Explanation: If we assign say, a = 1 and b = 1, then the first equation is satisfied, but not the second.  There is no way to assign the variables to satisfy both equations.
    

    Example 2:

    Input: ["b==a","a==b"]
    Output: true
    Explanation: We could assign a = 1 and b = 1 to satisfy both equations.
    

    Example 3:

    Input: ["a==b","b==c","a==c"]
    Output: true
    

    Example 4:

    Input: ["a==b","b!=c","c==a"]
    Output: false
    

    Example 5:

    Input: ["c==c","b==d","x!=z"]
    Output: true

    Note:

    1. 1 <= equations.length <= 500
    2. equations[i].length == 4
    3. equations[i][0] and equations[i][3] are lowercase letters
    4. equations[i][1] is either '=' or '!'
    5. equations[i][2] is '='

    给定一个由表示变量之间关系的字符串方程组成的数组,每个字符串方程 equations[i] 的长度为 4,并采用两种不同的形式之一:"a==b" 或 "a!=b"。在这里,a 和 b 是小写字母(不一定不同),表示单字母变量名。

    只有当可以将整数分配给变量名,以便满足所有给定的方程时才返回 true,否则返回 false。 

    示例 1:

    输入:["a==b","b!=a"]
    输出:false
    解释:如果我们指定,a = 1 且 b = 1,那么可以满足第一个方程,但无法满足第二个方程。没有办法分配变量同时满足这两个方程。
    

    示例 2:

    输出:["b==a","a==b"]
    输入:true
    解释:我们可以指定 a = 1 且 b = 1 以满足满足这两个方程。
    

    示例 3:

    输入:["a==b","b==c","a==c"]
    输出:true
    

    示例 4:

    输入:["a==b","b!=c","c==a"]
    输出:false
    

    示例 5:

    输入:["c==c","b==d","x!=z"]
    输出:true

    提示:

    1. 1 <= equations.length <= 500
    2. equations[i].length == 4
    3. equations[i][0] 和 equations[i][3] 是小写字母
    4. equations[i][1] 要么是 '=',要么是 '!'
    5. equations[i][2] 是 '='

    Runtime: 48 ms

    Memory Usage: 4 MB

      1 class Solution {
      2     func equationsPossible(_ equations: [String]) -> Bool {
      3         var ds:DJSet = DJSet(26)
      4         for e in equations
      5         {
      6             if e[1] == "="
      7             {
      8                 var l:Int = e[0].ascii - 97
      9                 var r:Int = e[3].ascii - 97
     10                 ds.union(l,r)
     11             }
     12         }
     13         for e in equations
     14         {
     15             if e[1] == "!"
     16             {
     17                 var l:Int = e[0].ascii - 97
     18                 var r:Int = e[3].ascii - 97
     19                 if ds.equiv(l,r)
     20                 {
     21                     return false
     22                 }
     23             } 
     24         }
     25         return true
     26     }
     27 }
     28 
     29 extension String {        
     30     //subscript函数可以检索数组中的值
     31     //直接按照索引方式截取指定索引的字符
     32     subscript (_ i: Int) -> Character {
     33         //读取字符
     34         get {return self[index(startIndex, offsetBy: i)]}
     35     }
     36 }
     37 
     38 extension Character  
     39 {  
     40   //属性:ASCII整数值(定义小写为整数值)
     41    var ascii: Int {
     42         get {
     43             let s = String(self).unicodeScalars
     44             return Int(s[s.startIndex].value)
     45         }
     46     }
     47 }
     48 
     49 public class DJSet
     50 {
     51     var upper:[Int]
     52     
     53     init(_ n:Int)
     54     {
     55         upper = [Int](repeating:-1,count:n)
     56     }
     57     
     58     func root(_ x:Int) -> Int
     59     {
     60         if(upper[x] < 0)
     61         {
     62             return x
     63         }
     64         else
     65         {
     66             upper[x] = root(upper[x])
     67             return upper[x]
     68         }
     69     }
     70     
     71     func equiv(_ x:Int,_ y:Int) -> Bool
     72     {
     73         return root(x) == root(y)
     74     }
     75     
     76     func union(_ x:Int,_ y:Int) -> Bool
     77     {
     78         var x:Int = root(x)
     79         var y:Int = root(y)
     80         if x != y
     81         {
     82             if upper[y] < upper[x]
     83             {
     84                 var d:Int = x
     85                 x = y
     86                 y = d
     87             }
     88             upper[x] += upper[y]
     89             upper[y] = x
     90         }
     91         return x == y
     92     }
     93     
     94     func count() -> Int
     95     {
     96         var ct:Int = 0
     97         for u in upper
     98         {
     99             if u < 0
    100             {
    101                 ct += 1
    102             }
    103         }
    104         return ct
    105     }
    106 }

    52ms
      1 class Solution {
      2     
      3     typealias Equation = (var1: Character, var2: Character, areEqual: Bool)
      4 
      5     func equationsPossible(_ equations: [String]) -> Bool {
      6         var equalHashMap = [Character: Character]()
      7 
      8         let equations = parseEquations(equations)
      9 
     10         // process equality conditions using union-finding algorithm
     11         // process inequality conditions
     12 
     13         let equalityEquations = equations.filter { $0.areEqual }
     14         let inEqualityEquations = equations.filter { !$0.areEqual }
     15 
     16         // similar union finding algorithm
     17         for equation in equalityEquations {
     18             let var1 = equation.var1
     19             let var2 = equation.var2
     20             if equalHashMap[var1] == nil && equalHashMap[var2] == nil {
     21                 equalHashMap[var1] = var1
     22                 equalHashMap[var2] = var1
     23             } else if equalHashMap[var1] == nil {
     24                 equalHashMap[var1] = findParent(var2, equalHashMap)
     25             } else { // equalHashMap[var2] == nil
     26                 equalHashMap[var2] = findParent(var1, equalHashMap)
     27             }
     28         }
     29 
     30         for equation in inEqualityEquations {
     31             let var1 = equation.var1
     32             let var2 = equation.var2
     33             let parentVar1 = equalHashMap[var1] ?? var1
     34             let parentVar2 = equalHashMap[var2] ?? var2
     35             if parentVar1 == parentVar2 {
     36                 return false
     37             }
     38         }
     39 
     40         return true
     41     }
     42 
     43     func findParent(_ ch: Character, _ hashMap: [Character: Character]) -> Character {
     44         var result = hashMap[ch] ?? ch
     45         while let parent = hashMap[result], parent != result {
     46             result = parent
     47         }
     48         return result
     49     }
     50 
     51     func parseEquations(_ equations: [String]) -> [Equation] {
     52         return equations.map { parseString($0) }
     53     }
     54 
     55     func parseString(_ string: String) -> Equation {
     56         guard string.count == 4 else {
     57             assertionFailure("input string: (string) not in correct format")
     58             return ("a", "a", false)
     59         }
     60 
     61         let var1 = string[0]
     62         let areEqual = string.subString(from: 1, to: 2) == "==" ? true : false
     63         let var2 = string[3]
     64         return (var1, var2, areEqual)
     65     }
     66     
     67 }
     68 
     69 extension String {
     70 
     71     subscript(i: Int) -> Character {
     72         get {
     73             return self[index(startIndex, offsetBy: i)]
     74         }
     75     }
     76     
     77     func subString(from: Int, to: Int) -> String {
     78         guard from <= to else {
     79             return ""
     80         }
     81         
     82         let startIndex = self.index(self.startIndex, offsetBy: from)
     83         let endIndex = self.index(self.startIndex, offsetBy: to)
     84         return String(self[startIndex...endIndex])
     85     }
     86     
     87     func subString(from: Int) -> String {
     88         let startIndex = self.index(self.startIndex, offsetBy: from)
     89         return String(self.suffix(from: startIndex))
     90     }
     91     
     92     func asciiValues() -> [Int] {
     93         return Array(self.utf16).map { Int($0) }
     94     }
     95     
     96     mutating func lTrim(_ regex: String = "^\s+") {
     97         if let trailingSpacesRange = self.range(of: regex, options: .regularExpression) {
     98             self.replaceSubrange(trailingSpacesRange, with: "")
     99         }
    100     }
    101     
    102     mutating func rTrim(_ regex: String = "\s+$") {
    103         if let trailingSpacesRange = self.range(of: regex, options: .regularExpression) {
    104             self.replaceSubrange(trailingSpacesRange, with: "")
    105         }
    106     }
    107 
    108     func stringByReplacingAt(_ index: Int, with ch: Character) -> String {
    109         var chars = Array(self)
    110         chars[index] = ch
    111         let modifiedString = String(chars)
    112         return modifiedString
    113     }
    114 }

    56ms

     1 class Solution {
     2     func equationsPossible(_ equations: [String]) -> Bool {
     3         let unionFind = UnionFind.init(26)
     4         let equalUnion = equations.filter { $0[1] == "=" }
     5         let notEqualUnion = equations.filter { $0[1] == "!" }
     6         let startingValue = Character("a").ascii!
     7         for item in equalUnion {
     8             let left = Int(item[0].ascii! - startingValue)
     9             let right = Int(item[3].ascii! - startingValue)
    10             unionFind.union(left, right)
    11         }
    12 
    13         for item in notEqualUnion {
    14             let left = Int(item[0].ascii! - startingValue)
    15             let right = Int(item[3].ascii! - startingValue)
    16             if unionFind.find(left) == unionFind.find(right) {
    17                 return false
    18             }
    19         }
    20         return true
    21     }
    22 }
    23 
    24 extension String {
    25     subscript (i: Int) -> Character {
    26         return self[index(startIndex, offsetBy: i)]
    27     }
    28 }
    29 
    30 extension Character {
    31     var isAscii: Bool {
    32         return unicodeScalars.first?.isASCII == true
    33     }
    34     var ascii: UInt32? {
    35         return isAscii ? unicodeScalars.first?.value : nil
    36     }
    37 }
    38 
    39 class UnionFind {
    40     var root = [Int]()
    41     var rank = [Int]()
    42     
    43     public init(_ n: Int) {
    44         // if root is not initialized, 'self' captured by a closure before all members were initialized
    45         (0...n-1).forEach { root.append($0) }
    46         rank = [Int](repeating: 1, count: n)
    47     }
    48     
    49     fileprivate func find(_ current: Int) -> Int {
    50         var path = [Int]()
    51         var current = current
    52         while root[current] != current {
    53             path.append(current)
    54             current = root[current]
    55         }
    56         
    57         for p in path {
    58             root[p] = current
    59         }
    60         return current
    61     }
    62     
    63     public func union(_ x: Int, _ y: Int) {
    64         let xRoot = find(x)
    65         let yRoot = find(y)
    66         
    67         if xRoot == yRoot {
    68             return
    69         }
    70         if rank[xRoot] > rank[yRoot] {
    71             root[yRoot] = xRoot
    72         } else if rank[xRoot] < rank[yRoot] {
    73             root[xRoot] = yRoot
    74         } else {
    75             rank[xRoot] = root[xRoot] + 1
    76             root[xRoot] = yRoot
    77         }
    78     }
    79 }

    64ms

     1 class Solution {
     2     func equationsPossible(_ equations: [String]) -> Bool {
     3         var dict: [Character: Set<Character>] = [:]
     4         var val = 0
     5         
     6         var res = true
     7         
     8         for equation in equations {
     9             var equation = equation
    10             
    11             let charA = equation.removeFirst()
    12             let sym = equation.removeFirst()
    13             if sym != "=" {continue}
    14             
    15             equation.removeFirst()
    16             let charB = equation.removeFirst()
    17             
    18             if dict[charA] == nil {
    19                 dict[charA] = [charA]
    20             }
    21             
    22             if dict[charB] == nil {
    23                 dict[charB] = [charB]
    24             }
    25             
    26             let unionSet = (dict[charA]!).union(dict[charB]!)
    27             
    28             for (char, _) in dict where unionSet.contains(char) {
    29                 dict[char] = unionSet
    30             }
    31         }
    32         
    33         for equation in equations {
    34             var equation = equation
    35             
    36             let charA = equation.removeFirst()
    37             let sym = equation.removeFirst()
    38             if sym != "!" {continue}
    39             
    40             equation.removeFirst()
    41             let charB = equation.removeFirst()
    42             
    43             if charA == charB || (dict[charA] != nil && dict[charB] != nil && dict[charA] == dict[charB] ) {
    44                 res = false
    45                 break
    46             }
    47         }
    48         
    49         return res
    50     }
    51 }

    76ms
     1 class Solution {
     2     func equationsPossible(_ equations: [String]) -> Bool {
     3         let unionFind = UnionFind.init(26)
     4         let startingValue = Character("a").ascii!
     5         for item in equations {
     6             if item[1] == "=" {
     7                 let left = Int(item.ascii[0] - startingValue)
     8                 let right = Int(item.ascii[3] - startingValue)
     9                 unionFind.union(left, right)
    10             }
    11         }
    12 
    13         for item in equations {
    14             if item[1] == "!" {
    15                 let left = Int(item.ascii[0] - startingValue)
    16                 let right = Int(item.ascii[3] - startingValue)
    17                 if unionFind.find(left) == unionFind.find(right) {
    18                     return false
    19                 }
    20             }
    21         }
    22         return true
    23     }
    24 }
    25 
    26 public extension String {
    27     subscript (i: Int) -> Character {
    28         return self[index(startIndex, offsetBy: i)]
    29     }
    30 }
    31 
    32 public extension StringProtocol {
    33     var ascii: [UInt32] {
    34         return compactMap { $0.ascii }
    35     }
    36 }
    37 
    38 extension Character {
    39     var isAscii: Bool {
    40         return unicodeScalars.first?.isASCII == true
    41     }
    42     var ascii: UInt32? {
    43         return isAscii ? unicodeScalars.first?.value : nil
    44     }
    45 }
    46 
    47 class UnionFind {
    48     var root = [Int]()
    49     var rank = [Int]()
    50     
    51     public init(_ n: Int) {
    52         // if root is not initialized, 'self' captured by a closure before all members were initialized
    53         (0...n-1).forEach { root.append($0) }
    54         rank = [Int](repeating: 1, count: n)
    55     }
    56     
    57     fileprivate func find(_ current: Int) -> Int {
    58         var path = [Int]()
    59         var current = current
    60         while root[current] != current {
    61             path.append(current)
    62             current = root[current]
    63         }
    64         
    65         for p in path {
    66             root[p] = current
    67         }
    68         return current
    69     }
    70     
    71     public func union(_ x: Int, _ y: Int) {
    72         let xRoot = find(x)
    73         let yRoot = find(y)
    74         
    75         if xRoot == yRoot {
    76             return
    77         }
    78         if rank[xRoot] > rank[yRoot] {
    79             root[yRoot] = xRoot
    80         } else if rank[xRoot] < rank[yRoot] {
    81             root[xRoot] = yRoot
    82         } else {
    83             rank[xRoot] = root[xRoot] + 1
    84             root[xRoot] = yRoot
    85         }
    86     }
    87 }
  • 相关阅读:
    ASP.NET Core 2.0 : 四. _Layout与_ViewStart
    [ASP.NET MVC 小牛之路]04
    [ASP.NET MVC 小牛之路]03
    [ASP.NET MVC 小牛之路]02
    [ASP.NET MVC 小牛之路]01
    Ext JS 4 的类系统
    生活沉思录 via 哲理小故事(一)
    ExtJS框架基础:事件模型及其常用功能
    ExtJS初探:了解 Ext Core
    ExtJS初探:在项目中使用ExtJS
  • 原文地址:https://www.cnblogs.com/strengthen/p/10361525.html
Copyright © 2011-2022 走看看