Skip to content

Commit 6260abc

Browse files
author
Partho Biswas
committed
KMP algorithm
1 parent b482976 commit 6260abc

File tree

8 files changed

+52
-57
lines changed

8 files changed

+52
-57
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -809,6 +809,7 @@ BFS, DFS, Dijkstra, Floyd–Warshall, Bellman-Ford, Kruskal, Prim's, Minimum Spa
809809
| --- | --- | --- | --- | --- | --- |
810810
|01| [Kadane's_Algorithm](algoexpert.io/questions/Kadane's_Algorithm.md) | [Python](algoexpert.io/python/Kadane's_Algorithm.py)|
811811
|02| [Topological_Sort](algoexpert.io/questions/Topological_Sort.md) | [Python](algoexpert.io/python/Topological_Sort.py) |
812+
|03| [KMP_Algorithm](algoexpert.io/questions/KMP_Algorithm.md) | [Python](algoexpert.io/python/KMP_Algorithm.py) |
812813

813814
</p>
814815
</details>
@@ -942,7 +943,7 @@ BFS, DFS, Dijkstra, Floyd–Warshall, Bellman-Ford, Kruskal, Prim's, Minimum Spa
942943
|02| [Longest_Palindromic_Substring](algoexpert.io/questions/Longest_Palindromic_Substring.md) | [Python](algoexpert.io/python/Longest_Palindromic_Substring.py)|
943944
|03| [Caesar_Cipher_Encryptor](algoexpert.io/questions/Caesar_Cipher_Encryptor.md) | [Python](algoexpert.io/python/Caesar_Cipher_Encryptor.py)|
944945
|04| [Longest_Substring_Without_Duplication](algoexpert.io/questions/Longest_Substring_Without_Duplication.md) | [Python](algoexpert.io/python/Longest_Substring_Without_Duplication.py)|
945-
|05| [Underscorify_Substring](algoexpert.io/questions/Underscorify_Substring.md) | [Python](algoexpert.io/python/Underscorify_Substring.py)|
946+
|05| [Underscorify_Substring](algoexpert.io/questions/Underscorify_Substring.md) | [Python](algoexpert.io/python/Underscorify_Substring.py)| --- | Hard | TODO: Check again. Difficult to analyse the space ad time complexity |
946947
|06| [Pattern_Matcher](algoexpert.io/questions/Pattern_Matcher.md) | [Python](algoexpert.io/python/Pattern_Matcher.py)|
947948

948949
</p>
Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,20 @@
11
# https://www.algoexpert.io/questions/Breadth-first%20Search
2-
3-
42
class Node:
5-
63
def __init__(self, name):
4+
self.children = []
75
self.name = name
8-
self.childern = []
96

10-
def add_children(self, name):
11-
self.childern.append(Node(name))
7+
def addChild(self, name):
8+
self.children.append(Node(name))
129
return self
1310

14-
# O(v + e) time | O(v) space
15-
def breadth_first_search(self, array):
11+
def breadthFirstSearch(self, array):
1612
queue = [self] # step 1 > add root node to the queue, the node on which we are calling BFS
1713
while len(queue) > 0:
1814
current = queue.pop(0) # step 2 > pop the root/current node
1915
array.append(current.name) # step 3 > add the current node to the final array
20-
for child in current.childern: # step 4 > add the children of the current node to the queue
16+
for child in current.children: # step 4 > add the children of the current node to the queue
2117
queue.append(child)
2218
return array
2319

20+

algoexpert.io/python/Find_Closest_Value_in_BST.py

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
2-
31
class BST:
42
def __init__(self, value):
53
self.value = value
@@ -23,7 +21,7 @@ def insert(self, value):
2321
def findClosestValueInBst(tree, target):
2422
return findClosestValueInBstHelper(tree, target, float("inf"))
2523

26-
# Solution 1 starts here
24+
# Solution 1
2725
# Avarage: O(log(n)) time | O(log(n)) space
2826
# Worst: O(n) time | O(n) space
2927
def findClosestValueInBstHelper(tree, target, closest):
@@ -37,9 +35,8 @@ def findClosestValueInBstHelper(tree, target, closest):
3735
return findClosestValueInBstHelper(tree.right, target, closest)
3836
else:
3937
return closest
40-
# Solution 1 ends here
4138

42-
# Solution 2 starts here
39+
# Solution 2
4340
# Avarage: O(log(n)) time | O(1) space
4441
# Worst: O(n) time | O() space
4542
def findClosestValueInBstHelper_2(tree, target, closest):
@@ -54,7 +51,6 @@ def findClosestValueInBstHelper_2(tree, target, closest):
5451
else:
5552
break
5653
return closest
57-
# Solution 2 ends here
5854

5955

6056
test_tree = BST(100).insert(5).insert(15).insert(5).insert(2).insert(1).insert(22) \
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
def knuthMorrisPrattAlgorithm(string, substring):
2+
pattern = buildPattern(substring)
3+
return doesMatch(string, substring, pattern)
4+
5+
def buildPattern(substring):
6+
pattern = [-1 for _ in substring]
7+
j, i = 0, 1
8+
while i < len(substring):
9+
if substring[i] == substring[j]:
10+
pattern[i] = j
11+
i += 1
12+
j += 1
13+
elif j > 0:
14+
j = pattern[j - 1] + 1
15+
else:
16+
i += 1
17+
return pattern
18+
19+
def doesMatch(string, substring, pattern):
20+
i, j = 0, 0
21+
while i + len(substring) - j <= len(string):
22+
if string[i] == substring[j]:
23+
if j == len(substring) - 1:
24+
return True
25+
i += 1
26+
j += 1
27+
elif j > 0:
28+
j = pattern[j - 1] + 1
29+
else:
30+
i += 1
31+
return False

algoexpert.io/python/Right_Sibling_Tree.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ def __init__(self, value, left=None, right=None):
55
self.left = left
66
self.right = right
77

8-
98
def rightSiblingTree(root):
109
mutate(root, None, None)
1110
return root

algoexpert.io/python/Search_For_Range.py

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
2-
3-
41
# Solution #1 - Recursive SOlution
52
# O(logn) time | O(logn) space
63
def searchForRange(array, target):
@@ -9,7 +6,6 @@ def searchForRange(array, target):
96
alteredBinarySearch(array, target, 0, len(array) - 1, finalRange, False)
107
return finalRange
118

12-
139
def alteredBinarySearch(array, target, left, right, finalRange, goLeft):
1410
if left > right:
1511
return
@@ -31,9 +27,6 @@ def alteredBinarySearch(array, target, left, right, finalRange, goLeft):
3127
alteredBinarySearch(array, target, mid + 1, right, finalRange, goLeft)
3228

3329

34-
35-
36-
3730
# Solution #2 - Iterative SOlution
3831
# O(logn) time | O(1) space
3932
def searchForRange(array, target):
@@ -42,7 +35,6 @@ def searchForRange(array, target):
4235
alteredBinarySearch(array, target, 0, len(array) - 1, finalRange, False)
4336
return finalRange
4437

45-
4638
def alteredBinarySearch(array, target, left, right, finalRange, goLeft):
4739
while left <= right:
4840
mid = (left + right) // 2
@@ -64,5 +56,10 @@ def alteredBinarySearch(array, target, left, right, finalRange, goLeft):
6456

6557

6658

67-
68-
59+
# Solution 3 - using python bisect library
60+
import bisect
61+
def searchForRange(array, target):
62+
# Write your code here.
63+
left = bisect.bisect_left(array, target)
64+
right = bisect.bisect_right(array, target)
65+
return [left, right - 1] if left < right else [-1, -1]

algoexpert.io/python/Topological_Sort.py

Lines changed: 2 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,43 @@
1-
21
# SOLUTION #1
3-
42
class JobNode:
53
def __init__(self, job):
64
self.job = job
75
self.prereqs = []
86
self.visited = False
97
self.visiting = False
108

11-
129
class JobGraph:
1310
def __init__(self, jobs):
1411
self.nodes = []
1512
self.graph = {}
1613
for job in jobs:
17-
self.addNodes(job)
18-
14+
self.addNode(job)
1915

2016
def addPrereq(self, job, prereq):
2117
jobNode = self.getNode(job)
2218
prereqNode = self.getNode(prereq)
2319
jobNode.prereqs.append(prereqNode)
2420

25-
2621
def addNode(self, job):
2722
self.graph[job] = JobNode(job)
2823
self.nodes.append(self.graph[job])
2924

30-
3125
def getNode(self, job):
3226
if job not in self.graph:
3327
self.addNode(job)
3428
return self.graph[job]
3529

36-
37-
3830
# O(v + e) time | O(v + e) space
3931
def topologicalSort(jobs, deps):
4032
jobGraph = createJobGraph(jobs, deps)
4133
return getOrderedJobs(jobGraph)
4234

43-
4435
def createJobGraph(jobs, deps):
4536
graph = JobGraph(jobs)
4637
for prereq, job in deps:
4738
graph.addPrereq(job, prereq)
4839
return graph
4940

50-
5141
def getOrderedJobs(graph):
5242
orderedJobs = []
5343
nodes = graph.nodes
@@ -58,7 +48,6 @@ def getOrderedJobs(graph):
5848
return []
5949
return orderedJobs
6050

61-
6251
def depthFirstTraverse(node, orderedJobs):
6352
if node.visited:
6453
return False
@@ -75,60 +64,46 @@ def depthFirstTraverse(node, orderedJobs):
7564
return False
7665

7766

78-
79-
80-
81-
82-
8367
# SOLUTION #2
84-
8568
class JobNode:
8669
def __init__(self, job):
8770
self.job = job
8871
self.deps = []
8972
self.numOfPrereqs = 0
9073

91-
9274
class JobGraph:
9375
def __init__(self, jobs):
9476
self.nodes = []
9577
self.graph = {}
9678
for job in jobs:
97-
self.addNodes(job)
98-
79+
self.addNode(job)
9980

10081
def addDep(self, job, dep):
10182
jobNode = self.getNode(job)
10283
depNode = self.getNode(dep)
10384
jobNode.dep.append(depNode)
10485
depNode.numOfPrereqs += 1
10586

106-
10787
def addNode(self, job):
10888
self.graph[job] = JobNode(job)
10989
self.nodes.append(self.graph[job])
11090

111-
11291
def getNode(self, job):
11392
if job not in self.graph:
11493
self.addNode(job)
11594
return self.graph[job]
11695

117-
118-
11996
# O(v + e) time | O(v + e) space
12097
def topologicalSort(jobs, deps):
12198
jobGraph = createJobGraph(jobs, deps)
12299
return getOrderedJobs(jobGraph)
123100

124-
125101
def createJobGraph(jobs, deps):
126102
graph = JobGraph(jobs)
127103
for job, dep in deps:
128104
graph.addDep(job, dep)
129105
return graph
130106

131-
132107
def getOrderedJobs(graph):
133108
orderedJobs = []
134109
nodesWithNoPrereqs = list(filter(lambda node: node.numOfPrereqs == 0, graph.nodes))
@@ -139,7 +114,6 @@ def getOrderedJobs(graph):
139114
graphHasEdges = any(node.numOfPrereqs for node in graph.nodes)
140115
return [] if graphHasEdges else orderedJobs
141116

142-
143117
def removeDeps(node, nodesWithNoPrereqs):
144118
while len(node.deps):
145119
dep = node.deps.pop()

algoexpert.io/python/Underscorify_Substring.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
21
# O(n*m) time | O(n) space
32
def underscorifySubstring(string, substring):
43
locations = collapse(getLocations(string, substring))
@@ -39,7 +38,7 @@ def underscorify(string, locations):
3938
inBetweenUnderscores = False
4039
finalChars = []
4140
i = 0
42-
while stringIdx < len(string) and locationsIdx < len(locationsIdx):
41+
while stringIdx < len(string) and locationsIdx < len(locations):
4342
if stringIdx == locations[locationsIdx][i]:
4443
finalChars.append("_")
4544
inBetweenUnderscores = not inBetweenUnderscores
@@ -60,3 +59,4 @@ def underscorify(string, locations):
6059

6160

6261

62+

0 commit comments

Comments
 (0)