0% found this document useful (0 votes)
41 views

Algorithm U3 Answer Key

ada notes

Uploaded by

Vikram Nairy
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
41 views

Algorithm U3 Answer Key

ada notes

Uploaded by

Vikram Nairy
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 26

UNIT 3

2 marks Questions
1. Define decrease and conquer technique and list any two of its variations.
Ans: Decrease and conquer is a problem-solving technique where a problem is solved
by reducing it to a simpler or smaller instance of the same problem and then solving
the simpler instance.
Variations:
1. Decrease by a constant: In each step, the problem size is reduced by a fixed amount.
2. Decrease by a constant factor: In each step, the problem size is reduced by a fixed
fraction.

2. What is a decrease by a constant technique and give an example.


Ans: In decrease by a constant technique, the size of the problem is reduced by a fixed
amount in each step.
Example:
Linear Search - In each step, the algorithm checks one element at a time, reducing the
search space by one element in each iteration.

3. What is a decrease by a constant factor technique and give an example.


Ans: In decrease by a constant factor technique, the size of the problem is reduced by
a fixed fraction in each step.
Example:
Binary Search - In each step, the algorithm divides the search space in half, reducing
the problem size by a factor of 2.

4. What is a variable size decrease technique and give an example.


Ans: In variable size decrease technique, the size of the problem is reduced by a
variable amount in each step.
Example:
Quick Sort - The pivot element is chosen dynamically, and the array is partitioned into
sub-arrays of varying sizes based on the pivot.
5. Write the time complexity for worst, best, and average case of Insertion sort.
Ans: Time Complexity:
- Worst Case: O(n^2)
- Best Case: O(n)
- Average Case: O(n^2)
Explanation:
- In the worst case, when the array is in reverse order, each element may need to be
compared and shifted, leading to quadratic time complexity.
- In the best case, when the array is already sorted, only one comparison per element
is needed, resulting in linear time complexity.
- The average case is quadratic, as it considers all possible input permutations and
their likelihood.6. Give any four comparisons among Depth First Search and Breadth
First Search.

7. Define digraph and dag.


Ans: -Digraph: A directed graph (digraph) is a graph in which edges have a direction,
i.e., they are ordered pairs of vertices (u, v) indicating a directed edge from vertex u to
vertex v. Digraphs are often used to model relationships between objects or entities,
such as the flow of information in a network or the dependencies between tasks in a
project.
-DAG (Directed Acyclic Graph): A directed acyclic graph (DAG) is a special type of
directed graph that does not contain any cycles. In other words, there is no sequence
of vertices such that the first vertex is also the last. AGs are often used to model
relationships that must be followed in a particular order, such as the order in which
tasks must be completed in a project.
8. Write an algorithm to find height of Binary tree.
Ans: def height_of_binary_tree(root):
if not root:
return 0
left_height = height_of_binary_tree(root.left)
right_height = height_of_binary_tree(root.right)

return max(left_height, right_height) + 1


9. Write the recurrence relation for Binary tree.
Ans: The recurrence relation for the number of nodes in a binary tree is:
T(n) = 2T(n-1) + 1
10.Define Topological sorting. Give a example.
Ans: Topological sorting is an ordering of the vertices in a directed acyclic graph (DAG)
such that for every directed edge (u, v), vertex u comes before v in the ordering.
Here is an example of a topological sort:
A -> B
B -> C
C -> D
A -> D
In this example, task A must be completed before task B can be completed, task B
must be completed before task C can be completed, and task C must be completed
before task D can be completed. A topological sort of this set of tasks is A, B, C, D.

11.Define following
a. Tree Edge
b. Cross Edge
c. Back Edge
Ans: --Tree Edge: A tree edge is an edge that connects two nodes in a tree. Tree edges
are directed from a parent node to a child node. In a depth-first search (DFS) tree, a
tree edge is an edge that connects a vertex to an ancestor in the tree.
--Cross Edge: A cross edge is an edge that connects two nodes in a tree that are not
parent-child relationships. Cross edges are not directed. A cross edge is an edge in a
DFS traversal that connects two vertices in different subtrees of the DFS tree and
doesn't create a cycle.
--Back Edge: A back edge is an edge that connects a node to one of its ancestors in a
tree. Back edges are directed. A back edge is an edge in a DFS traversal that connects a
vertex to an ancestor in the DFS tree and creates a cycle.

12.List the Two algorithms for solving topological sorting problem.


Ans: There are two main algorithms for topological sorting:
1. Kahn's algorithm: Based on the indegree of vertices. Kahn's algorithm is a
breadth-first search algorithm that uses a queue to keep track of nodes that can
be topologically sorted.

