You are on page 1of 34

DAA PROBLEMS & SOLUTIONS

NAME: Ketan Babbar SUBJECT CODE: 22CSH-282


UID: 22BCC70082 SUBMITTED TO: MR. PRABHJOT SINGH BALI
SECTION: 22AIT-KRG-1 DATE: 04 APRIL 2024
GROUP: B DAY: THURSDAY

QUICK SORT PROBLEMS

Problem: Sort an Array


Description: Given an array of integers nums, sort the array in ascending order.
Solution Code:
void quickSort(vector<int>& nums, int low, int high) {
if (low < high) {
int pivot = partition(nums, low, high);
quickSort(nums, low, pivot - 1);
quickSort(nums, pivot + 1, high);
}
}

int partition(vector<int>& nums, int low, int high) {


int pivot = nums[high];
int i = low - 1;
for (int j = low; j < high; ++j) {
if (nums[j] < pivot) {
++i;
swap(nums[i], nums[j]);
}
}
swap(nums[i + 1], nums[high]);
return i + 1;
}

Problem: Kth Largest Element in an Array


Description: Find the kth largest element in an unsorted array. Note that it is the kth largest
element in the sorted order, not the kth distinct element.
Solution Code:
int findKthLargest(vector<int>& nums, int k) {
int left = 0, right = nums.size() - 1;
while (true) {
int pos = partition(nums, left, right);
if (pos == k - 1) return nums[pos];
else if (pos > k - 1) right = pos - 1;
else left = pos + 1;
}
}

int partition(vector<int>& nums, int left, int right) {


int pivot = nums[left];
int l = left + 1, r = right;
while (l <= r) {
if (nums[l] < pivot && nums[r] > pivot) {
swap(nums[l++], nums[r--]);
}
if (nums[l] >= pivot) ++l;
if (nums[r] <= pivot) --r;
}
swap(nums[left], nums[r]);
return r;
}

Problem: Sort Colors

Description: Given an array nums with n objects colored red, white, or blue, sort them in-
place so that objects of the same color are adjacent, with the colors in the order red, white,
and blue.
Solution Code:
void sortColors(vector<int>& nums) {
int low = 0, mid = 0, high = nums.size() - 1;
while (mid <= high) {
if (nums[mid] == 0) {
swap(nums[low++], nums[mid++]);
} else if (nums[mid] == 1) {
++mid;
} else {
swap(nums[mid], nums[high--]);
}
}
}
Problem: Wiggle Sort II
Description: Given an unsorted array nums, reorder it such that nums[0] < nums[1] > nums[2]
< nums[3]....
Solution Code:
void wiggleSort(vector<int>& nums) {
vector<int> sorted(nums);
sort(sorted.begin(), sorted.end());
int n = nums.size(), j = n - 1;
for (int i = 1; i < n; i += 2)
nums[i] = sorted[j--];
for (int i = 0; i < n; i += 2)
nums[i] = sorted[j--];
}

Problem: Majority Element


Description: Given an array nums of size n, find the majority element. The majority element is
the element that appears more than ⌊n / 2⌋ times.
Solution Code:
int majorityElement(vector<int>& nums) {
int candidate = nums[0], count = 1;
for (int i = 1; i < nums.size(); ++i) {
if (count == 0) {
candidate = nums[i];
count = 1;
} else if (nums[i] == candidate) {
++count;
} else {
--count;
}
}
return candidate;
}

BINARY SEARCH PROBLEMS

Problem: Binary Search

Description: Given a sorted array of integers and a target value, implement binary search to
determine if the target is present in the array. If it is present, return the index of the target,
otherwise return -1.
Solution Code:
int binarySearch(vector<int>& nums, int target) {
int left = 0, right = nums.size() - 1;
while (left <= right) {
int mid = left + (right - left) / 2;
if (nums[mid] == target) return mid;
else if (nums[mid] < target) left = mid + 1;
else right = mid - 1;
}
return -1;
}

Problem: Square Root


