Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 57

Ques1: Given an array of nonnegative integers, design a linear algorithm and

implement it using a program to find whether given key element is present in the
array or not. Also, find total number of comparisons for each input case.

# Code

for _ in range(int(input())):
n = int(input().strip())
arr = list(map(int, input().strip().split()))
key = int(input().strip())
cmps = 0

for ele in arr:


cmps += 1
if ele == key:
print(f"Present {comps}")
break
else:
print(f"Not Present {cmps}")
Ques2: Given an already sorted array of positive integers, design an algorithm and
implement it using a program to find whether given key element is present in the
array or not. Also, find total number of comparisons for each input case. (Time
Complexity = O(nlogn), where n is the size of input).

# Code

def binary_search(arr, key):


l, r = 0, len(arr)-1
comps = 0

while l <= r:
mid = (l + r) // 2

if arr[mid] == key:
comps += 1
return f"Present {comps}"

if arr[mid] < key:


comps += 2
l = mid + 1
else:
r = mid - 1

return f"Not Present {comps}"

for _ in range(int(input().strip())):
n = int(input().strip())
arr = list(map(int, input().strip().split()))
key = int(input().strip())

res = binary_search(arr, key)


print(res)
Ques3: Given an already sorted array of positive integers, design an algorithm and
implement it using a program to find whether a given key element is present in the
sorted array or not. For an array arr[n], search at the indexes arr[0], arr[2],
k k k+1
arr[4],. ,arr[2 ] and so on. Once the interval (arr[2 ] < key < arr[ 2 ] ) is found,
k
perform a linear search operation from the index 2 to find the element key.
(Complexity < O(n), where n is the number of elements need to be scanned for
searching)

# Code

def jump_search(arr, key):


n = len(arr)
prev, start = 0, int(n**0.5)
cmps = 0
arr.sort()

while start < n and arr[start] < key:


cmps += 1
prev, start = start, start + int(n**0.5)

if prev >= n:
return f"Not Present {cmps}"

for i in range(prev, min(start+1, n)):


cmps += 1
if arr[i] == key:
return f"Present {cmps}"

return f"Not Present {cmps}"

for _ in range(int(input().strip())):
n = int(input().strip())
arr = list(map(int, input().strip().split()))
key = int(input().strip())

res = jump_search(arr, key)


print(res)
Ques4: Given a sorted array of positive integers containing few duplicate elements,
design an algorithm and implement it using a program to find whether the given key
element is present in the array or not. If present, then also find the number of copies
of given key. (Time Complexity = O(log n))

# Code

def find_copies(arr, key):


n = len(arr)
l, r = 0, n-1
is_present = False
left_most = right_most = 0

while l <= r:
mid = (l + r) // 2

if arr[mid] == key:
is_present = True
left_most = mid
r = mid - 1

elif arr[mid] < key:


l = mid + 1
else:
r = mid - 1

l, r = 0, n-1
while l <= r:
mid = (l + r) // 2

if arr[mid] == key:
is_present = True
right_most = mid
l = mid + 1

elif arr[mid] < key:


l = mid + 1
else:
r = mid - 1

if is_present:
return f"{key} - {(right_most - left_most) + 1}"

return f"Not Present"

for _ in range(int(input().strip())):
n = int(input().strip())
arr = list(map(int, input().strip().split()))
key = int(input().strip())

res = find_copies(arr, key)


print(res)
Ques5: Given a sorted array of positive integers, design an algorithm and
implement it using a program to find three indices i, j, k such that arr[i] + arr[j] =
arr[k].

# Code

for _ in range(int(input())):
n = int(input().strip())
arr = list(map(int, input().strip().split()))
found = False

for i in range(n):
target = arr[i]

l, r = 0, n-1
while l < r:
if arr[l] + arr[r] == target and i not in (l, r):
print(l, r, i)
found = True
break
if arr[l] + arr[r] < target:
l += 1
else:
r -= 1
if not found:
print("No sequence found")
Ques6: Given an array of non-negative integers, design an algorithm and a program
to count the number of pairs of integers such that their difference is equal to a given
key, K.

