|
| 1 | +class Solution { |
| 2 | + |
| 3 | + // Solution by Sergey Leschev |
| 4 | + // 2976. Minimum Cost to Convert String I |
| 5 | + // BFS/Djikstra |
| 6 | + |
| 7 | + func minimumCost( |
| 8 | + _ source: String, _ target: String, _ original: [Character], _ changed: [Character], |
| 9 | + _ cost: [Int] |
| 10 | + ) -> Int { |
| 11 | + var graph = [Character: [(Character, Int)]]() |
| 12 | + |
| 13 | + // Initializing the graph in the node schema: {parent, {(child, cost)}} |
| 14 | + for i in 0..<original.count { |
| 15 | + if graph[original[i]] == nil { |
| 16 | + graph[original[i]] = [(changed[i], cost[i])] |
| 17 | + } else { |
| 18 | + graph[original[i]]!.append((changed[i], cost[i])) |
| 19 | + } |
| 20 | + } |
| 21 | + |
| 22 | + // Distance array required will only need 26*26 space. |
| 23 | + var distances = Array(repeating: Array(repeating: Int.max, count: 26), count: 26) |
| 24 | + |
| 25 | + // Running BFS from every node of the original string. |
| 26 | + for char in original { |
| 27 | + bfs(graph, char, &distances) |
| 28 | + } |
| 29 | + |
| 30 | + var ans = 0 |
| 31 | + for i in source.indices { |
| 32 | + // No need to add anything to the answer if source and target are the same. |
| 33 | + if source[i] == target[i] { |
| 34 | + continue |
| 35 | + } |
| 36 | + |
| 37 | + // If the distance is infinite, the target is not achievable, and hence return -1. |
| 38 | + if distances[Int(source[i].asciiValue! - Character("a").asciiValue!)][ |
| 39 | + Int(target[i].asciiValue! - Character("a").asciiValue!)] == Int.max |
| 40 | + { |
| 41 | + return -1 |
| 42 | + } |
| 43 | + |
| 44 | + // Otherwise, add the corresponding value in the distances array. |
| 45 | + ans += |
| 46 | + distances[Int(source[i].asciiValue! - Character("a").asciiValue!)][ |
| 47 | + Int(target[i].asciiValue! - Character("a").asciiValue!)] |
| 48 | + } |
| 49 | + |
| 50 | + return ans |
| 51 | + } |
| 52 | + |
| 53 | + private func bfs( |
| 54 | + _ graph: [Character: [(Character, Int)]], _ source: Character, _ distances: inout [[Int]] |
| 55 | + ) { |
| 56 | + var queue = [(Character, Int)]() |
| 57 | + queue.append((source, 0)) |
| 58 | + |
| 59 | + while !queue.isEmpty { |
| 60 | + let (node, distance) = queue.removeFirst() |
| 61 | + |
| 62 | + for child in graph[node] ?? [] { |
| 63 | + if distances[Int(source.asciiValue! - Character("a").asciiValue!)][ |
| 64 | + Int(child.0.asciiValue! - Character("a").asciiValue!)] > distance + child.1 |
| 65 | + { |
| 66 | + distances[Int(source.asciiValue! - Character("a").asciiValue!)][ |
| 67 | + Int(child.0.asciiValue! - Character("a").asciiValue!)] = distance + child.1 |
| 68 | + queue.append((child.0, distance + child.1)) |
| 69 | + } |
| 70 | + } |
| 71 | + } |
| 72 | + } |
| 73 | +} |
0 commit comments