2. DFS-based algorithm: Uses depth-first search to explore the vertices. This


algorithm is a depth-first search algorithm that uses a stack to keep track of
nodes that have been visited.
13.Define decrease-by-one technique in topological sorting.
Ans: The decrease-by-one technique is a way to improve the time complexity of
topological sorting. This technique is based on the observation that each time a node
is topologically sorted, its in-degree decreases by one. By keeping track of the in-
degree of each node, we can avoid revisiting nodes that have already been
topologically sorted.

14.Define divide and conquer technique and list its steps.


Ans: In the decrease-by-one technique for topological sorting, one vertex with no
incoming edges (indegree of 0) is removed in each step until all vertices are removed.
This process is repeated until all vertices are removed or a cycle is detected. The
removed vertices form the topological order.
Steps:
1. Divide: Break the problem into smaller subproblems.
2. Conquer: Solve the subproblems recursively.
3. Combine: Combine the solutions of subproblems to solve the original problem.

15.Give the structure of Recurrence equation for Divide and Conquer.


Ans: The recurrence equation for divide and conquer is:
T(n) = aT(n/b) + c
where:
T(n) is the time complexity of solving the problem of size n
a is the number of subproblems into which the problem is divided
b is the size of each subproblem
c is the time taken to combine the solutions to the subproblem

16.Write the time complexity for Merge and Quick sort


Ans: The time complexity for merge sort is:
Worst case: O(n log n)
Best case: O(n log n)
Average case: O(n log n)
The time complexity for quicksort is:
Worst case: O(n^2)
Average case: O(n log n)
17.Write the time complexity for Strassen’s Matrix Multiplication and Multiplication
Larger integer.
Ans: The time complexity for Strassen's matrix multiplication is:
O(n^2.81)
The time complexity for the multiplication of two large integers is:
O(n log n log n)

18.State Mater theorem of Divide and conquer.


Ans: The master theorem of divide and conquer states that the time complexity of a
divide and conquer algorithm is given by:
T(n) = aT(n/b) + O(n^d)
where:
T(n) is the time complexity of solving the problem of size n
a is the number of subproblems into which the problem is divided
b is the size of each subproblem
d is the exponent of the growth rate of the problem

19.Write the time complexity for worst, best and average case of Binary Search.
Ans: The time complexity for binary search is:
Worst case: O(log n)
Best case: O(1)
Average case: O(log n)

20.Write the steps followed in divide and Conquer approach.


Ans: The steps followed in the divide and conquer approach are:
1. Divide the problem into smaller subproblems.
2. Solve the subproblems recursively.
3. Combine the solutions to the subproblems to solve the original problem.
Long Answer Questions (THREE, FOUR OR FIVE Marks Questions)
1. Write an algorithm to sort N numbers using Insertion sort. Derive the time
complexity for worst case and best case.
Ans: Algorithm: Insertion Sort
pythonCopy code
Algorithm: InsertionSort(arr)
Input: Unsorted array arr of length N
Output: Sorted array arr
for i from 1 to N-1:
key = arr[i]
j=i–1
while j >= 0 and key < arr[j]:
arr[j + 1] = arr[j]
j = j - 1 arr[j + 1] = key
Time Complexity Analysis:
• Worst Case: O(n^2) when the array is in reverse order, and each
element has to be compared and shifted.
• Best Case: O(n)when the array is already sorted, and only one
comparison per element is needed.
2. Define decrease and conquer technique and explain its variations.
Ans: Decrease and Conquer Technique: The decrease and conquer technique is a
problem-solving strategy that involves recursively breaking down a problem into
smaller subproblems until they can be solved directly, and then combining the
solutions to the subproblems to solve the original problem. It is a powerful technique
that can be used to solve a wide variety of problems.
Variations of Decrease and Conquer Technique:
• Divide and Conquer: This is the most common variation of decrease and conquer. It
involves dividing the problem into smaller subproblems, solving the subproblems
recursively, and then combining the solutions to the subproblems to solve the
original problem. An example of divide and conquer is the merge sort algorithm.
• Recursive Doubling: This variation involves repeatedly doubling the size of the
subproblems until they are small enough to be solved directly. This approach is
often used when the cost of solving a subproblem is proportional to the size of the
subproblem. An example of recursive doubling is the Strassen's algorithm for
matrix multiplication.
• Iterated Divide and Conquer: This variation involves repeatedly dividing the
problem into smaller subproblems, but instead of solving the subproblems
recursively, they are solved iteratively. This approach is often used when the cost of
recursion is significant. An example of iterated divide and conquer is the iterative
deepening search algorithm.
3. Write and explain Depth-First Search Algorithm with example.
Ans: DFS is an algorithm for traversing or searching tree or graph data structures. The
algorithm starts at the tree root (or some arbitrary node of a graph, sometimes called
a 'search key'), and explores as far as possible along each branch before backtracking.
Algorithm: Python code-
def dfs(graph, start):
visited = set()
stack = [start]