Description: Given a non-negative integer x, compute and return the square root of x.
Solution Code:
int mySqrt(int x) {
if (x == 0 || x == 1) return x;
int left = 1, right = x, ans;
while (left <= right) {
int mid = left + (right - left) / 2;
if (mid <= x / mid) {
left = mid + 1;
ans = mid;
} else {
right = mid - 1;
}
}
return ans;
}

Problem: Search in Rotated Sorted Array


Description: Suppose an array sorted in ascending order is rotated at some pivot unknown to
you beforehand. You are given a target value to search. If found in the array, return its index,
otherwise return -1.
Solution Code:
int search(vector<int>& nums, int target) {
int left = 0, right = nums.size() - 1;
while (left <= right) {
int mid = left + (right - left) / 2;
if (nums[mid] == target) return mid;
if (nums[left] <= nums[mid]) {
if (target >= nums[left] && target < nums[mid])
right = mid - 1;
else
left = mid + 1;
} else {
if (target > nums[mid] && target <= nums[right])
left = mid + 1;
else
right = mid - 1;
}
}
return -1;
}

Problem: Search Insert Position


Description: Given a sorted array and a target value, return the index where the target is
found in the array. If the target is not found, return the index where it would be if it were
inserted in order.
Solution Code:
int searchInsert(vector<int>& nums, int target) {
int left = 0, right = nums.size() - 1;
while (left <= right) {
int mid = left + (right - left) / 2;
if (nums[mid] == target) return mid;
else if (nums[mid] < target) left = mid + 1;
else right = mid - 1;
}
return left;
}
Problem: Find Peak Element
Description: A peak element is an element that is strictly greater than its neighbors. Given an
input array nums, where nums[i] ≠ nums[i+1], find a peak element and return its index. If the
array contains multiple peaks, return the index to any of the peaks.
Solution Code:
int findPeakElement(vector<int>& nums) {
int left = 0, right = nums.size() - 1;
while (left < right) {
int mid = left + (right - left) / 2;
if (nums[mid] < nums[mid + 1]) left = mid + 1;
else right = mid;
}
return left;
}

JOB SEQUENCING PROBLEMS

Problem: Job Sequencing with Deadlines


Description: Given a set of jobs each with a deadline and profit, select the jobs to maximize
profit while meeting all deadlines.
Solution Code:
#include <iostream>
#include <algorithm>
using namespace std;

struct Job {
char id;
int deadline;
int profit;
};

bool comparison(Job a, Job b) {


return (a.profit > b.profit);
}

void printJobScheduling(Job arr[], int n) {


sort(arr, arr + n, comparison);
int result[n];
bool slot[n];
for (int i = 0; i < n; i++)
slot[i] = false;
for (int i = 0; i < n; i++) {
for (int j = min(n, arr[i].deadline) - 1; j >= 0; j--) {
if (slot[j] == false) {
result[j] = i;
slot[j] = true;
break;
}
}
}
cout << "Job Sequence: ";
for (int i = 0; i < n; i++)
if (slot[i])
cout << arr[result[i]].id << " ";
cout << endl;
}

int main() {
Job arr[] = {{'a', 2, 100}, {'b', 1, 19}, {'c', 2, 27},
{'d', 1, 25}, {'e', 3, 15}};
int n = sizeof(arr) / sizeof(arr[0]);
cout << "Maximum profit sequence of jobs: ";
printJobScheduling(arr, n);
return 0;
}

Problem: Job Sequencing with Profits


Description: Given a set of jobs each with a deadline and profit, select the jobs to maximize
profit while meeting all deadlines.
Solution Code:
#include <iostream>
#include <algorithm>
using namespace std;

struct Job {
char id;
int deadline;
int profit;
};

bool comparison(Job a, Job b) {


return (a.profit > b.profit);
}

void printJobScheduling(Job arr[], int n) {


sort(arr, arr + n, comparison);
int maxDeadline = findMaxDeadline(arr, n);
int result[maxDeadline] = {-1};
bool slot[maxDeadline] = {false};
for (int i = 0; i < n; i++) {
for (int j = min(maxDeadline, arr[i].deadline) - 1; j >= 0; j--) {
if (slot[j] == false) {
result[j] = i;
slot[j] = true;
break;
}
}
}
cout << "Job Sequence: ";
for (int i = 0; i < maxDeadline; i++)
if (slot[i])
cout << arr[result[i]].id << " ";
cout << endl;
}

