[Question]: Given two string check weather they anagram
Example: abc & cab are anagram
// TC: O(N)
// SC: O(N)
func isAnagram(_ s: String, _ t: String) -> Bool {
var arr = [Int](repeating: 0, count: 26)
for char in s {
arr[Int(char.asciiValue!) % 26] += 1// Modulo is used to use values from 0 to 25 which is array optimised size.
}
for char in t {
arr[Int(char.asciiValue!) % 26] -= 1
}
for v in arr where v != 0 {
return false// If some value are non zero means different objects
}
return true
// Or we can also use contains return !arr.contains(where: { $0 != 0 })
}
let ana1 = "abc"
let ana2 = "cab"
let isAna = isAnagram(ana1, ana2)
print("isAna--- ", isAna) // true
Approach #2 Using Hash map / Dictionary
// TC: O(N)
// SC: O(N)
func isAnagram2(_ s: String, _ t: String) -> Bool {
guard s.count == t.count else { return false }
var map = [Character: Int]()
for char in s {
map[char, default: 0] += 1// filling first String characters count into map
}
for char in t {
map[char, default: 0] -= 1// removing second String characters count from map. Means all values in map should zero
}
for v in map.values where v != 0 {
return false// If some value are non zero means different objects
}
return true
// return map.values.filter { $0 > 0 }.count == 0
}
Approach #3: Using reduce function.
// TC: O(N).. because by default swift reduce function uses O(N) based on input
func isAnagram3(_ s: String, _ t: String) -> Bool {
return getCharacterMap(s) == getCharacterMap(t)
}
func getCharacterMap(_ s: String) -> [Character: Int] {
return s.reduce(into: [:], { $0[$1, default: 0] += 1 })
}