Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding Non commutative version and Doubly Linked List template #881

Open
wants to merge 122 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
122 commits
Select commit Hold shift + click to select a range
15c329d
Adding Non commutative version
sdt4936 Aug 29, 2022
000f13d
Adding Doubly Linked List
sdt4936 Sep 20, 2022
5da65cb
Fast Segment Tree
sdt4936 Sep 21, 2022
faf4d61
Updating gitignore
sdt4936 Sep 21, 2022
9d95930
Updating
sdt4936 Sep 21, 2022
bf749c1
Updating
sdt4936 Sep 21, 2022
e56c13e
Updating
sdt4936 Sep 21, 2022
4acdbde
Adding topological sorting
sdt4936 Sep 21, 2022
117ed64
correcting robit karp
sdt4936 Sep 21, 2022
851be5c
unnecessary comments
sdt4936 Sep 21, 2022
4825a38
reverting to stable
sdt4936 Sep 21, 2022
e2f5ea4
correcting code
sdt4936 Sep 21, 2022
fd76356
Disset of my own
sdt4936 Sep 25, 2022
3665c7b
Adding prime factors using sieve
sdt4936 Sep 29, 2022
751cc45
Correcting
sdt4936 Sep 29, 2022
8f1c37b
correcting
sdt4936 Sep 29, 2022
66ee5ba
Prime factorixation made sieve
sdt4936 Sep 29, 2022
4032d84
Correcting
sdt4936 Sep 29, 2022
de98646
factoring code
sdt4936 Sep 29, 2022
1f16a8e
correcting
sdt4936 Sep 29, 2022
c9353dd
improving
sdt4936 Sep 29, 2022
7152c9c
Wuick copy for fenwick
sdt4936 Oct 4, 2022
9258c84
adding
sdt4936 Oct 18, 2022
4fdca61
adding comments
sdt4936 Oct 18, 2022
e41d65a
prime-factors-my-style
sdt4936 Oct 18, 2022
421eb84
adding comments
sdt4936 Oct 18, 2022
b36ae8c
Adding prime-factorization-till 10^9
sdt4936 Oct 18, 2022
7314016
Best Trie Template for CP
sdt4936 Oct 19, 2022
f08d933
formatting
sdt4936 Oct 19, 2022
4f852d4
removing extra spaces
sdt4936 Oct 19, 2022
7dc7903
usin bitiwise
sdt4936 Oct 22, 2022
a6a3c1e
bitwise
sdt4936 Oct 22, 2022
f3951cc
KMP comments
sdt4936 Dec 25, 2022
28242fc
making min heap fun
sdt4936 Nov 2, 2023
b0e1003
fun
sdt4936 Nov 2, 2023
9d72cb7
adding a quick bucket
sdt4936 Nov 2, 2023
f6de9d4
formatting
sdt4936 Nov 2, 2023
1843dd4
adding rolling_hash of mine
sdt4936 Nov 2, 2023
cd4c248
changing terminology for ease
sdt4936 Nov 3, 2023
09a713c
formatting
sdt4936 Nov 3, 2023
f1ae8cb
fixing a bug
sdt4936 Nov 3, 2023
8fcf1d4
bugfix
sdt4936 Nov 3, 2023
1f55b19
improving readability
sdt4936 Nov 3, 2023
914e2ef
improved readability
sdt4936 Nov 3, 2023
157c007
improving readability
sdt4936 Nov 3, 2023
2a89fd6
improving readability
sdt4936 Nov 3, 2023
59cc682
easing names
sdt4936 Nov 3, 2023
b349ed9
optimizing
sdt4936 Nov 3, 2023
670d666
easing names
sdt4936 Nov 3, 2023
a130f0b
optimizing
sdt4936 Nov 3, 2023
1895655
changing variable names
sdt4936 Nov 3, 2023
2e85d36
easing
sdt4936 Nov 3, 2023
6d241d7
adding kmp
sdt4936 Nov 5, 2023
a7daf13
adding lru cache using doubly linked list
sdt4936 Nov 6, 2023
b599905
adding lca to the bucket
sdt4936 Nov 6, 2023
2027f8a
making changes for segment tree
sdt4936 Nov 7, 2023
f53b636
LIs with explanation
sdt4936 Nov 7, 2023
2829077
optimizing
sdt4936 Nov 8, 2023
aaf6dce
adding docs to algorithms
sdt4936 Nov 10, 2023
cb61251
learning kosaraju's algorithm
sdt4936 Nov 12, 2023
bc19449
Optimizing
sdt4936 Nov 12, 2023
b2a5e9f
adding doc
sdt4936 Nov 12, 2023
c4dcab3
formatted
sdt4936 Nov 12, 2023
0f21eb9
adding tarjan's algorithm
sdt4936 Nov 12, 2023
2b44d39
adding docs
sdt4936 Nov 12, 2023
fa0cce7
removing extra code
sdt4936 Nov 12, 2023
389c0b2
adding more docs
sdt4936 Nov 12, 2023
d45c7c4
renaming
sdt4936 Nov 12, 2023
160db2a
Making code more readable
sdt4936 Nov 13, 2023
0f103e6
more docs
sdt4936 Nov 13, 2023
5e68a27
Adding mo's algo and get palindromes
sdt4936 Dec 17, 2023
885e75c
dp converting solution
sdt4936 Dec 21, 2023
4d0a873
change names
sdt4936 Dec 21, 2023
5adf23d
adding binary indexed trees
sdt4936 Dec 30, 2023
8a46985
Made chnges to the BIT and tohers
sdt4936 Jan 10, 2024
fab6eb2
Finally able to get kth smallest element in BIT
sdt4936 Jan 10, 2024
30ea8b3
updates
sdt4936 Jan 14, 2024
285d2c8
Adding floyd warshall
sdt4936 Jan 19, 2024
d537a8d
Changing rolling hash a little bit
sdt4936 Jan 21, 2024
840bcc4
Rolling Hash perfected
sdt4936 Jan 21, 2024
14610a0
yess
sdt4936 Jan 21, 2024
9789649
nice
sdt4936 Jan 21, 2024
831af1f
formatting
sdt4936 Jan 21, 2024
1ba4d10
changing files
sdt4936 Jan 22, 2024
7ba3154
formatting changes
sdt4936 Jan 22, 2024
48d58ba
adding explanation
sdt4936 Jan 22, 2024
4f6d838
ADDING BRAIN KERNIGHAN ALGORITHM
sdt4936 Jan 23, 2024
70107df
kmp mismatch fixed
sdt4936 Jan 23, 2024
6f77c33
adding comments
sdt4936 Jan 23, 2024
f1bcd93
manacher
sdt4936 Jan 23, 2024
4ecea07
adding comments
sdt4936 Jan 23, 2024
ee06dcc
correcting tarjans algo
sdt4936 Jan 23, 2024
003bd5b
easing manacher
sdt4936 Jan 23, 2024
b085329
Adding binary lifting
sdt4936 Jan 23, 2024
1d71ef8
adding comments
sdt4936 Jan 23, 2024
58a4200
adding 2 useful formulas
sdt4936 Jan 24, 2024
15a8967
Adding z algorithm and prefix hash
sdt4936 Feb 4, 2024
500a880
advanced
sdt4936 Feb 5, 2024
f528c7c
Making fixes
sdt4936 Feb 21, 2024
2b04767
adding readability
sdt4936 Feb 21, 2024
c91014c
fixing
sdt4936 Feb 21, 2024
799df28
adding sieve easy
sdt4936 Feb 23, 2024
1350c82
fermat's little theorem
sdt4936 Feb 23, 2024
7443007
adding comparator functions
sdt4936 Mar 3, 2024
2b18a7f
changing names for proper finding
sdt4936 Apr 5, 2024
d21f187
Some tough practice
sdt4936 May 3, 2024
e285fb3
making code readable
sdt4936 May 3, 2024
e33edaa
correcting mistakes
sdt4936 May 3, 2024
d9c6b03
formatting
sdt4936 May 3, 2024
d924fc4
import fix
sdt4936 May 3, 2024
63f0315
improvement on dijkstra's
sdt4936 May 3, 2024
789d9bd
new segment trees
sdt4936 May 6, 2024
780b919
adding some more stuff + sorts
sdt4936 May 7, 2024
959d48d
fixing binary lifting
sdt4936 May 14, 2024
b262c6e
adding docs
sdt4936 May 14, 2024
f85ff5e
better naming
sdt4936 May 29, 2024
964e197
adding more comments
sdt4936 May 29, 2024
d6ddfe4
adding comments for more understanding
sdt4936 May 29, 2024
2f47355
more docs
sdt4936 May 29, 2024
b2c5a17
adding documentation
sdt4936 May 31, 2024
e132b41
trie adding word for more operations
sdt4936 Jun 7, 2024
06385e8
quick dsu
sdt4936 Jun 30, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,5 @@ build/
pythonenv3.8/
.vscode/
# Ignoring the virtual Environment when using GitHub Codespaces
.venv/
.venv/
.DS_Store
2 changes: 1 addition & 1 deletion algorithms/backtrack/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from .add_operators import *
from .anagram import *
from ..strings.anagram import *
from .array_sum_combinations import *
from .combination_sum import *
from .factor_combinations import *
Expand Down
32 changes: 32 additions & 0 deletions algorithms/graph/topological_sorting.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
def findOrder(self, numCourses, prerequisites):
def topologicalsort(g):
indegrees = {node : 0 for node in g}