int main() {
Job arr[] = {{'a', 2, 100}, {'b', 1, 19}, {'c', 2, 27},
{'d', 1, 25}, {'e', 3, 15}};
int n = sizeof(arr) / sizeof(arr[0]);
cout << "Maximum profit sequence of jobs: ";
printJobScheduling(arr, n);
return 0;
}

Problem: Job Sequencing with Penalties

Description: Given a set of jobs each with a deadline, profit, and penalty for missing the
deadline, select the jobs to maximize profit while meeting all deadlines or minimizing
penalties.
Solution Code:
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

struct Job {
int id, deadline, profit, penalty;
};

bool compare(Job a, Job b) {


return (a.profit > b.profit);
}

int findMaxDeadline(Job arr[], int n) {


int max = arr[0].deadline;
for (int i = 1; i < n; i++)
if (arr[i].deadline > max)
max = arr[i].deadline;
return max;
}

void jobSequencing(Job arr[], int n) {


sort(arr, arr + n, compare);
int maxDeadline = findMaxDeadline(arr, n);
vector<int> slots(maxDeadline, -1);
int profit = 0, penalty = 0;
for (int i = 0; i < n; i++) {
for (int j = arr[i].deadline - 1; j >= 0; j--) {
if (slots[j] == -1) {
slots[j] = arr[i].id;
profit += arr[i].profit;
break;
}
}
if (slots[arr[i].deadline - 1] == -1)
penalty += arr[i].penalty;
}
cout << "Job Sequence: ";
for (int i = 0; i < maxDeadline; i++)
if (slots[i] != -1)
cout << slots[i] << " ";
cout << endl;
cout << "Profit: " << profit << endl;
cout << "Penalty: " << penalty << endl;
}

int main() {
Job arr[] = {{1, 2, 100, 5}, {2, 1, 19, 2}, {3, 2, 27, 3},
{4, 1, 25, 4}, {5, 3, 15, 1}};
int n = sizeof(arr) / sizeof(arr[0]);
cout << "Maximum profit sequence of jobs: ";
jobSequencing(arr, n);
return 0;
}

Problem: Job Sequencing to Minimize Total Completion Time

Description: Given a set of jobs each with a deadline and profit, select the jobs to minimize
the total completion time while meeting all deadlines.
Solution Code:
#include <iostream>
#include <algorithm>
using namespace std;

struct Job {
char id;
int deadline;
int profit;
};

bool comparison(Job a, Job b) {


return (a.profit > b.profit);
}

void printJobScheduling(Job arr[], int n) {


sort(arr, arr + n, comparison);
int result[n];
bool slot[n];
for (int i = 0; i < n; i++)
slot[i] = false;
for (int i = 0; i < n; i++) {
for (int j = min(n, arr[i].deadline) - 1; j >= 0; j--) {
if (slot[j] == false) {
result[j] = i;
slot[j] = true;
break;
}
}
}
cout << "Job Sequence: ";
for (int i = 0; i < n; i++)
if (slot[i])
cout << arr[result[i]].id << " ";
cout << endl;
}

int main() {
Job arr[] = {{'a', 2, 100}, {'b', 1, 19}, {'c', 2, 27},
{'d', 1, 25}, {'e', 3, 15}};
int n = sizeof(arr) / sizeof(arr[0]);
cout << "Maximum profit sequence of jobs: ";
printJobScheduling(arr, n);
return 0;
}

Problem: Job Sequencing with Time and Profit

Description: Given a set of jobs each with a start time, end time, and profit, select the jobs to
maximize profit while not overlapping in time.
Solution Code:
#include <iostream>
#include <algorithm>
using namespace std;

struct Job {
int start;
int end;
int profit;
};

bool compare(Job a, Job b) {


return (a.end < b.end);
}

