Last active
January 6, 2019 13:48
-
-
Save sergeyprokudin/b0000ecf8c1cf6cd5d71a194fba3dc80 to your computer and use it in GitHub Desktop.
Test if the string is a permuted palindrome (problem 1.4. from "Cracking the Coding Interview")
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
def is_permuted_palindrome(s): | |
"""Checks if the string is a permuted version of a palindrome | |
Upper case do not matter, spaces can be ignored. | |
Example: | |
"cat cat" -> Yes (palindrome: "cat tac") | |
"cat do" -> No | |
Algorithm #1: | |
1. Make a dictionary of symbols (symbol:occ_cnt); | |
2. Iterate over string and count occurences. | |
Time complexity: n O(1) dictionary insertions => O(n); | |
Space complexity: O(n) for dictionary. | |
3. Check that no more than 1 symbol have odd number of occurences. Time complexity: O(n) | |
Overall complexity: space O(n), time O(n) | |
! Correction: this is not particularly True, since the number of letters in alpahber is constant! (So Algorithm would | |
have O(1) space complexity as well, and Algo#2 do not make any sense!). | |
Algorithm #2 (not relevant for finite alphabet): | |
1. Sort string with some inplace algorithm. Example: heap sort. Space: O(1), time: O(n*log(n)) | |
2. Iterate over sorted string: iterate until we find more than 2 symbols that have odd number of occurences | |
Overall complexity: space O(1), time O(n log(n)) | |
Corner cases: | |
0. Handling spaces? Special symbols, etc.? Upper\lower case? | |
1. Null string; | |
2. 1 character; | |
3. Check that it works for both odd and even; | |
4. Very large string that do not fit in memory? Can we apply map-reduce strategy here? | |
""" | |
#algo 1 implementation | |
occ_dict = {} # symbol occurency dictionary | |
for x in s: | |
x = x.lower() | |
if x==' ': | |
continue | |
if x in occ_dict: | |
occ_dict[x] += 1 | |
else: | |
occ_dict[x] = 1 | |
odd_cnt = 0 | |
for x in occ_dict.keys(): | |
if occ_dict[x] % 2 !=0: | |
odd_cnt += 1 | |
if odd_cnt>1: | |
is_perm_pal = False | |
else: | |
is_perm_pal = True | |
return is_perm_pal | |
# Demo | |
print("Test is_permuted_palindrome function") | |
test_strings = ['', ' ', 'Tact Coa', 'abd'] | |
for s in test_strings: | |
print("\'%s\' : %r" %(s, is_permuted_palindrome(s))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment