Skip to content
32 changes: 32 additions & 0 deletions LeetCode/Algorithms/CountSubsetsWithSumK.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
int mod = (int)(1e9 + 7);
int f(vector<int> &arr, int ind, int sum, vector<vector<int>> &dp) {
// if(sum == 0) return 1;
if(ind == 0) {
if(sum == 0 && arr[0] == 0) return 2; // 0 0 1 2 3, target = 5 - to handle case where multiple 0's
if(sum == 0) return 1; //
return arr[0] == sum;
// if(sum == 0 || sum == arr[0]) return 1;
// return 0;
}
if(dp[ind][sum] != -1) return dp[ind][sum];
// not take
int notTake = f(arr, ind - 1, sum, dp);

// take
int take = 0;
if(sum >= arr[ind]) {
take = f(arr, ind -1, sum - arr[ind], dp);
}

return dp[ind][sum] = (take + notTake) % mod;
}

int findWays(vector<int>& arr, int k)
{
// Write your code here.
int n = arr.size();
vector<vector<int>> dp(n, vector<int>(k + 1, -1));
return f(arr, n-1, k, dp);
}


78 changes: 78 additions & 0 deletions LeetCode/Algorithms/DisjoinSet.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
#include <bits/stdc++.h>
using namespace std;
class DisjoinSet {
vector<int> rank, parent, size;

public:
DisjoinSet(int n) {
rank.resize(n + 1, 0);
size.resize(n + 1, 0);
parent.resize(n + 1);
for(int i=0; i<=n; i++) {
parent[i] = i;
size[i] = 1;
}
}

int findUPar(int node) {
if(node == parent[node]) {
return node;
}
return parent[node] = findUPar(parent[node]);
}

void UnionByRank(int u, int v) {
int ulp_u = findUPar(u);
int ulp_v = findUPar(v);

if(ulp_u == ulp_v) {
return;
} else if(rank[ulp_v] > rank[ulp_u]) {
parent[ulp_u] = ulp_v;
} else if(rank[ulp_u] > rank[ulp_v]) {
parent[ulp_v] = ulp_u;
} else if(rank[ulp_u] == rank[ulp_v]) {
parent[ulp_v] = ulp_u;
rank[ulp_v]++;
}
}

void UnionBySize(int u, int v) {
int ulp_u = parent[u];
int ulp_v = parent[v];

if(ulp_u == ulp_v) return;
if(size[ulp_u] > size[ulp_v]) {
size[ulp_u] += size[ulp_v];
parent[ulp_v] = ulp_u;
} else {
size[ulp_v] += size[ulp_u];
parent[ulp_u] = ulp_v;
}
}
};

int main() {
DisjoinSet ds(7);
ds.UnionByRank(1, 2);
ds.UnionByRank(2, 3);
ds.UnionByRank(4, 5);
ds.UnionByRank(6, 7);
ds.UnionByRank(5, 6);
// ds.UnionByRank(1, 2);

// if 3 and 7 same or not
if(ds.findUPar(3) == ds.findUPar(7)) {
cout<<"Same"<<endl;
} else {
cout<<"Not Same"<<endl;
}
ds.UnionByRank(3, 7);
if(ds.findUPar(3) == ds.findUPar(7)) {
cout<<"Same"<<endl;
} else {
cout<<"Not Same"<<endl;
}

return 0;
}
50 changes: 50 additions & 0 deletions LeetCode/Algorithms/Easy/MeetingRooms.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/**
* Definition of Interval:
* class Interval {
* public:
* int start, end;
* Interval(int start, int end) {
* this->start = start;
* this->end = end;
* }
* }
*/

class Solution {
public:
// struct myComp {
// bool operator() (Interval &a, Interval &b) {
// return a.start < b.start;
// }
// };

static bool myComp(const Interval &a, const Interval &b) {
return a.start < b.start;
}

bool canAttendMeetings(vector<Interval>& intervals) {
if(intervals.empty()) return true;
sort(intervals.begin(), intervals.end(), myComp);

// sort(intervals.begin(), intervals.end(), myComp());

// sort(intervals.begin(), intervals.end(), [](Interval &a, Interval &b) {
// return a.start < b.start;
// });

int prevEnd = intervals[0].end;

for(int i=1; i<intervals.size(); i++) {
if(prevEnd <= intervals[i].start) {
prevEnd = intervals[i].end;
continue;
} else {
return false;
}
}
return true;
}
};


// All the sorting method results and functions work
66 changes: 66 additions & 0 deletions LeetCode/Algorithms/Hard/CountSubarraysWithScoreLessThanK.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#define ll long long
class Solution {
public:
long long countSubarrays(vector<int>& nums, long long k) {
ll left = 0, right = 0; // window is [left, right)
ll sum = 0; // sum of nums[left ... right -1]
ll count = 0;

ll n = nums.size();

while(left < n) {
// find larget valid window
while(right < n && (sum + nums[right] * (right - left + 1) < k)) {
sum += nums[right];
right++;
}

// All subarrays starting at 'left' and ending before 'right' are valid
count += right - left;

// Slide the window forward by removing nums[left]
// If we couldn't even include nums[left], move both pointer past it
if(left == right) {
right++;
} else {
sum -= nums[left];
}

left++;
}

return count;
}
};