int findMaxProfit(Job arr[], int n) {


sort(arr, arr + n, compare);
int dp[n];
dp[0] = arr[0].profit;
for (int i = 1; i < n; i++) {
dp[i] = max(arr[i].profit, dp[i - 1]);
for (int j = i - 1; j >= 0; j--) {
if (arr[j].end <= arr[i].start) {
dp[i] = max(dp[i], arr[i].profit + dp[j]);
break;
}
}
}
int maxProfit = 0;
for (int i = 0; i < n; i++)
maxProfit = max(maxProfit, dp[i]);
return maxProfit;
}

int main() {
Job arr[] = {{1, 2, 50}, {3, 5, 20}, {6, 19, 100}, {2, 100, 200}};
int n = sizeof(arr) / sizeof(arr[0]);
cout << "Maximum profit sequence of jobs: " << findMaxProfit(arr, n) << endl;
return 0;
}
KRUSKAL’S ALGORITHM MST(MINIMUM SPANNING TREE) PROBLEMS

Problem: Minimum Spanning Tree


Description: Given a weighted undirected graph, find the minimum spanning tree using
Kruskal's algorithm.
Solution Code:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

struct Edge {
int src, dest, weight;
};

struct Graph {
int V, E;
vector<Edge> edges;
};

struct Subset {
int parent, rank;
};

int find(Subset subsets[], int i) {


if (subsets[i].parent != i)
subsets[i].parent = find(subsets, subsets[i].parent);
return subsets[i].parent;
}

void Union(Subset subsets[], int x, int y) {


int xroot = find(subsets, x);
int yroot = find(subsets, y);

if (subsets[xroot].rank < subsets[yroot].rank)


subsets[xroot].parent = yroot;
else if (subsets[xroot].rank > subsets[yroot].rank)
subsets[yroot].parent = xroot;
else {
subsets[yroot].parent = xroot;
subsets[xroot].rank++;
}
}

void KruskalMST(Graph graph) {


int V = graph.V;
vector<Edge> result(V - 1);

sort(graph.edges.begin(), graph.edges.end(), [](Edge a, Edge b) {


return a.weight < b.weight;
});

Subset* subsets = new Subset[V];


for (int v = 0; v < V; ++v) {
subsets[v].parent = v;
subsets[v].rank = 0;
}

int e = 0;
int i = 0;
while (e < V - 1 && i < graph.E) {
Edge next_edge = graph.edges[i++];
int x = find(subsets, next_edge.src);
int y = find(subsets, next_edge.dest);

if (x != y) {
result[e++] = next_edge;
Union(subsets, x, y);
}
}

cout << "Edges of Minimum Spanning Tree:" << endl;


for (int i = 0; i < e; ++i)
cout << result[i].src << " - " << result[i].dest << " : " << result[i].weight << endl;
}

int main() {
Graph graph = {4, 5, {{0, 1, 10}, {0, 2, 6}, {0, 3, 5}, {1, 3, 15}, {2, 3, 4}}};
KruskalMST(graph);
return 0;
}

Problem: Connect Cities with Minimum Cost


Description: Given a set of cities and the cost of connecting each pair of cities, find the
minimum cost to connect all cities using Kruskal's algorithm.
Solution Code:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

struct Edge {
int src, dest, weight;
};

struct Graph {
int V, E;
vector<Edge> edges;
};

struct Subset {
int parent, rank;
};

int find(Subset subsets[], int i) {


if (subsets[i].parent != i)
subsets[i].parent = find(subsets, subsets[i].parent);
return subsets[i].parent;
}

void Union(Subset subsets[], int x, int y) {


int xroot = find(subsets, x);
int yroot = find(subsets, y);

if (subsets[xroot].rank < subsets[yroot].rank)


subsets[xroot].parent = yroot;
else if (subsets[xroot].rank > subsets[yroot].rank)
subsets[yroot].parent = xroot;
else {
subsets[yroot].parent = xroot;
subsets[xroot].rank++;
}
}

int kruskalMST(Graph graph) {


int V = graph.V;
vector<Edge> result(V - 1);

sort(graph.edges.begin(), graph.edges.end(), [](Edge a, Edge b) {


return a.weight < b.weight;
});

Subset* subsets = new Subset[V];


for (int v = 0; v < V; ++v) {
subsets[v].parent = v;
subsets[v].rank = 0;
}

int e = 0;
int i = 0;
int minCost = 0;
while (e < V - 1 && i < graph.E) {
Edge next_edge = graph.edges[i++];
int x = find(subsets, next_edge.src);
int y = find(subsets, next_edge.dest);

if (x != y) {
result[e++] = next_edge;
Union(subsets, x, y);
minCost += next_edge.weight;
}
}

return minCost;
}

int main() {
Graph graph = {4, 5, {{0, 1, 10}, {0, 2, 6}, {0, 3, 5}, {1, 3, 15}, {2, 3, 4}}};
int minCost = kruskalMST(graph);
cout << "Minimum cost to connect all cities: " << minCost << endl;
return 0;
}

Problem: MST with Maximum Cost

Description: Given a weighted undirected graph, find the maximum cost minimum spanning
tree using Kruskal's algorithm.
Solution Code:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

struct Edge {
int src, dest, weight;
};

struct Graph {
int V, E;
vector<Edge> edges;
};

struct Subset {
int parent, rank;
};

int find(Subset subsets[], int i) {


if (subsets[i].parent != i)
subsets[i].parent = find(subsets, subsets[i].parent);
return subsets[i].parent;
}

void Union(Subset subsets[], int x, int y) {


int xroot = find(subsets, x);
int yroot = find(subsets, y);

if (subsets[xroot].rank < subsets[yroot].rank)


subsets[xroot].parent = yroot;
else if (subsets[xroot].rank > subsets[yroot].rank)
subsets[yroot].parent = xroot;
else {
subsets[yroot].parent = xroot;
subsets[xroot].rank++;
}
}

int kruskalMST(Graph graph) {


int V = graph.V;
vector<Edge> result(V - 1);

sort(graph.edges.begin(), graph.edges.end(), [](Edge a, Edge b) {


return a.weight > b.weight; // Sort in descending order to find maximum cost
});

Subset* subsets = new Subset[V];


for (int v = 0; v < V; ++v) {
subsets[v].parent = v;
subsets[v].rank = 0;
}

int e = 0;
int i = 0;
int maxCost = 0;
while (e < V - 1 && i < graph.E) {
Edge next_edge = graph.edges[i++];
int x = find(subsets, next_edge.src);
int y = find(subsets, next_edge.dest);

if (x != y) {
result[e++] = next_edge;
Union(subsets, x, y);
maxCost = max(maxCost, next_edge.weight);
}
}

return maxCost;
}

int main() {
Graph graph = {4, 5, {{0, 1, 10}, {0, 2, 6}, {0, 3, 5}, {1, 3, 15}, {2, 3, 4}}};
int maxCost = kruskalMST(graph);
cout << "Maximum cost of MST: " << maxCost << endl;
return 0;
}

Problem: Building a Communication Network


Description: Given a set of cities and the cost of connecting each pair of cities, build a
communication network such that all cities are connected with the minimum cost using
Kruskal's algorithm.
Solution Code:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

struct Edge {
int src, dest, weight;
};

struct Graph {
int V, E;
vector<Edge> edges;
};

struct Subset {
int parent, rank;
};

int find(Subset subsets[], int i) {


if (subsets[i].parent != i)
subsets[i].parent = find(subsets, subsets[i].parent);
return subsets[i].parent;
}

void Union(Subset subsets[], int x, int y) {


int xroot = find(subsets, x);
int yroot = find(subsets, y);

if (subsets[xroot].rank < subsets[yroot].rank)


subsets[xroot].parent = yroot;
else if (subsets[xroot].rank > subsets[yroot].rank)
subsets[yroot].parent = xroot;
else {
subsets[yroot].parent = xroot;
subsets[xroot].rank++;
}
}

