├── OS └── fcfs.c ├── Arrays ├── sieve.cpp ├── binary_search.cpp ├── sliding_window.cpp └── catalan_number.cpp ├── Advanced Topics ├── line_sweep.cpp ├── seg_tree.cpp └── manacher.cpp ├── Trees ├── serialize_deserialize.cpp ├── lca.cpp ├── height.cpp ├── diameter_tree.cpp ├── level_order_traversal.cpp ├── recursive_traversals.cpp ├── trie.cpp ├── flatten_tree.cpp ├── segment_tree.cpp └── iterative_traversal.cpp ├── Dynamic Programming ├── Geeks For Geeks Top 20 │ ├── 19-box-stacking.cpp │ ├── test.cpp │ ├── 6-Longest-Increasing-Path.cpp │ ├── 5-Count-Distance.cpp │ ├── 18-dice-throw.cpp │ ├── 2-Longest-Increasing-Subseq.cpp │ ├── 20-egg-dropping.cpp │ ├── 14-Rod-cutting.cpp │ ├── 1-Longest-Common-Subseq.cpp │ ├── 3-Edit-Distance.cpp │ ├── 15-Coin-Change.cpp │ ├── 17-maximum-product-cutting.cpp │ ├── 9-Knapsack.cpp │ ├── 12-Matrix-chain-multiplication.cpp │ ├── 16-word-break.cpp │ ├── 4-Minimum-Partition.cpp │ ├── 13-Partition.cpp │ ├── 7-Subset-Sum.cpp │ ├── 8-Optimal-Stratergy-For-Game.cpp │ ├── 11-Shortest-common-super-sequence.cpp │ └── 10-Boolean.cpp ├── At Coder DP educational contest │ ├── E-Knapsack2.cpp │ ├── J-Sushi.cpp │ ├── M-Candies.cpp │ ├── Problem-List.md │ ├── K-Stones.cpp │ ├── A-Frog1.cpp │ ├── B-Frog2.cpp │ ├── L-Deque.cpp │ ├── I-Coins.cpp │ ├── G-LongestPath.cpp │ ├── F-LCS.cpp │ ├── H-Grid1.cpp │ ├── D-Knapsack1.cpp │ └── C-Vacation.cpp └── Top Coder │ ├── shortest_path.cpp │ ├── coin.cpp │ ├── lis.cpp │ ├── flower_garden.cpp │ ├── zigzag.cpp │ └── bad_neighbours.cpp ├── Searching and Sorting ├── binary_search.cpp ├── inversion_count.cpp ├── bubble.cpp ├── insertionsort.cpp ├── quicksort.cpp └── mergesort.cpp ├── Graphs ├── dfs-lca.cpp ├── dfs.cpp ├── dfs-cycle-in-directed-graph.cpp ├── dfs-connected-components.cpp ├── bfs.cpp ├── dfs-graph-coloring.cpp ├── dfs-topological-sort.cpp ├── bi-partite.cpp ├── dfs-ancestors-dag.cpp ├── dfs-2d-matrix.cpp ├── dfs-exit-entry.cpp ├── dsu-kruskal.cpp ├── bfs-2d-matrix.cpp ├── dsu.cpp ├── bfs-shortest-path-in-an-unweighted-graph.cpp ├── dijisktra.cpp ├── 0-1-bfs.cpp ├── graph_notes.md ├── convexhull.cpp └── bidirectional-bfs.cpp ├── .gitignore ├── Tries └── trie.cpp ├── LinkedList └── ll.cpp └── README.md /OS/fcfs.c: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Arrays/sieve.cpp: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Arrays/binary_search.cpp: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Arrays/sliding_window.cpp: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Advanced Topics/line_sweep.cpp: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Trees/serialize_deserialize.cpp: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Dynamic Programming/Geeks For Geeks Top 20/19-box-stacking.cpp: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Dynamic Programming/At Coder DP educational contest/E-Knapsack2.cpp: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Searching and Sorting/binary_search.cpp: -------------------------------------------------------------------------------- 1 | // Three templates of Binary Search -------------------------------------------------------------------------------- /Dynamic Programming/Geeks For Geeks Top 20/test.cpp: -------------------------------------------------------------------------------- 1 | //To-Do 2 | // Number 6 and 10 -------------------------------------------------------------------------------- /Graphs/dfs-lca.cpp: -------------------------------------------------------------------------------- 1 | // https://www.hackerrank.com/topics/lowest-common-ancestor 2 | -------------------------------------------------------------------------------- /Dynamic Programming/Top Coder/shortest_path.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int main() 4 | { 5 | 6 | } -------------------------------------------------------------------------------- /Advanced Topics/seg_tree.cpp: -------------------------------------------------------------------------------- 1 | // https://www.hackerearth.com/practice/data-structures/advanced-data-structures/segment-trees/tutorial/ -------------------------------------------------------------------------------- /Searching and Sorting/inversion_count.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | int main() 5 | { 6 | 7 | } -------------------------------------------------------------------------------- /Dynamic Programming/At Coder DP educational contest/J-Sushi.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | int main() 5 | { 6 | 7 | } 8 | -------------------------------------------------------------------------------- /Dynamic Programming/At Coder DP educational contest/M-Candies.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | int main() 5 | { 6 | 7 | } -------------------------------------------------------------------------------- /Dynamic Programming/Geeks For Geeks Top 20/6-Longest-Increasing-Path.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | int main() 5 | { 6 | 7 | } -------------------------------------------------------------------------------- /Advanced Topics/manacher.cpp: -------------------------------------------------------------------------------- 1 | // https://www.hackerearth.com/practice/algorithms/string-algorithm/manachars-algorithm/tutorial/ 2 | // https://cp-algorithms.com/string/manacher.html 3 | -------------------------------------------------------------------------------- /Dynamic Programming/At Coder DP educational contest/Problem-List.md: -------------------------------------------------------------------------------- 1 | #### Problem List 2 | - [x] A 3 | - [x] B 4 | - [x] C 5 | - [x] D 6 | - [ ] E 7 | - [x] F 8 | - [x] G 9 | - [x] H 10 | - [x] I 11 | - [ ] J 12 | - [x] K 13 | - [ ] L 14 | - [ ] M 15 | - [ ] N 16 | - [ ] O 17 | - [ ] P 18 | - [ ] Q 19 | - [ ] R 20 | - [ ] S 21 | - [ ] T 22 | - [ ] U 23 | - [ ] V 24 | - [ ] W 25 | - [ ] X 26 | - [ ] Y 27 | - [ ] Z 28 | -------------------------------------------------------------------------------- /Dynamic Programming/Geeks For Geeks Top 20/5-Count-Distance.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | int count_distance(int n) 5 | { 6 | int dp[n+1]={0}; 7 | dp[0] = 1; dp[1] = 1; dp[2] = 2; 8 | for (int i=3; i<=n; i++) 9 | dp[i] = dp[i-1] + dp[i-2] + dp[i-3]; 10 | 11 | return dp[n]; 12 | } 13 | int main() 14 | { 15 | int n; cin>>n; 16 | cout< 2 | using namespace std; 3 | void BubbleSort(vector &arr) { 4 | int i, j; 5 | int n = arr.size(); 6 | for (i = 0; i < n-1; i++) 7 | for (j = 0; j < n-i-1; j++) 8 | if (arr[j] > arr[j+1]) 9 | swap(arr[j], arr[j+1]); 10 | 11 | } 12 | int main() 13 | { 14 | vector arr = {9,3,4,1,-1,0,10,100,-3}; 15 | BubbleSort(arr); 16 | cout<<"Sorted Array"< 2 | using namespace std; 3 | 4 | int numRollsToTarget(int d, int f, int target) { 5 | vector dp(target + 1); 6 | dp[0] = 1; 7 | for (int i = 1; i <= d; ++i) { 8 | vector dp1(target + 1); 9 | for (int j = 1; j <= f; ++j) 10 | for (auto k = j; k <= target; ++k) 11 | dp1[k] = (dp1[k] + dp[k - j]) % 1000000007; 12 | swap(dp, dp1); 13 | } 14 | return dp[target]; 15 | } 16 | 17 | int main() 18 | { 19 | cout< 2 | using namespace std; 3 | 4 | int main() 5 | { 6 | int n, k; 7 | cin>>n>>k; 8 | vector a(n); 9 | for(int& x : a) { 10 | cin>>x; 11 | } 12 | vector dp(k + 1); 13 | for(int stones = 0; stones <= k; ++stones) { 14 | for(int x : a) { 15 | if(stones >= x && !dp[stones-x]) { 16 | dp[stones] = true; 17 | } 18 | } 19 | } 20 | if(dp[k]) 21 | cout<<"First"; 22 | else cout<<"Second"; 23 | return 0; 24 | } 25 | -------------------------------------------------------------------------------- /Dynamic Programming/Geeks For Geeks Top 20/2-Longest-Increasing-Subseq.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int main() 4 | { 5 | int n; cin>>n; 6 | int arr[n]; 7 | for(int i=0;i>arr[i]; 9 | 10 | int lis[n]; 11 | for(int i=0;ilis[j]) 19 | lis[j] = lis[i]+1; 20 | } 21 | } 22 | 23 | int ans = 1; 24 | for(int i=0;i 2 | using namespace std; 3 | int main() 4 | { 5 | int n; cin>>n; 6 | int arr[n]; 7 | for(int i=0;i>arr[i]; 10 | } 11 | int sum; cin>>sum; 12 | int min_arr[sum+1]; 13 | min_arr[0]=0; 14 | 15 | for(int i=1;i<=sum;i++) 16 | min_arr[i] = INT_MAX; 17 | 18 | for(int i=1;i<=sum;i++) 19 | { 20 | for(int j=0;j 2 | using namespace std; 3 | int main() 4 | { 5 | int t;cin>>t; 6 | while(t--){ 7 | int n; cin>>n; 8 | int arr[n]; 9 | for(int i=0;i>arr[i]; 11 | 12 | int lis[n]; 13 | for(int i=0;ilis[j]) 21 | lis[j] = lis[i]+1; 22 | } 23 | } 24 | 25 | int ans = 1; 26 | for(int i=0;i 4 | using namespace std; 5 | 6 | int eggDrop(int N, int K) 7 | { 8 | int dp[N+1][K+1] = {0}; 9 | int m = 0; 10 | while (dp[m][K] < N) { 11 | m++; 12 | for (int k = 1; k <= K; ++k) 13 | dp[m][k] = dp[m - 1][k - 1] + dp[m - 1][k] + 1; 14 | } 15 | return m; 16 | } 17 | 18 | int main() 19 | { 20 | int n = 2, k = 36; 21 | cout< 2 | using namespace std; 3 | 4 | int main() 5 | { 6 | long long int n; cin>>n; 7 | vector arr; 8 | for(int i=0;i>x; 11 | arr.push_back(x); 12 | } 13 | int dp[n+1]; 14 | dp[0]=0; 15 | dp[1]=abs(arr[0]-arr[1]); 16 | // cout< 2 | using namespace std; 3 | int cutRod(int price[], int n) 4 | { 5 | int val[n+1]; 6 | val[0] = 0; 7 | int i, j; 8 | 9 | for (i = 1; i<=n; i++) 10 | { 11 | int max_val = INT_MIN; 12 | for (j = 0; j < i; j++) 13 | max_val = max(max_val, price[j] + val[i-j-1]); 14 | val[i] = max_val; 15 | } 16 | 17 | return val[n]; 18 | } 19 | 20 | int main() 21 | { 22 | int arr[] = {1, 5, 8, 9, 10, 17, 17, 20}; 23 | int size = sizeof(arr)/sizeof(arr[0]); 24 | printf("Maximum Obtainable Value is %dn", cutRod(arr, size)); 25 | getchar(); 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /Dynamic Programming/At Coder DP educational contest/B-Frog2.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | const int INF = 1e9 + 5; 4 | int main() 5 | { 6 | long long int n; cin>>n; 7 | long long int k; cin>>k; 8 | vector arr; 9 | for(int i=0;i>x; 12 | arr.push_back(x); 13 | } 14 | vector dp(n, INF); 15 | dp[0] = 0; 16 | for(int i = 0; i < n; ++i) { 17 | for(int j = i + 1; j <= i + k; ++j) { 18 | if(j < n) { 19 | int cost = dp[i] + abs(arr[i] - arr[j]); 20 | dp[j] = min(dp[j], cost); 21 | } 22 | } 23 | } 24 | 25 | cout< 2 | using namespace std; 3 | 4 | int main() 5 | { 6 | int n; 7 | cin>>n; 8 | vector a(n); 9 | for(int i=0;i=0;L--) 15 | { 16 | for(int R=L;R 2 | using namespace std; 3 | 4 | bool visited[1000]={false}; 5 | void dfs(int v,vector> &adj) 6 | { 7 | visited[v]=true; 8 | cout<> &adj) 15 | { 16 | adj[v].push_back(w); 17 | adj[w].push_back(v); 18 | } 19 | 20 | int main() 21 | { 22 | int n = 5; 23 | vector> adj(n); 24 | addEdge(0, 1,adj); 25 | addEdge(0, 2,adj); 26 | addEdge(1, 2,adj); 27 | addEdge(2, 0,adj); 28 | addEdge(2, 3,adj); 29 | addEdge(3, 3,adj); 30 | dfs(2,adj); 31 | } -------------------------------------------------------------------------------- /Dynamic Programming/Geeks For Geeks Top 20/1-Longest-Common-Subseq.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int lcs(string a, string b) 4 | { 5 | int r = a.length(), c = b.length(); 6 | int dp[r+1][c+1]; 7 | for(int i=0;i<=r;i++) 8 | dp[i][0] = 0; 9 | 10 | for(int i=0;i<=c;i++) 11 | dp[0][i] = 0; 12 | 13 | for(int i=1;i<=r;i++) 14 | for(int j=1;j<=c;j++) 15 | { 16 | if(a[i-1] == b[j-1]) 17 | dp[i][j] = dp[i-1][j-1]+1; 18 | else 19 | dp[i][j] = max(dp[i-1][j],dp[i][j-1]); 20 | 21 | } 22 | return dp[r][c]; 23 | } 24 | 25 | int main() 26 | { 27 | string a = "ABCDGH"; 28 | string b = "AEDFHR"; 29 | cout< 2 | using namespace std; 3 | int edit_distance(string a, string b) 4 | { 5 | int r = a.length(), c = b.length(); 6 | int dp[r+1][c+1]; 7 | for(int i=0;i<=r;i++) 8 | dp[i][0] = 0; 9 | 10 | for(int i=0;i<=c;i++) 11 | dp[0][i] = 0; 12 | 13 | for(int i=0;i<=r;i++) 14 | for(int j=0;j<=c;j++) 15 | { 16 | int cost = 1; 17 | if(a[i-1] == b[j-1]) 18 | cost = 0; 19 | else 20 | dp[i][j] = min(min(dp[i-1][j],dp[i][j-1]),dp[i-1][j-1])+1; 21 | 22 | } 23 | return dp[r][c]; 24 | } 25 | 26 | int main() 27 | { 28 | string a = "ABCDGH"; 29 | string b = "AEDFHR"; 30 | cout< 2 | using namespace std; 3 | void InsertionSort(vector &arr) { 4 | for (int i = 1; i < arr.size(); i++) 5 | { 6 | int key = arr[i]; 7 | int j = i - 1; 8 | 9 | /* Move elements of arr[0..i-1], that are 10 | greater than key, to one position ahead 11 | of their current position */ 12 | while (j >= 0 && arr[j] > key) 13 | { 14 | arr[j + 1] = arr[j]; 15 | j = j - 1; 16 | } 17 | arr[j + 1] = key; 18 | } 19 | 20 | } 21 | int main() 22 | { 23 | vector arr = {9,3,4,1,-1,0,10,100,-3}; 24 | InsertionSort(arr); 25 | cout<<"Sorted Array"<left,n1,n2); 19 | TreeNode* r = lca(root->right,n1,n2); 20 | if(l && r) return root; 21 | return l != NULL ? l : r; 22 | } 23 | TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) { 24 | return lca(root,p,q); 25 | }rr 26 | }; 27 | -------------------------------------------------------------------------------- /Dynamic Programming/Geeks For Geeks Top 20/15-Coin-Change.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #define pb push_back 3 | using namespace std; 4 | int coinChange(vector& coins, int amount) { 5 | int mx = amount + 1; 6 | int dp[amount + 1]; 7 | 8 | for (int i = 0; i <= amount; i++) 9 | dp[i] = mx; 10 | 11 | dp[0] = 0; 12 | 13 | for (int i = 1; i <= amount; i++) { 14 | for (int j = 0; j < coins.size(); j++) { 15 | if (coins[j] <= i) { 16 | dp[i] = min(dp[i], dp[i - coins[j]] + 1); 17 | } 18 | } 19 | } 20 | 21 | return dp[amount] > amount ? -1 : dp[amount]; 22 | 23 | } 24 | int main() 25 | { 26 | vector coins; 27 | coins.pb(1); 28 | coins.pb(2); 29 | coins.pb(5); 30 | int amount = 11; 31 | cout< visited, dfsVisited; 3 | map> adj; 4 | 5 | bool dfs(int src) { 6 | visited.insert(src); 7 | dfsVisited.insert(src); 8 | for(auto nb:adj[src]) { 9 | if(visited.count(nb)==false) { 10 | if(dfs(nb)) return true; 11 | } else if(dfsVisited.count(nb)) { 12 | return true; 13 | } 14 | 15 | } 16 | dfsVisited.erase(src); 17 | return false; 18 | } 19 | int Solution::solve(int A, vector > &B) { 20 | visited.clear(); adj.clear(); dfsVisited.clear(); 21 | for(auto edge:B) { 22 | adj[edge[0]].push_back(edge[1]); 23 | } 24 | for(int i=1;i<=A;i++) 25 | if(visited.count(i)==false && dfs(i)) return true; 26 | return false; 27 | } 28 | -------------------------------------------------------------------------------- /Graphs/dfs-connected-components.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | bool visited[1000]={false}; 5 | void dfs(int v,vector> &adj) 6 | { 7 | visited[v]=true; 8 | //cout<> &adj) 15 | { 16 | adj[v].push_back(w); 17 | adj[w].push_back(v); 18 | } 19 | 20 | int main() 21 | { 22 | int n = 5; 23 | vector> adj(n); 24 | addEdge(0, 1,adj); 25 | addEdge(1, 2,adj); 26 | addEdge(3, 4,adj); 27 | int c = 0; 28 | for (int i=0; i 2 | using namespace std; 3 | 4 | // int integerBreak(int n) { 5 | // if(n==2) return 1; 6 | // if(n==3) return 2; 7 | // if(n==4) return 4; 8 | // int res = 1; 9 | // while (n > 4) 10 | // { 11 | // n -= 3; 12 | // res *= 3; // Keep multiplying 3 to res 13 | // } 14 | // return (n * res); 15 | // } 16 | 17 | int integerBreak(int n) { 18 | int val[n+1]; 19 | val[0] = val[1] = 0; 20 | 21 | for (int i = 1; i <= n; i++) 22 | { 23 | int max_val = 0; 24 | for (int j = 1; j <= i/2; j++) 25 | { 26 | int t = max( j*val[i-j],(i-j)*j); 27 | max_val = max(max_val,t); 28 | 29 | } 30 | val[i] = max_val; 31 | } 32 | return val[n]; 33 | } 34 | 35 | 36 | int main() 37 | { 38 | int n; cin>>n; 39 | cout< 2 | using namespace std; 3 | int partition (vector &arr, int low, int high) 4 | { 5 | int pivot = arr[high]; // pivot 6 | int i = low; // Index of smaller element 7 | int j = high; 8 | while(ipivot) 15 | { 16 | j--; 17 | } 18 | if(i &arr,int l,int h) 27 | { 28 | if(l arr = {9,3,4,1,-1,0,10,100,-3}; 37 | QuickSort(arr,0,arr.size()-1); 38 | cout<<"Sorted Array"< 2 | using namespace std; 3 | 4 | int knapsack(vector &val,vector &weights,int W) 5 | { 6 | int dp[val.size()+1][W+1]; 7 | 8 | for(int i=0;i<=val.size();i++) 9 | { 10 | for(int j=0;j<=W;j++) 11 | { 12 | if(i==0 || j==0) 13 | dp[i][j] = 0; 14 | else if(weights[i-1]<=j) 15 | dp[i][j] = max(dp[i-1][j],val[i-1] + dp[i-1][j-weights[i-1]]); 16 | else 17 | dp[i][j] = dp[i-1][j]; 18 | } 19 | } 20 | return dp[val.size()][W]; 21 | 22 | } 23 | 24 | int main() 25 | { 26 | vector values; 27 | values.push_back(60); 28 | values.push_back(100); 29 | values.push_back(120); 30 | 31 | vector weights; 32 | weights.push_back(10); 33 | weights.push_back(20); 34 | weights.push_back(30); 35 | 36 | int W = 50; 37 | 38 | printf("%d", knapsack(values,weights,W)); 39 | return 0; 40 | } -------------------------------------------------------------------------------- /Dynamic Programming/Geeks For Geeks Top 20/12-Matrix-chain-multiplication.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int matrix_chain(int m[],int n) 4 | { 5 | int dp[n+1][n+1]; 6 | int q = 0; 7 | 8 | for(int i=0;i 2 | using namespace std; 3 | 4 | bool wordBreak(string s, vector& wordDict) { 5 | unordered_set dict(wordDict.begin(), wordDict.end()); 6 | if(dict.size()==0) return false; 7 | 8 | vector dp(s.size()+1,false); 9 | dp[0]=true; 10 | 11 | for(int i=1;i<=s.size();i++) 12 | { 13 | for(int j=i-1;j>=0;j--) 14 | { 15 | if(dp[j]) 16 | { 17 | string word = s.substr(j,i-j); 18 | if(dict.find(word)!= dict.end()) 19 | { 20 | dp[i]=true; 21 | break; //next i 22 | } 23 | } 24 | } 25 | } 26 | 27 | return dp[s.size()]; 28 | } 29 | 30 | int main() 31 | { 32 | string s = "leetcode"; 33 | vector wordDict = {"leet", "code"}; 34 | cout< 2 | using namespace std; 3 | 4 | int main() 5 | { 6 | int N; cin>>N; 7 | double p[N+1]; 8 | p[0] = 0.0; 9 | for(int i=1;i<=N;i++) 10 | cin>>p[i]; 11 | double dp[N+1][N+1]; 12 | memset(dp,0,sizeof(dp)); 13 | dp[0][0] = 1; 14 | for(int i=1;i<=N;i++) 15 | { 16 | for(int j=0;j<=i;j++) 17 | { 18 | if(j==0) 19 | dp[i][j] = dp[i-1][j] * (1-p[i]); 20 | else 21 | { 22 | dp[i][j] = dp[i - 1][j]*(1.0 - p[i]) 23 | + dp[i - 1][j - 1] * p[i]; 24 | } 25 | 26 | } 27 | } 28 | for(int i=0;i<=N;i++){ 29 | for(int j=0;j<=N;j++) 30 | cout< 2 | using namespace std; 3 | bool visited[100000]={false}; 4 | void dfs(int v,vector> &adj,vector &dp) 5 | { 6 | visited[v]=true; 7 | // cout<>N>>M; 22 | vector> g(N+1); 23 | for(int i=0;i>x>>y; 27 | g[x].push_back(y); 28 | } 29 | vector dp(N+1); 30 | for (int i = 1; i <= N; i++) { 31 | if (!visited[i]) 32 | dfs(i, g, dp); 33 | } 34 | int ans = 0; 35 | 36 | // Traverse and find the maximum of all dp[i] 37 | for (int i = 1; i <= N; i++) { 38 | ans = max(ans, dp[i]); 39 | } 40 | cout< 2 | using namespace std; 3 | // Check if path exists from src to dest using BFS 4 | // https://cp-algorithms.com/graph/breadth-first-search.html 5 | void addEdge(vector adj[],int v,int u) 6 | { 7 | adj[v].push_back(u); 8 | adj[u].push_back(v); 9 | } 10 | void bfs(vector adj[],int s,int V) 11 | { 12 | queue q; 13 | vector used(V); 14 | q.push(s); 15 | used[s] = true; 16 | while (!q.empty()) { 17 | int v = q.front(); 18 | q.pop(); 19 | cout< adj[V]; 35 | addEdge(adj, 0, 1); 36 | addEdge(adj, 0, 4); 37 | addEdge(adj, 1, 2); 38 | addEdge(adj, 1, 3); 39 | addEdge(adj, 1, 4); 40 | addEdge(adj, 2, 3); 41 | addEdge(adj, 3, 4); 42 | printGraph(adj, V); 43 | bfs(adj,0,V); 44 | return 0; 45 | } -------------------------------------------------------------------------------- /Dynamic Programming/Top Coder/flower_garden.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | vector getOrdering(vector height, vector bloom, vector wilt) 5 | { 6 | vector used = vector(height.size()); 7 | vector res; 8 | for (size_t i=0;iwilt[k]) ); 20 | if( (height[j]>height[k]) && blocking ) 21 | { 22 | found = false; break; 23 | } 24 | } 25 | if ( found && (mxH 2 | #include 3 | using namespace std; 4 | int main() 5 | { 6 | int t; cin>>t; 7 | 8 | while(t--){ 9 | int n; cin>>n; 10 | int v[n]; 11 | for(int i=0;i>v[i]; 12 | 13 | vector arr; 14 | 15 | arr.push_back(v[0]); 16 | 17 | for(int i=1;i0) b[0]=1; 49 | 50 | int c = 1; 51 | for(int i=1;i0) b[i] = 1; 54 | if(b[i]!=b[i-1]) 55 | c++; 56 | } 57 | cout< 2 | using namespace std; 3 | 4 | // A BT Node 5 | struct Node 6 | { 7 | int data; 8 | struct Node* left, *right; 9 | }; 10 | 11 | int height(Node* node) 12 | { 13 | if (node == NULL) 14 | return 0; 15 | else 16 | { 17 | 18 | int lheight = height(node->left); 19 | int rheight = height(node->right); 20 | 21 | if (lheight > rheight) 22 | return(lheight + 1); 23 | else return(rheight + 1); 24 | } 25 | } 26 | // Utility function to create new Node 27 | Node *newNode(int data) 28 | { 29 | Node *temp = new Node; 30 | temp->data = data; 31 | temp->left = temp->right = NULL; 32 | return (temp); 33 | } 34 | 35 | // Driver program 36 | int main() 37 | { 38 | // Let us construct the Tree shown in the above figure 39 | Node *root = newNode(1); 40 | root->left = newNode(2); 41 | root->right = newNode(3); 42 | root->left->left = newNode(4); 43 | root->left->right = newNode(5); 44 | 45 | cout< 3 | using namespace std; 4 | 5 | vector color; 6 | int dfs_timer = 0; 7 | 8 | void addEdge(int v, int w,vector> &adj) 9 | { 10 | adj[v].push_back(w); 11 | adj[w].push_back(v); 12 | } 13 | bool dfs(int v, vector> &adj) { 14 | color[v] = 1; 15 | for (int u : adj[v]) 16 | { 17 | if(color[u]==1) 18 | return true; 19 | if (color[u] == 0 && dfs(u,adj)) 20 | return true; 21 | } 22 | color[v] = 2; 23 | return false; 24 | } 25 | int main() 26 | { 27 | int n = 4; 28 | vector> adj(n); 29 | addEdge(0, 1,adj); 30 | addEdge(0, 2, adj); 31 | addEdge(1, 2, adj); 32 | addEdge(2, 0, adj); 33 | addEdge(2, 3, adj); 34 | addEdge(3, 3, adj); 35 | color.resize(n); 36 | // for (int i = 0; i < V; i++) 37 | // if (color[i] == WHITE) 38 | // if (DFSUtil(i, color) == true) 39 | // return true; 40 | 41 | // return false; 42 | cout< 2 | using namespace std; 3 | 4 | int main() 5 | { 6 | string s,t; 7 | cin>>s>>t; 8 | int n = s.length(); 9 | int m = t.length(); 10 | int dp[n+1][m+1]={0}; 11 | for(int i=0;i<=n;i++) 12 | { 13 | for(int j=0;j<=m;j++) 14 | { 15 | if (i == 0 || j == 0) 16 | dp[i][j] = 0; 17 | else if(s[i-1]==t[j-1]) 18 | { 19 | dp[i][j] = dp[i-1][j-1] + 1; 20 | } 21 | else 22 | { 23 | dp[i][j] = max(dp[i-1][j],dp[i][j-1]); 24 | } 25 | 26 | } 27 | } 28 | // cout<<"Length:"< 0 && j > 0) 32 | { 33 | if (s[i-1] == t[j-1]) 34 | { 35 | ans += s[i-1]; 36 | i--; j--; 37 | } 38 | else if (dp[i-1][j] > dp[i][j-1]) 39 | i--; 40 | else 41 | j--; 42 | } 43 | 44 | // Print the lcs 45 | reverse(ans.begin(), ans.end()); 46 | cout< 2 | using namespace std; 3 | const long long int mod = 1000000007; 4 | long long int sum(long long int a,long long int b) 5 | { 6 | // add two numbers 7 | long long int s = a + b; 8 | 9 | // do a mod with m 10 | s = s % mod; 11 | 12 | return s; 13 | } 14 | int main() 15 | { 16 | long long int r,c; 17 | cin>>r>>c; 18 | long long int grid[r][c]; 19 | 20 | for(long long int i=0;i>c; 25 | if(c=='.') 26 | grid[i][j] = 0; 27 | else 28 | { 29 | grid[i][j] = 1; 30 | } 31 | } 32 | } 33 | 34 | vector > dp(r + 1, vector (c + 1, 0)); 35 | dp[0][1] = 1; 36 | 37 | for (int i = 1; i <= r; i++) 38 | for (int j = 1; j <= c; j++) 39 | if (grid[i - 1][j - 1]==0) 40 | dp[i][j] = sum(dp[i - 1][j],dp[i][j - 1]); 41 | 42 | cout< 3 | using namespace std; 4 | 5 | bool visited[1000]={false}; 6 | stack s; 7 | void dfs(int v,vector> &adj) 8 | { 9 | visited[v]=true; 10 | // cout<> &adj,int V) { 18 | for (int i = 0; i < V; i++) 19 | if (visited[i] == false) 20 | dfs(i,adj); 21 | 22 | // Print contents of stack 23 | while (s.empty() == false) 24 | { 25 | cout << s.top() << " "; 26 | s.pop(); 27 | } 28 | 29 | } 30 | void addEdge(int v, int w,vector> &adj) 31 | { 32 | adj[v].push_back(w); 33 | } 34 | 35 | int main() 36 | { 37 | int n = 6; 38 | vector> adj(n); 39 | addEdge(5, 2, adj); 40 | addEdge(5, 0, adj); 41 | addEdge(4, 0, adj); 42 | addEdge(4, 1, adj); 43 | addEdge(2, 3, adj); 44 | addEdge(3, 1, adj); 45 | topologicalSort(adj,n); 46 | } 47 | 48 | 49 | -------------------------------------------------------------------------------- /Dynamic Programming/Geeks For Geeks Top 20/4-Minimum-Partition.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | // https://www.youtube.com/watch?v=-GtpxG6l_Mc 4 | int partition(vector &arr) 5 | { 6 | int n = arr.size(); 7 | int sum = 0; 8 | for (int i = 0; i < n; i++) 9 | sum += arr[i]; 10 | 11 | int dp[n+1][sum+1]; 12 | 13 | for (int i=0; i<=n; i++) 14 | for (int j=0; j<=sum; j++) 15 | dp[i][j] = 0; 16 | 17 | for (int i = 0; i <= n; i++) 18 | dp[i][0] = true; 19 | 20 | for (int i = 1; i <= sum; i++) 21 | dp[0][i] = false; 22 | 23 | for (int i=1; i<=n; i++) 24 | { 25 | for (int j=0; j<=sum; j++) 26 | { 27 | if (arr[i-1] <= j) 28 | dp[i][j] = (dp[i - 1][j] || dp[i-1][j-arr[i-1]]); 29 | else dp[i][j] = dp[i-1][j]; 30 | } 31 | } 32 | 33 | int diff = INT_MAX; 34 | for (int j=sum/2; j>=0; j--) 35 | { 36 | if (dp[n][j] == true) 37 | { 38 | diff = sum-2*j; 39 | break; 40 | } 41 | } 42 | return diff; 43 | } 44 | 45 | int main() 46 | { 47 | vector arr; 48 | arr.push_back(1); 49 | arr.push_back(5); 50 | arr.push_back(6); 51 | arr.push_back(7); 52 | cout< 3 | using namespace std; 4 | 5 | // A BT Node 6 | struct Node 7 | { 8 | int data; 9 | struct Node* left, *right; 10 | }; 11 | int height(Node* node,int &res) 12 | { 13 | if (node == NULL) 14 | return 0; 15 | int lheight = height(node->left,res); 16 | int rheight = height(node->right,res); 17 | res = max(res,lheight+rheight); 18 | return max(lheight,rheight)+1; 19 | } 20 | int diameter(Node* node) 21 | { 22 | int res = 0; 23 | height(root,res); 24 | return res; 25 | } 26 | // Utility function to create new Node 27 | Node *newNode(int data) 28 | { 29 | Node *temp = new Node; 30 | temp->data = data; 31 | temp->left = temp->right = NULL; 32 | return (temp); 33 | } 34 | 35 | // Driver program 36 | int main() 37 | { 38 | // Let us construct the Tree shown in the above figure 39 | Node *root = newNode(1); 40 | root->left = newNode(2); 41 | root->right = newNode(3); 42 | root->left->left = newNode(4); 43 | root->left->right = newNode(5); 44 | 45 | cout< 3 | using namespace std; 4 | 5 | bool isBipartite(vector>& graph) { 6 | int n = graph.size(); 7 | vector color(n); // 0: uncolored; 1: color A; -1: color B 8 | 9 | queue q; // queue, resusable for BFS 10 | 11 | for (int i = 0; i < n; i++) { 12 | if (color[i]) continue; // skip already colored nodes 13 | 14 | // BFS with seed node i to color neighbors with opposite color 15 | color[i] = 1; // color seed i to be A (doesn't matter A or B) 16 | for (q.push(i); !q.empty(); q.pop()) { 17 | int cur = q.front(); 18 | for (int neighbor : graph[cur]) 19 | { 20 | if (!color[neighbor]) // if uncolored, color with opposite color 21 | { color[neighbor] = -color[cur]; q.push(neighbor); } 22 | 23 | else if (color[neighbor] == color[cur]) 24 | return false; // if already colored with same color, can't be bipartite! 25 | } 26 | } 27 | } 28 | 29 | return true; 30 | } 31 | 32 | int main() 33 | { 34 | vector> grid = {{1,3},{0,2},{1,3},{0,2}}; 35 | cout< 3 | using namespace std; 4 | 5 | bool visited[1000]={false}; 6 | vector st; 7 | unordered_map> m; 8 | void dfs(char v,vector> &adj) 9 | { 10 | visited[v-'0']=true; 11 | cout< t(st.begin(),st.end()); 13 | m[v] = t; 14 | st.push_back(v); 15 | 16 | for (size_t i = 0; i < (int) adj[v].size(); ++i) 17 | { 18 | if(!visited[adj[v][i]-'0']) 19 | { 20 | 21 | dfs(adj[v][i],adj); 22 | 23 | } 24 | } 25 | st.pop_back(); 26 | } 27 | 28 | void addEdge(char v, char w,vector> &adj) 29 | { 30 | adj[v].push_back(w); 31 | } 32 | 33 | int main() 34 | { 35 | int n = 5; 36 | vector> adj(n); 37 | addEdge('A', 'D',adj); 38 | addEdge('A', 'G',adj); 39 | addEdge('G', 'F',adj); 40 | addEdge('G', 'R',adj); 41 | // Store in-degree = 0 nodes and do dfs from them 42 | dfs('A',adj); 43 | for(auto node:m) 44 | { 45 | cout< c = node.second; 47 | for(auto e:c) 48 | cout< 2 | using namespace std; 3 | 4 | bool canPartition(vector& nums) { 5 | int n = nums.size(); 6 | int sum = 0; 7 | for (int i = 0; i < nums.size(); i++) 8 | sum += nums[i]; 9 | if(sum%2==1) 10 | return false; 11 | sum=sum/2; 12 | vector> dp(n, vector(sum+1)); 13 | 14 | for(int i=0;i arr; 38 | arr.push_back(1); 39 | arr.push_back(5); 40 | arr.push_back(6); 41 | arr.push_back(7); 42 | 43 | cout< 2 | using namespace std; 3 | int main() 4 | { 5 | long long int n,W; 6 | cin>>n>>W; 7 | long long int val[n+1]; 8 | long long int wt[n+1]; 9 | 10 | /* Space O(n*2) 11 | for(long long int i=0;i>wt[i]>>val[i]; 14 | } 15 | long long int i, w; 16 | long long int dp[n + 1][W + 1]; 17 | 18 | for (i = 0; i <= n; i++) { 19 | for (w = 0; w <= W; w++) { 20 | if (i == 0 || w == 0) 21 | dp[i][w] = 0; 22 | else if (wt[i - 1] <= w) 23 | dp[i][w] = max( 24 | val[i - 1] + dp[i - 1][w - wt[i - 1]], 25 | dp[i - 1][w]); 26 | else 27 | dp[i][w] = dp[i - 1][w]; 28 | } 29 | } 30 | 31 | cout<>wt[i]>>val[i]; 40 | } 41 | 42 | for(long long int i=0;i=wt[i]; j--) 44 | { 45 | dp[j] = max(dp[j],val[i]+dp[j-wt[i]]); 46 | } 47 | 48 | for(long long int i=0;i<=W;i++) 49 | ans = max(ans,dp[i]); 50 | cout< 2 | using namespace std; 3 | // https://leetcode.com/problems/number-of-islands/ 4 | int dirs[4][2] = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}}; 5 | void DFS(vector>& board, int i, int j, int m, int n) 6 | { 7 | if (i < 0 || i == m || j < 0 || j == n || board[i][j] == 0) { 8 | return; 9 | } 10 | for (auto d : dirs) { 11 | int x = i + d[0], y = j + d[1]; 12 | board[i][j] = 0; 13 | DFS(board, x, y, m, n); 14 | } 15 | } 16 | int connectedComponents(vector>& grid) { 17 | int nr = grid.size(); 18 | if (!nr) return 0; 19 | int nc = grid[0].size(); 20 | int num_islands = 0; 21 | for (int r = 0; r < nr; ++r) { 22 | for (int c = 0; c < nc; ++c) { 23 | if (grid[r][c] == 1) { 24 | num_islands++; 25 | DFS(grid, r, c,nr,nc); 26 | } 27 | } 28 | } 29 | 30 | return num_islands; 31 | } 32 | int main() 33 | { 34 | vector> grid ={{1, 1, 0, 0, 0}, 35 | {0, 1, 0, 0, 1}, 36 | {1, 0, 0, 1, 1}, 37 | {0, 0, 0, 0, 0}, 38 | {1, 0, 1, 0, 1}}; 39 | cout< 3 | using namespace std; 4 | bool subset_sum(vector &nums) 5 | { 6 | int n = nums.size(); 7 | int sum = 0; 8 | for (int i = 0; i < nums.size(); i++) 9 | sum += nums[i]; 10 | if(sum%2==1) 11 | return false; 12 | sum=sum/2; 13 | vector> dp(n, vector(sum+1)); 14 | 15 | for(int i=0;i arr; 40 | arr.push_back(1); 41 | arr.push_back(5); 42 | arr.push_back(6); 43 | arr.push_back(7); 44 | 45 | cout<exit[j]. 7 | 8 | **/ 9 | #include 10 | using namespace std; 11 | 12 | vector color; 13 | vector time_in, time_out; 14 | int dfs_timer = 0; 15 | 16 | void addEdge(int v, int w,vector> &adj) 17 | { 18 | adj[v].push_back(w); 19 | adj[w].push_back(v); 20 | } 21 | 22 | /* 23 | As described in the applications it might be useful to also compute the entry and exit times and vertex color. 24 | We will color all vertices with the color 0, if we haven't visited them, 25 | with the color 1 if we visited them, and 26 | with the color 2, if we already exited the vertex. 27 | */ 28 | void dfs(int v) { 29 | time_in[v] = dfs_timer++; 30 | color[v] = 1; 31 | for (int u : adj[v]) 32 | if (color[u] == 0) 33 | dfs(u); 34 | color[v] = 2; 35 | time_out[v] = dfs_timer++; 36 | } 37 | int main() 38 | { 39 | int n = 5; 40 | vector> adj(n); 41 | addEdge(0, 1,adj); 42 | addEdge(1, 2,adj); 43 | addEdge(3, 4,adj); 44 | dfs(0); 45 | } -------------------------------------------------------------------------------- /Trees/level_order_traversal.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | // A BT Node 5 | struct Node 6 | { 7 | int data; 8 | struct Node* left, *right; 9 | }; 10 | 11 | void levelorder(Node* root) 12 | { 13 | queue q; 14 | q.push(root); 15 | int nodeCount = q.size(); 16 | while(q.empty()==false) 17 | { 18 | int nodeCount = q.size(); 19 | while(nodeCount>0) 20 | { 21 | Node* t = q.front(); 22 | q.pop(); 23 | cout<data<<" "; 24 | if(t->left) q.push(t->left); 25 | if(t->right) q.push(t->right); 26 | nodeCount--; 27 | } 28 | cout<data = data; 36 | temp->left = temp->right = NULL; 37 | return (temp); 38 | } 39 | 40 | // Driver program 41 | int main() 42 | { 43 | // Let us construct the Tree shown in the above figure 44 | Node *root = newNode(1); 45 | root->left = newNode(2); 46 | root->right = newNode(3); 47 | root->left->left = newNode(4); 48 | root->left->right = newNode(5); 49 | 50 | cout<<"Level-order:"<<" "; 51 | levelorder(root); 52 | cout< 3 | using namespace std; 4 | 5 | int size[100000]={0}; 6 | int parent[100000]={-1}; 7 | int count = 1; 8 | int find_set(int v) { 9 | if(v==parent[v]) 10 | return v; 11 | return parent[v]=find_set(parent[v]); 12 | } 13 | 14 | void union_sets(int a, int b){ 15 | a = find_set(a); 16 | b = find_set(b); 17 | if (a != b) { 18 | if (size[a] < size[b]) 19 | swap(a, b); 20 | parent[b] = a; 21 | size[a] += size[b]; 22 | } 23 | } 24 | 25 | static bool comp(const vector& a, const vector& b) { 26 | return (a[2] < b[2]); 27 | } 28 | 29 | int minimumCost(int N, vector>& connections) { 30 | sort(connections.begin(), connections.end(), comp); 31 | for (int i = 1; i <= N; i++) { 32 | parent[i] = i; 33 | } 34 | int res = 0, count = 1; 35 | for (auto& c : connections) { 36 | int rx = find_set(c[0]), ry = find_set(c[1]); 37 | if (rx != ry) { 38 | res += c[2]; 39 | union_sets(rx, ry); 40 | count++; 41 | } 42 | if (count == N) return res; 43 | } 44 | return -1; 45 | } 46 | 47 | int main() 48 | { 49 | vector> c = {{1,2,5},{1,3,6},{2,3,1}}; 50 | int N = 3; 51 | cout< 2 | using namespace std; 3 | // https://leetcode.com/problems/shortest-path-in-binary-matrix/ 4 | int bfs(vector>& grid) { 5 | int res = 1; 6 | int row = grid.size(); 7 | if (row == 0) return -1; 8 | int col = grid[0].size(); 9 | if (col == 0 ) return -1; 10 | if (grid[0][0] != 0 | grid[row-1][col-1] != 0) return -1; 11 | queue> queue; 12 | queue.push(make_pair(0,0)); 13 | vector> directions = {{1,1}, {0,1},{1,0},{0,-1},{-1,0},{-1, -1},{1, -1},{-1, 1}}; 14 | grid[0][0] = 1; 15 | while(!queue.empty()){ 16 | auto curr = queue.front(); 17 | queue.pop(); 18 | int x = curr.first, y = curr.second; 19 | if( x == row -1 && y == col -1) return grid[x][y]; 20 | // For iterating over the directions 21 | for(auto direction : directions){ 22 | int nx = x + direction[0]; 23 | int ny = y + direction[1]; 24 | // Check if in range and some condition that needs to be fullfilled 25 | if(nx >= 0 && nx < row && ny >= 0 && ny < col && grid[nx][ny] == 0){ 26 | queue.push(make_pair(nx,ny)); 27 | // Increment length of path 28 | grid[nx][ny] = grid[x][y] + 1; 29 | } 30 | } 31 | } 32 | return -1; 33 | } 34 | int main() 35 | { 36 | vector> grid = {{0,1},{1,0}}; 37 | cout< 4 | using namespace std; 5 | 6 | int size[100000]={0}; 7 | int parent[100000]={-1}; 8 | 9 | void make_set(int v) { 10 | parent[v] = v; 11 | size[v] = 1; 12 | } 13 | 14 | int find_set(int v) { 15 | if(v==parent[v]) 16 | return v; 17 | return parent[v]=find_set(parent[v]); 18 | } 19 | 20 | void union_sets(int a, int b) { 21 | a = find_set(a); 22 | b = find_set(b); 23 | if (a != b) { 24 | if (size[a] < size[b]) 25 | swap(a, b); 26 | parent[b] = a; 27 | size[a] += size[b]; 28 | } 29 | } 30 | 31 | void addEdge(int v, int w,vector> &adj) 32 | { 33 | adj[v].push_back(w); 34 | adj[w].push_back(v); 35 | } 36 | 37 | int hasCycle(vector> &adj, int V) { 38 | 39 | 40 | for(auto edge:adj) 41 | { 42 | int x = edge[0]; 43 | int y = edge[1]; 44 | if(find_set(x)==find_set(y)) 45 | return 1; 46 | union_sets(x,y); 47 | } 48 | 49 | return 0; 50 | } 51 | 52 | int main() 53 | { 54 | int V; 55 | V=3; 56 | vector> adj(V); 57 | addEdge(2, 0,adj); 58 | addEdge(1, 2,adj); 59 | addEdge(0, 2,adj); 60 | 61 | if(hasCycle(adj,V)) 62 | cout<<"Has Cycle"< 3 | using namespace std; 4 | int optimal(vector &arr) 5 | { 6 | int n = arr.size(); 7 | int dp[n][n]; 8 | memset(dp,0,sizeof(dp)); 9 | 10 | for (int interval = 0; interval arr; 40 | arr.push_back(1); 41 | arr.push_back(5); 42 | arr.push_back(6); 43 | arr.push_back(7); 44 | 45 | cout< 14 | using namespace std; 15 | unsigned long int catalanDP(unsigned int n) 16 | { 17 | // Table to store results of subproblems 18 | unsigned long int catalan[n+1]; 19 | 20 | // Initialize first two values in table 21 | catalan[0] = catalan[1] = 1; 22 | 23 | // Fill entries in catalan[] using recursive formula 24 | for (int i=2; i<=n; i++) 25 | { 26 | catalan[i] = 0; 27 | for (int j=0; j 2 | using namespace std; 3 | 4 | // A BT Node 5 | struct Node 6 | { 7 | int data; 8 | struct Node* left, *right; 9 | }; 10 | 11 | void postorder(Node* root) 12 | { 13 | if(root==NULL) return; 14 | postorder(root->left); 15 | postorder(root->right); 16 | cout<data<<" "; 17 | } 18 | 19 | void preorder(Node* root) 20 | { 21 | if(root==NULL) return; 22 | cout<data<<" "; 23 | preorder(root->left); 24 | preorder(root->right); 25 | 26 | } 27 | 28 | void inorder(Node* root) 29 | { 30 | if(root==NULL) return; 31 | 32 | inorder(root->left); 33 | cout<data<<" "; 34 | inorder(root->right); 35 | 36 | } 37 | 38 | // Utility function to create new Node 39 | Node *newNode(int data) 40 | { 41 | Node *temp = new Node; 42 | temp->data = data; 43 | temp->left = temp->right = NULL; 44 | return (temp); 45 | } 46 | 47 | // Driver program 48 | int main() 49 | { 50 | // Let us construct the Tree shown in the above figure 51 | Node *root = newNode(1); 52 | root->left = newNode(2); 53 | root->right = newNode(3); 54 | root->left->left = newNode(4); 55 | root->left->right = newNode(5); 56 | 57 | cout<<"Postorder:"<<" "; 58 | postorder(root); 59 | cout< 2 | using namespace std; 3 | string scss(string a, string b) 4 | { 5 | // LCS 6 | int r = a.length(), c = b.length(); 7 | int dp[r+1][c+1]; 8 | for(int i=0;i<=r;i++) 9 | dp[i][0] = 0; 10 | 11 | for(int i=0;i<=c;i++) 12 | dp[0][i] = 0; 13 | 14 | for(int i=1;i<=r;i++) 15 | for(int j=1;j<=c;j++) 16 | { 17 | if(a[i-1] == b[j-1]) 18 | dp[i][j] = dp[i-1][j-1]+1; 19 | else 20 | dp[i][j] = max(dp[i-1][j],dp[i][j-1]); 21 | 22 | } 23 | 24 | // Backtracking to find LCS string 25 | string ans; 26 | int i = r, j = c; 27 | while (i > 0 && j > 0) 28 | { 29 | if (dp[i][j] == dp[i-1][j]) 30 | { 31 | ans+=a[i-1]; 32 | i--; 33 | } 34 | else if (dp[i][j] == dp[i][j-1]) 35 | { 36 | ans+=b[j-1]; 37 | j--; 38 | } 39 | else 40 | { 41 | ans+=a[i-1]; 42 | i--; 43 | j--; 44 | } 45 | } 46 | 47 | // Add remaining from a and b 48 | while(i-- > 0) { 49 | ans+=a[i]; 50 | } 51 | while(j-- > 0) { 52 | ans+=b[j]; 53 | } 54 | 55 | // Reverse string 56 | string t; 57 | for (int i=ans.length()-1; i>=0; i--) 58 | t+=ans[i]; 59 | 60 | return t; 61 | } 62 | 63 | int main() 64 | { 65 | string a = "geek"; 66 | string b = "eke"; 67 | string ans = scss(a,b); 68 | cout< 2 | using namespace std; 3 | 4 | void addEdge(vector adj[],int v,int u) 5 | { 6 | adj[v].push_back(u); 7 | adj[u].push_back(v); 8 | } 9 | void bfs(vector adj[],int s,int dest, int V) 10 | { 11 | queue q; 12 | vector used(V); 13 | vector d(V), p(V); 14 | q.push(s); 15 | used[s] = true; 16 | p[s] = -1; 17 | while (!q.empty()) { 18 | int v = q.front(); 19 | q.pop(); 20 | for (int u : adj[v]) { 21 | if (!used[u]) { 22 | used[u] = true; 23 | q.push(u); 24 | // stores distance 25 | d[u] = d[v] + 1; 26 | // stores immediate pre-decessor 27 | p[u] = v; 28 | } 29 | } 30 | } 31 | 32 | //Print Shortest Path 33 | if (!used[dest]) { 34 | cout << "No path!"; 35 | } 36 | else { 37 | vector path; 38 | for (int v = dest; v != -1; v = p[v]) 39 | path.push_back(v); 40 | reverse(path.begin(), path.end()); 41 | cout << "Path: "; 42 | for (int v : path) 43 | cout << v << " "; 44 | } 45 | } 46 | 47 | int main() 48 | { 49 | int V = 8; 50 | vector adj[V]; 51 | addEdge(adj, 0, 1); 52 | addEdge(adj, 0, 3); 53 | addEdge(adj, 1, 2); 54 | addEdge(adj, 3, 4); 55 | addEdge(adj, 3, 7); 56 | addEdge(adj, 4, 5); 57 | addEdge(adj, 4, 6); 58 | addEdge(adj, 4, 7); 59 | addEdge(adj, 5, 6); 60 | addEdge(adj, 6, 7); 61 | bfs(adj,0,6,V); 62 | return 0; 63 | } -------------------------------------------------------------------------------- /Trees/trie.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | class Trie { 5 | public: 6 | /** Initialize your data structure here. */ 7 | Trie() { 8 | } 9 | /** Inserts a word into the trie. */ 10 | void insert(string word) { 11 | Trie* node = this; 12 | for(auto ch:word) 13 | { 14 | if(!node->children.count(ch)) 15 | node->children[ch] = new Trie(); 16 | node = node->children[ch]; 17 | 18 | } 19 | node->end = true; 20 | 21 | } 22 | 23 | /** Returns if the word is in the trie. */ 24 | bool search(string word) { 25 | Trie* node = this; 26 | for(auto ch:word) 27 | { 28 | if(!node->children.count(ch)) 29 | return false; 30 | node = node->children[ch]; 31 | } 32 | return node->end; 33 | 34 | } 35 | 36 | /** Returns if there is any word in the trie that starts with the given prefix. */ 37 | bool startsWith(string prefix) { 38 | Trie* node = this; 39 | for(auto ch:prefix) 40 | { 41 | if(!node->children.count(ch)) 42 | return false; 43 | node = node->children[ch]; 44 | } 45 | return true; 46 | } 47 | private: 48 | map children={}; 49 | bool end = false; 50 | 51 | }; 52 | 53 | /** 54 | * Your Trie object will be instantiated and called as such: 55 | * Trie* obj = new Trie(); 56 | * obj->insert(word); 57 | * bool param_2 = obj->search(word); 58 | * bool param_3 = obj->startsWith(prefix); 59 | */ 60 | int main() 61 | { 62 | } 63 | -------------------------------------------------------------------------------- /Dynamic Programming/Geeks For Geeks Top 20/10-Boolean.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int count(vector &sy,vector &op) 4 | { 5 | int n = sy.size(); 6 | int t[n][n], f[n][n]; 7 | 8 | for(int i=0;i symbols, operators; 52 | 53 | symbols.push_back('T'); 54 | symbols.push_back('T'); 55 | symbols.push_back('F'); 56 | symbols.push_back('T'); 57 | 58 | operators.push_back('|'); 59 | operators.push_back('&'); 60 | operators.push_back('^'); 61 | 62 | cout< 2 | using namespace std; 3 | 4 | //graph 5 | unordered_map>> m; 6 | 7 | void addEdge(int u, int v, int dist, bool bi=true) 8 | { 9 | m[u].push_back(make_pair(v,dist)); 10 | if(bi) 11 | m[v].push_back(make_pair(u,dist)); 12 | } 13 | 14 | void print() 15 | { 16 | for(auto j:m){ 17 | cout<"; 18 | for(auto l: j.second){ 19 | cout<<"("< dist; 28 | for(auto j:m) 29 | dist[j.first] = INT_MAX; 30 | 31 | set> s; 32 | dist[src] = 0; 33 | s.insert(make_pair(0,src)); 34 | 35 | while(!s.empty()) 36 | { 37 | auto p = *(s.begin()); 38 | int node = p.second; 39 | 40 | int nodeDist = p.first; 41 | s.erase(s.begin()); 42 | 43 | for(auto childPair: m[node]){ 44 | if(nodeDist + childPair.second < dist[childPair.first]){ 45 | int dest = childPair.first; 46 | auto f = s.find( make_pair(dist[dest],dest)); 47 | if(f!=s.end()){ 48 | s.erase(f); 49 | } 50 | dist[dest] = nodeDist + childPair.second; 51 | s.insert(make_pair(dist[dest],dest)); 52 | } 53 | } 54 | } 55 | 56 | for(auto d:dist){ 57 | cout< 4 | using namespace std; 5 | 6 | struct TrieNode { 7 | bool flag; 8 | map next; 9 | }; 10 | 11 | class Trie { 12 | private: 13 | TrieNode* root; 14 | 15 | public: 16 | /** Initialize your data structure here. */ 17 | Trie() { 18 | root = new TrieNode(); 19 | } 20 | 21 | /** Inserts a word into the trie. */ 22 | void insert(string word) { 23 | TrieNode* p = root; 24 | for (int i = 0; i < word.length(); ++i) { 25 | if ((p->next).count(word[i]) <= 0) { 26 | // insert a new node if the path does not exist 27 | (p->next).insert(make_pair(word[i], new TrieNode())); 28 | } 29 | p = (p->next)[word[i]]; 30 | } 31 | p->flag = true; 32 | } 33 | 34 | /** Returns if the word is in the trie. */ 35 | bool search(string word) { 36 | TrieNode* p = root; 37 | for (int i = 0; i < word.length(); ++i) { 38 | if ((p->next).count(word[i]) <= 0) { 39 | return false; 40 | } 41 | p = (p->next)[word[i]]; 42 | } 43 | return p->flag; 44 | } 45 | 46 | /** Returns if there is any word in the trie that starts with the given prefix. */ 47 | bool startsWith(string prefix) { 48 | TrieNode* p = root; 49 | for (int i = 0; i < prefix.length(); ++i) { 50 | if ((p->next).count(prefix[i]) <= 0) { 51 | return false; 52 | } 53 | p = (p->next)[prefix[i]]; 54 | } 55 | return true; 56 | } 57 | }; 58 | 59 | /** 60 | * Your Trie object will be instantiated and called as such: 61 | * Trie obj = new Trie(); 62 | * obj.insert(word); 63 | * bool param_2 = obj.search(word); 64 | * bool param_3 = obj.startsWith(prefix); 65 | */ 66 | 67 | int main() 68 | { 69 | 70 | } 71 | -------------------------------------------------------------------------------- /Searching and Sorting/mergesort.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int temp[8] 4 | void merge(vector &count, vector > &v, int left, int mid, int right) { 5 | vector > tmp(right-left+1); 6 | int i = left; 7 | int j = mid+1; 8 | int k = 0; 9 | 10 | while (i <= mid && j <= right) { 11 | // mind that we're sorting in descending order 12 | if (v[i].first <= v[j].first) { 13 | tmp[k++] = v[j++]; 14 | } 15 | else { 16 | // only line responsible to update count, related to problem constraint, 17 | // remaining part is just regular mergeSort 18 | count[v[i].second] += right - j + 1; 19 | tmp[k++] = v[i++]; 20 | } 21 | } 22 | while (i <= mid) { 23 | tmp[k++] = v[i++]; 24 | } 25 | while (j <= right) { 26 | tmp[k++] = v[j++]; 27 | } 28 | for (int i = left; i <= right; i++) 29 | v[i] = tmp[i-left]; 30 | } 31 | 32 | void mergeSort(vector &count, vector > &v, int left, int right) { 33 | if (left >= right) 34 | return; 35 | 36 | int mid = left + (right-left)/2; 37 | mergeSort(count, v, left, mid); 38 | mergeSort(count, v, mid+1, right); 39 | merge(count, v, left, mid, right); 40 | } 41 | 42 | int main() 43 | { 44 | vector arr; 45 | arr.push_back(9); 46 | arr.push_back(3); 47 | arr.push_back(4); 48 | arr.push_back(1); 49 | arr.push_back(-1); 50 | arr.push_back(0); 51 | arr.push_back(10); 52 | int N = arr.size(); 53 | 54 | vector > v(N); 55 | for (int i = 0; i < N; i++) 56 | v[i] = make_pair(nums[i], i); 57 | 58 | vector count(N, 0); 59 | // sorting in descending order 60 | mergeSort(count, v, 0, N-1); 61 | 62 | cout<<"Sorted Array"< 6 | using namespace std; 7 | 8 | #define V 9 9 | 10 | struct node 11 | { 12 | int to, weight; 13 | }; 14 | 15 | // vector to store edges 16 | vector edges[V]; 17 | 18 | // Prints shortest distance from given source to 19 | // every other vertex 20 | void zeroOneBFS(int src) 21 | { 22 | // Initialize distances from given source 23 | int dist[V]; 24 | for (int i=0; i Q; 29 | dist[src] = 0; 30 | Q.push_back(src); 31 | 32 | while (!Q.empty()) 33 | { 34 | int v = Q.front(); 35 | Q.pop_front(); 36 | 37 | for (int i=0; i dist[v] + edges[v][i].weight) 41 | { 42 | dist[edges[v][i].to] = dist[v] + edges[v][i].weight; 43 | 44 | // Put 0 weight edges to front and 1 weight 45 | // edges to back so that vertices are processed 46 | // in increasing order of weights. 47 | if (edges[v][i].weight == 0) 48 | Q.push_front(edges[v][i].to); 49 | else 50 | Q.push_back(edges[v][i].to); 51 | } 52 | } 53 | } 54 | 55 | // printing the shortest distances 56 | for (int i=0; i 2 | // using namespace std; 3 | // int dp[1000000][3]; 4 | 5 | // int main(){ 6 | // int n; cin>>n; 7 | // int a,b,c; 8 | // cin>>a>>b>>c; 9 | // dp[1][1] =a; dp[1][2] = b;dp[1][3] = c; 10 | // for(int i=2;i<=n;i++){ 11 | // cin>>a>>b>>c; 12 | // dp[i][1] += a+max(dp[i-1][2],dp[i-1][3]); 13 | // dp[i][2] += b+max(dp[i-1][1],dp[i-1][3]); 14 | // dp[i][3] += c+max(dp[i-1][1],dp[i-1][2]); 15 | // } 16 | // cout< 21 | 22 | using namespace std; 23 | 24 | int dp[100005][4]; 25 | 26 | int solve(int day /*day*/,int prev_day_activity/* activity */, vector> &score) { 27 | 28 | int n = score.size(); 29 | if(day>=n) { 30 | return 0; 31 | } 32 | 33 | if(dp[day][prev_day_activity+1]!=-1) 34 | return dp[day][prev_day_activity+1]; 35 | 36 | int maxi = 0; 37 | 38 | if(prev_day_activity==-1) { 39 | maxi = max(maxi,score[day][0]+solve(day+1,0,score)); 40 | maxi = max(maxi,score[day][1]+solve(day+1,1,score)); 41 | maxi = max(maxi,score[day][2]+solve(day+1,2,score)); 42 | } else if(prev_day_activity==0) { 43 | maxi = max(maxi,score[day][1]+solve(day+1,1,score)); 44 | maxi = max(maxi,score[day][2]+solve(day+1,2,score)); 45 | } 46 | else if(prev_day_activity==1) { 47 | maxi = max(maxi,score[day][0]+solve(day+1,0,score)); 48 | maxi = max(maxi,score[day][2]+solve(day+1,2,score)); 49 | 50 | } else if(prev_day_activity==2) { 51 | maxi = max(maxi,score[day][0]+solve(day+1,0,score)); 52 | maxi = max(maxi,score[day][1]+solve(day+1,1,score)); 53 | } 54 | 55 | 56 | return dp[day][prev_day_activity+1]=maxi; 57 | } 58 | 59 | int main() { 60 | 61 | memset(dp, -1, sizeof dp); 62 | int N; cin>>N; 63 | 64 | vector> score; 65 | for(int i=0;i v; 68 | for(int j=0;j<3;j++) { 69 | int x; cin>>x; 70 | v.push_back(x); 71 | } 72 | score.push_back(v); 73 | } 74 | 75 | cout< 2 | using namespace std; 3 | 4 | // https://leetcode.com/problems/flatten-binary-tree-to-linked-list/solution/ 5 | struct Node 6 | { 7 | int data; 8 | struct Node* left, *right; 9 | }; 10 | Node* flattenWorker(Node* root) { 11 | if (root == nullptr) { 12 | return NULL; 13 | } 14 | if(root->left==NULL && root->right==NULL) 15 | return root; 16 | TreeNode* l = flattenWorker(root->left); 17 | TreeNode* r = flattenWorker(root->right); 18 | if(l) 19 | { 20 | l->right = root->right; 21 | root->right = root->left; 22 | root->left = NULL; 23 | } 24 | return r == NULL ? l :r; 25 | } 26 | // Greedily Change the Pointers 27 | void flattenWorkerIterative(Node* root) 28 | { 29 | if (root == nullptr) { 30 | return; 31 | } 32 | 33 | TreeNode* node = root; 34 | 35 | while (node != nullptr) { 36 | 37 | // If the node has a left child 38 | if (node->left != nullptr) { 39 | 40 | // Find the rightmost node 41 | TreeNode* rightmost = node->left; 42 | while (rightmost->right != nullptr) { 43 | rightmost = rightmost->right; 44 | } 45 | 46 | // rewire the connections 47 | rightmost->right = node->right; 48 | node->right = node->left; 49 | node->left = nullptr; 50 | } 51 | 52 | // move on to the right side of the tree 53 | node = node->right; 54 | } 55 | } 56 | void flatten(Node* root) 57 | { 58 | // Recursive, O(N) time , O(N) space 59 | flattenWorker(root); 60 | // Iterative O(n) time, O(1) space 61 | flattenWorkerIterative(root); 62 | } 63 | // Utility function to create new Node 64 | Node *newNode(int data) 65 | { 66 | Node *temp = new Node; 67 | temp->data = data; 68 | temp->left = temp->right = NULL; 69 | return (temp); 70 | } 71 | 72 | // Driver program 73 | int main() 74 | { 75 | // Let us construct the Tree shown in the above figure 76 | Node *root = newNode(1); 77 | root->left = newNode(2); 78 | root->right = newNode(3); 79 | root->left->left = newNode(4); 80 | root->left->right = newNode(5); 81 | 82 | cout<<"Level-order:"<<" "; 83 | flatten(root); 84 | cout< 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | int badNeighbours(int *a, int size) { 8 | 9 | if(size == 2) { 10 | int sum = max(a[0], a[1]); 11 | return sum; 12 | } 13 | 14 | int i, j; 15 | int *s = (int *)malloc(sizeof(int)*size); 16 | int *b = (int *)malloc(sizeof(int)*size); 17 | 18 | s[0]=a[0]; 19 | s[1]=a[1]; 20 | b[0]=1; 21 | b[1]=0; 22 | 23 | for(i=2;i 2 | using namespace std; 3 | 4 | //implement insert, delete, reverse// A simple CPP program to introduce 5 | // a linked list 6 | #include 7 | using namespace std; 8 | 9 | class Node { 10 | public: 11 | int data; 12 | Node* next; 13 | }; 14 | 15 | void printLinkedList(Node* head) 16 | { 17 | Node* root = head; 18 | while(root!=NULL) 19 | { 20 | cout<data<<" "; 21 | root=root->next; 22 | } 23 | cout<next!=NULL) 29 | { 30 | root=root->next; 31 | } 32 | 33 | Node* newNode = new Node(); 34 | newNode->next = NULL; 35 | newNode->data = val; 36 | root->next = newNode; 37 | } 38 | 39 | void deleteNthNode(Node* head, int n) 40 | { 41 | int len = 0; 42 | Node* node = head; 43 | Node* t = head; 44 | Node* prev = NULL; 45 | Node* nxt = NULL; 46 | 47 | while(t!=NULL) 48 | { 49 | len++; 50 | t= t->next; 51 | } 52 | 53 | if(len==n-1) head=head->next; 54 | else 55 | { 56 | int j = n-1; 57 | 58 | while(node->next!=NULL) 59 | { 60 | prev = node; 61 | node = node->next; 62 | nxt = node->next; 63 | j--; 64 | if(j==0) 65 | { 66 | prev->next = nxt; 67 | node->next = NULL; 68 | } 69 | } 70 | } 71 | } 72 | void reverse(Node** head) 73 | { 74 | Node* result = NULL; 75 | Node* current = *head; 76 | 77 | while (current != NULL) 78 | { 79 | Node* next = current->next; 80 | 81 | current->next = result; 82 | result = current; 83 | current = next; 84 | } 85 | 86 | // fix head pointer 87 | *head = result; 88 | } 89 | 90 | int main() 91 | { 92 | Node* head = NULL; 93 | Node* second = NULL; 94 | Node* third = NULL; 95 | 96 | head = new Node(); 97 | second = new Node(); 98 | third = new Node(); 99 | 100 | head->data = 1; 101 | head->next = second; 102 | second->data = 2; 103 | 104 | second->next = third; 105 | 106 | third->data = 3; 107 | third->next = NULL; 108 | insert(head,4); 109 | //deleteNthNode(head,2); 110 | printLinkedList(head); 111 | cout<<"Reversed Linked List:"< 2 | using namespace std; 3 | vector tree; 4 | 5 | int merge(int x,int y) { 6 | return x+y; 7 | } 8 | void updateValSegTree(int treeIndex, int lo, int hi, int arrIndex, int val) 9 | { 10 | if (lo == hi) { // leaf node. update element. 11 | tree[treeIndex] = val; 12 | return; 13 | } 14 | 15 | int mid = lo + (hi - lo) / 2; // recurse deeper for appropriate child 16 | 17 | if (arrIndex > mid) 18 | updateValSegTree(2 * treeIndex + 2, mid + 1, hi, arrIndex, val); 19 | else if (arrIndex <= mid) 20 | updateValSegTree(2 * treeIndex + 1, lo, mid, arrIndex, val); 21 | 22 | // merge updates 23 | tree[treeIndex] = merge(tree[2 * treeIndex + 1], tree[2 * treeIndex + 2]); 24 | } 25 | // call this method as updateValSegTree(0, 0, n-1, i, val); 26 | // Here you want to update the value at index i with value val. 27 | 28 | int querySegTree(int treeIndex, int lo, int hi, int i, int j) 29 | { 30 | // query for arr[i..j] 31 | 32 | if (lo > j || hi < i) // segment completely outside range 33 | return 0; // represents a null node 34 | 35 | if (i <= lo && j >= hi) // segment completely inside range 36 | return tree[treeIndex]; 37 | 38 | int mid = lo + (hi - lo) / 2; // partial overlap of current segment and queried range. Recurse deeper. 39 | 40 | if (i > mid) 41 | return querySegTree(2 * treeIndex + 2, mid + 1, hi, i, j); 42 | else if (j <= mid) 43 | return querySegTree(2 * treeIndex + 1, lo, mid, i, j); 44 | 45 | int leftQuery = querySegTree(2 * treeIndex + 1, lo, mid, i, mid); 46 | int rightQuery = querySegTree(2 * treeIndex + 2, mid + 1, hi, mid + 1, j); 47 | 48 | // merge query results 49 | return merge(leftQuery, rightQuery); 50 | } 51 | 52 | // call this method as querySegTree(0, 0, n-1, i, j); 53 | // Here [i,j] is the range/interval you are querying. 54 | // This method relies on "null" nodes being equivalent to storing zero. 55 | 56 | 57 | void buildSegTree(vector& arr, int treeIndex, int lo, int hi) 58 | { 59 | if (lo == hi) { // leaf node. store value in node. 60 | tree[treeIndex] = arr[lo]; 61 | return; 62 | } 63 | 64 | int mid = lo + (hi - lo) / 2; // recurse deeper for children. 65 | buildSegTree(arr, 2 * treeIndex + 1, lo, mid); 66 | buildSegTree(arr, 2 * treeIndex + 2, mid + 1, hi); 67 | 68 | // merge build results 69 | tree[treeIndex] = merge(tree[2 * treeIndex + 1], tree[2 * treeIndex + 2]); 70 | } 71 | 72 | // call this method as buildSegTree(arr, 0, 0, n-1); 73 | // Here arr[] is input array and n is its size. 74 | 75 | int main() { 76 | tree.resize(1000,0); 77 | 78 | } -------------------------------------------------------------------------------- /Trees/iterative_traversal.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | // A BT Node 5 | struct Node 6 | { 7 | int data; 8 | struct Node* left, *right; 9 | }; 10 | 11 | void dfs(Node* root) 12 | { 13 | stack s; 14 | s.push(root); 15 | while(s.empty()==false) 16 | { 17 | Node* t = s.top(); 18 | s.pop(); 19 | if(t != NULL){ 20 | // preorder 21 | cout<data<<" "; 22 | s.push(t->right); 23 | s.push(t->left); 24 | 25 | } 26 | } 27 | } 28 | 29 | void inorder(Node* root) 30 | { 31 | stack s; 32 | Node* t = root; 33 | while(s.empty()==false || t != NULL ) 34 | { 35 | while(t!=NULL) 36 | { 37 | s.push(t); 38 | t=t->left; 39 | } 40 | t = s.top(); s.pop(); 41 | cout << t->data << " "; 42 | t = t->right; 43 | } 44 | 45 | } 46 | 47 | void postorder(Node* root) 48 | { 49 | if (root == NULL) 50 | return; 51 | 52 | stack s1, s2; 53 | 54 | s1.push(root); 55 | Node* node; 56 | 57 | // Run while first stack is not empty 58 | while (!s1.empty()) { 59 | // Pop an item from s1 and push it to s2 60 | node = s1.top(); 61 | s1.pop(); 62 | s2.push(node); 63 | 64 | // Push left and right children 65 | // of removed item to s1 66 | if (node->left) 67 | s1.push(node->left); 68 | if (node->right) 69 | s1.push(node->right); 70 | } 71 | 72 | // Print all elements of second stack 73 | while (!s2.empty()) { 74 | node = s2.top(); 75 | s2.pop(); 76 | cout << node->data << " "; 77 | } 78 | 79 | } 80 | 81 | 82 | 83 | // Utility function to create new Node 84 | Node *newNode(int data) 85 | { 86 | Node *temp = new Node; 87 | temp->data = data; 88 | temp->left = temp->right = NULL; 89 | return (temp); 90 | } 91 | 92 | // Driver program 93 | int main() 94 | { 95 | // Let us construct the Tree shown in the above figure 96 | Node *root = newNode(1); 97 | root->left = newNode(2); 98 | root->right = newNode(3); 99 | root->left->left = newNode(4); 100 | root->left->right = newNode(5); 101 | 102 | cout<<"DFS/Pre-order:"<<" "; 103 | dfs(root); 104 | cout<(index,distance), like bfs push into pq and loop till not empty, iterate neighbors, relax edge, add key value pair to queue. 40 | - Another variant, you need to find shortest path and not distance. Keep a prev array and iterate from dest backward. 41 | - Stopping early: If we encounter destination, return. More iteration will not give a better approach. 42 | - https://leetcode.com/problems/network-delay-time/ 43 | - Variation: https://leetcode.com/problems/cheapest-flights-within-k-stops/solution/ Keep track of stops as well. 44 | - https://www.youtube.com/watch?v=pSqmAO-m7Lk&list=PLDV1Zeh2NRsDGO4--qE8yH72HFL1Km93P&index=19&ab_channel=WilliamFiset 45 | 46 | **Disjoint Set Union** 47 | - Useful to find valid tree, find out cycles etc. 48 | - https://cp-algorithms.com/data_structures/disjoint_set_union.html#naive-implementation 49 | - https://leetcode.com/problems/remove-max-number-of-edges-to-keep-graph-fully-traversable/ 50 | 51 | **Minimum Spanning Tree** 52 | - If we model the cities and connections as a graph, each connection is an edge (undirected) and each city is a node of the graph. We need to find a subset of edges which connects all the nodes of the graph with the minimum possible total weight. This is by definition the Minimum Spanning Tree or MST of a graph. 53 | - https://www.youtube.com/watch?v=JZBQLXgSGfs 54 | - Implemented using Disjoint Set Union (Kruskal's) 55 | - https://leetcode.com/problems/connecting-cities-with-minimum-cost/solution/ 56 | 57 | **Articulation Points and Bridges** 58 | - https://leetcode.com/problems/critical-connections-in-a-network/ 59 | - https://www.youtube.com/watch?v=2kREIkF9UAs&ab_channel=TusharRoy-CodingMadeSimple 60 | -------------------------------------------------------------------------------- /Graphs/convexhull.cpp: -------------------------------------------------------------------------------- 1 | // A C++ program to find convex hull of a set of points. Refer 2 | // https://www.geeksforgeeks.org/orientation-3-ordered-points/ 3 | // for explanation of orientation() 4 | // https://www.youtube.com/watch?v=UUCKvHTP4Gg 5 | #include 6 | #include 7 | #include 8 | using namespace std; 9 | 10 | struct Point 11 | { 12 | int x, y; 13 | }; 14 | 15 | // A global point needed for sorting points with reference 16 | // to the first point Used in compare function of qsort() 17 | Point p0; 18 | 19 | // A utility function to find next to top in a stack 20 | Point nextToTop(stack &S) 21 | { 22 | Point p = S.top(); 23 | S.pop(); 24 | Point res = S.top(); 25 | S.push(p); 26 | return res; 27 | } 28 | 29 | // A utility function to swap two points 30 | int swap(Point &p1, Point &p2) 31 | { 32 | Point temp = p1; 33 | p1 = p2; 34 | p2 = temp; 35 | } 36 | 37 | // A utility function to return square of distance 38 | // between p1 and p2 39 | int distSq(Point p1, Point p2) 40 | { 41 | return (p1.x - p2.x)*(p1.x - p2.x) + 42 | (p1.y - p2.y)*(p1.y - p2.y); 43 | } 44 | 45 | // To find orientation of ordered triplet (p, q, r). 46 | // The function returns following values 47 | // 0 --> p, q and r are colinear 48 | // 1 --> Clockwise 49 | // 2 --> Counterclockwise 50 | int orientation(Point p, Point q, Point r) 51 | { 52 | int val = (q.y - p.y) * (r.x - q.x) - 53 | (q.x - p.x) * (r.y - q.y); 54 | 55 | if (val == 0) return 0; // colinear 56 | return (val > 0)? 1: 2; // clock or counterclock wise 57 | } 58 | 59 | // A function used by library function qsort() to sort an array of 60 | // points with respect to the first point 61 | int compare(const void *vp1, const void *vp2) 62 | { 63 | Point *p1 = (Point *)vp1; 64 | Point *p2 = (Point *)vp2; 65 | 66 | // Find orientation 67 | int o = orientation(p0, *p1, *p2); 68 | if (o == 0) 69 | return (distSq(p0, *p2) >= distSq(p0, *p1))? -1 : 1; 70 | 71 | return (o == 2)? -1: 1; 72 | } 73 | 74 | // Prints convex hull of a set of n points. 75 | void convexHull(Point points[], int n) 76 | { 77 | // Find the bottommost point 78 | int ymin = points[0].y, min = 0; 79 | for (int i = 1; i < n; i++) 80 | { 81 | int y = points[i].y; 82 | 83 | // Pick the bottom-most or chose the left 84 | // most point in case of tie 85 | if ((y < ymin) || (ymin == y && 86 | points[i].x < points[min].x)) 87 | ymin = points[i].y, min = i; 88 | } 89 | 90 | // Place the bottom-most point at first position 91 | swap(points[0], points[min]); 92 | 93 | // Sort n-1 points with respect to the first point. 94 | // A point p1 comes before p2 in sorted output if p2 95 | // has larger polar angle (in counterclockwise 96 | // direction) than p1 97 | p0 = points[0]; 98 | qsort(&points[1], n-1, sizeof(Point), compare); 99 | 100 | // If two or more points make same angle with p0, 101 | // Remove all but the one that is farthest from p0 102 | // Remember that, in above sorting, our criteria was 103 | // to keep the farthest point at the end when more than 104 | // one points have same angle. 105 | int m = 1; // Initialize size of modified array 106 | for (int i=1; i S; 126 | S.push(points[0]); 127 | S.push(points[1]); 128 | S.push(points[2]); 129 | 130 | // Process remaining n-3 points 131 | for (int i = 3; i < m; i++) 132 | { 133 | // Keep removing top while the angle formed by 134 | // points next-to-top, top, and points[i] makes 135 | // a non-left turn 136 | while (orientation(nextToTop(S), S.top(), points[i]) != 2) 137 | S.pop(); 138 | S.push(points[i]); 139 | } 140 | 141 | // Now stack has the output points, print contents of stack 142 | while (!S.empty()) 143 | { 144 | Point p = S.top(); 145 | cout << "(" << p.x << ", " << p.y <<")" << endl; 146 | S.pop(); 147 | } 148 | } 149 | 150 | // Driver program to test above functions 151 | int main() 152 | { 153 | Point points[] = {{0, 3}, {1, 1}, {2, 2}, {4, 4}, 154 | {0, 0}, {1, 2}, {3, 1}, {3, 3}}; 155 | int n = sizeof(points)/sizeof(points[0]); 156 | convexHull(points, n); 157 | return 0; 158 | } 159 | -------------------------------------------------------------------------------- /Graphs/bidirectional-bfs.cpp: -------------------------------------------------------------------------------- 1 | // C++ program for Bidirectional BFS search 2 | // to check path between two vertices 3 | // https://leetcode.com/problems/word-ladder/ 4 | #include 5 | using namespace std; 6 | 7 | // class representing undirected graph 8 | // using adjacency list 9 | class Graph 10 | { 11 | //number of nodes in graph 12 | int V; 13 | 14 | // Adjacency list 15 | list *adj; 16 | public: 17 | Graph(int V); 18 | int isIntersecting(bool *s_visited, bool *t_visited); 19 | void addEdge(int u, int v); 20 | void printPath(int *s_parent, int *t_parent, int s, 21 | int t, int intersectNode); 22 | void BFS(list *queue, bool *visited, int *parent); 23 | int biDirSearch(int s, int t); 24 | }; 25 | 26 | Graph::Graph(int V) 27 | { 28 | this->V = V; 29 | adj = new list[V]; 30 | }; 31 | 32 | // Method for adding undirected edge 33 | void Graph::addEdge(int u, int v) 34 | { 35 | this->adj[u].push_back(v); 36 | this->adj[v].push_back(u); 37 | }; 38 | 39 | // Method for Breadth First Search 40 | void Graph::BFS(list *queue, bool *visited, 41 | int *parent) 42 | { 43 | int current = queue->front(); 44 | queue->pop_front(); 45 | list::iterator i; 46 | for (i=adj[current].begin();i != adj[current].end();i++) 47 | { 48 | // If adjacent vertex is not visited earlier 49 | // mark it visited by assigning true value 50 | if (!visited[*i]) 51 | { 52 | // set current as parent of this vertex 53 | parent[*i] = current; 54 | 55 | // Mark this vertex visited 56 | visited[*i] = true; 57 | 58 | // Push to the end of queue 59 | queue->push_back(*i); 60 | } 61 | } 62 | }; 63 | 64 | // check for intersecting vertex 65 | int Graph::isIntersecting(bool *s_visited, bool *t_visited) 66 | { 67 | int intersectNode = -1; 68 | for(int i=0;i path; 84 | path.push_back(intersectNode); 85 | int i = intersectNode; 86 | while (i != s) 87 | { 88 | path.push_back(s_parent[i]); 89 | i = s_parent[i]; 90 | } 91 | reverse(path.begin(), path.end()); 92 | i = intersectNode; 93 | while(i != t) 94 | { 95 | path.push_back(t_parent[i]); 96 | i = t_parent[i]; 97 | } 98 | 99 | vector::iterator it; 100 | cout<<"*****Path*****\n"; 101 | for(it = path.begin();it != path.end();it++) 102 | cout<<*it<<" "; 103 | cout<<"\n"; 104 | }; 105 | 106 | // Method for bidirectional searching 107 | int Graph::biDirSearch(int s, int t) 108 | { 109 | // boolean array for BFS started from 110 | // source and target(front and backward BFS) 111 | // for keeping track on visited nodes 112 | bool s_visited[V], t_visited[V]; 113 | 114 | // Keep track on parents of nodes 115 | // for front and backward search 116 | int s_parent[V], t_parent[V]; 117 | 118 | // queue for front and backward search 119 | list s_queue, t_queue; 120 | 121 | int intersectNode = -1; 122 | 123 | // necessary initialization 124 | for(int i=0; i