forked from gitgik/algorithms
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[chore] add markdown files for string notebooks
- Loading branch information
Showing
8 changed files
with
471 additions
and
0 deletions.
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
```python | ||
"""Caecar Cipher implementation. | ||
Given a non-empty string of lowercase alphabetic characters, write a function that | ||
takes in the string, and an integer called a key, | ||
And returns a string obtained by shifting every letter of the input string by k positions | ||
in the alphabet, where k is the key. | ||
Sample input: "xyz", 2 | ||
Sample output: "zab" | ||
""" | ||
|
||
|
||
def caesar_cipher_encryptor(string, key): | ||
""" | ||
Complexity: | ||
O(n) space | ||
O(n) time | ||
""" | ||
new_letters = [] | ||
new_key = key % 26 | ||
for letter in string: | ||
new_letter_code = ord(letter) + new_key | ||
if new_letter_code > 122: # z character code is 122 | ||
character = chr(96 + new_letter_code % 122) | ||
new_letters.append(character) | ||
else: | ||
new_letters.append(chr(new_letter_code)) | ||
|
||
return "".join(new_letters) | ||
``` | ||
|
||
|
||
```python | ||
caesar_cipher_encryptor("xyz", 2) | ||
``` | ||
|
||
|
||
|
||
|
||
'zab' | ||
|
||
|
||
|
||
|
||
```python | ||
|
||
``` |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
```python | ||
""" | ||
Reverse the words in a string but maintain the relative order of delimiters. | ||
For example: | ||
input = "hello:world/here" | ||
output = "here:world/hello" | ||
""" | ||
import re | ||
|
||
|
||
def reverse(string, delimiters): | ||
"""Split the words and delimiters into their respective lists. | ||
Then reverse the list of words and merge the two lists together. | ||
Complexity: O(n) time | O(n) space, where n == length of input string. | ||
""" | ||
words = re.split(f"[{delimiters}]+", string) | ||
not_words = re.split(f"[^({delimiters})]+", string) | ||
|
||
# remove last empty string if present | ||
if words[-1] == '': | ||
words = words[:-1] | ||
|
||
# NOTE: we can in built reverse but there's always another way | ||
# reversed_strings = list(reversed(words)) | ||
start = 0 | ||
end = len(words) - 1 | ||
while start < end: | ||
words[start], words[end] = words[end], words[start] | ||
start += 1 | ||
end -= 1 | ||
|
||
output = [] | ||
for index, delimiter in enumerate(not_words): | ||
print(index) | ||
output.append(delimiter) | ||
try: | ||
print(f"adding {words[index]}") | ||
output.append(words[index]) | ||
except IndexError: | ||
pass | ||
|
||
return ''.join(output) | ||
``` | ||
|
||
|
||
```python | ||
reverse("hello:world/here", ":/") | ||
``` | ||
|
||
0 | ||
adding here | ||
1 | ||
adding world | ||
2 | ||
adding hello | ||
3 | ||
|
||
|
||
|
||
|
||
|
||
'here:world/hello' | ||
|
||
|
||
|
||
|
||
```python | ||
|
||
``` |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
### Convert Number to palindrome | ||
Given an integer, write a function that returns True if the number can be converted into a palindrome, otherwise return False. | ||
|
||
If the conversion steps result in a number bigger than 1 million, return False. | ||
|
||
|
||
```python | ||
def convertToPalindrome(num): | ||
if isPalindrome(num): | ||
return True | ||
|
||
while num < 1000000: | ||
reverted = revert(num) | ||
num = num + reverted | ||
if isPalindrome(num): | ||
return True, num | ||
return False | ||
|
||
def revert(num): | ||
"""O(log10 (n) time -- since we are dividing by 10 every time. | O(1) space""" | ||
reverted = 0 | ||
while num > 0: | ||
reverted = (reverted * 10 + num % 10) | ||
num //= 10 | ||
return reverted | ||
|
||
def isPalindrome(x): | ||
if (x % 10 == 0 and x != 0) or x < 0: | ||
return False | ||
reverted = revert(x) | ||
return x == reverted or x == reverted // 10 | ||
``` | ||
|
||
|
||
```python | ||
convertToPalindrome(3335) | ||
``` | ||
|
||
|
||
|
||
|
||
(True, 8668) | ||
|
||
|
||
|
||
|
||
```python | ||
convertToPalindrome(95999) | ||
``` | ||
|
||
|
||
|
||
|
||
False | ||
|
||
|
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
```python | ||
""""All the ways to implement a palindrom checker. | ||
Check if the string is a palindrome, return True, otherwise, return False. | ||
A palindrome is defined as a string that is written the same forward and backward. | ||
""" | ||
|
||
|
||
def is_palindrome1(string): | ||
""" | ||
Complexity: | ||
O(n) space | ||
O(n) time | ||
""" | ||
reversed_char = [] | ||
for i in reversed(range(len(string))): | ||
reversed_char.append(string[i]) | ||
return string == "".join(reversed_char) | ||
|
||
|
||
def is_palindrome_best(string): | ||
""" | ||
Complexity: | ||
O(1) space | ||
O(n) time | ||
""" | ||
left_index = 0 | ||
right_index = len(string) - 1 | ||
|
||
while left_index < right_index: | ||
if string[left_index] != string[right_index]: | ||
return False | ||
left_index += 1 | ||
right_index -= 1 | ||
return True | ||
|
||
|
||
def is_palindrome2(string, i = 0): | ||
""" | ||
Recursive implementation. | ||
Complexity: | ||
O(n) space | ||
O(n) time | ||
""" | ||
j = len(string) - 1 - i | ||
return True if i >= j else string[i] == string[j] and is_palindrome2(string, i + 1) | ||
``` | ||
|
||
|
||
```python | ||
|
||
``` |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
## Count invalid parenthesis | ||
|
||
Given a string of parentheses, write a function to find the minimum number of parentheses to be removed to make the string valid (i.e. each open parenthesis is eventually closed). | ||
|
||
For example, given the string "()())()", you should return 1. Given the string ")(", you should return 2, since we must remove all of them. | ||
|
||
### Approach | ||
For each opening parenthesis to be considered valid, they should eventually be matched with an closing parenthesis. If not, they are counted as invalid. | ||
Whenever we encounter an unmatched closing parenthesis, we count as invalid. Eventually, we'll add the unmatched open count to the invalid one. | ||
|
||
|
||
```python | ||
def count_invalid_parenthesis(string) -> int: | ||
invalid = 0 | ||
opened = 0 | ||
|
||
for char in string: | ||
if char == "(": | ||
opened += 1 | ||
elif char == ")": | ||
if opened > 0: | ||
opened -= 1 | ||
else: | ||
invalid += 1 | ||
return invalid + opened | ||
``` | ||
|
||
|
||
```python | ||
count_invalid_parenthesis("((()(())") | ||
``` | ||
|
||
|
||
|
||
|
||
2 | ||
|
||
|
||
|
||
|
||
```python | ||
count_invalid_parenthesis("()()()") | ||
``` | ||
|
||
|
||
|
||
|
||
0 | ||
|
||
|
||
|
||
This solution runs at O(N) time, where N = number of characters in the string. | ||
|
||
|
||
```python | ||
|
||
``` |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
```python | ||
def reverse(array, start, end): | ||
"""Reverse characters in a string from start to end(inclusive).""" | ||
while start < end: | ||
array[start], array[end] = array[end], array[start] | ||
start += 1 | ||
end -= 1 | ||
|
||
|
||
def reverse_mutable_string(string_list): | ||
""" | ||
This function performs a reverse operation on a mutable string in-place. | ||
(saving on space) | ||
Since strings are immutable, a mutable string can be represented | ||
as a list of characters in a buffer e.g | ||
['h','e','l','l','o',' ','w','o','r','l','d']) == 'hello world' | ||
Approach: First, we reverse entire string to get 'dlrow olleh', | ||
then we reverse each word within the string to obtain original words. | ||
Worst-case complexity: | ||
Time: O(n) | ||
Space: O(1) - since the input memory location is overwritten by the | ||
output as we reverse the string as the algorithm executes. | ||
""" | ||
# reverse entire string | ||
reverse(string_list, 0, len(string_list) - 1) | ||
# reverse each word in the string | ||
start = 0 | ||
for end in range(len(string_list)): | ||
if string_list[end] == " ": | ||
reverse(string_list, start, end - 1) | ||
start = end + 1 | ||
|
||
# reverse last word since we stopped at the last white space in the list | ||
# remember, there are characters after the white space. | ||
reverse(string_list, start, len(string_list) - 1) | ||
return string_list | ||
``` | ||
|
||
|
||
```python | ||
reverse_mutable_string(['h','e','l','l','o',' ','w','o','r','l','d']) | ||
``` | ||
|
||
|
||
|
||
|
||
['w', 'o', 'r', 'l', 'd', ' ', 'h', 'e', 'l', 'l', 'o'] | ||
|
||
|
||
|
||
|
||
```python | ||
|
||
``` |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
## Problem | ||
|
||
Given a string of words delimited by spaces, reverse the words in string. For example, given "hello world here", return "here world hello" | ||
|
||
Follow-up: given a mutable string representation, can you perform this operation in-place? | ||
|
||
### Approach | ||
|
||
Since strings are immutable, a mutable string can be represented as a list of characters in a buffer e.g `['h','e','l','l','o',' ','w','o','r','l','d']` == 'hello world' | ||
|
||
First we reverse entire string to get `'dlrow olleh'`, then we reverse each word within the string to obtain original words. | ||
|
||
|
||
```python | ||
def reverse(string_list: list, start: int, end: int) -> str: | ||
while start < end: | ||
string_list[start], string_list[end] = string_list[end], string_list[start] | ||
start += 1 | ||
end -= 1 | ||
|
||
def reverse_words(string_list: list) -> str: | ||
reverse(string_list, 0, len(string_list) - 1) | ||
start = 0 | ||
for i in range(len(string_list)): | ||
if string_list[i] == " ": | ||
reverse(string_list, start, i - 1) | ||
start = i + 1 | ||
# we need to reverse the last sub-string | ||
reverse(string_list, start, len(string_list) - 1) | ||
return "".join(string_list) | ||
``` | ||
|
||
|
||
```python | ||
string_list = list("well hello there") | ||
reverse_words(string_list) | ||
``` | ||
|
||
|
||
|
||
|
||
'there hello well' | ||
|
||
|
||
|
||
|
Oops, something went wrong.