for node in g:
for neighbor in g[node]:
indegrees[neighbor] += 1

q = []
for node in g:
if indegrees[node] == 0:
q.append(node)

order = []
while q:
node = q.pop()
order.append(node)
for neighbor in g[node]:
indegrees[neighbor] -= 1
if indegrees[neighbor] == 0:
q.append(neighbor)

return order

g = {i : [] for i in range(numCourses)}
for p in prerequisites:
src,dest = p
g[src].append(dest)

order = topologicalsort(g)

return reversed(order) if len(order) == numCourses else []
57 changes: 12 additions & 45 deletions algorithms/heap/binary_heap.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
r"""
"""
Binary Heap. A min heap is a complete binary tree where each node is smaller than
its children. The root, therefore, is the minimum element in the tree. The min
heap uses an array to represent the data and operation. For example a min heap:
Expand Down Expand Up @@ -29,39 +29,7 @@
55 90 87 55 90 55 90

"""
from abc import ABCMeta, abstractmethod


class AbstractHeap(metaclass=ABCMeta):
"""Abstract Class for Binary Heap."""

def __init__(self):
"""Pass."""

@abstractmethod
def perc_up(self, i):
"""Pass."""

@abstractmethod
def insert(self, val):
"""Pass."""

@abstractmethod
def perc_down(self, i):
"""Pass."""

@abstractmethod
def min_child(self, i):
"""Pass."""

@abstractmethod
def remove_min(self):
"""Pass."""


class BinaryHeap(AbstractHeap):
"""Binary Heap Class"""

class BinaryHeap():
def __init__(self):
self.current_size = 0
self.heap = [(0)]
Expand All @@ -73,23 +41,22 @@ def perc_up(self, i):
self.heap[i], self.heap[i//2] = self.heap[i//2], self.heap[i]
i = i // 2

def insert(self, val):
"""
"""
Method insert always start by inserting the element at the bottom.
It inserts rightmost spot so as to maintain the complete tree property.
Then, it fixes the tree by swapping the new element with its parent,
until it finds an appropriate spot for the element. It essentially
perc_up the minimum element
Complexity: O(logN)
"""
"""
def insert(self, val):
self.heap.append(val)
self.current_size = self.current_size + 1
self.perc_up(self.current_size)

"""
Method min_child returns the index of smaller of 2 children of parent at index i
"""

"""
Method min_child returns the index of smaller of 2 children of parent at index i
"""
def min_child(self, i):
if 2 * i + 1 > self.current_size: # No right child
return 2 * i
Expand All @@ -98,25 +65,25 @@ def min_child(self, i):
return 2 * i

def perc_down(self, i):
while 2 * i < self.current_size:
while 2 * i <= self.current_size:
min_child = self.min_child(i)
if self.heap[min_child] < self.heap[i]:
# Swap min child with parent
self.heap[min_child], self.heap[i] = self.heap[i], self.heap[min_child]
i = min_child

"""
Remove Min method removes the minimum element and swap it with the last
element in the heap( the bottommost, rightmost element). Then, it
perc_down this element, swapping it with one of its children until the
min heap property is restored
Complexity: O(logN)
"""

def remove_min(self):
ret = self.heap[1] # the smallest value at beginning
popped = self.heap[1] # the smallest value at beginning
# Replace it by the last value
self.heap[1] = self.heap[self.current_size]
self.current_size = self.current_size - 1
self.heap.pop()
self.perc_down(1)
return ret
return popped
52 changes: 52 additions & 0 deletions algorithms/linkedlist/DoublyLinkedList.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
class DoublyLinkedListNode(object):
def __init__(self, value):
self.value = value
self.next = None
self.prev = None

class Doubly():
def _add_node(self, node):
"""
Always add the new node right after head.
"""
node.prev = self.head
node.next = self.head.next

self.head.next.prev = node
self.head.next = node

def _remove_node(self, node):
"""
Remove an existing node from the linked list.
"""
prev = node.prev
new = node.next

prev.next = new
new.prev = prev

def _move_to_head(self, node):
"""
Move certain node in between to the head.
"""
self._remove_node(node)
self._add_node(node)

def _pop_tail(self):
"""
Pop the current tail.
"""
res = self.tail.prev
self._remove_node(res)
return res

def __init__(self, capacity):
"""
:type capacity: int
"""
self.size = 0
self.capacity = capacity
self.head, self.tail = DoublyLinkedListNode(), DoublyLinkedListNode()

self.head.next = self.tail
self.tail.prev = self.head
21 changes: 21 additions & 0 deletions algorithms/maths/find_prime_factors.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Gives the shortest prime factor for a number
# Assign N the biggest num and then call getPrimeFactorization for each num
import math
N = 1000001
spf = [-1] * N
def shortesPrimeFactorForEachNum():
global spf
for i in range(4, N, 1):
spf[i] = 2
for i in range(3, math.ceil(N ** 0.5)):
if spf[i] == -1:
for j in range(i ** 2, N, i):
if spf[j] == -1:
spf[j] = i
shortesPrimeFactorForEachNum()
def getPrimeFactorization(x):
ret = list()
while (x != 1):
ret.append(spf[x])
x = x // spf[x]
return ret
38 changes: 38 additions & 0 deletions algorithms/maths/prime_factorization.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
from math import *
N = 10000001
# stores smallest prime factor for
# every number
spf = [0 for i in range(N)]
# Calculating SPF (Smallest Prime Factor)
# for every number till N.
# Time Complexity : O(nloglogn)
def sieve():
spf[1] = 1
for i in range(2, N):
# marking smallest prime factor
# for every number to be itself.
spf[i] = i
# separately marking spf for
# every even number as 2
for i in range(4, N, 2):
spf[i] = 2
for i in range(3, ceil(N ** 0.5)):
# checking if i is prime
if (spf[i] == i):
# marking SPF for all numbers
# divisible by i
for j in range(i * i, N, i):
# marking spf[j] if it is
# not previously marked
if (spf[j] == j):
spf[j] = i
# A O(log n) function returning prime
# factorization by dividing by smallest
# prime factor at every step
def getPrimeFactorization(x):
ret = list()
while (x != 1):
ret.append(spf[x])
x = x // spf[x]
return ret
sieve()
22 changes: 22 additions & 0 deletions algorithms/maths/prime_factorization_10^9.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
''' Uses the Idea that all prime numbers are odd and for numbers like 9 we can just
start from 3 and continously divide to eliminate 9 '''

import math
def primeFactors(n):
res = []
# Print the number of two's that divide n
while n & 1 ^ 1:
res.append(2)
n >>= 1
# n must be odd at this point
# so a skip of 2 ( i = i + 2) can be used
for i in range(3, int(math.sqrt(n)) + 1, 2):
# while i divides n , print i and divide n
while n % i == 0:
res.append(i)
n //= i
# Condition if n is a prime
# number greater than 2
if n > 2:
res.append(n)
return res
9 changes: 4 additions & 5 deletions algorithms/maths/primes_sieve_of_eratosthenes.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,13 @@ def get_primes(n):
if n <= 0:
raise ValueError("'n' must be a positive integer.")
# If x is even, exclude x from list (-1):
sieve_size = (n // 2 - 1) if n % 2 == 0 else (n // 2)
sieve_size = (n >> 1) if n & 1 else ((n >> 1) - 1)
sieve = [True for _ in range(sieve_size)] # Sieve
primes = [] # List of Primes
if n >= 2:
primes.append(2) # 2 is prime by default
primes = []
if n >= 2: primes.append(2) # 2 is prime by default
for i in range(sieve_size):
if sieve[i]:
value_at_i = i*2 + 3
value_at_i = i << 1 + 3
primes.append(value_at_i)
for j in range(i, sieve_size, value_at_i):
sieve[j] = False
Expand Down
36 changes: 36 additions & 0 deletions algorithms/shivsQuickBucket/2dDP_Space_optimization.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
from functools import cache

# 2D DP
class Solution:
def maxProfit(self, prices, fee: int) -> int:
@cache
def recursion(prev, curri):
if not curri < len(prices): return 0

profit = 0
if not prev:
profit = max(recursion(prev, curri + 1), recursion(prices[curri], curri + 1))
elif prices[curri] > prev:
profit = max((prices[curri] - prev - fee) + recursion(0, curri + 1), recursion(prev, curri + 1))
else:
profit = recursion(prev, curri + 1)
return profit
return recursion(0, 0)

# Converted to 2D DP space optimized
class Solution:
def maxProfit(self, prices, fee: int) -> int:
@cache
def recursion(curri, b):
if curri == len(prices): return 0

if b:
buy = recursion(curri + 1, 0) - prices[curri] - fee
notBuy = recursion(curri + 1, 1)
return max(buy, notBuy)

sell = recursion(curri + 1, 1) + prices[curri]
notSell = recursion(curri + 1, 0)
return max(sell, notSell)

return recursion(0, 1)
Loading