Skip to content
Merged
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
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