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

Done with precourse 2 #1653

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
Binary file added .DS_Store
Binary file not shown.
53 changes: 32 additions & 21 deletions Exercise_1.py
Original file line number Diff line number Diff line change
@@ -1,22 +1,33 @@
# Python code to implement iterative Binary
# Search.

# It returns location of x in given array arr
# if present, else returns -1
def binarySearch(arr, l, r, x):

#write your code here



# Test array
arr = [ 2, 3, 4, 10, 40 ]
# Python code to implement iterative Binary Search.
# It returns location of x in given array arr
# if present, else returns -1


# Time Complexity: O(log n) bcz serach space is halved with each step
# Space Complexity: O(1) as there is no additional DS getting used which grows with the input size
def binarySearch(arr, l, r, x):

# write your code here
while l <= r:
mid = (l + r) // 2

if arr[mid] == x: # check if x is at the mid index
return mid
elif arr[mid] > x: # if x is smaller then search on the left side
r = mid - 1
else: # if x is larger then search on the right side
l = mid + 1
return -1 # if x is not in the array


# Test array
arr = [2, 3, 4, 10, 40]
x = 10
# Function call
result = binarySearch(arr, 0, len(arr)-1, x)
if result != -1:
print "Element is present at index % d" % result
else:
print "Element is not present in array"

# Function call
result = binarySearch(arr, 0, len(arr) - 1, x)

if result != -1:
print(f"Element is present at index {result}")
else:
print("Element is not present in array")
73 changes: 51 additions & 22 deletions Exercise_2.py
Original file line number Diff line number Diff line change
@@ -1,23 +1,52 @@
# Python program for implementation of Quicksort Sort

# Python program for implementation of Quicksort Sort


# give you explanation for the approach
def partition(arr,low,high):


#write your code here


# Function to do Quick sort
def quickSort(arr,low,high):

#write your code here

# Driver code to test above
arr = [10, 7, 8, 9, 1, 5]
n = len(arr)
quickSort(arr,0,n-1)
print ("Sorted array is:")
for i in range(n):
print ("%d" %arr[i]),


# Divide-and-conquer sorting algorithm that recursively partitions the array using a pivot and sorts the sub-arrays

# Time complexity:
# 1) best/aveg case: O(nlog n) because partitioning at all the levels due to recursion
# 2) worst case: O(n^2) when pivot is either smallest or the largest element

# space complexity:
# 1) best case: O(log n): recursion stack size
# 2) worst case: O(n) : when recursion stack goes as deep as n


def partition(arr, low, high):
# write your code here
pivot = arr[low] # choosing pivot as the first element of an array
i = low # Moves from left to right, looking for elements greater than pivot
j = high # Moves from right to left. looking for elements smaller than pivot

while i < j:
while arr[i] <= pivot and i <= high - 1:
i += 1 # incrementing i untill current element is less than or equals to pivot
while arr[j] > pivot and j >= low + 1:
j -= 1 # decrementing j untill current element is greater than pivot
if i < j:
arr[i], arr[j] = arr[j], arr[i] # swap elements at i and j
arr[low], arr[j] = (
arr[j],
arr[low],
) # swap pivot with j that makes pivot at the right place and all the elements on the right side will be greater than j and left side smaller
return j # Return the pivot index


# Function to do Quick sort
def quickSort(arr, low, high):

# write your code here
if low < high:
p_index = partition(arr, low, high) # get the pivot index
quickSort(arr, low, p_index - 1) # left side of the arrray
quickSort(arr, p_index + 1, high) # right side array


# Driver code to test above
arr = [10, 7, 8, 9, 1, 5]
n = len(arr)
quickSort(arr, 0, n - 1)
print("Sorted array is:")
for i in range(n):
print("%d" % arr[i]),
71 changes: 45 additions & 26 deletions Exercise_3.py
Original file line number Diff line number Diff line change
@@ -1,26 +1,45 @@
# Node class
class Node:

# Function to initialise the node object
def __init__(self, data):

class LinkedList:

def __init__(self):


def push(self, new_data):


# Function to get the middle of
# the linked list
def printMiddle(self):

# Driver code
list1 = LinkedList()
list1.push(5)
list1.push(4)
list1.push(2)
list1.push(3)
list1.push(1)
list1.printMiddle()
# Finding middle element of the LL using Tortoise hare method
# Time complexity: O(n) iterating through whole array with both pointers
# space complexity: O(1) only two pointer are getting used that can be neglacted so constant space
# Node class
class Node:

# Function to initialise the node object
def __init__(self, data, next=None):
self.data = data
self.next = None


class LinkedList:

def __init__(self):
self.head = None