while stack:
node = stack.pop()
if node not

in visited:
visited.add(node)
for neighbor in graph[node]:
stack.append(neighbor)

Example: Python code:


graph = {
'A': ['B', 'C'],
'B': ['D', 'E'],
'C': ['F'],
'D': [],
'E': ['F'],
'F': []
}
dfs(graph, 'A')
This will print the following:
A
B
D
E
C
F

4. Write and explain Breadth-First Search Algorithm with example


Ans: BFS is an algorithm for traversing or searching tree or graph data structures. It
starts at the tree root (or some arbitrary node of a graph, sometimes called a 'search
key'), and explores the neighbor nodes first, before moving to the next level
neighbors.
Algorithm: Python code
def bfs(graph, start):
visited = set()
queue = [start]

while queue:
node = queue.pop(0)
if node not in visited:
visited.add(node)
for neighbor in graph[node]:
queue.append(neighbor)

Example: Python code


graph = {
'A': ['B', 'C'],
'B': ['D', 'E'],
'C': ['F'],
'D': [],
'E': ['F'],

5. Consider the following graph and perform following traversal


a. BFS
b. DFS

Ans: Breadth-First Search (BFS):


1. Start at node ‘a’
2. Visit 'a’s neighbors: ‘r’, ‘d’, ‘f’
3. Visit 'r’s unvisited neighbor: none
4. Visit 'd’s unvisited neighbor: none
5. Visit 'f’s unvisited neighbor: ‘e’
6. Visit 'e’s unvisited neighbors: ‘h’, ‘g’
7. Visit 'h’s unvisited neighbor: ‘i’
8. Visit 'g’s and 'i’s unvisited neighbors: none

So, the BFS traversal order is: a, r, d, f, e, h, g, i


Depth-First Search (DFS):

1. Start at node ‘a’


2. Visit 'a’s unvisited neighbor: ‘r’
3. Visit 'r’s unvisited neighbor: ‘d’
4. Visit 'd’s unvisited neighbor: ‘f’
5. Visit 'f’s unvisited neighbor: ‘e’
6. Visit 'e’s unvisited neighbors: ‘h’, ‘g’
7. Visit 'h’s unvisited neighbor: ‘i’
8. Visit 'g’s and 'i’s unvisited neighbors: none

So, the DFS traversal order is: a, r, d, f, e, h, g, i

Note that the traversal order can vary depending on the starting node and the order
in which the neighbors are visited. The above orders are based on starting from
node ‘a’ and visiting the neighbors in the order they were given.

6. Consider the following graph and perform following traversal


a. BFS
b. DFS

Ans: BFS:
f
b
c
d
a
e

DFS:
f
e
b
d
c
a
Explanation:
BFS: We start at the root node (f) and add all of its neighbors to a queue (b, c). We then
process the queue, removing the first node (b) and adding all of its neighbors to the queue
(d). We repeat this process until the queue is empty.
DFS: We start at the root node (f) and recursively explore all of its descendants. We mark
each node as visited so that we don't revisit it. We continue exploring all of the descendants
of the current node until we reach a node that has no unvisited neighbours. We then
backtrack to the parent node and explore any unvisited neighbors.
In this case, we start at the root node (f) and explore its child node (e). We then mark
e as visited and recursively explore its child node (b). We mark b as visited and recursively
explore its child node (d). We continue this process until we reach a node that has no
unvisited neighbors. We then backtrack to the parent node (b) and explore its other child
node (c). We continue this process until we have explored all of the nodes in the graph.

7. Give any five comparisons among Depth First Search and Breadth First Search.
Ans: Five comparisons between Depth First Search (DFS) and Breadth First Search
(BFS):
o Data Structure: BFS uses a queue to keep track of the next vertex to visit, whereas
DFS uses a stack or can be implemented with recursion.
o Traversal Order: BFS visits all the vertices of a level before going to the next level,
while DFS visits a vertex and then iteratively explores its adjacent vertices before
backtracking.
o Memory Space: DFS uses less memory than BFS because it’s not necessary to store
all the child pointers at each level.
o Cycle Detection: DFS is more suitable for cycle detection in a graph because it
explores vertices as far as possible before backtracking, while BFS is not suitable for
cycle detection.
o Path Finding: BFS is generally better for path finding problems where the shortest
path is required, as it explores vertices in order of their distance from the source,
while DFS is not suitable for such problems.

8. Write a note on topological sorting with an example.


Ans: Topological Sorting is a linear ordering of vertices in a directed acyclic graph
(DAG), where for every directed edge u -> v, vertex u comes before v in the ordering.
Topological Sorting is not possible if the graph is not a DAG.

For example, consider the following graph:


5 -> 0 -> 2 -> 3
| ^
v |
4 -> 1 ----

A topological sorting of this graph is: 5, 4, 1, 2, 0, 3. Note that for any directed edge u -
> v, u comes before v in the ordering.
The topological sorting for a graph is not unique. For the above graph, another
topological sorting could be: 4, 5, 1, 2, 0, 3. This is also a valid topological sorting.
9. Explain DFS-based algorithm to solve the topological sorting problem and also
write topological order for below graph.

Ans: C1 -> C3
C1 -> C5
C3 -> C4
C5 -> C4
C3 -> C2
C4 -> C2
DFS-based algorithm to solve the topological sorting problem:
1. Create a list of nodes that have zero indegree. This is a list of nodes that have no
incoming edges.
2. Iteratively remove the first node from the list and add it to the topological order.
3. For each neighbor of the removed node, decrease its indegree by one.
4. If a neighbor's indegree becomes zero, add it to the list.
5. Repeat steps 2-4 until the list is empty.
Topological order for the graph in the image:
C1
C3
C5
C4
C2
We start by creating a list of nodes that have zero indegree. In this case, the list
contains the node C1. We then remove C1 from the list and add it to the topological
order. Next, we look at the neighbors of C1. C1 has two neighbors, C3 and C5. We
decrease the indegree of C3 and C5 by one. Since C3 and C5 now have an indegree of
zero, we add them to the list.
We then repeat the process of removing nodes from the list and adding them to the
topological order, decreasing the indegree of neighbors along the way.

Step List Topological order

1 C3, C5 C1

2 C5 C1, C3

3 C5, C4 C1, C3

4 C4 C1, C3, C5
5 C4, C2 C1, C3, C5

6 C2 C1, C3, C5, C4

Once the list is empty, we have completed the topological sort and the
topological order is the following:
C1
C3
C5
C4
C2

10.Apply the DFS-based algorithm to solve the topological sorting problem for
the following digraphs

Ans: To apply the DFS-based algorithm to solve the topological sorting problem for
the following digraphs in the image:
Digraph A:
```
a -> b
b -> c
c -> d
```
Digraph B:
```
a -> b
b -> c
c -> d
a -> d
We can follow these steps:
1. Create a list of nodes that have zero indegree.
2. Iteratively remove the first node from the list and add it to the topological order.
3. For each neighbor of the removed node, decrease its indegree by one.
4. If a neighbor's indegree becomes zero, add it to the list.
5. Repeat steps 2-4 until the list is empty.
Digraph A:
1. The list of nodes with zero indegree is `a`.
2. Remove `a` from the list and add it to the topological order.
3. `a` has one neighbor, `b`. Decrease the indegree of `b` by one.
4. `b` now has an indegree of zero, so add it to the list.
5. Remove `b` from the list and add it to the topological order.
6. `b` has one neighbor, `c`. Decrease the indegree of `c` by one.
7. `c` now has an indegree of zero, so add it to the list.
8. Remove `c` from the list and add it to the topological order.
9. `c` has one neighbor, `d`. Decrease the indegree of `d` by one.
10. `d` now has an indegree of zero, so add it to the list.
11. Remove `d` from the list and add it to the topological order.
12. The list is now empty, so we have completed the topological sort.

The topological order for digraph A is:


a
b
c
d
```

Digraph B:
1. The list of nodes with zero indegree is `a`.
2. Remove `a` from the list and add it to the topological order.
3. `a` has two neighbors, `b` and `d`. Decrease the indegree of `b` and `d` by one.
4. `b` and `d` now have an indegree of zero, so add them to the list.
5. Remove `b` from the list and add it to the topological order.
6. `b` has one neighbor, `c`. Decrease the indegree of `c` by one.
7. `c` now has an indegree of zero, so add it to the list.
8. Remove `c` from the list and add it to the topological order.
9. `c` has one neighbor, `d`. Decrease the indegree of `d` by one.
10. `d` now has an indegree of zero, so add it to the list.
11. Remove `d` from the list and add it to the topological order.
12. The list is now empty, so we have completed the topological sort.

The topological order for digraph B is:


```
a
b
c
d
```
11.Apply the source-removal algorithm to solve the topological sorting problem for
the following digraphs

Ans: To apply the source-removal algorithm to solve the topological sorting


problem for the digraphs in the image, we can follow these steps:
1. Identify all of the nodes that have no incoming edges. These nodes are
the sources of the graph.
2. Remove the sources from the graph and add them to a list.
3. Repeat steps 1 and 2 until the graph is empty.
4. The list of nodes that we removed is a topological ordering of the graph.
For the first digraph in the image, we have the following steps:
1. Identify all of the nodes that have no incoming edges: A, B, and D.
2. Remove the sources from the graph and add them to a list: [A, B, D]
3. Repeat steps 1 and 2:
o Identify all of the nodes that have no incoming edges: C
o Remove the sources from the graph and add them to the list: [A,
B, D, C]
4. The list of nodes that we removed is a topological ordering of the graph:
[A, B, D, C]
For the second digraph in the image, we have the following steps:
1. Identify all of the nodes that have no incoming edges: A and B.
2. Remove the sources from the graph and add them to a list: [A, B]
3. Repeat steps 1 and 2:
o Identify all of the nodes that have no incoming edges: C
o Remove the sources from the graph and add them to the list: [A,
B, C]
4. The list of nodes that we removed is a topological ordering of the graph:
[A, B, C]
Therefore, the topological orderings of the two digraphs in the image are:
• First digraph: [A, B, D, C]
• Second digraph: [A, B, C]
12.Explain source-removal algorithm to solve the topological sorting problem and
also write topological order for below graph

Ans: The source-removal algorithm is a simple and efficient algorithm for solving the
topological sorting problem. It works by repeatedly removing the nodes with zero
indegree from the graph and adding them to the topological order. The algorithm
terminates when the graph is empty or when there are no nodes with zero indegree
left in the graph.
Algorithm:
1. Create a list of nodes with zero indegree.
2. While the list is not empty:
o Remove the first node from the list and add it to the topological order.
o For each neighbor of the removed node, decrease its indegree by one.
o If a neighbor's indegree becomes zero, add it to the list.
3. If the graph is not empty and there are no nodes with zero indegree left in the
graph, then the graph is cyclic and there is no topological order.
Topological order for the graph in the image:
C1
C3
C5
C4
C2
Explanation:
1. The list of nodes with zero indegree is C1.
2. Remove C1 from the list and add it to the topological order.
3. C1 has two neighbors, C3 and C5. Decrease the indegree of C3 and C5 by one.
4. C3 and C5 now have an indegree of zero, so add them to the list.
5. Remove C3 from the list and add it to the topological order.
6. C3 has one neighbor, C4. Decrease the indegree of C4 by one.
7. C4 now has an indegree of zero, so add it to the list.
8. Remove C4 from the list and add it to the topological order.
9. C4 has one neighbor, C2. Decrease the indegree of C2 by one.
10. C2 now has an indegree of zero, so add it to the list.
11. Remove C2 from the list and add it to the topological order.
12. The list is now empty, so we have completed the topological sort.
Therefore, the topological order for the graph in the image is C1, C3, C5, C4, C2.
13.Explain divide and conquer technique of solving problem with diagram.
Ans: The divide and conquer technique is a problem-solving strategy that involves
recursively breaking down a problem into smaller subproblems until they can be
solved directly, and then combining the solutions to the subproblems to solve the
original problem. This technique is often used to solve problems that are too difficult
or time-consuming to solve directly.
Steps in the Divide and Conquer Technique:
1. Divide: Break the problem into smaller subproblems.
2. Conquer: Solve the subproblems recursively.
3. Combine: Combine the solutions to the subproblems to solve the original
problem.

Diagram :
Problem
/ \
/ \
Subproblem 1 Subproblem 2

/ \ / \
/ \ / \
... ... ... ...

Solution 1 Solution 2

\ /
\ /
\ /
\/
Combined Solution

Advantages of the Divide and Conquer Technique:


• Efficiency: The divide and conquer technique can often be more efficient than
other problem-solving strategies, such as brute-force search.
• Elegance: The divide and conquer technique is often very elegant and can be
applied to a wide variety of problems.

Examples of Divide and Conquer Algorithms:


• Merge sort: Merge sort is a sorting algorithm that uses the divide and conquer
technique to sort a list of numbers.
• Quicksort: Quicksort is another sorting algorithm that uses the divide and
conquer technique.
• Binary search: Binary search is an algorithm for searching for a value in a sorted
list.
14.Solve the recursion relation using Master theorems
T(n)=2T(n/2)-n / T(1)=2
Ans: To solve this recurrence using the Master theorem, we first need to identify the
values of a, b, and f(n).
• a: The value of a is 2.
• b: The value of b is 2.
• f(n): The value of f(n) is -n.

Next, we need to compare f(n) to n^(log_b a) to determine the appropriate case of


the Master theorem.

• n^(log_b a): n^(log_2 2) = n.

Since f(n) is O(n), which is the same as the worst-case time complexity of the
subproblems, we have Case 2 of the Master theorem. This means that the time
complexity of the recurrence is T(n) = O(n log n).

15.Solve the recursion relation using Master theorems.


A(n)=2A(n/2)+1.
Ans: To solve this recurrence using the Master theorem, we first need to identify the
values of a, b, and f(n).
• a: The value of a is 2.
• b: The value of b is 2.
• f(n): The value of f(n) is 1.
Next, we need to compare f(n) to n^(log_b a) to determine the appropriate case of
the Master theorem.
• n^(log_b a): n^(log_2 2) = n.
Since f(n) is O(1), which is smaller than n^(log_b a), we have Case 3 of the Master
theorem. This means that the time complexity of the recurrence is T(n) = O(f(n)). In
this case, the time complexity is O(1).

16. Write an algorithm to sort N numbers using Merge sort.


Ans: ```python code:
def merge_sort(array):
if len(array) <= 1:
return array
mid = len(array) // 2
left = merge_sort(array[:mid])
right = merge_sort(array[mid:])
return merge(left, right)
def merge(left, right):
result = []
i=0
j=0
while i < len(left) and j < len(right):
if left[i] <= right[j]:

result.append(left[i])
i += 1
else:
result.append(right[j])
j += 1
result += left[i:]
result += right[j:]

return result
```
Time complexity:
The time complexity of merge sort is O(n log n).

17. Write an algorithm to sort N numbers using Quick sort.


Ans: ```python code:
def quick_sort(array):
if len(array) <= 1:
return array
pivot = array[0]
left = []
right = []
for i in range(1, len(array)):
if array[i] <= pivot:
left.append(array[i])
else:
right.append(array[i])
left = quick_sort(left)
right = quick_sort(right)

return left + [pivot] + right


```
Time complexity:The average time complexity of quick sort is O(n log n), but the
worst-case time complexity is O(n^2).18.Write an algorithm to find maximum and
minimum element in array Derive the time complexity.
18.Write an algorithm to find maximum and minimum element in array Derive the
time complexity.
Ans: algorithm to find the maximum and minimum element in an array:
Python code:
def find_max_min(arr):
max_val = arr[0]
min_val = arr[0]
for i in range(1, len(arr)):
if arr[i] > max_val:
max_val = arr[i]
elif arr[i] < min_val:
min_val = arr[i]
return max_val, min_valTime complexity:
The time complexity of this algorithm is O(n), where n is the length of the array. This is
because the algorithm iterates over all elements of the array once.
Explanation:
1. Initialize two variables, max_element and min_element, to the first
element of the array.
2. Iterate over all elements of the array.
3. For each element, compare it to max_element and update max_element
if the element is greater.
4. For each element, compare it to min_element and update min_element
if the element is smaller.
5. Return max_element and min_element.
6.
19.Write an algorithm to search an element in an array of N numbers using Binary
search. Derive the time complexity.
Python code:
def binary_search(array, target):
low = 0
high = len(array) – 1
while low <= high:
mid = (low + high) // 2
if array[mid] == target:
return mid
elif array[mid] < target:
low = mid + 1
else:
high = mid - 1
return -1
Time complexity:
The time complexity of binary search is O(log n), where n is the number of elements
in the array. This is because binary search repeatedly divides the search space in
half, until the target element is found or the search space is empty. Each time the
search space is divided in half, the number of elements in the search space is
reduced by half. Therefore, the number of times the search space needs to be
divided is logarithmic in the number of elements in the array.
Here is a table of the time complexity of binary search for different values of n:

n log n

10 3.32

100 6.64

1,000 9.97

10,000 13.29

100,000 16.61

As you can see, the time complexity of binary search grows very slowly as the
number of elements in the array increases. This makes binary search a very efficient
algorithm for searching large arrays.

20.Traverse the Binary Tree a) Inorder b) Preorder c) Postorder