/*

Time Complexity - O(N)
Space Complexity - O(1)

Counting Logic
0 1 2 3 4 5
a[]: [2, 1, 1, 3, 4, 1], k = 15
| |
start end

1. Increase end till sum * len < k
2. Count = end - start
3. Increase start pointer and again when sum * len >= k,
calculate count and increment start++ pointer

[start, End) => largest subarray starting at '0' which has (sum * size) < k

start, end - 1 ie 4 * 3 < 15

Count of such Subarrays start at '0' = 3

in general [start, start], [start, start+ 1], ... [start, end-1]

count = end - start

// Two Pointer + Sliding Window



*/
111 changes: 111 additions & 0 deletions LeetCode/Algorithms/Hard/FindMinimumDiameterAfterMergingTwoTrees.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
class Solution {
public:
int diameter(unordered_map<int, vector<int>>& adj, int n) {
// pick any node and find the farthest from that node
vector<bool> visited(n, false);
queue<int> q;
q.push(0);
visited[0] = true;
int last;
while(!q.empty()) {
int size = q.size();
for(int i=0; i<size; ++i) {
last = q.front();
q.pop();

visited[last] = true;
for(int ele: adj[last]) {
if(!visited[ele]) {
q.push(ele);
}
}
}
}

// Now find the farthest node from here and hop == diameter
q.push(last);
int hop = 0;
vector<int> vis(n, false);
vis[last] = true;
while(!q.empty()) {
int size = q.size();
for(int i=0; i<size; ++i) {
int curr = q.front();
q.pop();

vis[curr] = true;
for(int ele: adj[curr]) {
if(!vis[ele]) {
q.push(ele);
}
}
}
hop += 1;
}
return hop-1;
}

int findDiameter(vector<vector<int>>& edges) {
if(edges.size() == 0) {
return 0;
}

unordered_map<int, vector<int>> adj;
unordered_set<int> nodes;

for(auto &edge: edges) {
cout<<edge[0]<<" "<<edge[1]<<endl;
adj[edge[0]].push_back(edge[1]);
adj[edge[1]].push_back(edge[0]);
nodes.insert(edge[0]);
nodes.insert(edge[1]);
}

return diameter(adj, nodes.size());
}

int minimumDiameterAfterMerge(vector<vector<int>>& edges1, vector<vector<int>>& edges2) {
int dia1 = findDiameter(edges1);
int dia2 = findDiameter(edges2);

int radius1 = (dia1 + 1) / 2;
int radius2 = (dia2 + 1) / 2;
int sum = 1 + radius1 + radius2;

return max(sum, max(dia1, dia2));
}
};

// Time Complexity - O(N + M)
// Space Complexity - O(N + M)

// Follow-up
// 1. Prove the greedy algo.
// 2. Find al diameters of a tree

// How to find optimal path?

// Note: It is always optimal to join at midpoint of diameter

// total height = h1 / 2 + bridge (1) + h2 / 2

// Cases

// Even-Even ==> ans = 1 + dia1 / 2 + dia2 / 2
// Odd-Even ==> ans = 1 + (dia1 + 1) / 2 + dia2 / 2
// Odd-Odd ==> ans = 1 + (dia1 + 1) / 2 + (dia2 + 1) / 2

// How to find diameter of undirected tree?
// Greedy Algorithm
// 1. Choose any node (a)
// 2. Find farthest node from a (b) --> BFS(levelorder)
// 3. Find farthest node from b and count no. of hops / levels
// diameter = no. of hops

// Case 1: Your chosen node is already on diameter

// Joining may not always contain diameter

// max diameter = max{dia1, dia2, 1 + (dia1 + 1) / 2 + (dia2 + 1) / 2}


42 changes: 42 additions & 0 deletions LeetCode/Algorithms/Hard/LargestRectangleInHistogram.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
class Solution {
public:
int largestRectangleArea(vector<int>& heights) {
int maxArea = 0;
stack<pair<int, int>> stk; // (index, height)
int n = heights.size();
for(int i=0; i<heights.size(); i++) {
int start = i;

// remove top of stack and calculate area
// and set index as the index of popped out element
while(!stk.empty() && stk.top().second > heights[i]) {
auto temp = stk.top();
stk.pop();

int index = temp.first;
int height = temp.second;
maxArea = max(maxArea, height * (i - index));
start = index;
}

stk.push({start, heights[i]});
}

// calculate the area of the remaining elements
// in stack, area to be calcualted by condering from
// length of height array
while(!stk.empty()) {
auto temp = stk.top();
stk.pop();

int index = temp.first;
int height = temp.second;

maxArea = max(maxArea, height * (n - index));
}
return maxArea;
}
};

// Time Complexity - O(N)
// Space Complexity - O(N)
Loading