# Code

for _ in range(int(input())):
n = int(input().strip())
arr = list(map(int, input().strip().split()))
key = int(input().strip())
arr.sort()

l=r=0
cnt = 0
while r < n:
if arr[r] - arr[l] == key:
cnt += 1
l += 1
r += 1
elif arr[r] - arr[l] < key:
r += 1
else:
l += 1

print(cnt)
Ques7: Given an unsorted array of integers, design an algorithm and a program to
sort the array using insertion sort. Your program should be able to find number of
comparisons and shifts ( shifts - total number of times the array elements are
shifted from their place) required for sorting the array.

# Code

def insertion_sort(arr, n):


cmps = shifts = 0

for i in range(1, n):


j=i-1
key = arr[i]

while j >= 0 and arr[j] > key:


arr[j+1] = arr[j]
j -= 1
shifts += 1
cmps += 1

arr[j+1] = key
shifts += 1

return cmps, shifts

for _ in range(int(input())):
n = int(input().strip())
arr = list(map(int, input().strip().split()))

shifts, cmps = insertion_sort(arr, n)


print()
print(*arr)
print(f"Shifts: {shifts} Comparisions: {cmps}")
Ques8: Given an unsorted array of integers, design an algorithm and implement a
program to sort this array using selection sort. Your program should also find
number of comparisons and number of swaps required.

# Code

def selection_sort(arr, n):


cmps = swaps = 0

for i in range(n-1):
min_ = i
for j in range(i+1, n):
if arr[j] < arr[min_]:
j = min_
cmps += 1

arr[i], arr[min_] = arr[min_], arr[i]


swaps += 1

return cmps, swaps

for _ in range(int(input())):
n = int(input().strip())
arr = list(map(int, input().strip().split()))

cmps, swaps = selection_sort(arr, n)


print(*arr)
print(f"Comparisions: {cmps}, Swaps: {swaps}")
Ques9: Given an unsorted array of positive integers, design an algorithm and
implement it using a program to find whether there are any duplicate elements in
the array or not. (use sorting) (Time Complexity = O(n log n))

# Code

for _ in range(int(input())):
n = int(input().strip())
arr = list(map(int, input().strip().split()))
arr.sort()

for i in range(1, n):


if arr[i] == arr[i-1]:
print("YES")
break
else:
print("NO")
Ques10: Given an unsorted array of integers, design an algorithm and implement it
using a program to sort an array of elements by dividing the array into two
subarrays and combining these subarrays after sorting each one of them. Your
program should also find number of comparisons and inversions during sorting the
array.

# Code

def cnt_inversions(arr, n):


return sum(arr[i] > arr[j] for i in range(n-1) for j in range(i+1, n))

def merge_arrays(arr1, arr2, cmps):


res = []
i=j=0

while i < len(arr1) and j < len(arr2):


if arr1[i] <= arr2[j]:
res.append(arr1[i])
i += 1
else:
res.append(arr2[j])
j += 1

cmps[0] += 1

return res + arr1[i:] + arr2[j:]

def merge_sort(arr, cmps):


if not arr or len(arr) == 1:
return arr

mid = len(arr) // 2
left_part = arr[:mid]
right_part = arr[mid:]

left_sorted, right_sorted = merge_sort(left_part, cmps), merge_sort(right_part, cmps)


res = merge_arrays(left_sorted, right_sorted, cmps)

return res
for _ in range(int(input())):
n = int(input().strip())
arr = list(map(int, input().strip().split()))

cmps = [0]
inversions = cnt_inversions(arr, n)
res = merge_sort(arr, cmps)