int kruskalMST(Graph graph) {


int V = graph.V;
vector<Edge> result(V - 1);

sort(graph.edges.begin(), graph.edges.end(), [](Edge a, Edge b) {


return a.weight < b.weight;
});
Subset* subsets = new Subset[V];

for (int v = 0; v < V; ++v) {


subsets[v].parent = v;
subsets[v].rank = 0;
}

int e = 0;
int i = 0;
int totalCost = 0;
while (e < V - 1 && i < graph.E) {
Edge next_edge = graph.edges[i++];
int x = find(subsets, next_edge.src);
int y = find(subsets, next_edge.dest);

if (x != y) {
result[e++] = next_edge;
Union(subsets, x, y);
totalCost += next_edge.weight;
}
}

return totalCost;
}

int main() {
Graph graph = {4, 5, {{0, 1, 10}, {0, 2, 6}, {0, 3, 5}, {1, 3, 15}, {2, 3, 4}}};
int minCost = kruskalMST(graph);
cout << "Minimum cost to build a communication network: " << minCost << endl;
return 0;
}

Problem: Minimum Spanning Forest


Description: Given a set of disconnected graphs, find the minimum spanning forest using
Kruskal's algorithm.
Solution Code:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

struct Edge {
int src, dest, weight;
};

struct Graph {
int V, E;
vector<Edge> edges;
};

struct Subset {
int parent, rank;
};
int find(Subset subsets[], int i) {
if (subsets[i].parent != i)
subsets[i].parent = find(subsets, subsets[i].parent);
return subsets[i].parent;
}

void Union(Subset subsets[], int x, int y) {


int xroot = find(subsets, x);
int yroot = find(subsets, y);

if (subsets[xroot].rank < subsets[yroot].rank)


subsets[xroot].parent = yroot;
else if (subsets[xroot].rank > subsets[yroot].rank)
subsets[yroot].parent = xroot;
else {
subsets[yroot].parent = xroot;
subsets[xroot].rank++;
}
}

vector<int> kruskalMST(Graph graph, int& minCost) {


int V = graph.V;
vector<Edge> result(V - 1);

sort(graph.edges.begin(), graph.edges.end(), [](Edge a, Edge b) {


return a.weight < b.weight;
});
Subset* subsets = new Subset[V];

for (int v = 0; v < V; ++v) {


subsets[v].parent = v;
subsets[v].rank = 0;
}

int e = 0;
int i = 0;
vector<int> minCosts(V, 0); // Stores the minimum cost for each connected component
vector<int> mstEdges;
while (e < V - 1 && i < graph.E) {
Edge next_edge = graph.edges[i++];
int x = find(subsets, next_edge.src);
int y = find(subsets, next_edge.dest);

if (x != y) {
result[e++] = next_edge;
Union(subsets, x, y);
minCost += next_edge.weight;
mstEdges.push_back(i - 1); // Index of the edge in the original sorted edge list
minCosts[x] = next_edge.weight; // Update minCosts for the component
minCosts[y] = next_edge.weight; // Update minCosts for the component
}
}
// If there are remaining vertices not connected, they form separate trees
for (int j = i; j < graph.E; ++j) {
Edge edge = graph.edges[j];
int x = find(subsets, edge.src);
int y = find(subsets, edge.dest);
if (x != y) {
mstEdges.push_back(j); // Index of the edge in the original sorted edge list
minCosts[x] = edge.weight; // Update minCosts for the component
minCosts[y] = edge.weight; // Update minCosts for the component
}
}

delete[] subsets;
return minCosts;
}

int main() {
Graph graph = {4, 6, {{0, 1, 10}, {0, 2, 6}, {0, 3, 5}, {1, 3, 15}, {2, 3, 4}, {4, 5, 20}}};
int minCost = 0;
vector<int> minCosts = kruskalMST(graph, minCost);

cout << "Minimum cost of Minimum Spanning Forest: " << minCost << endl;
cout << "Minimum cost for each connected component:" << endl;
for (int i = 0; i < minCosts.size(); ++i) {
if (minCosts[i] != 0)
cout << "Component " << i << ": " << minCosts[i] << endl;
}
return 0;
}

You might also like