# insert new node/data at the beginning/ Head insertion
def push(self, new_data):
newNode = Node(new_data)
newNode.next = self.head
self.head = newNode

# Function to get the middle of
# the linked list
# using tortoise-hare method
def printMiddle(self):
# both pointers starts from the head
slow = self.head
fast = self.head
if self.head:
while fast and fast.next:
slow = slow.next # slow moves one step
fast = fast.next.next # fast moves two steps
print("The middle element is:", slow.data)


# Driver code
list1 = LinkedList()
list1.push(5)
list1.push(4)
list1.push(2)
list1.push(3)
list1.push(1)
list1.printMiddle()
76 changes: 59 additions & 17 deletions Exercise_4.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,60 @@
# Python program for implementation of MergeSort
# Python program for implementation of MergeSort
# Divide-and-conquear algorithm in which array gets splitted recursively
# until left with one element and then gets merged back in sorted array

# Time complexity: O(nlog n) as array is splitting in two halves and each half is processed seperately
# Space Complexity: O(n) as temp arrays are getting used


def mergeSort(arr):

#write your code here

# Code to print the list
def printList(arr):

#write your code here

# driver code to test the above code
if __name__ == '__main__':
arr = [12, 11, 13, 5, 6, 7]
print ("Given array is", end="\n")
printList(arr)
mergeSort(arr)
print("Sorted array is: ", end="\n")
printList(arr)

# write your code here
if len(arr) > 1: # if only one element, already sorted
mid = len(arr) // 2 # get the mid

leftHalf = arr[:mid] # left subarray
rightHalf = arr[mid:] # right subarray

# recursion to split both the sides
mergeSort(leftHalf)
mergeSort(rightHalf)

# merge back together in sorted manner
i = j = k = 0
while i < len(leftHalf) and j < len(rightHalf):
if leftHalf[i] < rightHalf[j]:
arr[k] = leftHalf[i]
i += 1
else:
arr[k] = rightHalf[j]
j += 1
k += 1

# if element left in leftHalf
while i < len(leftHalf):
arr[k] = leftHalf[i]
i += 1
k += 1
# if any element left in right Half
while j < len(rightHalf):
arr[k] = rightHalf[j]
j += 1
k += 1


# Code to print the list
def printList(arr):

# write your code here
for i in arr:
print(i, end="\n")


# driver code to test the above code
if __name__ == "__main__":
arr = [12, 11, 13, 5, 6, 7]
print("Given array is", end="\n")
printList(arr)
mergeSort(arr)
print("Sorted array is: ", end="\n")
printList(arr)
51 changes: 47 additions & 4 deletions Exercise_5.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,53 @@
# Python program for implementation of Quicksort

# Time complexity:
# 1) best/aveg case: O(nlog n) because array will be divided into equaly roghly same size subarrays and stack will process them iteratively
# 2) worst case: O(n^2) when pivot is either smallest or the largest element

# space complexity:
# 1) best case: O(log n): stack size/depth
# 2) worst case: O(n) : when stack depth is linear


# This function is same in both iterative and recursive
def partition(arr, l, h):
#write your code here
# just for the partition
def partition(arr, low, high):
# write your code here
pivot = arr[low] # choosing pivot as the first element of an array
i = low # Moves from left to right, looking for elements greater than pivot
j = high # Moves from right to left. looking for elements smaller than pivot

while i < j:
while arr[i] <= pivot and i <= high - 1:
i += 1 # incrementing i untill current element is less than or equals to pivot
while arr[j] > pivot and j >= low + 1:
j -= 1 # decrementing j untill current element is greater than pivot
if i < j:
arr[i], arr[j] = arr[j], arr[i] # swap elements at i and j
arr[low], arr[j] = (
arr[j],
arr[low],
) # swap pivot with j that makes pivot at the right place and all the elements on the right side will be greater than j and left side smaller
return j # Return the pivot index


def quickSortIterative(arr, low, high):
# write your code here
# using stack to store sub array indices and to process them iteratively, with same partitioning logic used in recursive approach
stack = []
stack.append((low, high)) # push the initial low,high values onto stack
while stack:
low, high = stack.pop() # pop the topmost elements for indices
p_index = partition(arr, low, high) # find pivot and do partitioning
if p_index - 1 > low:
stack.append((low, p_index - 1)) # push left subarray into stack
if p_index + 1 < high:
stack.append((p_index + 1, high)) # push right subarray into stack

def quickSortIterative(arr, l, h):
#write your code here

arr = [10, 7, 8, 9, 1, 5]
n = len(arr)
quickSortIterative(arr, 0, n - 1)
print("Sorted array is:")
for i in range(n):
print("%d" % arr[i]),