Skip to content
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
Empty file added .Rhistory
Empty file.
39 changes: 34 additions & 5 deletions Exercise_1.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,49 @@

# It returns location of x in given array arr
# if present, else returns -1

# Time Complexity : O(log n)
# - In each recursive call, the search space is reduced by half.
# Space Complexity : O(log n)
# - Due to recursion stack. Each recursive call adds a frame to the stack.
# Did this code successfully run on Leetcode : NA
# Any problem you faced while coding this : NA

def binarySearch(arr, l, r, x):

#write your code here


# low and high represent the current portion of the array we are looking at
low = l
high = r

# if the current search space is valid
if low <= high:
# find the middle element
mid = low + (high - low) // 2

# if the middle element is what we are looking for, return its index
if arr[mid] == x:
return mid

# if x is bigger than the middle, search in the right half
if arr[mid] < x:
return binarySearch(arr, mid + 1, high, x)

# if x is smaller than the middle, search in the left half
if arr[mid] > x:
return binarySearch(arr, low, mid - 1, x)
else:
# if we reach here, the element is not in the array
return -1

# Test array
arr = [ 2, 3, 4, 10, 40 ]
x = 10
x = 2

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

if result != -1:
print "Element is present at index % d" % result
print ("Element is present at index % d" % result )
else:
print "Element is not present in array"
print( "Element is not present in array")
49 changes: 38 additions & 11 deletions Exercise_2.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,43 @@
# 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
# Time Complexity : O(n log n)
# Space Complexity : O(log n) due to recursion stack
# Did this code successfully run on Leetcode : NA
# Any problem you faced while coding this : NA

def partition(arr, low, high):
"""
This function takes the last element as pivot,
places the pivot at its correct position in sorted array,
and puts smaller elements before it and larger after it.
"""
i = low - 1 # index of smaller element
pivot = arr[high] # choose the last element as pivot

# go through all elements and swap if smaller than pivot
for j in range(low, high):
if arr[j] < pivot:
i += 1
arr[i], arr[j] = arr[j], arr[i] # swap

# put pivot in the correct position
arr[i + 1], arr[high] = arr[high], arr[i + 1]
return i + 1

def quickSort(arr, low, high):
"""
Main Quick Sort function that recursively sorts elements before and after partition
"""
if low < high:
# partition the array and get pivot index
pi = partition(arr, low, high)

# recursively sort the left part
quickSort(arr, low, pi - 1)

# recursively sort the right part
quickSort(arr, pi + 1, high)


# Driver code to test above
arr = [10, 7, 8, 9, 1, 5]
Expand Down
43 changes: 34 additions & 9 deletions Exercise_3.py
Original file line number Diff line number Diff line change
@@ -1,26 +1,51 @@
# Node class

# Time Complexity : O(n) because we traverse the list once
# Space Complexity : O(1) because we only use two pointers
# Did this code successfully run on Leetcode : NA
# Any problem you faced while coding this : NA

# Node class for linked list
class Node:

# Function to initialise the node object
# Initialize a node with data and next pointer
def __init__(self, data):
self.data = data
self.next = None

# Linked List class
class LinkedList:

def __init__(self):


self.top = None # head of the list

# Add a new element to the end of the list
def push(self, new_data):
temp = Node(new_data)
if self.top is None: # if list is empty
self.top = temp
else:
curr = self.top
while curr.next: # go to the last node
curr = curr.next
curr.next = temp # attach new node at the end


# Function to get the middle of
# the linked list
# Function to get the middle of the linked list
def printMiddle(self):
slow = self.top # moves one step at a time
fast = self.top # moves two steps at a time

# traverse the list
while fast is not None and fast.next is not None:
fast = fast.next.next # move fast pointer twice
slow = slow.next # move slow pointer once

# when fast reaches end, slow is at the middle

print( slow.data)
# Driver code
list1 = LinkedList()
list1.push(5)
list1.push(4)
list1.push(2)
list1.push(3)
list1.push(1)

list1.printMiddle()
65 changes: 61 additions & 4 deletions Exercise_4.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,69 @@
# Python program for implementation of MergeSort
# This is a simple Merge Sort implementation
# Time Complexity : O(n log n)
# Space Complexity : O(n) due to temp arrays used for merging
# Did this code successfully run on Leetcode : NA
# Any problem you faced while coding this : NA

def mergeSort(arr):

#write your code here
# left and right define the current part of the array we are sorting
left = 0
right = len(arr) - 1

# Only sort if there is more than one element
if left < right:
mid = (left + right) // 2 # find the middle index

# Recursively sort the left half and right half
l1 = mergeSort(arr[left:mid])
l2 = mergeSort(arr[mid + 1:right])

# lengths of left and right halves
n1 = mid - left + 1
n2 = right - mid

# Create temporary arrays to hold the split parts
L = [0] * n1
R = [0] * n2

# Copy data into temp arrays
for i in range(n1):
L[i] = arr[left + i]
for j in range(n2):
R[j] = arr[mid + 1 + j]

# Merge the temp arrays back into arr
i = j = 0
k = left
while i < n1 and j < n2:
if L[i] <= R[j]:
arr[k] = L[i]
i += 1
else:
arr[k] = R[j]
j += 1
k += 1

# Copy any remaining elements of L[]
while i < n1:
arr[k] = L[i]
i += 1
k += 1

# Copy any remaining elements of R[]
while j < n2:
arr[k] = R[j]
j += 1
k += 1

return arr # return the sorted array



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

#write your code here


# driver code to test the above code
if __name__ == '__main__':
Expand Down
66 changes: 63 additions & 3 deletions Exercise_5.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,70 @@
# Python program for implementation of Quicksort

# This function is same in both iterative and recursive

# Time Complexity : O(n log n)
# Space Complexity: O(n) due to the explicit stack used
# Did this code successfully run on Leetcode: NA
# Any problem you faced while coding this: NA

# Partition function (same as recursive Quick Sort)
def partition(arr, l, h):
#write your code here
# i tracks the position for elements smaller than pivot
i = l - 1
pivot = arr[h] # pick the last element as pivot

# move all smaller elements to the left of pivot
for j in range(l, h):
if arr[j] < pivot:
i += 1
arr[i], arr[j] = arr[j], arr[i] # swap

# put pivot in its correct position
arr[i + 1], arr[h] = arr[h], arr[i + 1]
return i + 1

# Main iterative Quick Sort function
def quickSortIterative(arr, l, h):
#write your code here
# create a stack to simulate recursion
size = h - l + 1
stack = [0] * size

top = -1 # initialize stack top

# push initial low and high indices
top += 1
stack[top] = l
top += 1
stack[top] = h

# keep processing while stack is not empty
while top >= 0:
# pop high and low from stack
h = stack[top]
top -= 1
l = stack[top]
top -= 1

# partition the current sub-array
p = partition(arr, l, h)

# if left part exists, push it to stack
if p - 1 > l:
top += 1
stack[top] = l
top += 1
stack[top] = p - 1

# if right part exists, push it to stack
if p + 1 < h:
top += 1
stack[top] = p + 1
top += 1
stack[top] = h

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]),