I came across a funny question, I am wondering whether we can solve it.
In time complexity O(n), can we find the letters occurring odd number of times, Output a list contain letters and keep the order of letters consistent with original string.
In case of multiple options to choose from, take the last occurence as the unpaired character.
Here is an example:
# note we should keep the order of letters
findodd('Hello World') == ["H", "e", " ", "W", "r", "l", "d"] # it is good
findodd('Hello World') == ["H", "l", " ", "W", "r", "e", "d"] # it is wrong
def findodd(s):
hash_map = {}
# This step is a bit strange. I will show an example:
# If I have a string 'abc', I will convert string to list = ['a','b','c'].
# Just because we can not use dict.get(a) to lookup dict. However, dict.get('a') works well.
s = list(s)
res = []
for i in range(len(s)):
if hash_map.get(s[i]) == 1:
hash_map[s[i]] = 0
res.remove(s[i])
else:
hash_map[s[i]] = 1
res.append(s[i])
return res
findodd('Hello World')
Out:
["H", "e", " ", "W", "r", "l", "d"]
However, since I use list.remove
, the time complexity is above O(n) in my solution.
s = list(s)
, how to iterate over a string 'abc'
to lookup the value of key = 'a'
in a dict? dict.get('a')
works but dict.get(a)
won't work.Here are 2 webpage I watched, however they did not take the order of letter into account and did not provide O(n) solution.
Python 3.7 up has dictionary keys input ordered. Use collection.OrderedDict for lower python versions.
Go through your word, add letter do dict if not in, else delete key from dict.
Solution is the dict.keys() collection:
t = "Hello World"
d = {}
for c in t:
if c in d: # even time occurences: delete key
del d[c]
else:
d[c] = None # odd time occurence: add key
print(d.keys())
Output:
dict_keys(['H', 'e', ' ', 'W', 'r', 'l', 'd'])
Its O(n) because you touch each letter in your input exactly once - lookup into dict is O(1).
There is some overhead by key adding/deleting. If that bothers you, use a counter instead and filter the key() collection for those that are odd - this will make it O(2*n) - 2 is constant so still O(n).