Ans: Inorder Traversal: To traverse the binary tree in inorder, we follow these steps:
1. Visit the left subtree.
2. Visit the root node.
3. Visit the right subtree.
Preorder traversal: To traverse the binary tree in preorder, we follow these steps:
1. Visit the root node.
2. Visit the left subtree.
3. Visit the right subtree.
Postorder Traversal: To traverse the binary tree in postorder, we follow these steps:
1. Visit the left subtree.
2. Visit the right subtree.
3. Visit the root node.
Inorder traversal: gdebacf
Preorder traversal: abdgecf
Postorder traversal: gdebfca

21.Explain the Strassen’s algorithm of matrix multiplication and derive the time
complexity.
Ans: Strassen's algorithm is a method for matrix multiplication that is more efficient
than the naive algorithm. It was invented by Volker Strassen in 1969 and is based on
the principle of divide and conquer.
1. Divide the input matrices A and B, and the output matrix C into n/2 x n/2
submatrices:
```
A = | A11 A12 | B = | B11 B12 | C = | C11 C12 |
| | | | | |
| A21 A22 | | B21 B22 | | C21 C22 |

2. Conquer by recursively computing seven products of submatrices:


```
P1 = A11 * (B12 - B22)
P2 = (A11 + A12) * B22
P3 = (A21 + A22) * B11
P4 = A22 * (B21 - B11)
P5 = (A11 + A22) * (B11 + B22)
P6 = (A12 - A22) * (B21 + B22)
P7 = (A11 - A21) * (B11 + B12)
3. Combine by computing the submatrices of C from the seven products:
```
C11 = P5 + P4 - P2 + P6
C12 = P1 + P2
C21 = P3 + P4
C22 = P5 + P1 - P3 - P7
```
The time complexity of Strassen's algorithm is derived from the recurrence relation:
T(n) = 7T(n/2) + O(n^2)
Using the master theorem, we can solve this recurrence relation to find that the time
complexity of Strassen's algorithm is:
T(n) = O(n^log2(7)) ≈ O(n^2.81)
This is an improvement over the naive matrix multiplication algorithm, which has a
time complexity of O(n^3). However, Strassen's algorithm has a larger constant factor
and is more complex to implement, so it is not always faster in practice. It is also worth
noting that there are even faster algorithms for matrix multiplication, such as the
Coppersmith–Winograd algorithm, which has a time complexity of O(n^2.376).
However, these algorithms are even more complex and have even larger constant
factors, so they are not commonly used in practice.

