Created
January 17, 2019 11:16
-
-
Save parrotbait/78bb0bd17eb86355132d85449605084b to your computer and use it in GitHub Desktop.
Algorithm to determine if a string has all unique characters. What if you cannot use any additional data structures?
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import UIKit | |
// This code is based on implementing the following: | |
// Implement an algorithm to determine if a string has all unique characters. What if you cannot use any additional data structures? | |
extension Character { | |
func toString() -> String { | |
return String(self) | |
} | |
} | |
// Runs at O(n) due to O(1) set lookup (and insertion) but still need to potentially iterate through all N elements. This cannot be avoided. | |
// Insertion and lookup of sets can degrade to O(n) if there are many hashing clashes and end up iterating through the 'buckets' but in this case there shouldn't be as it's individual characters | |
// This algorithm uses potentially N extra elements stored in the Set, if string has unique characters | |
func hasUniqueCharactersWithDataStructure(_ toCheck: String) -> Bool { | |
var existingChars = Set<String>() | |
for char in toCheck { | |
let charAsString = char.toString() | |
if existingChars.contains(charAsString) { | |
return false | |
} | |
existingChars.insert(charAsString) | |
} | |
return true | |
} | |
// Should operate at O(nlog(n) + n) which is O(nlog(n)) in the end | |
// In terms of size, it uses an extra string of size N which is sorted | |
func hasUniqueCharactersWithoutDataStructure(_ toCheck: String) -> Bool { | |
var sortedStr = toCheck.sorted() | |
var index = sortedStr.startIndex | |
for _ in 0..<sortedStr.count-1 { | |
let indexNext = sortedStr.index(index, offsetBy: 1) | |
if sortedStr[index] == sortedStr[indexNext] { | |
return false | |
} | |
index = indexNext | |
} | |
return true | |
} | |
// This is the worst algorithm, operating at O(nΒ²) | |
// It all happens in place so it the most efficient in terms of space | |
func hasUniqueCharactersInPlace(_ toCheck: String) -> Bool { | |
var index = toCheck.startIndex | |
for _ in 0..<toCheck.count-1 { | |
var indexNext = toCheck.index(index, offsetBy: 1) | |
while indexNext != toCheck.endIndex { | |
if toCheck[index] == toCheck[indexNext] { | |
return false | |
} | |
indexNext = toCheck.index(indexNext, offsetBy: 1) | |
} | |
index = toCheck.index(index, offsetBy: 1) | |
} | |
return true | |
} | |
func iterate(_ uniquefunc: (_: String)->Bool, _ toCheck: String) -> (Bool, Double) { | |
let t1 = CACurrentMediaTime() | |
let iterations = 1000 | |
var result = false | |
for i in 0..<iterations { | |
result = uniquefunc(toCheck) | |
} | |
return (result, CACurrentMediaTime() - t1) | |
} | |
func checkUniqueCharacters(_ toCheck: String) { | |
print ("Checking '\(toCheck)':") | |
if toCheck.isEmpty { | |
return | |
} | |
if toCheck.count == 1 { | |
return | |
} | |
var result = iterate(hasUniqueCharactersWithDataStructure, toCheck) | |
print ("Extra dataset (Set), result: \(result.0) - duration: \(result.1)s") | |
result = iterate(hasUniqueCharactersWithoutDataStructure, toCheck) | |
print ("Sorted, result: \(result.0) - duration: \(result.1)s") | |
result = iterate(hasUniqueCharactersInPlace, toCheck) | |
print ("In place, result: \(result.0) - duration: \(result.1)s") | |
} | |
var unique1 = "abcdefg" | |
checkUniqueCharacters(unique1) | |
var unique2 = "a 34vsdjy" | |
checkUniqueCharacters(unique2) | |
var unique3 = "a" | |
checkUniqueCharacters(unique3) | |
var notunique1 = "aa" | |
checkUniqueCharacters(notunique1) | |
var notunique2 = "" | |
checkUniqueCharacters(notunique2) | |
var notunique3 = "abcdefghijkal" | |
checkUniqueCharacters(notunique3) | |
var emojirepeat = "ππππππ" | |
checkUniqueCharacters(emojirepeat) | |
var emojinorepeat = "πππ" | |
checkUniqueCharacters(emojinorepeat) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment