Skip to content

Commit 7cbbae1

Browse files
committed
18/06/21
1 parent 607bc1f commit 7cbbae1

16 files changed

+498
-166
lines changed

Arrays/Anagrams.py

+7-15
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,10 @@
11
from nose.tools import assert_equal
22

33
################ Problem Definition #####################################
4-
5-
# Given an integer array, output all the **unique** pairs that sum up to a specific value **k**.
6-
7-
# So the input:
8-
9-
# pair_sum([1,3,2,2],4)
10-
11-
# would return **2** pairs:
12-
13-
# (1,3)
14-
# (2,2)
15-
4+
"""
5+
Given two strings find if they are anagrams, that is contain the same letters
6+
but in different order.
7+
"""
168
################ Solution #####################################
179

1810

@@ -74,6 +66,6 @@ def test(self, sol):
7466
print(anagram('clint eastwood', 'old west action'))
7567

7668
# Run Tests
77-
# t = AnagramTest()
78-
# t.test(anagram)
79-
# t.test(anagram2)
69+
t = AnagramTest()
70+
t.test(anagram)
71+
t.test(anagram2)

Arrays/Reversing a string.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
def reverse(stri):
22
mylist = []
3-
for i in range(len(stri)-1, -1, -1):
3+
for i in range(len(stri) - 1, -1, -1):
44
mylist.append(stri[i])
55
return ''.join(mylist)
66

Arrays/Sentence_reversal.py

+11-11
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,25 @@
11
from nose.tools import assert_equal
22

33
################ Problem Definition #####################################
4+
"""
5+
Given a string of words, reverse all the words. For example:
46
5-
# Given a string of words, reverse all the words. For example:
7+
Given:
68
7-
# Given:
9+
'This is the best'
810
9-
# 'This is the best'
11+
Return:
1012
11-
# Return:
13+
'best the is This'
1214
13-
# 'best the is This'
15+
As part of this exercise you should remove all leading and trailing whitespace. So that inputs such as:
1416
15-
# As part of this exercise you should remove all leading and trailing whitespace. So that inputs such as:
17+
' space here' and 'space here '
1618
17-
# ' space here' and 'space here '
18-
19-
# both become:
20-
21-
# 'here space'
19+
both become:
2220
21+
'here space'
22+
"""
2323
################################# Solution ##############################
2424

2525

Arrays/String_compression.py

+6-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
##################### Problem ######################
22

3-
# Given a string in the form 'AAAABBBBCCCCCDDEEEE' compress it to become 'A4B4C5D2E4'. For this problem, you can falsely "compress" strings of single or double letters. For instance, it is okay for 'AAB' to return 'A2B1' even though this technically takes more space.
3+
"""
4+
Given a string in the form 'AAAABBBBCCCCCDDEEEE' compress it to become 'A4B4C5D2E4'. For this problem,
5+
you can falsely "compress" strings of single or double letters. For instance, it is okay for 'AAB' to
6+
return 'A2B1' even though this technically takes more space.
47
5-
# The function should also be case sensitive, so that a string 'AAAaaa' returns 'A3a3'.
8+
The function should also be case sensitive, so that a string 'AAAaaa' returns 'A3a3'.
9+
"""
610

711
##################### Solution #####################
812

Arrays/first_unique_char.py

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
def first_unique_chars(myStr):
2+
chars = {}
3+
for i, x in enumerate(myStr):
4+
if x not in chars:
5+
chars[x] = i
6+
else:
7+
chars[x] = -1
8+
9+
for x in chars:
10+
if x != -1:
11+
return chars[x]
12+
13+
return -1
14+
15+
16+
myStr = 'helleo'
17+
print(first_unique_chars(myStr))

Arrays/kth_largest_element.py

+116
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
from queue import PriorityQueue
2+
3+
# O(NlogN)
4+
5+
6+
def simple_method(arr, k):
7+
arr.sort()
8+
return arr[len(arr) - k]
9+
10+
11+
"""
12+
O(N*logK) Approach with heap
13+
14+
We throw away items that items smaller then
15+
the kth largest item. So that we grab the smallest item
16+
left in the heap is the second largest item.
17+
"""
18+
19+
20+
def heap_approach(arr, k):
21+
q = PriorityQueue()
22+
for num in arr:
23+
q.put(num)
24+
if q.qsize() > k:
25+
q.get()
26+
27+
return q.get()
28+
29+
30+
"""
31+
O(N) Approach using partitions
32+
Think of BUD (Bottlenecks, Unnecessary work, Duplicate work)
33+
34+
We can do a partition and eliminate half of the search space (on average)self.
35+
It works on the fact that in a sorted array:
36+
37+
- The kth largest item must be at index n-k
38+
- Generally speaking if we do a partition then if we know the
39+
kth largest item should be at an index greater then the index of pivot
40+
then we should focus our search on the items with greater indices (or to the right)
41+
"""
42+
43+
44+
import math
45+
import random
46+
47+
48+
def kthLargest(arr, k):
49+
'''
50+
:type arr: list of int
51+
:type k: int
52+
:rtype: int
53+
'''
54+
n = len(arr)
55+
left = 0
56+
right = n - 1
57+
58+
while left <= right:
59+
# Random pivot index will ensure on average we avoid
60+
# O(N^2) runtime
61+
choosen_pivot_index = random.randint(left, right)
62+
63+
final_index_of_choosen_pivot = partition(
64+
arr, left, right, choosen_pivot_index)
65+
66+
# What does the 'finalIndexOfChoosenPivot' tell us?
67+
if (final_index_of_choosen_pivot == n - k):
68+
69+
# If the pivot index in the (n-k)th index then we are done and can stop here
70+
return arr[final_index_of_choosen_pivot]
71+
elif (final_index_of_choosen_pivot > n - k):
72+
# k'th largest must be in the left partition.
73+
right = final_index_of_choosen_pivot - 1
74+
else:
75+
# finalIndexOfChoosenPivot < n - k
76+
77+
# k'th largest must be in the right partition.
78+
79+
left = final_index_of_choosen_pivot + 1
80+
81+
return -1
82+
83+
84+
def partition(self, arr, left, right, pivot_index):
85+
pivot_value = arr[pivot_index]
86+
lesser_items_tail_index = left
87+
88+
# Move the item at the 'pivotIndex' OUT OF THE WAY. We are about to bulldoze
89+
# through the partitioning space and we don't want it in the way
90+
swap(arr, pivot_index, right)
91+
92+
for i in range(left, right):
93+
if arr[i] < pivot_value:
94+
swap(arr, i, lesser_items_tail_index)
95+
lesser_items_tail_index += 1
96+
97+
# Ok...partitioning is done. Swap the pivot item BACK into the space we just
98+
# partitioned at the 'lesserItemsTailIndex'...that's where the pivot item
99+
# belongs
100+
101+
# In the middle of the "sandwich".
102+
103+
swap(arr, right, lesser_items_tail_index)
104+
105+
return lesser_items_tail_index
106+
107+
108+
def swap(self, arr, first, second):
109+
temp = arr[first]
110+
arr[first] = arr[second]
111+
arr[second] = temp
112+
113+
114+
arr = [8, 1, 3, 2, 6, 7]
115+
116+
print(heap_approach(arr, 2))

Arrays/largest_continuous_sum.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
from nose.tools import assert_equal
22

33
################ Problem Definition ###########################
4-
# Given an array of integers (positive and negative) find the largest continuous sum.
4+
"""
5+
Given an array of integers (positive and negative) find the largest continuous sum.
6+
"""
57

68
################ Solution #####################################
79