22.ApplyStrassen's algorithm to multiply two Matrixes.

Ans: Let's apply Strassen's algorithm to multiply the given matrices:


Matrix A:
```
[3 -1]
[2 4]
Matrix B:
```
[2 3]
[-1 4]
```

We first calculate the seven products:


```
P1 = A11 * (B12 - B22) = 3 * (3 - 4) = -3
P2 = (A11 + A12) * B22 = (3 + (-1)) * 4 = 8
P3 = (A21 + A22) * B11 = (2 + 4) * 2 = 12
P4 = A22 * (B21 - B11) = 4 * ((-1) - 2) = -12
P5 = (A11 + A22) * (B11 + B22) = (3 + 4) * (2 + 4) = 28
P6 = (A12 - A22) * (B21 + B22) = ((-1) - 4) * ((-1) + 4) = 15
P7 = (A11 - A21) * (B11 + B12) = (3 - 2) * (2 + 3) = 5
``
Then we calculate the submatrices of the result matrix C:
```
C11 = P5 + P4 - P2 + P6 = 28 + (-12) - 8 + 15 = 23
C12 = P1 + P2 = -3 + 8 = 5
C21 = P3 + P4 = 12 + (-12) = 0
C22 = P5 + P1 - P3 - P7 = 28 + (-3) - 12 - 5 = 8
```
So, the result of the multiplication is:
```
[23 5]
[0 8]
```

