Skip to content

Commit 5c7e102

Browse files
author
Мето Трајковски
committed
Added new solutions
1 parent 2711195 commit 5c7e102

File tree

9 files changed

+278
-5
lines changed

9 files changed

+278
-5
lines changed

Other/palindrome_integer.py

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
'''
2+
Palindrome Integer
3+
4+
Determine whether an integer is a palindrome.
5+
An integer is a palindrome when it reads the same backward as forward.
6+
7+
Input: 121
8+
Output: True
9+
10+
Input: -121
11+
Output: False
12+
Output explanation: From left to right, it reads -121. From right to left, it becomes 121-. Therefore it is not a palindrome.
13+
14+
Input: 10
15+
Output: false
16+
Output oxplanation: Reads 01 from right to left. Therefore it is not a palindrome.
17+
18+
=========================================
19+
Juste reverse the number and compare it with the original.
20+
Time Complexity: O(N) , N = number of digits
21+
Space Complexity: O(1)
22+
If you care about integer overflow (in Python you shouldn't care about this), then reverse only a half of the number
23+
and compare it with the other half. Also this solution is faster than the previous one because iterates only a half of the number.
24+
Time Complexity: O(N)
25+
Space Complexity: O(1)
26+
'''
27+
28+
29+
##############
30+
# Solution 1 #
31+
##############
32+
33+
def palindrome_integer_1(x):
34+
if x < 0:
35+
return False
36+
37+
rev = 0
38+
temp = x
39+
while temp > 0:
40+
rev = (rev * 10) + (temp % 10)
41+
temp //= 10
42+
43+
return rev == x
44+
45+
46+
##############
47+
# Solution 2 #
48+
##############
49+
50+
def palindrome_integer_2(x):
51+
# check if negative or ends with zero
52+
if (x < 0) or (x > 0 and x % 10 == 0):
53+
return False
54+
55+
rev = 0
56+
# if the reversed number is bigger from the original
57+
# that means the reversed number has same number of digits or more (1 or 2 more)
58+
while x > rev:
59+
rev = (rev * 10) + (x % 10)
60+
x //= 10
61+
62+
# first comparison is for even number of digits and the second for odd number of digits
63+
return (rev == x) or (rev // 10 == x)
64+
65+
66+
###########
67+
# Testing #
68+
###########
69+
70+
# Test 1
71+
# Correct result => True
72+
print(palindrome_integer_1(121))
73+
print(palindrome_integer_2(121))
74+
75+
# Test 2
76+
# Correct result => False
77+
print(palindrome_integer_1(-121))
78+
print(palindrome_integer_2(-121))
79+
80+
# Test 2
81+
# Correct result => False
82+
print(palindrome_integer_1(10))
83+
print(palindrome_integer_2(10))

Other/reverse_integer.py

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
'''
2+
Reverse Integer
3+
4+
Given signed integer, reverse digits of an integer.
5+
6+
Input: 123
7+
Output: 321
8+
9+
Input: -123
10+
Output: -321
11+
12+
Input: 120
13+
Output: 21
14+
15+
=========================================
16+
Simple solution, mod 10 to find all digits.
17+
Time Complexity: O(N) , N = number of digits
18+
Space Complexity: O(1)
19+
'''
20+
21+
22+
############
23+
# Solution #
24+
############
25+
26+
def reverse_integer(x):
27+
if x == 0:
28+
return 0
29+
30+
sign = x // abs(x) # find the sign, -1 or 1
31+
x *= sign # make positive x, or x = abs(x)
32+
33+
res = 0
34+
while x > 0:
35+
res = (res * 10) + (x % 10)
36+
x //= 10
37+
38+
return res * sign
39+
40+
41+
###########
42+
# Testing #
43+
###########
44+
45+
# Test 1
46+
# Correct result => 321
47+
print(reverse_integer(123))
48+
49+
# Test 2
50+
# Correct result => -321
51+
print(reverse_integer(-123))
52+
53+
# Test 3
54+
# Correct result => 21
55+
print(reverse_integer(120))

Strings/anagram_indices.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
'''
2-
Anagram indices
2+
Anagram Indices
33
44
Given a word and a string S, find all starting indices in S which are anagrams of word.
55
(An anagram is a word or phrase formed by rearranging the letters of a different word or phrase, typically using all the original letters exactly once)

Strings/group_anagrams.py

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
'''
2+
Group Anagrams
3+
4+
Given an array of strings, group anagrams together.
5+
(An anagram is a word or phrase formed by rearranging the letters of a different word or phrase, typically using all the original letters exactly once)
6+
7+
Input: ['eat', 'tea', 'tan', 'ate', 'nat', 'bat']
8+
Output: [['eat', 'ate', 'tea'], ['tan', 'nat'], ['bat']]
9+
10+
=========================================
11+
This problem can be solved using a dictionary (hash map), but in order to use a dictinary you'll need to find
12+
a way to calculate the keys for all strings. This is a same solution but 2 different hash functions.
13+
14+
Sort the letters from the strings, and use the sorted letters as key.
15+
Time Complexity: O(N * KLogK) , N = number of strings, K = number of characters (chars in the string with most chars)
16+
Space Complexity: O(N)
17+
Use a letter counter (some kind of counting sort).
18+
Time Complexity: O(N * K) , O(N * K * 26) = O(N * K), if all of the strings have several chars (less than ~8) the first hash function is better.
19+
Space Complexity: O(N)
20+
'''
21+
22+
23+
############
24+
# Solution #
25+
############
26+
27+
def group_anagrams(strs):
28+
anagrams = {}
29+
30+
for st in strs:
31+
# or hashable_object = hash_1(st)
32+
hashable_object = hash_2(st)
33+
34+
if hashable_object not in anagrams:
35+
anagrams[hashable_object] = []
36+
anagrams[hashable_object].append(st)
37+
38+
return [anagrams[res] for res in anagrams]
39+
40+
def hash_1(st):
41+
chars = list(st)
42+
chars.sort()
43+
# or you can use a string as hash, ''.join(chars)
44+
return tuple(chars)
45+
46+
def hash_2(st):
47+
all_letters = [0]*26
48+
ord_a = 97 # ord('a')
49+
for c in st:
50+
all_letters[ord(c) - ord_a] += 1
51+
# or you can use a string as hash, '<some non-digit character>'.join(all_letters), example: ' '.join(all_letters)
52+
return tuple(all_letters)
53+
54+
55+
###########
56+
# Testing #
57+
###########
58+
59+
# Test 1
60+
# Correct result => [['eat', 'ate', 'tea'], ['tan', 'nat'], ['bat']]
61+
print(group_anagrams(['eat', 'tea', 'tan', 'ate', 'nat', 'bat']))

Strings/longest_common_prefix.py

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
'''
2+
Longest Common Prefix
3+
4+
Write a function to find the longest common prefix string amongst an array of strings.
5+
If there is no common prefix, return an empty string ''.
6+
7+
Input: ['flower', 'flow', 'flight']
8+
Output: 'fl'
9+
10+
Input: ['dog', 'racecar', 'car']
11+
Output: ''
12+
13+
Input: ['aa', 'a']
14+
Output: 'a'
15+
16+
=========================================
17+
Many solutions for this problem exist (Divide and Conquer, Trie, etc) but this is the simplest and the fastest one.
18+
Use the first string as LCP and iterate the rest in each step compare it with another one.
19+
Time Complexity: O(N*A) , N = number of strings, A = average chars, or simplest notation O(S) = total number of chars
20+
Space Complexity: O(1)
21+
'''
22+
23+
24+
############
25+
# Solution #
26+
############
27+
28+
def longest_common_prefix(strs):
29+
n = len(strs)
30+
if n == 0:
31+
return ''
32+
33+
lcp = strs[0]
34+
# instead of string manipulations, manipulate with the last common index
35+
lcp_idx = len(lcp)
36+
37+
for i in range(1, n):
38+
lcp_idx = min(lcp_idx, len(strs[i]))
39+
40+
for j in range(lcp_idx):
41+
if lcp[j] != strs[i][j]:
42+
lcp_idx = j
43+
break
44+
45+
return lcp[:lcp_idx]
46+
'''
47+
# if you like string manipulations, you can use this code
48+
# i don't like string manipulations in Python because they're immutable
49+
lcp = strs[0]
50+
for i in range(1, n):
51+
lcp = lcp[:len(strs[i])]
52+
for j in range(len(lcp)):
53+
if lcp[j] != strs[i][j]:
54+
lcp = lcp[:j]
55+
break
56+
return lcp
57+
'''
58+
59+
60+
###########
61+
# Testing #
62+
###########
63+
64+
# Test 1
65+
# Correct result => 'fl'
66+
print(longest_common_prefix(['flower', 'flow', 'flight']))
67+
68+
# Test 2
69+
# Correct result => ''
70+
print(longest_common_prefix(['dog', 'racecar', 'car']))
71+
72+
# Test 3
73+
# Correct result => 'a'
74+
print(longest_common_prefix(['aa', 'a']))

Strings/reverse_string.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
############
2424

2525
def reverse_sentence(sentence):
26-
arr = [c for c in sentence]
26+
arr = [c for c in sentence] # or just arr = list(sentence)
2727
start = 0
2828
end = len(arr) - 1
2929

Strings/reverse_vowels.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
############
2323

2424
def reverse_vowels(sentence):
25-
arr = [c for c in sentence]
25+
arr = [c for c in sentence] # or just arr = list(sentence)
2626

2727
vowels = {
2828
'a': True, 'A': True,

Strings/reverse_words_in_sentence.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
############
2626

2727
def reverse_words_in_sentence(sentence):
28-
arr = [c for c in sentence]
28+
arr = [c for c in sentence] # or just arr = list(sentence)
2929
n = len(arr)
3030
last_idx = n - 1
3131
start = 0

Strings/swap_first_and_last_word.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
############
2323

2424
def swap_first_and_last_word(sentence):
25-
arr = [c for c in sentence]
25+
arr = [c for c in sentence] # or just arr = list(sentence)
2626
first_idx = 0
2727
last_idx = len(arr) - 1
2828

0 commit comments

Comments
 (0)