print(*res)
print(f"Comparisions: {cmps[0]}, Inversions: {inversions}”)
Ques11: Given an unsorted array of integers, design an algorithm and implement it
using a program to sort an array of elements by partitioning the array into two
subarrays based on a pivot element such that one of the sub array holds values
smaller than the pivot element while another sub array holds values greater than the
pivot element. Pivot element should be selected randomly from the array. Your
program should also find number of comparisons and swaps required for sorting
the array.

# Code

def partition(arr, start, end, cmps, swaps):


# Chose last element to be the pivot
low, high = 0, end - 1

while low <= high:


if arr[low] <= arr[end]:
low += 1
cmps[0] += 1
elif arr[high] > arr[end]:
high -= 1
cmps[0] += 2
else:
arr[low], arr[high] = arr[high], arr[low]
swaps[0] += 1

if arr[low] >= arr[end]:


arr[low], arr[end] = arr[end], arr[low]
cmps[0] += 1
swaps[0] += 1
return low

return end

def quick_sort(arr, start, end, cmps, swaps):


if start < end:
pivot = partition(arr, start, end, cmps, swaps)
quick_sort(arr, pivot + 1, end, cmps, swaps)
quick_sort(arr, start, pivot - 1, cmps, swaps)

return arr
for _ in range(int(input())):
n = int(input().strip())
arr = list(map(int, input().strip().split()))

cmps, swaps = [0], [0]


quick_sort(arr, 0, n-1, cmps, swaps)
print(*arr)
print(f"Comparisions: {cmps[0]}, Swaps: {swaps[0]}”)
Ques12: Given an unsorted array of integers, design algorithm and implement it
using a program to an find Kth smallest or largest element in the array.(Worst case
Time Complexity = O(n))

# Code

def quick_select(arr, start, end):


def pivot():
low, high = 0, end - 1

while low <= high:


if arr[low] <= arr[end]:
low += 1
elif arr[high] > arr[end]:
high -= 1
else:
arr[low], arr[high] = arr[high], arr[low]

if arr[low] >= arr[end]:


arr[low], arr[end] = arr[end], arr[low]
return low
return end

p = pivot()
if p > k: return quick_select(arr, start, p-
1) if p < k: return quick_select(arr, p+1,
end) return arr[p]

for _ in range(int(input())):
n = int(input().strip())
arr = list(map(int, input().strip().split()))
k = int(input().strip()) - 1

kth_smallest = quick_select(arr, 0, len(arr)-1)


print(kth_smallest)
Ques13: Given an unsorted array of alphabets containing duplicate elements.
Design an algorithm and implement it using a program to find which alphabet has
maximum number of occurrences and print it.

# Code

for _ in range(int(input())):
n = int(input().strip())
arr = input().strip().split()

freq = {}
for c in arr:
freq[c] = freq.get(c, 0) + 1

max_freq, res = 0, None


for k, v in freq.items():
if max_freq < v:
max_freq = v
res = k

if max_freq < 2:
print("No duplicates present")
else:
print(f"{res} - {max_freq}")
Ques14: Given an unsorted array of integers, design an algorithm and implement it
using a program to find whether two elements exist such that their sum is equal to
the given key element. (Time Complexity = O(n log n))

# Code

for _ in range(int(input())):
n = int(input().strip())
arr = list(map(int, input().strip().split()))
key = int(input().strip())
arr.sort()

l, r = 0, n-1
while l < r:
if arr[l] + arr[r] == key:
print(arr[l], arr[r])
break

if arr[l] + arr[r] < key:


l += 1
else:
r -= 1

else:
print("No such elements exists")
Ques15: You have been given two sorted integer arrays of size m and n. Design an
algorithm and implement it using a program to find list of elements which are
common to both. (Time Complexity = O(m+n))

# Code

m = int(input())
arr1 = list(map(int, input().split()))
n = int(input())
arr2 = list(map(int, input().split()))

common = set()
for ele in arr1:
common.add(ele)

for i in range(n):
if arr2[i] in common:
print(arr2[i], end=" ")
Ques16: Given a (directed/undirected) graph, design an algorithm and implement it
using a program to find if a path exists between two given vertices or not.

# Code
# Undirected Graph Assumed

def bfs(graph, src, dst):


q = [src]
visited = set()
visited.add(src)

while q:
curr = q.pop(0)

for node in graph[curr]:


if node not in visited:
visited.add(node)
q.append(node)

return "Yes Path Exists" if len(visited) == len(graph) else "No Path Exists"

for _ in range(int(input())):
graph = {}
node = 1
for _ in range(int(input())):
edges = list(map(int, input().strip().split()))
graph[node] = [i for i in range(1, len(edges)+1) if edges[i-1]]
node += 1

src, dst = map(int, input().strip().split())


res = bfs(graph, src, dst)
print()
print(res)
Ques17: Given a graph, design an algorithm and implement it using a program to
find if a graph is bipartite or not.

# Code

def bfs(graph, src):


q = [src]
visited = [-1] * (len(graph))
visited[src-1] = 1
while q:
curr = q.pop(0)

if graph[curr][curr-1]:
return "Not Bipartite”

for i in range(len(graph[curr])):
if graph[curr][i] and visited[i] == -1:
visited[i] = 1 - visited[curr]
q.append(i)

elif visited[i] == visited[curr]:


return "Not Bipartite"

return "Yes Bipartite"

graph = {}
node = 1
for _ in range(int(input())):
edges = list(map(int, input().strip().split()))
graph[node] = edges
node += 1

res = bfs(graph, 1)
print(res)
Ques18: Given a directed graph, design an algorithm and implement it using a
program to find whether cycle exists in the graph or not.

# Code

def bfs(graph, n):


degree = [0] * n
for node in range(1, n+1):
for i in range(len(graph[node])):
if graph[node][i]:
degree[i] += 1

bfs_queue = [i for i in range(1, n+1) if not degree[i-1]]


cnt = 0

while bfs_queue:
node = bfs_queue.pop(0)
cnt += 1
for i in range(len(graph[node])):
if graph[node][i]:
degree[i] -= 1
if not degree[i]:
bfs_queue.append(i+1)

return "No cycle exists" if cnt == n else "Yes cycle exists"

graph = {}
node = 1
n = int(input())
for _ in range(n):
edges = list(map(int, input().strip().split()))
graph[node] = edges
node += 1

res = bfs(graph, n)
print(res)
Ques19: Design an algorithm and implement it using a program to solve problem
using Dijkstra’s shortest path algorithm.

# Code

import heapq

def dijkstra_algo(graph, src, dst):


heap = []
heapq.heappush(heap, (0, src))
path = []
while heap:
curr_weight, curr_node = heapq.heappop(heap)
path.append(curr_node)
if curr_node == dst:
return f"{path} : {curr_weight}"

for node, weight in graph[curr_node]:


heapq.heappush(heap, (curr_weight + weight, node))

graph = {}
node = 1
n = int(input())
for _ in range(n):
edges = list(map(int, input().strip().split()))
graph[node] = [(i, edges[i-1]) for i in range(1, n+1) if edges[i-1]]
node += 1

src = int(input())
for i in range(1, n+1):
res = dijkstra_algo(graph, src, i)
print(res)
Ques20: Design an algorithm and implement it using a program to solve problem
using Bellman-Ford shortest path algorithm.

# Code

def bellman_ford(graph, src, num_nodes):


distance = [float("inf")] * num_nodes
distance[src-1] = 0

for node1 in range(num_nodes):


for node2, w in graph[node1+1]:
if distance[node1] != float("inf") and distance[node1] + w < distance[node2-1]:
distance[node2-1] = distance[node1] + w

for node1 in range(num_nodes):


for node2, w in graph[node1+1]:
if distance[node1] != float("inf") and distance[node1] + w < distance[node2-1]:
return "Negative weight cycle detected!"

return distance

graph = {}
node = 1
n = int(input())
for _ in range(n):
edges = list(map(int, input().strip().split()))
graph[node] = [(i, edges[i-1]) for i in range(1, n+1) if edges[i-1]]
node += 1

src = int(input())
for i in range(1, n+1):
res = bellman_ford(graph, src, n)
print(f"{src} to {i} : {res[i-1]}")
Ques21: Given a directed graph with two vertices ( source and destination). Design
an algorithm and implement it using a program to find the weight of the shortest
path from source to destination with exactly k edges on the path.

# Code

def shortest_path(graph, src, dst, k, n):


if k == 0 and src == dst:
return 0
if k == 1 and graph[src][dst-1] != float("inf"):
return graph[src][dst-1]
if k <= 0:
return float("inf")

res = float("inf")
for i in range(n):
if graph[src][i] != float("inf") and src != i+1 and dst != i:
rec_res = shortest_path(graph, i+1, dst, k - 1, n)
if rec_res != float("inf"):
res = min(res, graph[src][i] + rec_res)
return res

graph = {}
node = 1
n = int(input())
for _ in range(n):
edges = list(map(int, input().strip().split()))
graph[node] = edges
node += 1

src, dst = map(int, input().strip().split())


k = int(input().strip())

res = shortest_path(graph, src, dst, k, n)


print(f"Weight of the shortest path from {src} to {dst} with {k} nodes is: {res}")
Ques22: Connect cities with minimum cost using Prim’s Algorithm

# Code

def min_node(n, keyval, mstset):


min_ = float("inf")
mini_index = None

for i in range(n):
if (mstset[i] == False and
keyval[i] < min_):
min_ = keyval[i]
mini_index = i

return mini_index

def find_cost(n, city):


parent = [None] * n
keyval = [None] * n
mstset = [None] * n

for i in range(n):
keyval[i] = float("inf")
mstset[i] = False

parent[0] = -1
keyval[0] = 0

for i in range(n - 1):

u = min_node(n, keyval, mstset)


mstset[u] = True

for v in range(n):
if (city[u+1][v] and mstset[v] == False and
city[u+1][v] < keyval[v]):
keyval[v] = city[u+1][v]
parent[v] = u
cost = 0
for i in range(1, n):
cost += city[parent[i]+1][i]

return cost

graph = {}
node = 1
n = int(input())
for _ in range(n):
edges = list(map(int, input().strip().split()))
graph[node] = edges
node += 1

res = find_cost(n, graph)


print(f"Minimum Cost:", res)
Ques23: Assume that same road construction project is given to another person.
The amount he will earn from this project is directly proportional to the budget of
the project. This person is greedy, so he decided to maximize the budget by
constructing those roads who have highest construction cost. Design an algorithm
and implement it using a program to find the maximum budget required for the
project.

# Code

def min_node(n, keyval, mstset):


max_ = float("-inf")
max_index = None

for i in range(n):
if (mstset[i] == False and
keyval[i] > max_):
max_ = keyval[i]
max_index = i

return max_index

def find_cost(n, city):


parent = [None] * n
keyval = [None] * n
mstset = [None] * n

for i in range(n):
keyval[i] = float("-inf")
mstset[i] = False

parent[0] = -1
keyval[0] = float("inf")

for i in range(n - 1):


u = min_node(n, keyval, mstset)
mstset[u] = True

for v in range(n):
if (city[v+1][u] and mstset[v] == False and
city[v+1][u] > keyval[v]):
keyval[v] = city[v+1][u]
parent[v] = u

cost = 0
for i in range(1, n):
cost += city[parent[i]+1][i]

return cost

graph = {}
node = 1
n = int(input())
for _ in range(n):
edges = list(map(int, input().strip().split()))
graph[node] = edges
node += 1

res = find_cost(n, graph)


print(f"Max Cost:", res)
Ques24: Given a graph, Design an algorithm and implement it using a program to
implement Floyd- Warshall all pair shortest path algorithm.

# Code

def floyd_warshall(graph, n):


for k in range(n):
for i in range(n):
for j in range(n):
graph[i][j] = min(graph[i][j], graph[i][k] + graph[k][j])

n = int(input())
graph = [[None] * n for _ in range(n)]

for i in range(n):
for j in range(n):
if i == j:
graph[i][j] = 0
else:
graph[i][j] = float("inf")

node = 0
for _ in range(n):
edges = list(map(int, input().strip().split()))
connections = [(node, i, edges[i]) for i in range(n)]

for node1, node2, weight in connections:


graph[node1][node2] = weight
node += 1

floyd_warshall(graph, n)
print("\nShortest Distance Matrix:")
print(*graph, sep="\n")
Ques25: Given a knapsack of maximum capacity w. N items are provided, each
having its own value and weight. You have to Design an algorithm and implement it
using a program to find the list of the selected items such that the final selected
content has weight w and has maximum value. You can take fractions of items,i.e.
the items can be broken into smaller pieces so that you have to carry
only a fraction xi of item i, where 0 ≤xi≤ 1.

# Code

def fractional_knapsack(weight, vals, capacity):


index = list(range(len(vals)))
ratio = [v/w for v, w in zip(vals, weight)]
index.sort(key=lambda i: ratio[i], reverse=True)

max_value = 0
fractions = [0] * len(vals)
for i in index:
if weight[i] <= capacity:
fractions[i] = 1
max_value += vals[i]
capacity -= weight[i]
else:
fractions[i] = round(capacity / weight[i], 2)
max_value += vals[i] * capacity / weight[i]
break

return round(max_value, 2), list(zip(vals, fractions))

for _ in range(int(input())):
weights = list(map(int, input().strip().split()))
vals = list(map(int, input().strip().split()))
capacity = int(input().strip())

max_val, fracs = fractional_knapsack(weights, vals, capacity)


print(max_val)
print(fracs)
Ques26: Given an array of elements. Assume arr[i] represents the size of file i. Write
an algorithm and a program to merge all these files into single file with minimum
computation. For given two files A and B with sizes m and n, computation cost of
merging them is O(m+n). (Hint: use greedy approach).

# Code

import heapq

def get_min_merge_cost(arr):
heapq.heapify(arr)
cost = 0
while len(arr) > 1:
v1 = heapq.heappop(arr)
v2 = heapq.heappop(arr)

cost += (v1 + v2)


heapq.heappush(arr, (v1 + v2))

return cost

for _ in range(int(input())):
arr = list(map(int, input().split()))

min_cost = get_min_merge_cost(arr)
print(min_cost)
Ques27: Given a list of activities with their starting time and finishing time. Your
goal is to select maximum number of activities that can be performed by a single
person such that selected activities must be non-conflicting. Any activity is said to
be non-conflicting if starting time of an activity is greater than or equal to the
finishing time of the other activity. Assume that a person can only work on a single
activity at a time.

# Code

n = int(input())
start = list(map(int, input().strip().split()))
end = list(map(int, input().strip().split()))

intervals = [[s, e] for s, e in zip(start, end)]


intervals = sorted(intervals, key=lambda x: x[1])

res = [intervals[0]]
i=0
for j in range(1, n):
if intervals[j][0] >= intervals[i][1]:
res.append(intervals[j])
i=j

print(len(res))
print(*res)
Ques28: Given a long list of tasks. Each task takes specific time to accomplish it
and each task has a deadline associated with it. You have to design an algorithm
and implement it using a program to find maximum number of tasks that can be
completed without crossing their deadlines and also find list of selected tasks.

# Code

n = int(input())
time = list(map(int, input().strip().split()))
deadline = list(map(int, input().strip().split()))

slots = [False] * max(deadline)


jobs = list(zip(time, deadline))

res = []
for t, d in jobs:
if not slots[d-1]:
slots[d-1] = True
res.append(t)
else:
tmp = d - 1
while tmp >= 0 and slots[tmp]:
tmp -= 1

if tmp >= 0:
slots[tmp] = True
res.append(t)

print("Max number of tasks:", len(res))


print("Tasks:", *res)
Ques29: Given an unsorted array of elements, design an algorithm and implement it
using a program to find whether majority element exists or not. Also find median of
the array. A majority element is an element that appears more than n/2 times, where
n is the size of array.

# Code

n = int(input().strip())
arr = list(map(int, input().strip().split()))
arr.sort()

candidate = arr[n // 2]
cnt = 0
for ele in arr:
if ele == candidate:
cnt += 1

print("Yes" if cnt > (n // 2) else "No")


median = arr[n // 2] if n % 2 else (arr[n // 2 - 1] + arr[n // 2]) // 2
print(median)

You might also like