23.Compute 1234 x 2526 using divide and conquer approach for the multiplication of
two large numbers.
Ans: To multiply two large integers using the divide and conquer approach, we can
follow these steps:
1. Divide the integers into smaller subproblems. In this case, we can divide the
numbers 1234 and 2526 into their digit representations.
1234 = 1000 + 200 + 30 + 4
2526 = 2000 + 500 + 20 + 6
2. Recursively solve the subproblems. In this case, we can recursively multiply
each of the digit representations of the two numbers:
1000 * 2000 = 2000000
200 * 500 = 100000
30 * 20 = 600
4 * 6 = 24
3. Combine the solutions to the subproblems. In this case, we can add up the
products of the digit representations.
2000000 + 100000 + 600 + 24 = 2100624
Therefore, 1234 x 2526 = 2100624.

24.Explain the Multiplication two larger integer using divide and conquer approach
and derive the time complexity.
Ans: The divide and conquer approach for multiplication of two large integers is a
recursive algorithm that breaks down the problem into smaller subproblems until they
can be solved directly, and then combines the solutions to the subproblems to solve
the original problem. The time complexity of the algorithm is O(n^1.585), where n is
the number of digits in the two integers.
The divide-and-conquer approach for multiplying two large integers is a recursive
algorithm that works by breaking the problem down into smaller subproblems until
they can be solved directly, and then combining the solutions to the subproblems to
solve the original problem. This approach is also known as Karatsuba multiplication,
named after the Soviet mathematician Anatoliy Karatsuba, who first published the
algorithm in 1960.
Algorithm:
1. Divide the integers into smaller subproblems: Divide the two integers into two
halves of approximately equal size. For example, if we want to multiply the
integers 1234 and 2526, we can divide them into the following halves:
``1234 = 1200 + 34 2526 = 2500 + 26
2. Recursively solve the subproblems: Multiply the two halves of each integer
recursively. In our example, this would involve the following multiplications:
``1200 * 2500 = 3000000 34 * 26 = 884
3. Combine the solutions to the subproblems: Combine the results of the recursive
multiplications to obtain the final product. In our example, this involves the
following steps:
• Compute the product of the first halves of the two integers and the product of
the second halves of the two integers. In our example, these products are 3000000
and 884, respectively.
• Compute the product of the sum of the first halves and the sum of the second
halves. In our example, this product is (1200 + 34) * (2500 + 26) = 3100624.
• Subtract the product of the first and second halves from the product obtained in
the previous step to obtain the final product. In our example, this calculation is
3100624 - 884 = 3100000.

