diff --git a/LeetCode/Algorithms/CountSubsetsWithSumK.cpp b/LeetCode/Algorithms/CountSubsetsWithSumK.cpp new file mode 100644 index 0000000..8e43621 --- /dev/null +++ b/LeetCode/Algorithms/CountSubsetsWithSumK.cpp @@ -0,0 +1,32 @@ +int mod = (int)(1e9 + 7); +int f(vector &arr, int ind, int sum, vector> &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& arr, int k) +{ + // Write your code here. + int n = arr.size(); + vector> dp(n, vector(k + 1, -1)); + return f(arr, n-1, k, dp); +} + + diff --git a/LeetCode/Algorithms/DisjoinSet.cpp b/LeetCode/Algorithms/DisjoinSet.cpp new file mode 100644 index 0000000..e55db19 --- /dev/null +++ b/LeetCode/Algorithms/DisjoinSet.cpp @@ -0,0 +1,78 @@ +#include +using namespace std; +class DisjoinSet { + vector 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"<& 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 + + + +*/ \ No newline at end of file