func commonChars(_ inputs: [String]) -> [String] { guard let lastString = inputs.last else { return [] } var commonCountedChars = CountedSet() for char in lastString { commonCountedChars.add(String(char)) } var strings = inputs strings.removeLast() // removing last is more computationally efficient than removing first in Swift for string in strings { var stringCountedChars = CountedSet() for char in string { stringCountedChars.add(String(char)) } for (commonChar, commonCount) in commonCountedChars.asDictionary { if let stringCharCount = stringCountedChars.count(for: commonChar) { if stringCharCount < commonCount { commonCountedChars.remove(commonChar, count: commonCount - stringCharCount) } } else { commonCountedChars.removeAll(of: commonChar) } } } return commonCountedChars.asArray } struct CountedSet { private var dict = [Element: UInt]() var asArray: [Element] { var array = [Element]() for (element, count) in dict { array.append(contentsOf: [Element](repeating: element, count: Int(count))) } return array } var asDictionary: [Element: UInt] { dict } init() {} init(from array: [Element]) { for element in array { if self.dict.keys.contains(element) { self.dict[element]! += 1 } else { self.dict[element] = 1 } } } func count(for element: Element) -> UInt? { return (dict[element] != nil) ? dict[element]! : nil } mutating func add(_ element: Element) { dict[element] = (dict[element] == nil) ? 1 : dict[element]! + 1 } mutating func remove(_ element: Element, count removingCount: UInt = 1) { if let currentCount = dict[element] { dict[element] = (currentCount <= removingCount) ? nil : currentCount - removingCount } } mutating func removeAll(of element: Element) { dict[element] = nil } } print(commonChars(["bella","label","roller"])) print(commonChars(["cool","lock","cook"]))