Comparison with Traditional Multiplication Algorithm:


The traditional multiplication algorithm works by multiplying each digit of one integer
by each digit of the other integer and then adding up the products. This algorithm has
a time complexity of O(n^2), where n is the number of digits in the two integers.

The divide-and-conquer approach is significantly faster than the traditional


multiplication algorithm because it breaks the problem down into smaller
subproblems that can be solved more efficiently. As a result, the divide-and-conquer
approach is often used for multiplying very large integers.

25.Compute 34 x 26 using divide and conquer approach for the multiplication of two
large numbers.
Ans: Using the same steps as in question 23, we can compute 34 x 26 as follows:
1. Divide the integers into smaller subproblems.
34 = 30 + 4
26 = 20 + 6
2. Recursively solve the subproblems.
30 * 20 = 600
4 * 6 = 24
3. Combine the solutions to the subproblems.
600 + 24 = 624
Therefore, 34 x 26 = 624.

26.Apply Strassen's algorithm to compute exiting the recursion when n = 2, i.e.,


computing the products of 2-by-2 matrices by the brute-force algorithm.

Ans: Let’s apply Strassen’s algorithm to multiply the given matrices:


Matrix A:
[1 0 2 1]
[4 1 1 0]
[0 1 3 0]
[5 0 2 1]