Arrays/largest_subarray.py

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# O(N^2)
2+
def quadratic_approach(arr):
3+
maxSum = -float('inf')
4+
maxSub = []
5+
for left in range(len(arr)):
6+
runningWindowSum = 0
7+
runningSubArray = []
8+
9+
for right in range(left, len(arr)):
10+
runningWindowSum += arr[right]
11+
runningSubArray.append(arr[right])
12+
if (runningWindowSum > maxSum):
13+
maxSum = runningWindowSum
14+
maxSub = runningSubArray[:]
15+
16+
return [maxSum, maxSub]
17+
18+
19+
# O(N)
20+
def kadane_algorithm(arr):
21+
runningSum = arr[0]
22+
maxSum = arr[0]
23+
maxSub = []
24+
runningSub = []
25+
26+
for i in range(1, len(arr)):
27+
if (runningSum < arr[i]):
28+
runningSum = arr[i]
29+
runningSub = [arr[i]]
30+
else:
31+
runningSum += arr[i]
32+
runningSub.append(arr[i])
33+
34+
if runningSum > maxSum:
35+
maxSum = runningSum
36+
maxSub = runningSub[:]
37+
38+
return [maxSum, maxSub]
39+
40+
41+
arr = [-2, 1, -3, 4, -1, 2, 1, -5, 4]
42+
43+
print(kadane_algorithm(arr))

Arrays/missing_item.py

+12-8
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,23 @@
33
import collections
44

55
################ Problem Definition ###########################
6+
"""
7+
Consider an array of non-negative integers. A second array is formed by
8+
shuffling the elements of the first array and deleting a random element.
9+
Given these two arrays, find which element is missing in the second array.
610
7-
# Consider an array of non-negative integers. A second array is formed by shuffling the elements of the first array and deleting a random element. Given these two arrays, find which element is missing in the second array.
11+
Here is an example input, the first array is shuffled and the number 5 is
12+
removed to construct the second array.
813
9-
# Here is an example input, the first array is shuffled and the number 5 is removed to construct the second array.
14+
Input:
1015
11-
# Input:
16+
finder([1,2,3,4,5,6,7],[3,7,2,1,4,6])
1217
13-
# finder([1,2,3,4,5,6,7],[3,7,2,1,4,6])
18+
Output:
1419
15-
# Output:
16-
17-
# 5 is the missing number
20+
5 is the missing number
1821
22+
"""
1923
################ Solution #####################################
2024

2125
# naive solution
@@ -68,7 +72,7 @@ def finder3(arr1, arr2):
6872

6973
# Perform an XOR between the numbers in the arrays
7074
# XOR is good for pairs
71-
for num in arr1+arr2: # O(N) time complexity
75+
for num in arr1 + arr2: # O(N) time complexity
7276
result ^= num
7377

7478
return result

Dynamic Programming/knapsack.py

+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
"""
2+
A naive recursive implementation
3+
of 0-1 Knapsack Problem
4+
5+
Returns the maximum value that
6+
can be put in a knapsack of
7+
capacity W
8+
9+
References
10+
- https://www.geeksforgeeks.org/0-1-knapsack-problem-dp-10/
11+
- https://www.youtube.com/watch?v=qOUsP4eoYls&list=PLyEvk8ZeQDMVbsg7CEfT0NV3s3GkMx1vN&index=10
12+
"""
13+
14+
15+
def knapSack(W, wt, val, n):
16+
17+
# Base Case
18+
if n == 0 or W == 0:
19+
return 0
20+
21+
# If weight of the nth item is
22+
# more than Knapsack of capacity W,
23+
# then this item cannot be included
24+
# in the optimal solution
25+
if (wt[n - 1] > W):
26+
return knapSack(W, wt, val, n - 1)
27+
28+
# return the maximum of two cases:
29+
# (1) nth item included
30+
# (2) not included
31+
else:
32+
return max(
33+
val[n - 1] + knapSack(
34+
W - wt[n - 1], wt, val, n - 1),
35+
knapSack(W, wt, val, n - 1))
36+
37+
# end of function knapSack
38+
39+
40+
# Driver Code
41+
val = [60, 100, 120]
42+
wt = [10, 20, 30]
43+
W = 50
44+
n = len(val)
45+
print(knapSack(W, wt, val, n))

Hashtables/First Recurring Character.py

+2-3
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,13 @@
22
def func(mylist):
33

44
for i in range(0, len(mylist)):
5-
for j in range(i+1, len(mylist)):
5+
for j in range(i + 1, len(mylist)):
66
if mylist[i] == mylist[j]:
77
return mylist[i]
88
return 0
99

10-
# O(N) time complexity
11-
1210

11+
# O(N) time complexity
1312
def hashtable(mylist):
1413
mydict = {}
1514
for i in range(0, len(mylist)):

0 commit comments

Comments
 (0)