Matrix B:
[0 1 0 1]
[2 1 0 4]
[2 0 1 1]
[1 3 5 0]

We first divide the matrices into 2x2 submatrices:


Matrix A:
A11 = [1 0] A12 = [2 1]
[4 1] [1 0]
A21 = [0 1] A22 = [3 0]
[5 0] [2 1]

Matrix B:
B11 = [0 1] B12 = [0 1]
[2 1] [0 4]
B21 = [2 0] B22 = [1 1]
[1 3] [5 0]

We then compute the seven products using the brute-force algorithm:

P1 = A11 * (B12 - B22) = [1 0] * ([0 1] - [1 1]) = [1 0] * [-1 0] = [-1 0]


P2 = (A11 + A12) * B22 = ([1 0] + [2 1]) * [1 1] = [3 1] * [1 1] = [3 1]

P3 = (A21 + A22) * B11 = ([0 1] + [3 0]) * [0 1] = [3 1] * [0 1] = [0 1]

P4 = A22 * (B21 - B11) = [3 0] * ([2 0] - [0 1]) = [3 0] * [2 -1] = [6 0]

P5 = (A11 + A22) * (B11 + B22) = ([1 0] + [3 0]) * ([0 1] + [1 1]) = [4 0] * [1 2] = [4 0]

P6 = (A12 - A22) * (B21 + B22) = ([2 1] - [3 0]) * ([2 0] + [1 1]) = [-1 1] * [3 1] = [-3 1]

P7 = (A11 - A21) * (B11 + B12) = ([1 0] - [0 1]) * ([0 1] + [0 1]) = [1 -1] * [0 2] = [0 -2]

Finally, we compute the submatrices of the result matrix C:


C11 = P5 + P4 - P2 + P6 = [4 0] + [6 0] - [3 1] + [-3 1] = [4 0]
C12 = P1 + P2 = [-1 0] + [3 1] = [2 1]
C21 = P3 + P4 = [0 1] + [6 0] = [6 1]
C22 = P5 + P1 - P3 - P7 = [4 0] + [-1 0] - [0 1] - [0 -2] = [3 1]

So, the result of the multiplication is:


[4 0 2 1]
[6 1 2 1]
[6 1 3 1]
[3 1 3 1]

You might also like