├── DS ├── README.md ├── Stack_StringReverse.cpp ├── LinkedList_InsertNodeAtBeginning.c ├── BinaryTreeHeight.cpp ├── Graph_AdjacencyListImplementation_using_STL.cpp ├── LinkedList_Traversal_Recursion.c ├── LinkedList_Reverse_Recursion.c ├── LinkedList_InsertNodeAtNthPosition.c ├── Stack_LinkedListImplementation.c ├── BalancedParenthesisCheck_Stack.cpp ├── Stack_ArrayImplementation.c ├── Stack_LinkedListReverse.cpp ├── LinkedList_Reverse_Iterative.c ├── BinaryTree_InorderTraversal.cpp ├── DoublyLinkedList.c ├── Queue_LinkedListImplementation.c ├── BinaryTree_PostorderTraversal.cpp ├── BinaryTree_Height.c ├── BinaryTree_PreorderTraversal.cpp ├── BinarySearchTree_Validation.cpp ├── Graph_AdjacencyListImplementation_Directed.cpp ├── BinarySearchTree_C.c ├── DepthFirstSearch_using_STL_Iterative.cpp ├── Queue_ArrayImplementation.c ├── BreadthFirstSearch_using_STL.cpp ├── DepthFirstSearch_using_STL_Recursive.cpp ├── BinarySearchTree_Validation_InorderTraversal.cpp ├── LinkedList_DeleteNodeAtNthPosition.c ├── BinaryTree_LevelOrderTraversal.cpp └── Graph_AdjacencyListImplementation_in_C.c ├── Graph ├── README.md ├── PrintEulerCycle_DirectedGraph.cpp ├── TopologicalSorting.cpp ├── DepthFirstSearch.cpp ├── ConnectedComponents_UndirectedGraph.cpp └── DetectCycle_UndirectedGraph_Approach1.cpp ├── Queue ├── README.md ├── QueueTwoStacks.cpp ├── ReverseFirst-k-ElementsQueue.cpp ├── StackTwoQueues.cpp └── InterleaveQueue.cpp ├── Stack ├── README.md ├── ReverseString.cpp ├── NearestGreaterReplace.cpp ├── StockSpan.cpp ├── PairwiseConsecutive.cpp ├── BalancedParenthesesCheck.cpp ├── InfixToPostfix.cpp ├── PostfixEvaluation.cpp ├── MinStack.cpp ├── PrefixEvaluation.cpp └── LargestRectangleHistogram.cpp ├── Strings ├── README.md ├── LongestSubstringWithoutRepeatingCharacters.cpp ├── PatternSearch_BruteForce.cpp ├── LongestPalindromicSubsequence.cpp ├── LongestPalindromicSubsequence_Method2.cpp ├── LongestPalindromicSubstring_Method2.cpp ├── LongestPalindromicSubstring.cpp └── RemoveDuplicates.cpp ├── Tree ├── README.md ├── Height_N-aryTree.cpp ├── RemoveLeafNodes_BinaryTree.cpp ├── HeightBalancedCheck_BinaryTree.cpp ├── CheckSameElements_BinarySearchTree.cpp ├── ExpressionTree.cpp ├── RemoveHalfNodes_BinaryTree.cpp ├── ConstructBinaryTree_InorderPostorder.cpp ├── AncestorsPrint_BinaryTree.cpp ├── ConstructBinaryTree_InorderPreorder.cpp ├── KthLargestElement_BinarySearchTree.cpp ├── KthSmallestElement_BinarySearchTree.cpp ├── RootToNodePath_BinaryTree.cpp └── MaximumPathSum_BinaryTree.cpp ├── Trie ├── README.md └── CountNumberOfWords_Trie.cpp ├── Linked Lists ├── README.md ├── RotateKPlacesLeft_LinkedList.cpp └── RotateKPlacesRight_LinkedList.cpp ├── Segment Tree ├── README.md ├── SumQuery_NoUpdate.cpp ├── MaximumQuery_NoUpdate.cpp └── MinimumQuery_NoUpdate.cpp ├── Binary Indexed Tree ├── README.md ├── InversionCount.cpp ├── RangeSumQuery_PointUpdate.cpp └── RangeSumQuery_RangeUpdate.cpp ├── Priority Queue and Heaps └── README.md ├── README.md ├── Dynamic Programming ├── Fibonacci_Nth_Term_BottomUpApproach.cpp ├── Fibonacci_Nth_Term_TopDownApproach.cpp ├── CatalanNumber.cpp └── BuildingBridges.cpp ├── Sorts ├── README.md ├── BubbleSort.cpp ├── SelectionSort.cpp ├── HeapSort.cpp ├── InsertionSort.cpp └── MergeSort.cpp └── Arrays ├── MissingNumberInArray_UsingSummation.cpp ├── MissingNumberInArray_UsingXor.cpp ├── MissingAndRepeatingElement.cpp ├── Maximum_SubArray_Sum_KadaneAlgorithm.cpp ├── Maximum_SubArray_Sum_KadaneAlgorithm1.cpp ├── TrappingRainWater_BruteForce.cpp ├── TrappingRainWater_Approach2.cpp ├── PythagoreanTriplet.cpp ├── Maximum_Sum_Subarray_Size_K_BruteForce.cpp ├── LargestNumberFormation.cpp ├── Maximum_SubArray_Sum_BruteForce2.cpp ├── TripletWhereSumOfTwoEqualsThirdElement.cpp ├── Maximum_SubArray_Sum_BruteForce.cpp ├── FirstMissingPositiveInteger.cpp ├── Maximum_Sum_Subarray_Size_K_SlidingWindowTechnique.cpp ├── MajorityElement.cpp ├── TrappingRainWater_Approach3.cpp ├── RotationCount_SortedArray.cpp ├── MergeTwoSortedArrays.cpp ├── Maximum_SubArray_Sum_DivideAndConquer.cpp ├── TripletSumEqualToAGivenValue_BruteForce.cpp ├── BitonicArrayMaximumElement.cpp ├── MergeOverlappingIntervals.cpp ├── MergeTwoSortedArrays_NoExtraSpace.cpp ├── RearrangeArrayElementsZigZagFashion.cpp ├── LastOccurrence_SortedArray.cpp ├── FirstOccurrence_SortedArray.cpp ├── Subarray_sum_equals_given_sum.cpp ├── TripletSumEqualToAGivenValue_Hashing.cpp ├── PeakElement.cpp ├── MinimumElement_SortedArray.cpp ├── Subarray_sum_equals_given_sum_BruteForce.cpp ├── MergeKSortedArrays.cpp ├── TripletSumEqualToAGivenValue_TwoPointer.cpp ├── Subarray_sum_equals_given_sum_HandlesNegativeValues.cpp ├── SpirallyTraverseMatrix.cpp └── SearchElement_RotatedSortedArray.cpp /DS/README.md: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /Graph/README.md: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /Queue/README.md: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /Stack/README.md: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /Strings/README.md: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /Tree/README.md: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /Trie/README.md: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /Linked Lists/README.md: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /Segment Tree/README.md: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /Binary Indexed Tree/README.md: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /Priority Queue and Heaps/README.md: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Data Structures and Algorithms (DSA) 2 | Some data structures, algorithms and their implementations. 3 | -------------------------------------------------------------------------------- /DS/Stack_StringReverse.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | using namespace std; 6 | 7 | void Reverse(char C[],int n) 8 | { 9 | stack S; 10 | for(int i=0;i 10 | using namespace std; 11 | 12 | int fib(int); 13 | 14 | int main() { 15 | 16 | int n; 17 | cin>>n; 18 | cout< 7 | using namespace std; 8 | 9 | int main() { 10 | 11 | cout << "Enter the range : "; 12 | int n; 13 | cin >> n; 14 | 15 | int sum = n * (n + 1) / 2; 16 | 17 | vector a(n-1); 18 | 19 | cout << "Enter " << n-1 << " elements : "; 20 | for (int i = 0; i < n-1; ++i) { 21 | cin >> a[i]; 22 | sum -= a[i]; 23 | } 24 | 25 | cout << "Missing Number is : " << sum << "\n"; 26 | 27 | return 0; 28 | 29 | } 30 | 31 | /* 32 | * Time Complexity : O(n) 33 | * Space Complexity : O(1) 34 | */ 35 | -------------------------------------------------------------------------------- /Arrays/MissingNumberInArray_UsingXor.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Title : Missing number in array (Using XOR) 3 | * Author : Tridib Samanta 4 | **/ 5 | 6 | #include 7 | using namespace std; 8 | 9 | int main() { 10 | 11 | cout << "Enter the range : "; 12 | int n; 13 | cin >> n; 14 | 15 | cout << "Enter " << n-1 << " elements : "; 16 | vector a(n-1); 17 | for (int i = 0; i < n-1; ++i) 18 | cin >> a[i]; 19 | 20 | int x1 = a[0], x2 = 1; 21 | 22 | for (int i = 1; i < n-1; ++i) 23 | x1 = x1 ^ a[i]; 24 | 25 | for (int i = 2; i <= n; ++i) 26 | x2 = x2 ^ i; 27 | 28 | cout << "Missing Number is : " << (x1 ^ x2) << "\n"; 29 | 30 | return 0; 31 | 32 | } 33 | 34 | /* 35 | * Time Complexity : O(n) 36 | * Space Complexity : O(1) 37 | */ 38 | -------------------------------------------------------------------------------- /Dynamic Programming/Fibonacci_Nth_Term_TopDownApproach.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Title : Fibonacci Nth Term (Top Down Approach - Memoization) 3 | * Author : Tridib Samanta 4 | **/ 5 | 6 | // time complexity - O(n) 7 | // space complexity - O(n) 8 | 9 | #include 10 | using namespace std; 11 | 12 | #define MAX 100 13 | 14 | int F[MAX]; 15 | 16 | void _initialize(); 17 | int fib(int); 18 | 19 | 20 | int main() { 21 | int n; 22 | cin>>n; 23 | _initialize(); 24 | cout< 7 | using namespace std; 8 | 9 | string reverseString(string str) { 10 | 11 | stack S; 12 | string rev = ""; 13 | 14 | for (int i = 0; i < str.length(); ++i) 15 | S.push(str[i]); 16 | 17 | while (!S.empty()) { 18 | rev += S.top(); 19 | S.pop(); 20 | } 21 | 22 | return rev; 23 | } 24 | 25 | int main() { 26 | string str; 27 | cout << "Enter the string : "; 28 | cin >> str; 29 | int len = str.length(); 30 | string res = reverseString(str); 31 | cout << "Reversed string : " << res << '\n'; 32 | return 0; 33 | } 34 | 35 | /* 36 | ~ Time Complexity : O(n), since we are scanning the input string only once. 37 | ~ Space Complexity : O(n), for the stack. 38 | */ 39 | -------------------------------------------------------------------------------- /DS/LinkedList_InsertNodeAtBeginning.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | struct Node { 5 | int data; 6 | struct Node* next; 7 | }; 8 | 9 | struct Node* head; // Global 10 | 11 | void Insert(int x); 12 | void Print(); 13 | 14 | int main() { 15 | 16 | head=NULL; //empty list 17 | printf("How many numbers ? \n"); 18 | int n,i,x; 19 | scanf("%d",&n); 20 | for(i=0;idata=x; 33 | temp->next=head; 34 | head=temp; 35 | } 36 | 37 | void Print() 38 | { 39 | struct Node* temp=head; 40 | printf("List is : "); 41 | while(temp!=NULL) { 42 | printf("%d ",temp->data); 43 | temp=temp->next; 44 | } 45 | } 46 | 47 | -------------------------------------------------------------------------------- /Stack/NearestGreaterReplace.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Title : Replace element with nearest greater element 3 | * Author : Tridib Samanta 4 | **/ 5 | 6 | #include 7 | using namespace std; 8 | 9 | void replaceNearestGreater(int arr[], int n) { 10 | stack S; 11 | int res[n]; 12 | for (int i = n - 1; i >= 0; --i) { 13 | while (!S.empty() && arr[i] >= S.top()) 14 | S.pop(); 15 | 16 | if (S.empty()) 17 | res[i] = -1; 18 | else 19 | res[i] = S.top(); 20 | 21 | S.push(arr[i]); 22 | } 23 | for (int i = 0; i < n; ++i) 24 | cout << res[i] << " "; 25 | } 26 | 27 | int main() { 28 | int n; 29 | cin >> n; 30 | int arr[n]; 31 | for (int i = 0; i < n; ++i) 32 | cin >> arr[i]; 33 | replaceNearestGreater(arr, n); 34 | cout << '\n'; 35 | return 0; 36 | } 37 | 38 | /* 39 | ~ Time Complexity : O(n) 40 | ~ Space Complexity : O(n) 41 | */ 42 | -------------------------------------------------------------------------------- /DS/BinaryTreeHeight.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | struct Node { 5 | int data; 6 | Node* left; 7 | Node* right; 8 | }; 9 | 10 | Node* CreateNode(int data) { 11 | Node* newNode = new Node(); 12 | newNode->data = data; 13 | newNode->left = newNode->right = NULL; 14 | return newNode; 15 | } 16 | 17 | Node* InsertNode(Node* root, int data) { 18 | if (root == NULL) 19 | root = CreateNode(data); 20 | else if (data <= root->data) 21 | root->left = InsertNode(root->left, data); 22 | else 23 | root->right = InsertNode(root->right, data); 24 | return root; 25 | } 26 | 27 | int FindHeight(Node* root) { 28 | if (root == NULL) 29 | return -1; 30 | return max(FindHeight(root->left), FindHeight(root->right)) + 1; 31 | } 32 | 33 | int main() { 34 | Node* root = NULL; 35 | 36 | root = InsertNode(root, 15); root = InsertNode(root, 10); 37 | root = InsertNode(root, 20); root = InsertNode(root, 8); 38 | 39 | cout << "Height of the tree = " << FindHeight(root); 40 | } 41 | -------------------------------------------------------------------------------- /Stack/StockSpan.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Title : Stock Span 3 | * Author : Tridib Samanta 4 | **/ 5 | 6 | #include 7 | using namespace std; 8 | 9 | void findSpans(int arr[], int n, int span[]) { 10 | stack S; 11 | for (int i = 0; i < n; ++i) { 12 | while (!S.empty() && arr[i] >= arr[S.top()]) 13 | S.pop(); 14 | if (S.empty()) 15 | span[i] = i + 1; 16 | else 17 | span[i] = i - S.top(); 18 | S.push(i); 19 | } 20 | } 21 | 22 | int main() { 23 | int n; 24 | cout << "Enter the number of days : "; 25 | cin >> n; 26 | int arr[n]; 27 | cout << "Enter stock price for " << n << " days : "; 28 | for (int i = 0; i < n; ++i) 29 | cin >> arr[i]; 30 | int S[n]; 31 | findSpans(arr, n, S); 32 | cout << "Span of stock's price : "; 33 | for (int i = 0; i < n; ++i) 34 | cout << S[i] << ' '; 35 | cout << '\n'; 36 | return 0; 37 | } 38 | 39 | /* 40 | ~ Time Complexity : O(n) 41 | ~ Space Complexity : O(n) 42 | */ 43 | -------------------------------------------------------------------------------- /Arrays/MissingAndRepeatingElement.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Title : Find the missing and repeating element in an array 3 | * Author : Tridib Samanta 4 | **/ 5 | 6 | #include 7 | using namespace std; 8 | 9 | void findMissingRepeating(int arr[], int n) { 10 | 11 | for (int i = 0; i < n; ++i) { 12 | if (arr[abs(arr[i]) - 1] > 0) 13 | arr[abs(arr[i]) - 1] = -arr[abs(arr[i]) - 1]; 14 | else 15 | cout << "Repeating element : " << abs(arr[i]) << '\n'; 16 | } 17 | 18 | for (int i = 0; i < n; ++i) { 19 | if (arr[i] > 0) 20 | cout << "Missing element : " << i + 1 << '\n'; 21 | } 22 | 23 | } 24 | 25 | int main() { 26 | int n; 27 | cout << "Enter the number of array elements : "; 28 | cin >> n; 29 | int arr[n]; 30 | cout << "Enter the array elements : "; 31 | for (int i = 0; i < n; ++i) 32 | cin >> arr[i]; 33 | findMissingRepeating(arr, n); 34 | return 0; 35 | } 36 | 37 | /* 38 | ~ Time Complexity : O(n) 39 | ~ Space Complexity : O(1) 40 | */ 41 | -------------------------------------------------------------------------------- /Strings/LongestSubstringWithoutRepeatingCharacters.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Title : Longest Substring Without Repeating Characters 3 | * Author : Tridib Samanta 4 | **/ 5 | 6 | #include 7 | using namespace std; 8 | 9 | #define ALL_CHARS 256 10 | 11 | int findLength(string s) { 12 | 13 | vector lastIndex(ALL_CHARS, -1); 14 | int maxLength = 0, start = 0; 15 | 16 | for (int j = 0; j < s.size(); ++j) { 17 | start = max(start, lastIndex[s[j]] + 1); 18 | maxLength = max(maxLength, j - start + 1); 19 | lastIndex[s[j]] = j; 20 | } 21 | return maxLength; 22 | } 23 | 24 | int main() { 25 | 26 | string s; 27 | cout << "Enter the string : "; 28 | cin >> s; 29 | 30 | int res = findLength(s); 31 | cout << "Length of the longest substr without repeating chars = " << res; 32 | 33 | return 0; 34 | } 35 | 36 | /* 37 | ~ Time Complexity : O(n) 38 | where 'n' is length of the string 39 | ~ Auxiliary Space : O(m) 40 | where 'm' is total number of permissible characters in the string 41 | */ 42 | -------------------------------------------------------------------------------- /Tree/Height_N-aryTree.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Title : Height of a N-ary Tree 3 | * Author : Tridib Samanta 4 | **/ 5 | 6 | #include 7 | using namespace std; 8 | 9 | int findHeight(int parent[], int n) { 10 | 11 | int maxHeight = INT_MIN; 12 | 13 | for (int i = 0; i < n; ++i) { 14 | 15 | int currHeight = 0, j = i; 16 | 17 | while(parent[j] != -1) { 18 | ++currHeight; 19 | j = parent[j]; 20 | } 21 | 22 | maxHeight = max(maxHeight, currHeight); 23 | } 24 | 25 | return maxHeight; 26 | } 27 | 28 | int main() { 29 | 30 | // Given a parent array, where parent[i] indicates the parent of i-th node in the tree 31 | // Assume, parent of root node is indicate with -1 32 | 33 | int parent[] = {-1, 0, 1, 6, 6, 0, 0, 2 ,7}; 34 | int n = sizeof(parent) / sizeof(parent[0]); 35 | 36 | int height = findHeight(parent, n); 37 | cout << "Height of the N-ary tree is : " << height << '\n'; 38 | 39 | return 0; 40 | } 41 | 42 | /* 43 | ~ Time Complexity : O(n^2) 44 | ~ Space Complexity : O(1) 45 | */ 46 | -------------------------------------------------------------------------------- /Arrays/Maximum_SubArray_Sum_KadaneAlgorithm.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Title : Maximum sum sub-array (Kadane's Algorithm) 3 | * Author : Tridib Samanta 4 | **/ 5 | 6 | //Overall Time Complexity - O(n) 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | using namespace std; 16 | 17 | int Maximum_Subarray_Sum(int [],int); 18 | 19 | int main() { 20 | 21 | int n; 22 | cout<<"Enter the size of the array : "<>n; 24 | int arr[n]; 25 | cout<<"Enter the array elements : "<>arr[i]; 28 | int max_sum=Maximum_Subarray_Sum(arr,n); 29 | cout<<"The Maximum Sub-array Sum is = "<0) 40 | sum+=arr[i]; 41 | else 42 | sum=0; 43 | ans=max(ans,sum); 44 | } 45 | return ans; 46 | } 47 | -------------------------------------------------------------------------------- /Arrays/Maximum_SubArray_Sum_KadaneAlgorithm1.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Title : Maximum sum sub-array (Kadane's Algorithm) 3 | * Author : Tridib Samanta 4 | **/ 5 | 6 | //Overall Time Complexity - O(n) 7 | 8 | #include 9 | using namespace std; 10 | 11 | int Maximum_Subarray_Sum(int [],int); 12 | 13 | int main() { 14 | 15 | int T; 16 | cin>>T; 17 | while(T--) { 18 | int n; 19 | cin>>n; 20 | int arr[n]; 21 | int cnt=0; 22 | for(int i=0;i>arr[i]; 24 | if(arr[i]<0) 25 | cnt++; 26 | } 27 | if(cnt==n) 28 | cout<<*max_element(arr, arr + n)<0) 43 | sum+=arr[i]; 44 | else 45 | sum=0; 46 | ans=max(ans,sum); 47 | } 48 | return ans; 49 | } 50 | -------------------------------------------------------------------------------- /DS/Graph_AdjacencyListImplementation_using_STL.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | void addEdge(vector adj[], int source, int destination) 6 | { 7 | adj[source].push_back(destination); 8 | //As graph is undirected, there must be an edge from destination to source also 9 | adj[destination].push_back(source); 10 | } 11 | 12 | void displayGraph(vector adj[], int vertices) { 13 | for(int vertex = 0; vertex < vertices; ++vertex) { 14 | cout << "Edges from vertex " << vertex << " :\n"; 15 | for(auto itr : adj[vertex]) 16 | cout << "(" << vertex << " -> " << itr << ") "; 17 | cout << "\n"; 18 | } 19 | } 20 | 21 | 22 | int main() { 23 | int totalVertices = 5; 24 | vector adj[totalVertices]; 25 | //Let's add some edges 26 | addEdge(adj, 0, 1); 27 | addEdge(adj, 0, 4); 28 | addEdge(adj, 1, 2); 29 | addEdge(adj, 1, 3); 30 | addEdge(adj, 1, 4); 31 | addEdge(adj, 2, 3); 32 | addEdge(adj, 3, 4); 33 | //Let's display the edges 34 | cout << "Graph is - \n"; 35 | displayGraph(adj, totalVertices); 36 | } 37 | -------------------------------------------------------------------------------- /Arrays/TrappingRainWater_BruteForce.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Title : Trapping Rain Water (Brute force) 3 | * Author : Tridib Samanta 4 | **/ 5 | 6 | #include 7 | using namespace std; 8 | 9 | int findTrappedWater(int arr[], int n) { 10 | if (n == 0 || n == 1) 11 | return 0; 12 | int res = 0; 13 | for (int i = 0; i < n; ++i) { 14 | int leftMax = arr[i]; 15 | for (int j = 0; j < i; ++j) 16 | leftMax = max(leftMax, arr[j]); 17 | int rightMax = arr[i]; 18 | for (int j = i + 1; j < n; ++j) 19 | rightMax = max(rightMax, arr[j]); 20 | res += min(leftMax, rightMax) - arr[i]; 21 | } 22 | return res; 23 | } 24 | 25 | int main() { 26 | int n; 27 | cout << "Enter the number of elements : "; 28 | cin >> n; 29 | int arr[n]; 30 | if (n != 0) { 31 | cout << "Enter " << n << " elements : "; 32 | for (int i = 0; i < n; ++i) 33 | cin >> arr[i]; 34 | } 35 | cout << "Result : "<< findTrappedWater(arr, n) << '\n'; 36 | return 0; 37 | } 38 | 39 | /* 40 | ~ Time Complexity : O(n^2) 41 | ~ Space Complexity : O(1) 42 | */ 43 | -------------------------------------------------------------------------------- /Arrays/TrappingRainWater_Approach2.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Title : Trapping Rain Water (Using two auxiliary arrays) 3 | * Author : Tridib Samanta 4 | **/ 5 | 6 | #include 7 | using namespace std; 8 | 9 | int findTrappedWater(int arr[], int n) { 10 | if (n == 0 || n == 1) 11 | return 0; 12 | int leftMax[n], rightMax[n], res = 0; 13 | leftMax[0] = arr[0]; 14 | for (int i = 1; i < n; ++i) 15 | leftMax[i] = max(leftMax[i - 1], arr[i]); 16 | rightMax[n - 1] = arr[n - 1]; 17 | for (int i = n - 2; i >= 0; --i) 18 | rightMax[i] = max(rightMax[i + 1], arr[i]); 19 | for (int i = 0; i < n; ++i) 20 | res += min(leftMax[i], rightMax[i]) - arr[i]; 21 | return res; 22 | } 23 | 24 | int main() { 25 | int n; 26 | cout << "Enter the number of elements : "; 27 | cin >> n; 28 | int arr[n]; 29 | if (n != 0) { 30 | cout << "Enter " << n << " elements : "; 31 | for (int i = 0; i < n; ++i) 32 | cin >> arr[i]; 33 | } 34 | cout << "Result : "<< findTrappedWater(arr, n) << '\n'; 35 | return 0; 36 | } 37 | 38 | /* 39 | ~ Time Complexity : O(n) 40 | ~ Space Complexity : O(n), for the two auxiliary arrays 41 | */ 42 | -------------------------------------------------------------------------------- /Strings/PatternSearch_BruteForce.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Title : Search for a pattern in a text (Brute-force) 3 | * Author : Tridib Samanta 4 | **/ 5 | 6 | #include 7 | using namespace std; 8 | 9 | int patternSearch(string text, string pattern) { 10 | 11 | int m = pattern.length(); 12 | int n = text.length(); 13 | 14 | for (int i = 0; i <= n - m; ++i) { 15 | int j; 16 | for (j = 0; j < m; ++j) { 17 | if (text[i + j] != pattern[j]) 18 | break; 19 | } 20 | if (j == m) 21 | return i; 22 | } 23 | return -1; 24 | } 25 | 26 | int main() { 27 | 28 | string text, pattern; 29 | 30 | cout << "Enter the text: "; 31 | getline(cin, text); 32 | 33 | cout << "Enter the pattern: "; 34 | getline(cin, pattern); 35 | 36 | int index = patternSearch(text, pattern); 37 | 38 | if (index == -1) 39 | cout << "Pattern not found in text"; 40 | else 41 | cout << "Pattern starts in text from index " << index << '\n'; 42 | 43 | return 0; 44 | } 45 | 46 | /* 47 | ~ Time Complexity : O(n*m) 48 | where 'n' is length of the text and 'm' is the length of the pattern 49 | ~ Space Complexity : O(1) 50 | */ 51 | -------------------------------------------------------------------------------- /Arrays/PythagoreanTriplet.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Title : Pythagorean Triplet (Using Sorting) 3 | * Author : Tridib Samanta 4 | **/ 5 | 6 | #include 7 | using namespace std; 8 | 9 | bool findPythagoreanTriplet(int arr[], int n) { 10 | for (int i = 0; i < n; ++i) 11 | arr[i] *= arr[i]; 12 | sort(arr, arr + n); 13 | for (int i = n - 1; i > 1; --i) { 14 | int leftPtr = 0, rightPtr = i - 1; 15 | while (leftPtr < rightPtr) { 16 | if (arr[leftPtr] + arr[rightPtr] == arr[i]) 17 | return true; 18 | else { 19 | if (arr[leftPtr] + arr[rightPtr] < arr[i]) 20 | ++leftPtr; 21 | else 22 | --rightPtr; 23 | } 24 | } 25 | } 26 | return false; 27 | } 28 | 29 | int main() { 30 | int n; 31 | cout << "Enter the number of elements : "; 32 | cin >> n; 33 | int arr[n]; 34 | cout << "Enter " << n << " elements : "; 35 | for (int i = 0; i < n; ++i) 36 | cin >> arr[i]; 37 | cout << (findPythagoreanTriplet(arr, n) ? "Yes" : "No") << '\n'; 38 | return 0; 39 | } 40 | 41 | /* 42 | ~ Time Complexity : O(n^2) 43 | ~ Space Complexity : O(1) 44 | */ 45 | 46 | -------------------------------------------------------------------------------- /Arrays/Maximum_Sum_Subarray_Size_K_BruteForce.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Title : Maximum Sum Sub-array of Size K (Brute Force Algorithm) 3 | * Author : Tridib Samanta 4 | **/ 5 | 6 | //Overall Time Complexity - O(n^2) 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | using namespace std; 16 | 17 | int getMaxSubArrayOfSizeK(int [],int,int); 18 | 19 | int main() { 20 | 21 | int n,k; 22 | cout<<"Enter the size of the array : "<>n; 24 | int arr[n]; 25 | cout<<"Enter the array elements : "<>arr[i]; 28 | cout<<"Enter the value of k : "<>k; 30 | int max_sum=getMaxSubArrayOfSizeK(arr,k,n); 31 | cout<<"The maximum sum of subarray of size "<> n; 33 | 34 | vector nums; 35 | 36 | cout << "Enter " << n << " elements : "; 37 | int element; 38 | for (int i = 0; i < n; ++i) { 39 | cin >> element; 40 | nums.push_back(element); 41 | } 42 | 43 | string res = findLargestNumber(nums); 44 | cout << "Largest number : " << res << '\n'; 45 | 46 | return 0; 47 | } 48 | 49 | /* 50 | ~ Time Complexity : O(nlogn) 51 | ~ Space Complexity : O(n) 52 | */ 53 | -------------------------------------------------------------------------------- /Arrays/Maximum_SubArray_Sum_BruteForce2.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Title : Maximum sum sub-array (Brute Force Approach) 3 | * Author : Tridib Samanta 4 | **/ 5 | 6 | //Overall Time Complexity - O(n^2) 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | using namespace std; 16 | 17 | int Maximum_Sum_Subarray(int [],int); 18 | 19 | int main() { 20 | 21 | int n; 22 | cout<<"Enter the size of the array : "<>n; 24 | int arr[n]; 25 | cout<<"Enter the array elements : "<>arr[i]; 28 | int max_sum=Maximum_Sum_Subarray(arr,n); 29 | cout<<"The Maximum Sub-array Sum is = "<n) 41 | break; 42 | sum+=arr[start_index+(sub_array_size-1)]; 43 | ans=max(ans,sum); 44 | } 45 | } 46 | return ans; 47 | } 48 | -------------------------------------------------------------------------------- /DS/LinkedList_Traversal_Recursion.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | struct Node { 5 | int data; 6 | struct Node * next; 7 | }; 8 | 9 | struct Node * head = NULL; 10 | 11 | void Print(struct Node * temp) { 12 | if(temp==NULL) 13 | return; 14 | printf("%d ",temp->data); 15 | Print(temp->next); 16 | } 17 | 18 | void ReversePrint(struct Node * temp) { 19 | if(temp==NULL) 20 | return; 21 | ReversePrint(temp->next); 22 | printf("%d ",temp->data); 23 | } 24 | 25 | void Insert(int data, int n) { 26 | struct Node * temp1 = (struct Node *)malloc(sizeof(struct Node *)); 27 | temp1->data=data; 28 | temp1->next=NULL; 29 | if(n==1) { 30 | temp1->next=head; 31 | head=temp1; 32 | return; 33 | } 34 | struct Node * temp2 = head; 35 | int i; 36 | for(i=0;inext; 38 | } 39 | temp1->next=temp2->next; 40 | temp2->next=temp1; 41 | } 42 | 43 | int main() { 44 | head=NULL; 45 | Insert(20,1); 46 | Insert(40,2); 47 | Insert(60,3); 48 | Insert(50,4); 49 | printf("The list is : \n"); 50 | Print(head); 51 | printf("\nThe reversed list is : \n"); 52 | ReversePrint(head); 53 | return 0; 54 | } 55 | -------------------------------------------------------------------------------- /Strings/LongestPalindromicSubsequence.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Title : Length of Longest Palindromic Subsequence (Recursive Approach) 3 | * Author : Tridib Samanta 4 | **/ 5 | 6 | #include 7 | using namespace std; 8 | 9 | int findLPS(string s, int startIdx, int endIdx) { 10 | 11 | // A single character is always a palindrome 12 | if (startIdx == endIdx) 13 | return 1; 14 | 15 | // A sequence of two equal characters are always palindrome 16 | if (s[startIdx] == s[endIdx] && endIdx == startIdx + 1) 17 | return 2; 18 | 19 | // For sequences greater than 2, we check first and last character 20 | // and also check if the string in between first and last character is palindrome or not 21 | if (s[startIdx] == s[endIdx]) 22 | return findLPS(s, startIdx + 1, endIdx - 1) + 2; 23 | 24 | return max(findLPS(s, startIdx, endIdx - 1), findLPS(s, startIdx + 1, endIdx)); 25 | } 26 | 27 | int main() { 28 | 29 | string s; 30 | cout << "Enter the string : "; 31 | cin >> s; 32 | 33 | int len = s.length(); 34 | 35 | int res = findLPS(s, 0, len - 1); 36 | cout << "Length of the Longest Palindromic Subsequence is : " << res << '\n'; 37 | 38 | return 0; 39 | } 40 | 41 | /* 42 | ~ Time Complexity : O(n^2) 43 | ~ Space Complexity : O(n^2) 44 | */ 45 | -------------------------------------------------------------------------------- /Arrays/TripletWhereSumOfTwoEqualsThirdElement.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Title : Triplet where sum of two elements equals third element (Using Two-pointer technique) 3 | * Author : Tridib Samanta 4 | **/ 5 | 6 | #include 7 | using namespace std; 8 | 9 | bool FindTriplet(int arr[], int size) { 10 | 11 | sort(arr, arr + size); 12 | 13 | int l, r; 14 | 15 | for (int i = size - 1; i > 1; --i) { 16 | l = 0; 17 | r = i - 1; 18 | while (l < r) { 19 | if (arr[l] + arr[r] == arr[i]) { 20 | cout << "Triplet is = {" << arr[l] << ", " << arr[r] << ", " << arr[i] << "} \n"; 21 | return true; 22 | } 23 | else if (arr[l] + arr[r] < arr[i]) 24 | ++l; 25 | else 26 | --r; 27 | } 28 | } 29 | return false; 30 | } 31 | 32 | int main() { 33 | 34 | int n; 35 | cout << "Enter the number of array elements = "; 36 | cin >> n; 37 | 38 | int arr[n]; 39 | cout << "Enter the array elements = "; 40 | for (int i = 0; i < n; ++i) 41 | cin >> arr[i]; 42 | 43 | if (!FindTriplet(arr, n)) 44 | cout << "No such triplet exists !\n"; 45 | 46 | return 0; 47 | } 48 | 49 | /* 50 | * Time Complexity : O(n^2) 51 | * Space Complexity : O(1) 52 | */ 53 | -------------------------------------------------------------------------------- /Arrays/Maximum_SubArray_Sum_BruteForce.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Title : Maximum sum sub-array (Brute Force Approach) 3 | * Author : Tridib Samanta 4 | **/ 5 | 6 | //Overall Time Complexity - O(n^3) 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | using namespace std; 16 | 17 | int Maximum_Sum_Subarray(int [],int); 18 | 19 | int main() { 20 | 21 | int n; 22 | cout<<"Enter the size of the array : "<>n; 24 | int arr[n]; 25 | cout<<"Enter the array elements : "<>arr[i]; 28 | int max_sum=Maximum_Sum_Subarray(arr,n); 29 | cout<<"The Maximum Sub-array Sum is = "<n) //Sub-array exceeds bounds 39 | break; 40 | int sum=0; 41 | for(int i=start_index;i<(start_index+sub_array_size);i++) 42 | sum+=arr[i]; 43 | ans=max(ans,sum); 44 | } 45 | } 46 | return ans; 47 | } 48 | -------------------------------------------------------------------------------- /Arrays/FirstMissingPositiveInteger.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Title : Find the first missing positive integer in an unsorted array 3 | * Author : Tridib Samanta 4 | **/ 5 | 6 | #include 7 | using namespace std; 8 | 9 | class Solution { 10 | public: 11 | int firstMissingPositive(vector& nums) { 12 | 13 | int n = nums.size(); 14 | 15 | for (int i = 0; i < n; ++i) { 16 | while ((nums[i] >= 1 && nums[i] <= n) && (nums[i] != nums[nums[i] - 1])) 17 | swap(nums[i], nums[nums[i] - 1]); 18 | } 19 | 20 | for (int i = 0; i < n; ++i) { 21 | if (nums[i] != i + 1) 22 | return i + 1; 23 | } 24 | 25 | return n + 1; 26 | } 27 | }; 28 | 29 | int main() { 30 | 31 | int n; 32 | cout << "Enter the number of elements: "; 33 | cin >> n; 34 | 35 | vector nums; 36 | 37 | cout << "Enter " << n << " elements: "; 38 | for (int i = 0; i < n; ++i) { 39 | int element; 40 | cin >> element; 41 | nums.emplace_back(element); 42 | } 43 | 44 | Solution ob; 45 | 46 | int res = ob.firstMissingPositive(nums); 47 | cout << "First missing positive integer is: " << res << ' '; 48 | 49 | return 0; 50 | } 51 | 52 | /* 53 | * Time Complexity : O(n) 54 | * Space Complexity : O(1) 55 | */ 56 | -------------------------------------------------------------------------------- /DS/LinkedList_Reverse_Recursion.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | struct Node { 5 | int data; 6 | struct Node * next; 7 | }; 8 | 9 | struct Node * head = NULL; 10 | 11 | void Print(struct Node * temp) { 12 | if(temp==NULL) 13 | return; 14 | printf("%d ",temp->data); 15 | Print(temp->next); 16 | } 17 | 18 | void Reverse(struct Node * p) { 19 | if(p->next==NULL) { 20 | head=p; 21 | return; 22 | } 23 | Reverse(p->next); 24 | struct Node * q = p->next; 25 | q->next=p; 26 | p->next=NULL; 27 | } 28 | 29 | void Insert(int data, int n) { 30 | struct Node * temp1 = (struct Node *)malloc(sizeof(struct Node *)); 31 | temp1->data=data; 32 | temp1->next=NULL; 33 | if(n==1) { 34 | temp1->next=head; 35 | head=temp1; 36 | return; 37 | } 38 | struct Node * temp2 = head; 39 | int i; 40 | for(i=0;inext; 42 | } 43 | temp1->next=temp2->next; 44 | temp2->next=temp1; 45 | } 46 | 47 | int main() { 48 | head=NULL; 49 | Insert(20,1); 50 | Insert(40,2); 51 | Insert(60,3); 52 | Insert(50,4); 53 | printf("Before reversal : \n"); 54 | Print(head); 55 | Reverse(head); 56 | printf("\nAfter reversal : \n"); 57 | Print(head); 58 | return 0; 59 | } 60 | -------------------------------------------------------------------------------- /Arrays/Maximum_Sum_Subarray_Size_K_SlidingWindowTechnique.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Title : Maximum Sum Sub-array of Size K (Sliding Window Technique) 3 | * Author : Tridib Samanta 4 | **/ 5 | 6 | //Overall Time Complexity - O(n) 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | using namespace std; 16 | 17 | int getMaxSubArrayOfSizeK(int [],int,int); 18 | 19 | int main() { 20 | 21 | int n,k; 22 | cout<<"Enter the size of the array : "<>n; 24 | int arr[n]; 25 | cout<<"Enter the array elements : "<>arr[i]; 28 | cout<<"Enter the value of k : "<>k; 30 | int max_sum=getMaxSubArrayOfSizeK(arr,k,n); 31 | cout<<"The maximum sum of subarray of size "<data=data; 33 | temp1->next=NULL; 34 | if(n==1) { 35 | temp1->next=head; 36 | head=temp1; 37 | return; 38 | } 39 | struct Node * temp2 = head; 40 | int i; 41 | for(i=0;inext; 43 | } 44 | temp1->next=temp2->next; 45 | temp2->next=temp1; 46 | } 47 | 48 | void Print() { 49 | struct Node * temp = head; 50 | printf("The list is - \n"); 51 | while(temp!=NULL) { 52 | printf("%d ",temp->data); 53 | temp=temp->next; 54 | } 55 | printf("\n"); 56 | } 57 | -------------------------------------------------------------------------------- /Stack/PairwiseConsecutive.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Title : Check if stack elements are pairwise consecutive 3 | * Author : Tridib Samanta 4 | **/ 5 | 6 | #include 7 | #include 8 | #include 9 | using namespace std; 10 | 11 | bool checkConsecutivePair(stack S){ 12 | 13 | bool res = true; 14 | 15 | stack aux; 16 | while (!S.empty()) { 17 | aux.push(S.top()); 18 | S.pop(); 19 | } 20 | 21 | while (aux.size() > 1) { 22 | 23 | int temp1 = aux.top(); 24 | aux.pop(); 25 | int temp2 = aux.top(); 26 | aux.pop(); 27 | 28 | if (abs(temp1 - temp2) != 1) 29 | res = false; 30 | 31 | S.push(temp1); 32 | S.push(temp2); 33 | } 34 | 35 | if (aux.size() == 1) 36 | S.push(aux.top()); 37 | 38 | return res; 39 | 40 | } 41 | 42 | 43 | int main() { 44 | 45 | int n; 46 | cin >> n; 47 | 48 | stack S; 49 | 50 | int element; 51 | for (int i = 0; i < n; ++i) { 52 | cin >> element; 53 | S.push(element); 54 | } 55 | 56 | if (checkConsecutivePair(S)) 57 | cout << "Successive pairs are consecutive\n"; 58 | else 59 | cout << "Successive pairs are not consecutive\n"; 60 | 61 | return 0; 62 | } 63 | 64 | /* 65 | ~ Time Complexity : O(n) 66 | ~ Space Complexity : O(n) 67 | */ 68 | -------------------------------------------------------------------------------- /Arrays/MajorityElement.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Title : Majority element in an array (Boyer-Moore Majority Vote Algorithm) 3 | * Author : Tridib Samanta 4 | **/ 5 | 6 | #include 7 | using namespace std; 8 | 9 | int boyerMooreMajorityVote(int arr[], int n) { 10 | 11 | int element = 0, count = 0; 12 | 13 | for (int i = 0; i < n; ++i) { 14 | if (count == 0) 15 | element = arr[i]; 16 | if (element == arr[i]) 17 | ++count; 18 | else 19 | --count; 20 | } 21 | 22 | count = 0; 23 | for (int i = 0; i < n; ++i) { 24 | if (element == arr[i]) 25 | ++count; 26 | if (count > (n / 2)) { 27 | return element; 28 | } 29 | } 30 | 31 | return INT_MIN; 32 | } 33 | 34 | int main() { 35 | 36 | int n; 37 | cout << "Enter the number of elements : "; 38 | cin >> n; 39 | 40 | int arr[n]; 41 | cout << "Enter " << n << " elements : "; 42 | for (int i = 0; i < n; ++i) { 43 | cin >> arr[i]; 44 | } 45 | 46 | int majority = boyerMooreMajorityVote(arr, n); 47 | 48 | if (majority == INT_MIN) 49 | cout << "Majority element does not exist\n"; 50 | else 51 | cout << "Majority element is : " << majority << '\n'; 52 | 53 | return 0; 54 | } 55 | 56 | /* 57 | ~ Time Complexity : O(n) 58 | ~ Space Complexity : O(1) 59 | */ 60 | -------------------------------------------------------------------------------- /Arrays/TrappingRainWater_Approach3.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Title : Trapping Rain Water (Using two pointers) 3 | * Author : Tridib Samanta 4 | **/ 5 | 6 | #include 7 | using namespace std; 8 | 9 | int findTrappedWater(int arr[], int n) { 10 | if (n == 0 || n == 1) 11 | return 0; 12 | int leftPtr = 0, rightPtr = n - 1; 13 | int leftMax = 0, rightMax = 0; 14 | int res = 0; 15 | while (leftPtr < rightPtr) { 16 | if (arr[leftPtr] < arr[rightPtr]) { 17 | if (arr[leftPtr] > leftMax) 18 | leftMax = arr[leftPtr]; 19 | else 20 | res += leftMax - arr[leftPtr]; 21 | ++leftPtr; 22 | } 23 | else { 24 | if (arr[rightPtr] > rightMax) 25 | rightMax = arr[rightPtr]; 26 | else 27 | res += rightMax - arr[rightPtr]; 28 | --rightPtr; 29 | } 30 | } 31 | return res; 32 | } 33 | 34 | int main() { 35 | int n; 36 | cout << "Enter the number of elements : "; 37 | cin >> n; 38 | int arr[n]; 39 | if (n != 0) { 40 | cout << "Enter " << n << " elements : "; 41 | for (int i = 0; i < n; ++i) 42 | cin >> arr[i]; 43 | } 44 | cout << "Result : "<< findTrappedWater(arr, n) << '\n'; 45 | return 0; 46 | } 47 | 48 | /* 49 | ~ Time Complexity : O(n) 50 | ~ Space Complexity : O(1) 51 | */ 52 | -------------------------------------------------------------------------------- /Arrays/RotationCount_SortedArray.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Title : Find the number of times a sorted array is rotated 3 | * Author : Tridib Samanta 4 | **/ 5 | 6 | #include 7 | using namespace std; 8 | 9 | int findRotationCount(vector &nums) { 10 | 11 | int n = nums.size(); 12 | int low = 0, high = n - 1; 13 | 14 | while (low <= high) { 15 | 16 | if (nums[low] <= nums[high]) 17 | return low; 18 | 19 | int mid = low + (high - low) / 2; 20 | int next = (mid + 1) % n, prev = (mid - 1 + n) % n; 21 | 22 | if (nums[mid] <= nums[prev] && nums[mid] <= nums[next]) 23 | return mid; 24 | else if (nums[low] <= nums[mid]) 25 | low = mid + 1; 26 | else if (nums[mid] <= nums[high]) 27 | high = mid - 1; 28 | } 29 | return -1; 30 | } 31 | 32 | int main() { 33 | 34 | int n; 35 | cout << "Enter the number of elements: "; 36 | cin >> n; 37 | 38 | vector nums; 39 | 40 | cout << "Enter " << n << " elements: "; 41 | for (int i = 0; i < n; ++i) { 42 | int element; 43 | cin >> element; 44 | nums.emplace_back(element); 45 | } 46 | 47 | int count = findRotationCount(nums); 48 | cout << "Sorted array is rotated " << count << " times"; 49 | 50 | return 0; 51 | } 52 | 53 | /* 54 | * Time Complexity : O(log n) 55 | * Space Complexity : O(1) 56 | */ 57 | -------------------------------------------------------------------------------- /Arrays/MergeTwoSortedArrays.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Title : Merge two sorted arrays 3 | * Author : Tridib Samanta 4 | **/ 5 | 6 | 7 | #include 8 | using namespace std; 9 | 10 | void mergeArrays(int a[], int b[], int m, int n, int c[]) { 11 | 12 | int i = 0, j =0, k = 0; 13 | 14 | while (i < m && j < n) { 15 | if (a[i] < b[j]) 16 | c[k++] = a[i++]; 17 | else 18 | c[k++] = b[j++]; 19 | } 20 | while (i < m) 21 | c[k++] = a[i++]; 22 | while (j < n) 23 | c[k++] = b[j++]; 24 | } 25 | 26 | int main() { 27 | 28 | cout << "Enter the size of array 1 = "; 29 | int m; 30 | cin >> m; 31 | 32 | int a[m]; 33 | cout << "Enter the " << m << " array elements = "; 34 | for (int i = 0; i < m; ++i) 35 | cin >> a[i]; 36 | 37 | cout << "Enter the size of array 2 = "; 38 | int n; 39 | cin >> n; 40 | 41 | int b[n]; 42 | cout << "Enter the " << n << " array elements = "; 43 | for (int i = 0; i < n; ++i) 44 | cin >> b[i]; 45 | 46 | int c[m+n]; 47 | 48 | mergeArrays(a, b, m, n, c); 49 | 50 | cout << "\nAfter Merging -\n"; 51 | 52 | cout << "Array is = "; 53 | for (int i = 0; i < m+n; ++i) 54 | cout << c[i] << " "; 55 | cout << "\n"; 56 | 57 | return 0; 58 | } 59 | 60 | /* 61 | * Time Complexity : O(m+n) 62 | * Auxiliary Space : O(m+n) 63 | */ 64 | 65 | -------------------------------------------------------------------------------- /Arrays/Maximum_SubArray_Sum_DivideAndConquer.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Title : Maximum sum sub-array (Divide and Conquer Approach) 3 | * Author : Tridib Samanta 4 | **/ 5 | 6 | //Overall Time Complexity - O(n log n) 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | using namespace std; 16 | 17 | int Maximum_Subarray_Sum(int [],int); 18 | 19 | int main() { 20 | 21 | int n; 22 | cout<<"Enter the size of the array : "<>n; 24 | int arr[n]; 25 | cout<<"Enter the array elements : "<>arr[i]; 28 | int max_sum=Maximum_Subarray_Sum(arr,n); 29 | cout<<"The Maximum Sub-array Sum is = "<=0;i--) { 49 | sum+=arr[i]; 50 | leftsum=max(leftsum,sum); 51 | } 52 | int ans=max(left_MSS,right_MSS); 53 | return max(ans,leftsum+rightsum); 54 | } 55 | -------------------------------------------------------------------------------- /Sorts/BubbleSort.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Title : Bubble Sort 3 | * Author : Tridib Samanta 4 | **/ 5 | 6 | #include 7 | using namespace std; 8 | 9 | void bubbleSort(int arr[], int n) { 10 | 11 | bool swapping; 12 | 13 | for (int i = 0; i < n - 1; ++i) { 14 | 15 | swapping = false; 16 | 17 | for (int j = 0; j < n - i - 1; ++j) { 18 | 19 | if (arr[j] > arr[j + 1]) { 20 | int temp = arr[j]; 21 | arr[j] = arr[j + 1]; 22 | arr[j + 1] = temp; 23 | swapping = true; 24 | } 25 | } 26 | 27 | if (!swapping) 28 | return; 29 | } 30 | } 31 | 32 | void displayArray(int arr[], int n) { 33 | cout << "The array elements are - "; 34 | for (int i = 0; i < n; ++i) 35 | cout << arr[i] << " "; 36 | cout << "\n"; 37 | } 38 | 39 | int main() { 40 | 41 | int n; 42 | cout << "Enter the size of the array - "; 43 | cin >> n; 44 | 45 | int arr[n]; 46 | cout << "Enter the " << n << " array elements - "; 47 | for (int i = 0; i < n; ++i) 48 | cin >> arr[i]; 49 | 50 | cout << "\nBefore sorting\n"; 51 | displayArray(arr, n); 52 | 53 | bubbleSort(arr, n); 54 | 55 | cout << "\nAfter sorting\n"; 56 | displayArray(arr, n); 57 | 58 | return 0; 59 | } 60 | 61 | /* 62 | * Time Complexity : O(n^2) 63 | * Auxiliary Space : O(1) 64 | */ 65 | -------------------------------------------------------------------------------- /Stack/BalancedParenthesesCheck.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Title : Check for balanced parentheses 3 | * Author : Tridib Samanta 4 | **/ 5 | 6 | #include 7 | #include 8 | using namespace std; 9 | 10 | bool checkPair(char open, char close) { 11 | if (open == '(' && close == ')') 12 | return true; 13 | else if (open == '{' && close == '}') 14 | return true; 15 | else if (open == '[' && close == ']') 16 | return true; 17 | else 18 | return false; 19 | } 20 | 21 | bool checkBalancedParenthesis(string exp) { 22 | stack S; 23 | for (int i = 0; i < exp.length(); ++i) { 24 | if (exp[i] == '(' || exp[i] == '{' || exp[i] == '[') 25 | S.push(exp[i]); 26 | else if (exp[i] == ')' || exp[i] == '}' || exp[i] == ']') { 27 | if (S.empty() || !checkPair(S.top(), exp[i])) 28 | return false; 29 | else 30 | S.pop(); 31 | } 32 | } 33 | return (S.empty() ? true : false); 34 | } 35 | 36 | int main() { 37 | 38 | string exp; 39 | cout << "Enter the expression : "; 40 | cin >> exp; 41 | 42 | if (checkBalancedParenthesis(exp)) 43 | cout << "Balanced"; 44 | else 45 | cout << "Not balanced"; 46 | 47 | return 0; 48 | } 49 | 50 | /* 51 | ~ Time Complexity : O(n), since we are scanning the input only once. 52 | ~ Space Complexity : O(n), for the stack. 53 | */ 54 | -------------------------------------------------------------------------------- /Arrays/TripletSumEqualToAGivenValue_BruteForce.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Title : Triplet sum that is equal to a given value (Brute-Force) 3 | * Author : Tridib Samanta 4 | **/ 5 | 6 | #include 7 | using namespace std; 8 | 9 | bool FindTriplet(int arr[], int size, int sum) { 10 | 11 | for(int i = 0; i < size - 2; ++i) { 12 | for(int j = i + 1; j < size - 1; ++j) { 13 | for(int k = j + 1; k < size; ++k) { 14 | int curr_sum = arr[i] + arr[j] + arr[k]; 15 | if(curr_sum == sum) { 16 | cout << "Triplet elements with sum " << sum << " are " << arr[i] << ", " << arr[j] << " and " << arr[k] << "\n"; 17 | return true; 18 | } 19 | } 20 | } 21 | } 22 | // Indicates no triplet with the given sum exists 23 | return false; 24 | } 25 | 26 | int main() { 27 | 28 | int n; 29 | cout << "Enter the number of array elements = "; 30 | cin >> n; 31 | 32 | int arr[n]; 33 | cout << "Enter the array elements = "; 34 | for (int i = 0; i < n; ++i) 35 | cin >> arr[i]; 36 | 37 | int sum; 38 | cout << "Enter the sum of the triplet = "; 39 | cin >> sum; 40 | 41 | if (!FindTriplet(arr, n, sum)) 42 | cout << "No triplet having sum " << sum << " exists !\n"; 43 | 44 | return 0; 45 | } 46 | 47 | /* 48 | * Time Complexity : O(n^3) 49 | * Space Complexity : O(1) 50 | */ 51 | -------------------------------------------------------------------------------- /Arrays/BitonicArrayMaximumElement.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Title : Bitonic array maximum element 3 | * Author : Tridib Samanta 4 | **/ 5 | 6 | #include 7 | using namespace std; 8 | 9 | int findMaxBitonic(int arr[], int low, int high) { 10 | 11 | // If the array has 1 element 12 | if (low == high) 13 | return arr[low]; 14 | 15 | // If the array has 2 elements 16 | if (high == low + 1) { 17 | if (arr[low] > arr[high]) 18 | return arr[low]; 19 | else 20 | return arr[high]; 21 | } 22 | 23 | // If the array has more than 2 elements 24 | int mid = low + high / 2; 25 | if (arr[mid] > arr[mid - 1] && arr[mid] > arr[mid + 1]) 26 | return arr[mid]; 27 | if (arr[mid] < arr[mid - 1] && arr[mid] > arr[mid + 1]) 28 | return findMaxBitonic(arr, low, mid - 1); 29 | else 30 | return findMaxBitonic(arr, mid + 1, high); 31 | } 32 | 33 | int main() { 34 | 35 | cout << "Enter the number of elements in the bitonic array - "; 36 | int n; 37 | cin >> n; 38 | 39 | int arr[n]; 40 | cout << "Enter " << n << " elements - "; 41 | for (int i = 0; i < n; ++i) 42 | cin >> arr[i]; 43 | 44 | int max_element = findMaxBitonic(arr, 0, n-1); 45 | cout << "Maximum element of the bitonic array is = " << max_element << "\n"; 46 | 47 | return 0; 48 | } 49 | 50 | /* 51 | * Time Complexity : O(log n) 52 | * Auxiliary Space : O(1) 53 | */ 54 | -------------------------------------------------------------------------------- /Strings/LongestPalindromicSubsequence_Method2.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Title : Length of Longest Palindromic Subsequence (Dynamic Programming Approach) 3 | * Author : Tridib Samanta 4 | **/ 5 | 6 | #include 7 | using namespace std; 8 | 9 | int findLPS(string s) { 10 | 11 | int n = s.length(); 12 | int dp[n][n]; 13 | memset(dp, 0, sizeof(dp)); 14 | 15 | // Every single character is a palindrome itself, of length 1 16 | for (int i = 0; i < n; ++i) 17 | dp[i][i] = 1; 18 | 19 | // Check every subsequence of length 2 and greater, upto length of the string 20 | for (int len = 2; len <= n; ++len) { 21 | 22 | for (int i = 0; i <= n - len; ++i) { 23 | 24 | int j = i + len - 1; 25 | 26 | if (s[i] == s[j] && len == 2) 27 | dp[i][j] = 2; 28 | else if (s[i] == s[j]) 29 | dp[i][j] = dp[i+1][j-1] + 2; 30 | else 31 | dp[i][j] = max(dp[i][j-1], dp[i+1][j]); 32 | } 33 | } 34 | 35 | // Top-right corner cell will contain the length of LPS 36 | return dp[0][n-1]; 37 | } 38 | 39 | int main() { 40 | 41 | string s; 42 | cout << "Enter the string : "; 43 | cin >> s; 44 | 45 | int res = findLPS(s); 46 | cout << "Length of the Longest Palindromic Subsequence is : " << res << '\n'; 47 | 48 | return 0; 49 | } 50 | 51 | /* 52 | ~ Time Complexity : O(n^2) 53 | ~ Space Complexity : O(n^2) 54 | */ 55 | -------------------------------------------------------------------------------- /Sorts/SelectionSort.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Title : Selection Sort 3 | * Author : Tridib Samanta 4 | **/ 5 | 6 | #include 7 | using namespace std; 8 | 9 | void selectionSort(int arr[], int n) { 10 | 11 | int minIdx; 12 | bool swapRequired; 13 | 14 | for (int i = 0; i < n - 1; ++i) { 15 | 16 | minIdx = i; 17 | swapRequired = false; 18 | 19 | for (int j = i + 1; j < n; ++j) { 20 | 21 | if (arr[j] < arr[minIdx]) { 22 | minIdx = j; 23 | swapRequired = true; 24 | } 25 | } 26 | 27 | if (swapRequired) { 28 | int temp = arr[minIdx]; 29 | arr[minIdx] = arr[i]; 30 | arr[i] = temp; 31 | } 32 | } 33 | } 34 | 35 | void displayArray(int arr[], int n) { 36 | cout << "The array elements are - "; 37 | for (int i = 0; i < n; ++i) 38 | cout << arr[i] << " "; 39 | cout << "\n"; 40 | } 41 | 42 | int main() { 43 | 44 | int n; 45 | cout << "Enter the size of the array - "; 46 | cin >> n; 47 | 48 | int arr[n]; 49 | cout << "Enter the " << n << " array elements - "; 50 | for (int i = 0; i < n; ++i) 51 | cin >> arr[i]; 52 | 53 | cout << "\nBefore sorting\n"; 54 | displayArray(arr, n); 55 | 56 | selectionSort(arr, n); 57 | 58 | cout << "\nAfter sorting\n"; 59 | displayArray(arr, n); 60 | 61 | return 0; 62 | } 63 | 64 | /* 65 | * Time Complexity : O(n^2) 66 | * Auxiliary Space : O(1) 67 | */ 68 | -------------------------------------------------------------------------------- /DS/Stack_LinkedListImplementation.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | struct Node { 5 | int data; 6 | struct Node * link; 7 | }; 8 | 9 | struct Node * top; 10 | 11 | void Push(int x) { 12 | struct Node * temp = (struct Node *)malloc(sizeof(struct Node)); 13 | temp->data=x; 14 | temp->link=top; 15 | top=temp; 16 | } 17 | 18 | void Pop() { 19 | struct Node * temp; 20 | if(top==NULL) return; 21 | temp=top; 22 | top=top->link; 23 | free(temp); 24 | } 25 | 26 | int IsEmpty() { 27 | if(top==NULL) 28 | return 1; 29 | else 30 | return 0; 31 | } 32 | 33 | int Top() { 34 | return(top->data); 35 | } 36 | 37 | void Print() { 38 | struct Node * temp = top; 39 | if(temp==NULL) { 40 | printf("Hey ! Stack is empty..\n"); 41 | return; 42 | } 43 | printf("Stack : \n"); 44 | while(temp!=NULL) { 45 | printf("%d\n",temp->data); 46 | temp=temp->link; 47 | } 48 | printf("\n"); 49 | } 50 | 51 | int main() { 52 | top=NULL; 53 | //Perform some Push() and Pop() operations and Print() the stack contents 54 | Push(2); Push(4); Push(7); Print(); 55 | Pop(); Print(); 56 | Push(6); Print(); 57 | //Check if Stack is empty or not 58 | printf("\nIs stack empty ?\n"); 59 | if(IsEmpty()) 60 | printf("Yes\n"); 61 | else 62 | printf("No\n"); 63 | 64 | int top_data = Top(); 65 | printf("\nData at the top of stack = %d\n",top_data); 66 | 67 | return 0; 68 | } 69 | -------------------------------------------------------------------------------- /Arrays/MergeOverlappingIntervals.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Title : Merge overlapping intervals 3 | * Author : Tridib Samanta 4 | **/ 5 | 6 | #include 7 | using namespace std; 8 | 9 | vector> mergeIntervals(vector>& intervals) { 10 | 11 | if (intervals.size() <= 1) 12 | return intervals; 13 | 14 | sort(intervals.begin(), intervals.end()); 15 | 16 | vector > res; 17 | res.emplace_back(intervals[0]); 18 | 19 | for (int i = 1; i < intervals.size(); ++i) { 20 | 21 | if (intervals[i][0] <= res.back()[1]) 22 | res.back()[1] = max(res.back()[1], intervals[i][1]); 23 | else 24 | res.emplace_back(intervals[i]); 25 | } 26 | 27 | return res; 28 | } 29 | 30 | int main() { 31 | 32 | int n; 33 | cout << "Enter the number of intervals : "; 34 | cin >> n; 35 | 36 | vector > intervals(n); 37 | 38 | cout << "Enter start and end value of each interval : "; 39 | for (int i = 0; i < n; ++i) { 40 | int start, end; 41 | cin >> start >> end; 42 | intervals[i].emplace_back(start); 43 | intervals[i].emplace_back(end); 44 | } 45 | 46 | vector > res = mergeIntervals(intervals); 47 | 48 | cout << "Merged intervals are : "; 49 | for (int i = 0; i < res.size(); ++i) { 50 | cout << res[i][0] << ' ' << res[i][1] << '\n'; 51 | } 52 | 53 | return 0; 54 | } 55 | 56 | /* 57 | ~ Time Complexity : O(nlogn) 58 | ~ Auxiliary Space : O(1) 59 | */ 60 | -------------------------------------------------------------------------------- /DS/BalancedParenthesisCheck_Stack.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | C++ Program to check for balanced parentheses in an expression using stack. 3 | Given an expression as string comprising of opening and closing characters 4 | of parentheses - (), curly braces - {} and square brackets - [], we need to 5 | check whether symbols are balanced or not. 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | using namespace std; 12 | 13 | bool CheckPair(char opening, char closing) { 14 | if(opening == '(' && closing == ')') 15 | return true; 16 | else if(opening == '{' && closing == '}') 17 | return true; 18 | else if(opening == '[' && closing == ']') 19 | return true; 20 | else 21 | return false; 22 | } 23 | 24 | bool CheckBalancedParenthesis(string exp) { 25 | stack S; 26 | for(int i=0;i>exp; 45 | if(CheckBalancedParenthesis(exp)) 46 | cout<<"Parenthesis are balanced !"< 8 | using namespace std; 9 | 10 | void mergeArrays(int a[], int b[], int m, int n) { 11 | 12 | for (int i = n - 1; i >= 0; --i) { 13 | 14 | int j, last = a[m-1]; 15 | 16 | for (j = m-2; j>=0 && a[j] > b[i]; --j) 17 | a[j+1] = a[j]; 18 | 19 | if (j != m-2 || last > b[i]) { 20 | a[j+1] = b[i]; 21 | b[i] = last; 22 | } 23 | } 24 | } 25 | 26 | int main() { 27 | 28 | cout << "Enter the size of array 1 = "; 29 | int m; 30 | cin >> m; 31 | 32 | int a[m]; 33 | cout << "Enter the " << m << " array elements = "; 34 | for (int i = 0; i < m; ++i) 35 | cin >> a[i]; 36 | 37 | cout << "Enter the size of array 2 = "; 38 | int n; 39 | cin >> n; 40 | 41 | int b[n]; 42 | cout << "Enter the " << n << " array elements = "; 43 | for (int i = 0; i < n; ++i) 44 | cin >> b[i]; 45 | 46 | mergeArrays(a, b, m, n); 47 | 48 | cout << "\nAfter Merging -\n"; 49 | 50 | cout << "Array 1 is = "; 51 | for (int i = 0; i < m; ++i) 52 | cout << a[i] << " "; 53 | cout << "\n"; 54 | 55 | cout << "Array 2 is = "; 56 | for (int i = 0; i < n; ++i) 57 | cout << b[i] << " "; 58 | cout << "\n"; 59 | 60 | return 0; 61 | } 62 | 63 | /* 64 | * Time Complexity : O(m*n) 65 | * Auxiliary Space : O(1) 66 | */ 67 | 68 | -------------------------------------------------------------------------------- /DS/Stack_ArrayImplementation.c: -------------------------------------------------------------------------------- 1 | #include 2 | #define MAX_SIZE 101 3 | 4 | int A[MAX_SIZE]; 5 | int top=-1; 6 | 7 | void Push(int x) { 8 | if(top==MAX_SIZE-1) { 9 | printf("Error : Stack Overflow !\n"); 10 | return; 11 | } 12 | top++; 13 | A[top]=x; 14 | } 15 | 16 | void Pop() { 17 | if(top==-1) { 18 | printf("Error : Stack is empty !\n"); 19 | return; 20 | } 21 | top--; 22 | } 23 | 24 | int Top() { 25 | return A[top]; 26 | } 27 | 28 | void Print() { 29 | if(top==-1) { 30 | printf("Stack is empty !\n"); 31 | return; 32 | } 33 | int i; 34 | printf("Stack : "); 35 | for(i=0;i<=top;i++) 36 | printf("%d ",A[i]); 37 | printf("\n"); 38 | } 39 | 40 | int main() { 41 | printf("1->Push\n"); 42 | printf("2->Pop\n"); 43 | printf("3->Print\n"); 44 | printf("Enter your choice ? \n"); 45 | int ch,val; 46 | scanf("%d",&ch); 47 | switch(ch) { 48 | case 1: 49 | printf("Enter the value : \n"); 50 | scanf("%d",&val); 51 | Push(val); 52 | break; 53 | case 2: 54 | printf("Executing Pop function !\n"); 55 | Pop(); 56 | break; 57 | case 3: 58 | Print(); 59 | break; 60 | default: 61 | printf("Enter the choice correctly !\n"); 62 | } 63 | int cnt; 64 | printf("\nDo you want to continue ? 1->Yes 0->Exit \n"); 65 | scanf("%d",&cnt); 66 | if(cnt==1) 67 | main(); 68 | printf("\n"); 69 | return 0; 70 | } 71 | -------------------------------------------------------------------------------- /Arrays/RearrangeArrayElementsZigZagFashion.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Title : Rearrange array elements in a Zig-Zag fashion 3 | (A[0] < A[1] > A[2] < A[3] > A[4] < A[5]) 4 | * Author : Tridib Samanta 5 | **/ 6 | 7 | #include 8 | using namespace std; 9 | 10 | class Solution { 11 | public: 12 | void arrangeZigZag(vector& nums) { 13 | 14 | bool relation = true; // true = '<', false = '>' 15 | 16 | for (int i = 0; i < nums.size() - 1; ++i) { 17 | 18 | if (relation) { 19 | // If nums[i] < nums[i+1] is not satisfied 20 | if (nums[i] > nums[i + 1]) 21 | swap(nums[i], nums[i + 1]); 22 | } 23 | else { 24 | // If nums[i] > nums[i+1] is not satisfied 25 | if (nums[i] < nums[i + 1]) 26 | swap(nums[i], nums[i + 1]); 27 | } 28 | // Change flag for next iteration 29 | relation = !relation; 30 | } 31 | } 32 | }; 33 | 34 | int main() { 35 | 36 | int n; 37 | cout << "Enter the number of elements: "; 38 | cin >> n; 39 | 40 | vector nums(n); 41 | 42 | cout << "Enter " << n << " elements: "; 43 | for (int i = 0; i < n; ++i) 44 | cin >> nums[i]; 45 | 46 | Solution ob; 47 | 48 | ob.arrangeZigZag(nums); 49 | cout << "Zig-Zag array: "; 50 | for (auto i : nums) 51 | cout << i << ' '; 52 | 53 | return 0; 54 | } 55 | 56 | /* 57 | * Time Complexity : O(n) 58 | * Space Complexity : O(1) 59 | */ 60 | -------------------------------------------------------------------------------- /Arrays/LastOccurrence_SortedArray.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Title : Find the last occurrence of an element in a sorted (non-decreasing) array 3 | * Author : Tridib Samanta 4 | **/ 5 | 6 | #include 7 | using namespace std; 8 | 9 | int findLastOccurrenceIndex(vector &nums, int target) { 10 | 11 | int n = nums.size(); 12 | 13 | int low = 0, high = n - 1, idx = -1; 14 | 15 | while (low <= high) { 16 | 17 | int mid = low + (high - low) / 2; 18 | 19 | if (nums[mid] == target) { 20 | idx = mid; 21 | low = mid + 1; 22 | } 23 | else if (nums[mid] < target) { 24 | low = mid + 1; 25 | } 26 | else { 27 | high = mid - 1; 28 | } 29 | } 30 | 31 | return idx; 32 | } 33 | 34 | int main() { 35 | 36 | int n; 37 | cout << "Enter the number of elements: "; 38 | cin >> n; 39 | 40 | vector nums; 41 | 42 | cout << "Enter " << n << " elements: "; 43 | for (int i = 0; i < n; ++i) { 44 | int element; 45 | cin >> element; 46 | nums.emplace_back(element); 47 | } 48 | 49 | int target; 50 | cout << "Enter the target element: "; 51 | cin >> target; 52 | 53 | int lastOccIdx = findLastOccurrenceIndex(nums, target); 54 | if (lastOccIdx == -1) 55 | cout << "Element not found !" << '\n'; 56 | else 57 | cout << "Last occurrence index: " << lastOccIdx << '\n'; 58 | 59 | return 0; 60 | } 61 | 62 | /* 63 | * Time Complexity : O(log n) 64 | * Space Complexity : O(1) 65 | */ 66 | -------------------------------------------------------------------------------- /Arrays/FirstOccurrence_SortedArray.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Title : Find the first occurrence of an element in a sorted (non-decreasing) array 3 | * Author : Tridib Samanta 4 | **/ 5 | 6 | #include 7 | using namespace std; 8 | 9 | int findFirstOccurrenceIndex(vector &nums, int target) { 10 | 11 | int n = nums.size(); 12 | 13 | int low = 0, high = n - 1, idx = -1; 14 | 15 | while (low <= high) { 16 | 17 | int mid = low + (high - low) / 2; 18 | 19 | if (nums[mid] == target) { 20 | idx = mid; 21 | high = mid - 1; 22 | } 23 | else if (nums[mid] < target) { 24 | low = mid + 1; 25 | } 26 | else { 27 | high = mid - 1; 28 | } 29 | } 30 | 31 | return idx; 32 | } 33 | 34 | int main() { 35 | 36 | int n; 37 | cout << "Enter the number of elements: "; 38 | cin >> n; 39 | 40 | vector nums; 41 | 42 | cout << "Enter " << n << " elements: "; 43 | for (int i = 0; i < n; ++i) { 44 | int element; 45 | cin >> element; 46 | nums.emplace_back(element); 47 | } 48 | 49 | int target; 50 | cout << "Enter the target element: "; 51 | cin >> target; 52 | 53 | int firstOccIdx = findFirstOccurrenceIndex(nums, target); 54 | if (firstOccIdx == -1) 55 | cout << "Element not found !" << '\n'; 56 | else 57 | cout << "First occurrence index: " << firstOccIdx << '\n'; 58 | 59 | return 0; 60 | } 61 | 62 | /* 63 | * Time Complexity : O(log n) 64 | * Space Complexity : O(1) 65 | */ 66 | -------------------------------------------------------------------------------- /Binary Indexed Tree/InversionCount.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Title : Inversion count in an array 3 | * Author : Tridib Samanta 4 | **/ 5 | 6 | #include 7 | using namespace std; 8 | 9 | const int MAXN = 2 * 1e5 + 5; 10 | 11 | int n; // n <= 200000 12 | long long arr[MAXN]; 13 | int bit[MAXN]; 14 | 15 | void compress() { 16 | map mp; 17 | 18 | for (int i = 1; i <= n; ++i) { 19 | mp[arr[i]]; 20 | } 21 | 22 | int idx = 1; 23 | 24 | for (auto& pr : mp) { 25 | pr.second = idx++; 26 | } 27 | 28 | for (int i = 1; i <= n; ++i) { 29 | arr[i] = mp[arr[i]]; 30 | } 31 | } 32 | 33 | void update(int i, int val) { 34 | for (; i < MAXN; i += (i & -i)) { 35 | bit[i] += val; 36 | } 37 | } 38 | 39 | int query(int i) { 40 | int ans = 0; 41 | for (; i > 0; i -= (i & -i)) { 42 | ans += bit[i]; 43 | } 44 | return ans; 45 | } 46 | 47 | int main() { 48 | 49 | cin >> n; 50 | 51 | for (int i = 1; i <= n; ++i) { 52 | cin >> arr[i]; 53 | } 54 | 55 | // index compression to handle cases such as: 56 | // 1. arr[i] is negative 57 | // 2. arr[i] > 1e6 (insufficient memory for bit[]) 58 | compress(); 59 | 60 | int inversionCount = 0; 61 | 62 | for (int i = 1; i <= n; ++i) { 63 | inversionCount += query(MAXN) - query(arr[i]); 64 | update(arr[i], 1); 65 | } 66 | 67 | cout << inversionCount << '\n'; 68 | 69 | return 0; 70 | } 71 | 72 | /* 73 | ~ Time Complexity: O(n * log n) 74 | ~ Auxiliary Space: O(MAXN) 75 | */ 76 | -------------------------------------------------------------------------------- /DS/Stack_LinkedListReverse.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | 6 | struct Node { 7 | int data; 8 | struct Node* next; 9 | }; 10 | 11 | struct Node* head; 12 | 13 | void Insert(int x); 14 | void Print(); 15 | void Reverse(); 16 | 17 | int main() { 18 | 19 | head=NULL; //empty list 20 | printf("Number of elements in the linked list ? \n"); 21 | int n,i,x; 22 | scanf("%d",&n); 23 | for(i=1;i<=n;i++) { 24 | printf("Enter the %d element = \n",i); 25 | scanf("%d",&x); 26 | Insert(x); 27 | } 28 | Print(); 29 | Reverse(); 30 | printf("\nAfter Reversing"); 31 | Print(); 32 | return 0; 33 | } 34 | 35 | void Insert(int x) 36 | { 37 | Node* temp=new Node; 38 | temp->data=x; 39 | temp->next=head; 40 | head=temp; 41 | } 42 | 43 | void Print() 44 | { 45 | if(head==NULL) { 46 | printf("\nEmpty List!"); 47 | return; 48 | } 49 | struct Node* temp=head; 50 | printf("\nList is : "); 51 | while(temp!=NULL) { 52 | printf("%d ",temp->data); 53 | temp=temp->next; 54 | } 55 | } 56 | 57 | void Reverse() { 58 | if(head==NULL) 59 | return; 60 | stack S; 61 | Node * temp = head; 62 | while(temp!=NULL) { 63 | S.push(temp); 64 | temp=temp->next; 65 | } 66 | temp=S.top(); 67 | head=temp; 68 | S.pop(); 69 | while(!S.empty()) { 70 | temp->next=S.top(); 71 | S.pop(); 72 | temp=temp->next; 73 | } 74 | temp->next=NULL; 75 | } 76 | -------------------------------------------------------------------------------- /Strings/LongestPalindromicSubstring_Method2.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Title : Longest Palindromic Substring (Method 2) 3 | * Author : Tridib Samanta 4 | **/ 5 | 6 | #include 7 | using namespace std; 8 | 9 | void findLongestPalindromicSubstring(string s) { 10 | 11 | int n = s.length(); 12 | 13 | int startIdx = 0, maxLen = 1, low, high; 14 | 15 | for (int i = 1; i < n; ++i) { 16 | 17 | low = i - 1; 18 | high = i; 19 | while ((low >= 0 && high < n) && (s[low] == s[high])) { 20 | 21 | if (high - low + 1 > maxLen) { 22 | maxLen = high - low + 1; 23 | startIdx = low; 24 | } 25 | --low; 26 | ++high; 27 | } 28 | 29 | low = i - 1; 30 | high = i + 1; 31 | while ((low >= 0 && high < n) && (s[low] == s[high])) { 32 | 33 | if (high - low + 1 > maxLen) { 34 | maxLen = high - low + 1; 35 | startIdx = low; 36 | } 37 | --low; 38 | ++high; 39 | } 40 | } 41 | 42 | cout << "Longest Palindromic Substring is : "; 43 | for (int i = startIdx; i < startIdx + maxLen; ++i) 44 | cout << s[i]; 45 | cout << '\n'; 46 | cout << "Length of the Longest Palindromic Substring is : "; 47 | cout << maxLen << '\n'; 48 | } 49 | 50 | int main() { 51 | 52 | string s; 53 | cout << "Enter the string : "; 54 | cin >> s; 55 | 56 | findLongestPalindromicSubstring(s); 57 | 58 | return 0; 59 | } 60 | 61 | /* 62 | ~ Time Complexity : O(n^2) 63 | ~ Space Complexity : O(1) 64 | */ 65 | -------------------------------------------------------------------------------- /Arrays/Subarray_sum_equals_given_sum.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Title : Subarray sum equals given sum 3 | * Author : Tridib Samanta 4 | **/ 5 | 6 | #include 7 | using namespace std; 8 | 9 | int SubArraySum(int arr[], int size, int sum) { 10 | 11 | int curr_sum = arr[0], start = 0; 12 | 13 | //Loop that traverses the array 14 | for (int i = 1; i <= size; ++i) { 15 | // If current sum exceeds the desired sum we need to substract the elements from the start of the current subarray 16 | // Also increment the start index by 1 on every substraction 17 | while (curr_sum > sum && start < i-1) { 18 | curr_sum -= arr[start]; 19 | ++start; 20 | } 21 | // If current sum is equal with desired sum, print the indices and return to main function 22 | if (curr_sum == sum) { 23 | cout << "Sum found between index " << start << " and " << i-1 << "\n"; 24 | return 1; 25 | } 26 | // If index is less than size of the array, add an element to the existing current sum 27 | if (i < size) 28 | curr_sum += arr[i]; 29 | } 30 | // If sum of any subarray does not match with our desired sum then subarray does not exists 31 | cout << "No subarray containing the given sum exists !\n"; 32 | return 0; 33 | } 34 | 35 | int main() { 36 | int n; 37 | cout << "Enter the size of the array = "; 38 | cin >> n; 39 | 40 | int arr[n]; 41 | cout << "Enter the " << n << " array elements = "; 42 | for(int i = 0; i < n; ++i) 43 | cin >> arr[i]; 44 | 45 | int sum; 46 | cout << "Enter the sum = "; 47 | cin >> sum; 48 | 49 | SubArraySum(arr, n, sum); 50 | 51 | return 0; 52 | } 53 | 54 | /* 55 | * Time Complexity : O(n) 56 | * Space Complexity : O(1) 57 | */ 58 | -------------------------------------------------------------------------------- /Queue/QueueTwoStacks.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Title : Implement a queue using two stacks 3 | * Author : Tridib Samanta 4 | **/ 5 | 6 | #include 7 | using namespace std; 8 | 9 | stack S1, S2; 10 | 11 | void enqueue(int x) { 12 | S1.push(x); 13 | } 14 | 15 | int dequeue() { 16 | if (S2.empty() && S1.empty()) 17 | return -1; 18 | if (S2.empty()) { 19 | while (!S1.empty()) { 20 | S2.push(S1.top()); 21 | S1.pop(); 22 | } 23 | } 24 | int element = S2.top(); 25 | S2.pop(); 26 | return element; 27 | } 28 | 29 | int printFront() { 30 | if (S2.empty() && S1.empty()) 31 | return -1; 32 | if (S2.empty()) { 33 | while (!S1.empty()) { 34 | S2.push(S1.top()); 35 | S1.pop(); 36 | } 37 | } 38 | return S2.top(); 39 | } 40 | 41 | int main() { 42 | int q; 43 | cin >> q; 44 | while (q--) { 45 | 46 | int type; 47 | cin >> type; 48 | 49 | switch(type) { 50 | case 1: { 51 | int element; 52 | cin >> element; 53 | enqueue(element); 54 | break; 55 | } 56 | case 2: { 57 | int element; 58 | element = dequeue(); 59 | break; 60 | } 61 | case 3: { 62 | int element; 63 | element = printFront(); 64 | cout << element << '\n'; 65 | } 66 | default : 67 | // Do nothing 68 | break; 69 | } 70 | } 71 | return 0; 72 | } 73 | -------------------------------------------------------------------------------- /Sorts/HeapSort.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Title : Heap Sort 3 | * Author : Tridib Samanta 4 | **/ 5 | 6 | #include 7 | using namespace std; 8 | 9 | void heapify(int arr[], int n, int pos) { 10 | 11 | int leftChildIdx = (2 * pos) + 1; 12 | int rightChildIdx = (2 * pos) + 2; 13 | int maxIdx = pos; 14 | 15 | if ((leftChildIdx < n) && (arr[leftChildIdx] > arr[maxIdx])) 16 | maxIdx = leftChildIdx; 17 | if ((rightChildIdx < n) && (arr[rightChildIdx] > arr[maxIdx])) 18 | maxIdx = rightChildIdx; 19 | 20 | if (maxIdx != pos) { 21 | swap(arr[pos], arr[maxIdx]); 22 | heapify(arr, n, maxIdx); 23 | } 24 | } 25 | 26 | void heapSort(int arr[], int n) { 27 | 28 | for (int i = n / 2 - 1; i >= 0; --i) 29 | heapify(arr, n, i); 30 | 31 | for (int i = n - 1; i > 0; --i) { 32 | swap(arr[0], arr[i]); 33 | heapify(arr, i, 0); 34 | } 35 | } 36 | 37 | void displayArray(int arr[], int n) { 38 | cout << "The array elements are - "; 39 | for (int i = 0; i < n; ++i) 40 | cout << arr[i] << " "; 41 | cout << "\n"; 42 | } 43 | 44 | int main() { 45 | 46 | int n; 47 | cout << "Enter the size of the array - "; 48 | cin >> n; 49 | 50 | int arr[n]; 51 | cout << "Enter the " << n << " array elements - "; 52 | for (int i = 0; i < n; ++i) 53 | cin >> arr[i]; 54 | 55 | cout << "\nBefore sorting\n"; 56 | displayArray(arr, n); 57 | 58 | heapSort(arr, n); 59 | 60 | cout << "\nAfter sorting\n"; 61 | displayArray(arr, n); 62 | 63 | return 0; 64 | } 65 | 66 | /* 67 | * Time Complexity : O(n log n) 68 | * Auxiliary Space : O(1) 69 | */ 70 | -------------------------------------------------------------------------------- /Arrays/TripletSumEqualToAGivenValue_Hashing.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Title : Triplet sum that is equal to a given value (Hashing based) 3 | * Author : Tridib Samanta 4 | **/ 5 | 6 | #include 7 | using namespace std; 8 | 9 | bool FindTriplet(int arr[], int size, int sum) { 10 | 11 | for(int i = 0; i < size - 2; ++i) { 12 | 13 | unordered_set hs; 14 | int curr_sum = sum - arr[i]; // Current sum has the value of the other two elements if triplet exists 15 | 16 | for(int j = i + 1; j < size; ++j) { 17 | // Basically we again subtract another element from current sum and hence search for the third element in the set 18 | if (hs.find(curr_sum - arr[j]) != hs.end()) { 19 | cout << "Triplet elements with sum " << sum << " are " << arr[i] << ", " << arr[j] << " and " << curr_sum - arr[j] << "\n"; 20 | return true; 21 | } 22 | 23 | hs.insert(arr[j]); 24 | } 25 | } 26 | // Indicates no triplet with the given sum exists 27 | return false; 28 | } 29 | 30 | int main() { 31 | 32 | int n; 33 | cout << "Enter the number of array elements = "; 34 | cin >> n; 35 | 36 | int arr[n]; 37 | cout << "Enter the array elements = "; 38 | for (int i = 0; i < n; ++i) 39 | cin >> arr[i]; 40 | 41 | int sum; 42 | cout << "Enter the sum of the triplet = "; 43 | cin >> sum; 44 | 45 | if (!FindTriplet(arr, n, sum)) 46 | cout << "No triplet having sum " << sum << " exists !\n"; 47 | 48 | return 0; 49 | } 50 | 51 | /* 52 | * Time Complexity : O(n^2) 53 | * Space Complexity : O(n) // Space for the storing the set 54 | */ 55 | -------------------------------------------------------------------------------- /Arrays/PeakElement.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Title : Find a peak element's index in an array 3 | * Author : Tridib Samanta 4 | **/ 5 | 6 | #include 7 | using namespace std; 8 | 9 | int getPeakElement(vector &nums) { 10 | 11 | int n = nums.size(); 12 | 13 | if (n == 1) 14 | return 0; 15 | 16 | int low = 0, high = n - 1; 17 | 18 | while (low <= high) { 19 | 20 | int mid = low + (high - low) / 2; 21 | 22 | if ((mid > 0) && (mid < n -1)) { 23 | 24 | if ((nums[mid] >= nums[mid + 1]) && (nums[mid] >= nums[mid - 1])) 25 | return mid; 26 | else if (nums[mid - 1] > nums[mid]) 27 | high = mid - 1; 28 | else 29 | low = mid + 1; 30 | } 31 | else if (mid == 0) { 32 | 33 | if (nums[mid] >= nums[mid + 1]) 34 | return 0; 35 | else 36 | return 1; 37 | } 38 | else if (mid == n - 1) { 39 | 40 | if (nums[n - 1] >= nums[n - 2]) 41 | return n - 1; 42 | else 43 | return n - 2; 44 | } 45 | } 46 | } 47 | 48 | int main() { 49 | 50 | int n; 51 | cout << "Enter the number of elements: "; 52 | cin >> n; 53 | 54 | vector nums; 55 | 56 | cout << "Enter " << n << " elements: "; 57 | for (int i = 0; i < n; ++i) { 58 | int x; 59 | cin >> x; 60 | nums.emplace_back(x); 61 | } 62 | 63 | int res = getPeakElement(nums); 64 | cout << "Peak element index: " << res << '\n'; 65 | 66 | return 0; 67 | } 68 | 69 | /* 70 | ~ Time Complexity : O(n) 71 | ~ Space Complexity : O(1) 72 | */ 73 | -------------------------------------------------------------------------------- /Arrays/MinimumElement_SortedArray.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Title : Find the minimum element in a sorted array (without duplicate elements) 3 | * Author : Tridib Samanta 4 | **/ 5 | 6 | #include 7 | using namespace std; 8 | 9 | int findMinimumElement(vector &nums) { 10 | 11 | int n = nums.size(); 12 | int low = 0, high = n - 1; 13 | 14 | while (low <= high) { 15 | 16 | // Current segment is already sorted 17 | if (nums[low] <= nums[high]) 18 | return nums[low]; 19 | 20 | int mid = low + (high - low) / 2; 21 | int next = (mid + 1) % n, prev = (mid - 1 + n) % n; 22 | 23 | // Current mid element is the minimum element 24 | if (nums[mid] <= nums[prev] && nums[mid] <= nums[next]) 25 | return nums[mid]; 26 | // Minimum element lies in the unsorted segment (reducing search space) 27 | else if (nums[low] <= nums[mid]) 28 | low = mid + 1; 29 | else if (nums[mid] <= nums[high]) 30 | high = mid - 1; 31 | } 32 | return -1; 33 | } 34 | 35 | int main() { 36 | 37 | int n; 38 | cout << "Enter the number of elements: "; 39 | cin >> n; 40 | 41 | vector nums; 42 | 43 | cout << "Enter " << n << " elements: "; 44 | for (int i = 0; i < n; ++i) { 45 | int element; 46 | cin >> element; 47 | nums.emplace_back(element); 48 | } 49 | 50 | int minElement = findMinimumElement(nums); 51 | cout << "Minimum element is: " << minElement << '\n'; 52 | 53 | return 0; 54 | } 55 | 56 | /* 57 | * Time Complexity : O(log n) 58 | * Space Complexity : O(1) 59 | */ 60 | 61 | // N.B.: If the array contains duplicate elements we cannot apply Binary Search 62 | -------------------------------------------------------------------------------- /Stack/InfixToPostfix.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Title : Infix to Postfix Conversion 3 | * Author : Tridib Samanta 4 | **/ 5 | 6 | #include 7 | #include 8 | using namespace std; 9 | 10 | int prec(char ch) { 11 | if (ch == '^') 12 | return 3; 13 | else if (ch == '*' || ch == '/') 14 | return 2; 15 | else if (ch == '+' || ch == '-') 16 | return 1; 17 | else 18 | return -1; 19 | } 20 | 21 | string infixToPostfix(string exp) { 22 | stack s; 23 | string res; 24 | for (int i = 0; i < exp.length(); ++i) { 25 | if ((exp[i] >= 'A' && exp[i] <= 'Z') || (exp[i] >= 'a' && exp[i] <= 'z')) 26 | res += exp[i]; 27 | else if (exp[i] == '(') 28 | s.push('('); 29 | else if (exp[i] == ')') { 30 | while (!s.empty() && s.top() != '(') { 31 | res += s.top(); 32 | s.pop(); 33 | } 34 | if (s.top() == '(') 35 | s.pop(); 36 | } 37 | else { 38 | while (!s.empty() && prec(exp[i]) <= prec(s.top())) { 39 | res += s.top(); 40 | s.pop(); 41 | } 42 | s.push(exp[i]); 43 | } 44 | } 45 | while (!s.empty()) { 46 | res += s.top(); 47 | s.pop(); 48 | } 49 | return res; 50 | } 51 | 52 | int main() { 53 | string exp; 54 | cout << "Enter the infix expression : "; 55 | getline(cin, exp); 56 | string postfix = infixToPostfix(exp); 57 | cout << "Postfix : " << postfix << '\n'; 58 | return 0; 59 | } 60 | 61 | /* 62 | ~ Time Complexity : O(n), since we are scanning the input only once. 63 | ~ Space Complexity : O(n), for the stack. 64 | */ 65 | -------------------------------------------------------------------------------- /Dynamic Programming/CatalanNumber.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Title : Find the Nth Catalan Number 3 | * Author : Tridib Samanta 4 | **/ 5 | 6 | #include 7 | using namespace std; 8 | 9 | #define ull unsigned long long 10 | 11 | // ***** Approach 1 (Recursive) ***** 12 | /* 13 | ull catalan(int n) { 14 | 15 | if (n <= 1) 16 | return 1; 17 | 18 | ull res = 0; 19 | 20 | for (int i = 0; i < n; ++i) { 21 | res += catalan(i) * catalan(n - i - 1); 22 | } 23 | 24 | return res; 25 | } 26 | */ 27 | 28 | ull dp[105]; 29 | 30 | // ***** Approach 2 (Top-Down) ***** 31 | /* 32 | ull catalanUtil(int n) { 33 | 34 | if (n <= 1) 35 | return 1; 36 | 37 | if (dp[n] != -1) 38 | return dp[n]; 39 | 40 | ull res = 0; 41 | 42 | for (int i = 0; i < n; ++i) 43 | res += catalanUtil(i) * catalanUtil(n - i - 1); 44 | 45 | return dp[n] = res; 46 | } 47 | 48 | ull catalan(int n) { 49 | fill(dp, dp + 105, -1); 50 | return catalanUtil(n); 51 | } 52 | */ 53 | 54 | // ***** Approach 3 (Bottom-Up) ***** 55 | 56 | ull catalan(int n) { 57 | 58 | fill(dp, dp + 105, 0); 59 | 60 | dp[0] = dp[1] = 1; 61 | 62 | for (int i = 2; i < n + 1; ++i) { 63 | 64 | for (int j = 0; j < i; ++j) { 65 | 66 | dp[i] += dp[j] * dp[i - j - 1]; 67 | } 68 | } 69 | 70 | return dp[n]; 71 | } 72 | 73 | 74 | int main() { 75 | 76 | int n; 77 | cin >> n; 78 | 79 | ull res = catalan(n); 80 | cout << res << '\n'; 81 | 82 | return 0; 83 | } 84 | 85 | /* 86 | ***** Approach 1 ***** 87 | ~ Time Complexity : O(n^2) 88 | ~ Space Complexity : O(n^2) 89 | 90 | ***** Approach 2 ***** 91 | ~ Time Complexity : O(n) 92 | ~ Space Complexity : O(n) 93 | 94 | ***** Approach 3 ***** 95 | ~ Time Complexity : O(n) 96 | ~ Space Complexity : O(n) 97 | */ 98 | -------------------------------------------------------------------------------- /Dynamic Programming/BuildingBridges.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Title : Building Bridges (Longest Increasing Subsequence Variation) 3 | * Author : Tridib Samanta 4 | **/ 5 | 6 | #include 7 | using namespace std; 8 | 9 | /***** Approach 1 (Sort + DP) *****/ 10 | /* 11 | int maxBridges(vector >& cities) { 12 | 13 | int n = cities.size(); 14 | 15 | if (n <= 1) 16 | return n; 17 | 18 | sort(cities.begin(), cities.end()); 19 | 20 | vector dp(n, 1); 21 | 22 | int maxCnt = 1; 23 | 24 | for (int i = 1; i < n; ++i) { 25 | 26 | for (int j = 0; j < i; ++j) { 27 | 28 | if (cities[i][1] > cities[j][1] && dp[i] < dp[j] + 1) 29 | dp[i] = dp[j] + 1; 30 | } 31 | 32 | maxCnt = max(maxCnt, dp[i]); 33 | } 34 | 35 | return maxCnt; 36 | } 37 | */ 38 | 39 | /***** Approach 2 (Sort + Binary Search + DP) *****/ 40 | 41 | int maxBridges(vector >& cities) { 42 | 43 | int n = cities.size(); 44 | 45 | if (n <= 1) 46 | return n; 47 | 48 | sort(cities.begin(), cities.end()); 49 | 50 | vector dp; 51 | dp.emplace_back(cities[0][1]); 52 | 53 | for (int i = 1; i < n; ++i) { 54 | 55 | auto itr = lower_bound(dp.begin(), dp.end(), cities[i][1]); 56 | 57 | if (itr == dp.end()) 58 | dp.emplace_back(cities[i][1]); 59 | else 60 | *itr = cities[i][1]; 61 | } 62 | 63 | return dp.size(); 64 | } 65 | 66 | int main() { 67 | 68 | vector > cities{{5, 6}, {3, 4}, {10, 1}}; 69 | 70 | cout << "Maximum number of bridges = " << maxBridges(cities); 71 | 72 | return 0; 73 | } 74 | 75 | /* 76 | ***** Approach 1 ***** 77 | ~ Time Complexity : O(n^2) 78 | ~ Space Complexity : O(n) 79 | 80 | ***** Approach 2 ***** 81 | ~ Time Complexity : O(nlogn) 82 | ~ Space Complexity : O(n) 83 | */ 84 | -------------------------------------------------------------------------------- /Sorts/InsertionSort.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Title : Insertion Sort 3 | * Author : Tridib Samanta 4 | **/ 5 | 6 | #include 7 | using namespace std; 8 | 9 | void insertionSort(int arr[], int n) { 10 | int key; 11 | for (int i = 1; i < n; ++i) { 12 | key = arr[i]; 13 | int j = i - 1; 14 | while (j >= 0 && arr[j] > key) { 15 | arr[j+1] = arr[j]; 16 | --j; 17 | } 18 | arr[j+1] = key; 19 | } 20 | } 21 | 22 | void displayArray(int arr[], int n) { 23 | cout << "The array elements are - "; 24 | for (int i = 0; i < n; ++i) 25 | cout << arr[i] << " "; 26 | cout << "\n"; 27 | } 28 | 29 | int main() { 30 | 31 | int n; 32 | cout << "Enter the size of the array - "; 33 | cin >> n; 34 | 35 | int arr[n]; 36 | cout << "Enter the " << n << " array elements - "; 37 | for (int i = 0; i < n; ++i) 38 | cin >> arr[i]; 39 | 40 | cout << "\nBefore sorting\n"; 41 | displayArray(arr, n); 42 | 43 | insertionSort(arr, n); 44 | 45 | cout << "\nAfter sorting\n"; 46 | displayArray(arr, n); 47 | 48 | return 0; 49 | } 50 | 51 | /* 52 | * Time Complexity : O(n^2) 53 | * Auxiliary Space : O(1) 54 | */ 55 | 56 | /* 57 | Additional Notes - 58 | 1. Efficient when the number of elements in the list are quite small 59 | 2. Adaptive, i.e., efficient for already substantially sorted list of elements 60 | 3. Stable, i.e., does not change the relative order of elements with equal keys 61 | 4. In-place, i.e., only requires a constant amount - O(1) of additional memory space 62 | 5. Online, i.e., can sort a list as it receives it 63 | 6. More efficient in practice than other simple quadratic (i.e., O(n^2)) algorithms, such as selection sort or bubble sort 64 | */ 65 | -------------------------------------------------------------------------------- /Binary Indexed Tree/RangeSumQuery_PointUpdate.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Title : Range Sum Queries allowing point updates 3 | * Author : Tridib Samanta 4 | **/ 5 | 6 | #include 7 | using namespace std; 8 | 9 | const int MAXN = 1e5 + 5; 10 | 11 | int n; 12 | int arr[MAXN]; 13 | int bit[MAXN]; 14 | 15 | void update(int i, int x) { 16 | for (; i <= n; i += (i & -i)) { 17 | bit[i] += x; 18 | } 19 | } 20 | 21 | int query(int i) { 22 | int ans = 0; 23 | for (; i > 0; i -= (i & -i)) { 24 | ans += bit[i]; 25 | } 26 | return ans; 27 | } 28 | 29 | int main() { 30 | 31 | cin >> n; 32 | 33 | // 1-indexed for ease of implementation 34 | for (int i = 1; i <= n; ++i) { 35 | cin >> arr[i]; 36 | } 37 | 38 | // build the bit array (1-indexed) - O(n * log n) 39 | for (int i = 1; i <= n; ++i) { 40 | update(i, arr[i]); 41 | } 42 | 43 | int q; 44 | cin >> q; 45 | 46 | while (q--) { 47 | 48 | // Type 1: update(index, value) -> replace arr[index] with value 49 | // Type 2: query(l, r) -> sum of elements from arr[l..r]; 50 | 51 | int type; 52 | cin >> type; 53 | 54 | if (type == 1) { 55 | int index, val; 56 | cin >> index >> val; 57 | 58 | update(index, val - arr[index]); 59 | arr[index] = val; 60 | } 61 | else if (type == 2) { 62 | int l, r; 63 | cin >> l >> r; 64 | 65 | // sum(l..r) = sum(r) - sum(l - 1) 66 | cout << query(r) - query(l - 1) << '\n'; 67 | } 68 | } 69 | 70 | return 0; 71 | } 72 | 73 | /* 74 | ~ Time Complexity: 75 | update() -> O(log n) 76 | query() -> O(log n) 77 | ~ Space Complexity: O(n) 78 | */ 79 | -------------------------------------------------------------------------------- /Arrays/Subarray_sum_equals_given_sum_BruteForce.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Title : Subarray sum equals given sum (Brute Force Approach) 3 | * Author : Tridib Samanta 4 | **/ 5 | 6 | #include 7 | using namespace std; 8 | 9 | int SubArraySum(int arr[], int size, int sum) { 10 | int curr_sum = 0; 11 | 12 | // Loop that denotes the starting index of traversal 13 | for (int i = 0; i < size; ++i) { 14 | curr_sum = arr[i]; 15 | // Loop that fetches all sub arrays from the current starting index 16 | for (int j = i+1; j <= size; ++j) { 17 | // If current sum is equal with desired sum, print the indices and return to main function 18 | if (curr_sum == sum) { 19 | cout << "Sum found between index " << i << " and " << j-1 << "\n"; //According to 0 indexing of array 20 | return 1; 21 | } 22 | // If current sum exceeds the desired sum, no need to add elements further to the current subarray 23 | // If no elements left to be added to the current subarray, break from the loop 24 | if (curr_sum > sum || j == size) 25 | break; 26 | // If current sum is less than desired sum, add an element to the existing current sum 27 | curr_sum += arr[j]; 28 | } 29 | } 30 | // If sum of any subarray does not match with our desired sum then subarray does not exists 31 | cout << "No subarray containing the given sum exists !\n"; 32 | return 0; 33 | } 34 | 35 | int main() { 36 | int n; 37 | cout << "Enter the size of the array = "; 38 | cin >> n; 39 | 40 | int arr[n]; 41 | cout << "Enter the " << n << " array elements = "; 42 | for(int i = 0; i < n; ++i) 43 | cin >> arr[i]; 44 | 45 | int sum; 46 | cout << "Enter the sum = "; 47 | cin >> sum; 48 | 49 | SubArraySum(arr, n, sum); 50 | 51 | return 0; 52 | } 53 | 54 | /* 55 | * Time Complexity : O(n^2) 56 | * Space Complexity : O(1) 57 | */ 58 | -------------------------------------------------------------------------------- /Queue/ReverseFirst-k-ElementsQueue.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Title : Reverse the first K elements of a Queue 3 | * Author : Tridib Samanta 4 | **/ 5 | 6 | #include 7 | using namespace std; 8 | 9 | void reverse_k_elements(queue &q, int k) { 10 | 11 | // Preliminary check to avoid abnormal behavior of code 12 | if (k > q.size() || k <= 0 || q.empty()) 13 | return; 14 | 15 | // Initialize a auxiliary stack 16 | stack aux; 17 | 18 | // Dequeue the first 'k' elements from the queue and push them into the stack 19 | for (int i = 0; i < k; ++i) { 20 | aux.push(q.front()); 21 | q.pop(); 22 | } 23 | 24 | // Pop all the elements from the stack and enqueue them to the queue 25 | while (!aux.empty()) { 26 | q.push(aux.top()); 27 | aux.pop(); 28 | } 29 | 30 | // Dequeue the first (Queue size - k) elements from the queue and enqueue them to the same queue 31 | for (int i = 0; i < (q.size() - k); ++i) { 32 | q.push(q.front()); 33 | q.pop(); 34 | } 35 | 36 | } 37 | 38 | int main() { 39 | 40 | int n; 41 | cout << "Enter the number of elements : "; 42 | cin >> n; 43 | 44 | queue q; 45 | 46 | int element; 47 | cout << "Enter the elements of the queue : "; 48 | for (int i = 0; i < n; ++i) { 49 | cin >> element; 50 | q.push(element); 51 | } 52 | 53 | int k; 54 | cout << "Enter the number of elements to reverse : "; 55 | cin >> k; 56 | 57 | reverse_k_elements(q, k); 58 | 59 | cout << "Modified Queue is : "; 60 | while (!q.empty()) { 61 | cout << q.front() << ' '; 62 | q.pop(); 63 | } 64 | 65 | return 0; 66 | } 67 | 68 | /* 69 | ~ Time Complexity : O(n) 70 | ~ Space Complexity : O(n) 71 | */ 72 | -------------------------------------------------------------------------------- /DS/LinkedList_Reverse_Iterative.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | struct Node { 5 | int data; 6 | struct Node * next; 7 | }; 8 | 9 | struct Node * head; 10 | 11 | void Insert(int data, int n); 12 | void Print(); 13 | void Reverse(); 14 | 15 | int main() { 16 | head=NULL; //empty list 17 | printf("How many nodes you want to insert ?\n"); 18 | int nodes,i,data,pos; 19 | scanf("%d",&nodes); 20 | for(i=0;idata=data; 38 | temp1->next=NULL; 39 | if(n==1) { 40 | temp1->next=head; 41 | head=temp1; 42 | return; 43 | } 44 | struct Node * temp2 = head; 45 | int i; 46 | for(i=0;inext; 48 | } 49 | temp1->next=temp2->next; 50 | temp2->next=temp1; 51 | } 52 | 53 | void Print() { 54 | struct Node * temp = head; 55 | while(temp!=NULL) { 56 | printf("%d ",temp->data); 57 | temp=temp->next; 58 | } 59 | printf("\n"); 60 | } 61 | 62 | void Reverse() { 63 | struct Node *current, *prev, *next; 64 | current = head; 65 | prev=NULL; 66 | while(current!=NULL) 67 | { 68 | next=current->next; 69 | current->next=prev; 70 | prev=current; 71 | current=next; 72 | } 73 | head = prev; 74 | } 75 | -------------------------------------------------------------------------------- /Strings/LongestPalindromicSubstring.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Title : Longest Palindromic Substring 3 | * Author : Tridib Samanta 4 | **/ 5 | 6 | #include 7 | using namespace std; 8 | 9 | void findLongestPalindromicSubstring(string s) { 10 | 11 | int n = s.length(); 12 | 13 | bool dp[n][n]; 14 | 15 | memset(dp, 0, sizeof(dp)); 16 | 17 | int maxLen = 1, startIdx = 0; 18 | 19 | // All substrings of length 1 are palindromes 20 | for (int i = 0; i < n; ++i) { 21 | dp[i][i] = true; 22 | } 23 | 24 | // Check for substrings of length 2 25 | for (int i = 0; i < n - 1; ++i) { 26 | if (s[i] == s[i + 1]) { 27 | dp[i][i + 1] = true; 28 | startIdx = i; 29 | maxLen = 2; 30 | } 31 | } 32 | 33 | // Check for substring of length greater than 2 34 | for (int k = 3; k <= n; ++k) { 35 | 36 | for(int i = 0; i <= n - k; ++i) { 37 | 38 | int j = i + k - 1; 39 | 40 | if (s[i] == s[j] && dp[i + 1][j - 1]) { 41 | 42 | dp[i][j] = true; 43 | 44 | if (k > maxLen) { 45 | maxLen = k; 46 | startIdx = i; 47 | } 48 | } 49 | } 50 | } 51 | 52 | cout << "Longest Palindromic Substring is : "; 53 | for (int i = startIdx; i < startIdx + maxLen; ++i) 54 | cout << s[i]; 55 | cout << '\n'; 56 | cout << "Length of the Longest Palindromic Substring is : "; 57 | cout << maxLen << '\n'; 58 | } 59 | 60 | int main() { 61 | 62 | string s; 63 | cout << "Enter the string : "; 64 | cin >> s; 65 | 66 | findLongestPalindromicSubstring(s); 67 | 68 | return 0; 69 | } 70 | 71 | /* 72 | ~ Time Complexity : O(n^2) 73 | ~ Space Complexity : O(n^2) 74 | */ 75 | -------------------------------------------------------------------------------- /Stack/PostfixEvaluation.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Title : Postfix Evaluation 3 | * Author : Tridib Samanta 4 | **/ 5 | 6 | #include 7 | #include 8 | using namespace std; 9 | 10 | int evaluatePostfix(string exp) { 11 | stack S; 12 | for(int i = 0; i < exp.length(); ++i) { 13 | if (exp[i] == ' ') 14 | continue; 15 | else if (exp[i] == '+' || exp[i] == '-' || exp[i] == '*' || exp[i] == '/') { 16 | int result = 0; 17 | int operand2 = S.top(); S.pop(); 18 | int operand1 = S.top(); S.pop(); 19 | if (exp[i] == '+') 20 | result = operand1 + operand2; 21 | else if (exp[i] == '-') 22 | result = operand1 - operand2; 23 | else if (exp[i] == '*') 24 | result = operand1 * operand2; 25 | else 26 | result = operand1 / operand2; 27 | S.push(result); 28 | } 29 | else if (exp[i] >= '0' && exp[i] <= '9') { 30 | int operand = 0; 31 | while(i < exp.length() && (exp[i] >= '0' && exp[i] <= '9')) { 32 | operand = (operand * 10) + (exp[i] - '0'); 33 | ++i; 34 | } 35 | S.push(operand); 36 | --i; 37 | } 38 | } 39 | return S.top(); 40 | } 41 | 42 | int main() { 43 | string exp; 44 | cout << "Enter the postfix expression : "; 45 | getline(cin, exp); 46 | int res = evaluatePostfix(exp); 47 | cout << "Result = " << res << '\n'; 48 | return 0; 49 | } 50 | 51 | // N.B. : The input expression values must be separated by blank spaces. This code takes care of multi-digit numbers too. 52 | 53 | /* 54 | ~ Time Complexity : O(n), since we are scanning the input only once. 55 | ~ Space Complexity : O(n), for the stack. 56 | */ 57 | -------------------------------------------------------------------------------- /DS/BinaryTree_InorderTraversal.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Inorder Traversal of a Binary Tree 3 | 4 | Example - 5 | F 6 | / \ 7 | D J 8 | / \ / \ 9 | B E G K 10 | / \ \ 11 | A C I 12 | 13 | Inorder Traversal - A B C D E F G I J K 14 | */ 15 | 16 | #include 17 | #include 18 | using namespace std; 19 | 20 | struct Node { 21 | char data; 22 | Node* left; 23 | Node* right; 24 | }; 25 | 26 | Node* GetNewNode(char data) { 27 | Node* newNode = new Node(); 28 | newNode->data = data; 29 | newNode->left = newNode->right = NULL; 30 | return newNode; 31 | } 32 | 33 | Node* Insert(Node* root, char data) { 34 | if(root == NULL) 35 | root = GetNewNode(data); 36 | else if(data <= root->data) 37 | root->left = Insert(root->left, data); 38 | else 39 | root->right = Insert(root->right, data); 40 | return root; 41 | } 42 | 43 | void InorderTraversal(Node* root) { 44 | if(root == NULL) 45 | return; 46 | InorderTraversal(root->left); 47 | printf("%c ", root->data); 48 | InorderTraversal(root->right); 49 | } 50 | 51 | int main() { 52 | Node* root = NULL; 53 | int c; 54 | do { 55 | printf("1. Insert element\n2. Display tree (Inorder Traversal)\n"); 56 | printf("Enter your choice ? \n"); 57 | int ch; 58 | scanf("%d", &ch); 59 | switch(ch) { 60 | case 1: 61 | { 62 | char data; 63 | printf("Enter the node value ? \n"); 64 | fflush(stdin); 65 | data = getchar(); 66 | root = Insert(root, data); 67 | break; 68 | } 69 | case 2: 70 | { 71 | printf("Tree is : "); 72 | InorderTraversal(root); 73 | printf("\n"); 74 | break; 75 | } 76 | default: 77 | printf("Incorrect choice !\n"); 78 | } 79 | printf("Want to continue ? (1. Yes 2. No) \n"); 80 | scanf("%d", &c); 81 | } while(c == 1); 82 | } 83 | -------------------------------------------------------------------------------- /Queue/StackTwoQueues.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Title : Implement a stack using two queues 3 | * Author : Tridib Samanta 4 | **/ 5 | 6 | #include 7 | using namespace std; 8 | 9 | queue q1, q2; 10 | 11 | void push(long int x) { 12 | q1.push(x); 13 | } 14 | 15 | long int pop() { 16 | if (q1.empty()) 17 | return -1; 18 | while (q1.size() != 1) { 19 | q2.push(q1.front()); 20 | q1.pop(); 21 | } 22 | 23 | long int topElement = q1.front(); 24 | q1.pop(); 25 | 26 | queue q = q1; 27 | q1 = q2; 28 | q2 = q; 29 | 30 | return topElement; 31 | } 32 | 33 | long int top() { 34 | if (q1.empty()) 35 | return -1; 36 | while (q1.size() != 1) { 37 | q2.push(q1.front()); 38 | q1.pop(); 39 | } 40 | long int topElement = q1.front(); 41 | q2.push(q1.front()); 42 | q1.pop(); 43 | 44 | queue q = q1; 45 | q1 = q2; 46 | q2 = q; 47 | 48 | return topElement; 49 | } 50 | 51 | int main() { 52 | int q; 53 | cin >> q; 54 | while (q--) { 55 | 56 | int type; 57 | cin >> type; // 1 -> push(), 2 -> pop(), 3 -> top() 58 | 59 | switch(type) { 60 | case 1: { 61 | long int element; 62 | cin >> element; 63 | push(element); 64 | break; 65 | } 66 | case 2: { 67 | long int element = pop(); 68 | cout << element << '\n'; 69 | break; 70 | } 71 | case 3: { 72 | long int element = top(); 73 | cout << element << '\n'; 74 | } 75 | default : 76 | // Do nothing 77 | break; 78 | } 79 | } 80 | return 0; 81 | } 82 | -------------------------------------------------------------------------------- /Strings/RemoveDuplicates.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Title : Remove duplicates from a string 3 | * Author : Tridib Samanta 4 | **/ 5 | 6 | #include 7 | using namespace std; 8 | 9 | /* Approach 1 : (Brute-force) */ 10 | /* 11 | void removeDuplicates(string s) { 12 | int pos = 0; 13 | for (int i = 0; i < s.length(); ++i) { 14 | int j; 15 | for (j = 0; j < i; ++j) { 16 | if (s[i] == s[j]) 17 | break; 18 | } 19 | if (j == i) 20 | s[pos++] = s[i]; 21 | } 22 | s[pos] = '\0'; 23 | for (int i = 0; s[i]; ++i) 24 | cout << s[i]; 25 | } 26 | */ 27 | /* 28 | ~ Time Complexity : O(n*n) 29 | ~ Space Complexity : O(1) 30 | */ 31 | 32 | /* Approach 2 : (Using set of C++ STL) */ 33 | /* 34 | void removeDuplicates(string s) { 35 | set str(begin(s), end(s)); 36 | set :: iterator itr; 37 | for (itr = str.begin(); itr != str.end(); ++itr) 38 | cout << *itr; 39 | } 40 | */ 41 | /* 42 | ~ Time Complexity : O(nlogn) 43 | ~ Space Complexity : O(n) 44 | */ 45 | 46 | /* Approach 3 : (Using unordered_map of C++ STL) */ 47 | 48 | void removeDuplicates(string s) { 49 | unordered_map check; 50 | int pos = 0; 51 | for (int i = 0; i < s.length(); ++i) { 52 | if (check[s[i]] == false) { 53 | s[pos++] = s[i]; 54 | check[s[i]] = true; 55 | } 56 | } 57 | s[pos] = '\0'; 58 | for (int i = 0; s[i]; ++i) 59 | cout << s[i]; 60 | } 61 | 62 | /* 63 | ~ Time Complexity : O(n) 64 | ~ Space Complexity : O(n) 65 | */ 66 | 67 | int main() { 68 | 69 | string s; 70 | cout << "Enter a string : "; 71 | cin >> s; 72 | 73 | cout << "After removing duplicates string is : "; 74 | removeDuplicates(s); 75 | cout << '\n'; 76 | 77 | return 0; 78 | } 79 | -------------------------------------------------------------------------------- /Tree/RemoveLeafNodes_BinaryTree.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Title : Remove all the leaf nodes in a Binary Tree 3 | * Author : Tridib Samanta 4 | **/ 5 | 6 | #include 7 | using namespace std; 8 | 9 | struct Node { 10 | int data; 11 | Node *left, *right; 12 | 13 | Node(int x) { 14 | data = x; 15 | left = right = NULL; 16 | } 17 | }; 18 | 19 | Node* insertNode(Node *root, int data) { 20 | if (!root) 21 | return new Node(data); 22 | if (data < root -> data) 23 | root -> left = insertNode(root -> left, data); 24 | else if (data > root -> data) 25 | root -> right = insertNode(root -> right, data); 26 | return root; 27 | } 28 | 29 | void inorderTraversal(Node *root) { 30 | if (!root) 31 | return; 32 | inorderTraversal(root -> left); 33 | cout << root -> data << ' '; 34 | inorderTraversal(root -> right); 35 | } 36 | 37 | Node *removeLeafNodes(Node *root) { 38 | if (!root) 39 | return NULL; 40 | if (root -> left == NULL && root -> right == NULL) { 41 | delete root; 42 | return NULL; 43 | } 44 | root -> left = removeLeafNodes(root -> left); 45 | root -> right = removeLeafNodes(root -> right); 46 | return root; 47 | } 48 | 49 | int main() 50 | { 51 | Node *root = NULL; 52 | 53 | root = insertNode(root, 15); root = insertNode(root, 12); root = insertNode(root, 20); 54 | root = insertNode(root, 25); root = insertNode(root, 5); root = insertNode(root, 10); 55 | 56 | cout << "Before removing leaf nodes tree is : "; 57 | inorderTraversal(root); 58 | cout << endl; 59 | 60 | root = removeLeafNodes(root); 61 | 62 | cout << "After removing leaf nodes tree is : "; 63 | inorderTraversal(root); 64 | cout << endl; 65 | 66 | return 0; 67 | } 68 | 69 | /* 70 | ~ Time Complexity : O(n) 71 | ~ Space Complexity : O(n) 72 | */ 73 | -------------------------------------------------------------------------------- /Arrays/MergeKSortedArrays.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Title : Merge k sorted arrays 3 | * Author : Tridib Samanta 4 | **/ 5 | 6 | #include 7 | using namespace std; 8 | 9 | vector mergeKSortedArrays(vector > arr) { 10 | 11 | priority_queue>, vector>>, greater>> > minHeap; 12 | 13 | // Each element of the min heap has 3 elements as follows: 14 | // integer 1 contains the element itself 15 | // integer 2 contains the element's array index 16 | // integer 3 contains the element's index in the array 17 | 18 | for (int i = 0; i < arr.size(); i++){ 19 | if (arr[i].size() != 0) 20 | minHeap.push({arr[i][0], {i, 0}}); 21 | } 22 | 23 | if (minHeap.empty()) 24 | return vector {}; 25 | 26 | vector res; 27 | 28 | while (!minHeap.empty()) { 29 | 30 | pair > curr = minHeap.top(); 31 | minHeap.pop(); 32 | 33 | res.emplace_back(curr.first); 34 | 35 | int arrayIdx = curr.second.first; 36 | int elementIdx = curr.second.second; 37 | 38 | if (++elementIdx < arr[arrayIdx].size()) 39 | minHeap.push({arr[arrayIdx][elementIdx], {arrayIdx, elementIdx}}); 40 | } 41 | 42 | return res; 43 | } 44 | 45 | int main() { 46 | 47 | vector > arr {{1, 4, 5, 6}, 48 | {1, 3, 4}, 49 | {2, 6}}; 50 | 51 | vector res = mergeKSortedArrays(arr); 52 | 53 | cout << "Merged array is: "; 54 | for (int i = 0; i < res.size(); ++i) { 55 | cout << res[i] << ' '; 56 | } 57 | 58 | return 0; 59 | } 60 | 61 | /* 62 | ~ Time Complexity : O(Nlogk) 63 | ~ Space Complexity : O(k) 64 | 65 | where, N - total number of elements 66 | k - total number of sorted arrays 67 | */ 68 | -------------------------------------------------------------------------------- /DS/DoublyLinkedList.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | struct Node { 5 | int data; 6 | struct Node * next; 7 | struct Node * prev; 8 | }; 9 | 10 | struct Node * head; 11 | 12 | struct Node * GetNewNode(int x) { 13 | struct Node * newNode = (struct Node *)malloc(sizeof(struct Node)); 14 | newNode->data = x; 15 | newNode->prev = NULL; 16 | newNode->next = NULL; 17 | return newNode; 18 | } 19 | 20 | void InsertAtHead(int x) { 21 | struct Node * newNode = GetNewNode(x); 22 | if(head==NULL) 23 | { 24 | head=newNode; 25 | return; 26 | } 27 | head->prev = newNode; 28 | newNode->next = head; 29 | head = newNode; 30 | } 31 | 32 | void InsertAtTail(int x) { 33 | struct Node * temp = head; 34 | struct Node * newNode = GetNewNode(x); 35 | if(head==NULL) 36 | { 37 | head = newNode; 38 | return; 39 | } 40 | while(temp->next!=NULL) 41 | temp = temp->next; 42 | temp->next = newNode; 43 | newNode->prev=temp; 44 | } 45 | 46 | void Print() { 47 | struct Node * temp = head; 48 | printf("Forward : "); 49 | while(temp!=NULL) 50 | { 51 | printf("%d ",temp->data); 52 | temp = temp->next; 53 | } 54 | printf("\n"); 55 | } 56 | 57 | void ReversePrint() { 58 | struct Node * temp = head; 59 | if(head==NULL) 60 | return; 61 | while(temp->next!=NULL) 62 | temp = temp->next; 63 | printf("Reverse : "); 64 | while(temp!=NULL) 65 | { 66 | printf("%d ",temp->data); 67 | temp = temp->prev; 68 | } 69 | printf("\n"); 70 | } 71 | 72 | int main() { 73 | head = NULL; 74 | InsertAtTail(2); Print(); ReversePrint(); 75 | InsertAtTail(4); Print(); ReversePrint(); 76 | InsertAtHead(6); Print(); ReversePrint(); 77 | InsertAtTail(8); Print(); ReversePrint(); 78 | return 0; 79 | } 80 | -------------------------------------------------------------------------------- /Arrays/TripletSumEqualToAGivenValue_TwoPointer.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Title : Triplet sum that is equal to a given value (Two-pointer technique) 3 | * Author : Tridib Samanta 4 | **/ 5 | 6 | #include 7 | using namespace std; 8 | 9 | bool FindTriplet(int arr[], int size, int sum) { 10 | 11 | // Sort the array elements 12 | sort(arr, arr + size); 13 | 14 | int l, r; // Declare the left and the right pointer 15 | 16 | for(int i = 0; i < size - 2; ++i) { 17 | 18 | l = i + 1; // Setting left pointer 19 | r = size - 1; // Setting the right pointer 20 | 21 | // Continue loop as long as left pointer lies behind right pointer 22 | while (l < r) { 23 | // Triplet has value equal to sum 24 | if (arr[i] + arr[l] + arr[r] == sum) { 25 | cout << "Triplet elements with sum " << sum << " are " << arr[i] << ", " << arr[l] << " and " << arr[r] << "\n"; 26 | return true; 27 | } 28 | // Triplet has value less than sum 29 | else if (arr[i] + arr[l] + arr[r] < sum) 30 | ++l; 31 | // Triplet has value greater than sum 32 | else 33 | --r; 34 | } 35 | } 36 | // Indicates no triplet with the given sum exists 37 | return false; 38 | } 39 | 40 | int main() { 41 | 42 | int n; 43 | cout << "Enter the number of array elements = "; 44 | cin >> n; 45 | 46 | int arr[n]; 47 | cout << "Enter the array elements = "; 48 | for (int i = 0; i < n; ++i) 49 | cin >> arr[i]; 50 | 51 | int sum; 52 | cout << "Enter the sum of the triplet = "; 53 | cin >> sum; 54 | 55 | if (!FindTriplet(arr, n, sum)) 56 | cout << "No triplet having sum " << sum << " exists !\n"; 57 | 58 | return 0; 59 | } 60 | 61 | /* 62 | * Time Complexity : O(n^2) 63 | * Space Complexity : O(1) 64 | */ 65 | -------------------------------------------------------------------------------- /DS/Queue_LinkedListImplementation.c: -------------------------------------------------------------------------------- 1 | /* Linked List Implementation of Queue */ 2 | 3 | #include 4 | #include 5 | 6 | struct Node { 7 | int data; 8 | struct Node * next; 9 | }; 10 | 11 | //Global variables to store address of front and rear nodes 12 | struct Node * front = NULL; 13 | struct Node * rear = NULL; 14 | 15 | void Enqueue(int x) { 16 | struct Node * temp = (struct Node *)malloc(sizeof(struct Node*)); 17 | temp->data = x; 18 | temp->next = NULL; 19 | printf("Inserting element : %d\n",x); 20 | if(front == NULL && rear == NULL) { 21 | front = rear = temp; 22 | return; 23 | } 24 | rear->next = temp; 25 | rear = temp; 26 | } 27 | 28 | void Dequeue() { 29 | struct Node * temp = front; 30 | if(front == NULL) { 31 | printf("Queue is empty !\n"); 32 | return; 33 | } 34 | printf("Deleting element : %d\n",Front()); 35 | if(front == rear) { 36 | front = rear = NULL; 37 | } 38 | else { 39 | front = front->next; 40 | } 41 | //Anything in dynamic memory has to be explicitly freed 42 | free(temp); 43 | } 44 | 45 | int Front() { 46 | if(front == NULL) { 47 | printf("Queue is empty !\n"); 48 | return; 49 | } 50 | return front->data; 51 | } 52 | 53 | void Print() { 54 | if(front == NULL) { 55 | printf("Queue is empty !\n"); 56 | return; 57 | } 58 | printf("Queue is : "); 59 | struct Node * temp = front; 60 | while(temp != NULL) { 61 | printf("%d ",temp->data); 62 | temp = temp->next; 63 | } 64 | printf("\n"); 65 | } 66 | 67 | int main() { 68 | Dequeue(); Print(); 69 | Enqueue(15); Print(); 70 | Dequeue(); Print(); 71 | Enqueue(23); Print(); 72 | Enqueue(31); Print(); 73 | Enqueue(47); Print(); 74 | Dequeue(); Print(); 75 | Enqueue(53); Print(); 76 | return 0; 77 | } 78 | -------------------------------------------------------------------------------- /Tree/HeightBalancedCheck_BinaryTree.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Title : Determine if a binary tree is height balanced 3 | * Author : Tridib Samanta 4 | **/ 5 | 6 | #include 7 | using namespace std; 8 | 9 | struct Node { 10 | int data; 11 | Node *left, *right; 12 | 13 | Node(int x) { 14 | data = x; 15 | left = right = NULL; 16 | } 17 | }; 18 | 19 | int isBalancedUtil(Node *root) { 20 | if (!root) 21 | return 0; 22 | 23 | int lh = isBalancedUtil(root -> left); 24 | if (lh == -1) 25 | return -1; 26 | 27 | int rh = isBalancedUtil(root -> right); 28 | if (rh == -1) 29 | return -1; 30 | 31 | if (abs(lh - rh) > 1) 32 | return -1; 33 | 34 | return max(lh, rh) + 1; 35 | } 36 | 37 | bool isBalanced(Node *root) { 38 | return (isBalancedUtil(root) == -1 ? false : true); 39 | } 40 | 41 | void inorderTraversal(Node *root) 42 | { 43 | if (!root) 44 | return; 45 | inorderTraversal(root -> left); 46 | cout << root -> data << ' '; 47 | inorderTraversal(root -> right); 48 | } 49 | 50 | int main() 51 | { 52 | Node *root = NULL; 53 | 54 | /* Sample tree : (Not Height Balanced) 55 | 1 56 | / \ 57 | 2 3 58 | / 59 | 4 60 | \ 61 | 5 62 | */ 63 | 64 | root = new Node(1); 65 | root -> left = new Node(2); 66 | root -> right = new Node(3); 67 | root -> left -> left = new Node(4); 68 | root -> left -> left -> right = new Node(5); 69 | 70 | cout << "Tree is : "; 71 | inorderTraversal(root); 72 | cout << endl; 73 | 74 | if (isBalanced(root)) 75 | cout << "Tree is height balanced"; 76 | else 77 | cout << "Tree is not height balanced"; 78 | 79 | return 0; 80 | } 81 | 82 | /* 83 | ~ Time Complexity : O(n) 84 | ~ Space Complexity : O(n) 85 | */ 86 | -------------------------------------------------------------------------------- /Arrays/Subarray_sum_equals_given_sum_HandlesNegativeValues.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Title : Subarray sum equals given sum (Handles negative values) 3 | * Author : Tridib Samanta 4 | **/ 5 | 6 | #include 7 | using namespace std; 8 | 9 | void SubArraySum(int arr[], int size, int sum) { 10 | 11 | unordered_map hm; 12 | 13 | int curr_sum = 0; 14 | 15 | for(int i = 0; i < size; ++i) { 16 | 17 | curr_sum += arr[i]; 18 | 19 | // If current sum is equal to sum, subarray has starting index of 0 and end index is the current index 20 | if (curr_sum == sum) { 21 | cout << "Sum found between index 0 and " << i << "\n"; 22 | return; 23 | } 24 | 25 | // If the difference of current sum and desired sum is present in the map, 26 | // Then our required sum subarray must start from the index next to the difference index, upto the current index 27 | if (hm.find(curr_sum - sum) != hm.end()) { 28 | cout << "Sum found between index " << hm[curr_sum - sum] + 1 << " and " << i << "\n"; 29 | return; 30 | } 31 | 32 | // Else store the current index as the value for the current sum in the map 33 | hm[curr_sum] = i; 34 | } 35 | 36 | // If sum of any subarray does not match with our desired sum then subarray does not exists 37 | cout << "No subarray containing the desired sum exists !\n"; 38 | } 39 | 40 | int main() { 41 | int n; 42 | cout << "Enter the size of the array = "; 43 | cin >> n; 44 | 45 | int arr[n]; 46 | cout << "Enter the " << n << " array elements = "; 47 | for(int i = 0; i < n; ++i) 48 | cin >> arr[i]; 49 | 50 | int sum; 51 | cout << "Enter the sum = "; 52 | cin >> sum; 53 | 54 | SubArraySum(arr, n, sum); 55 | 56 | return 0; 57 | } 58 | 59 | /* 60 | * Time Complexity : O(n) 61 | * Space Complexity : O(n) (As a HashMap is needed, this takes a linear space) 62 | */ 63 | -------------------------------------------------------------------------------- /Segment Tree/SumQuery_NoUpdate.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Title : Answer Sum queries (Find the sum of all elements in a given range) 3 | * Author : Tridib Samanta 4 | **/ 5 | 6 | #include 7 | using namespace std; 8 | 9 | const int MAXN = 1e5 + 5; 10 | 11 | int arr[MAXN]; 12 | int seg[4 * MAXN]; 13 | 14 | /* Construct the Segment Tree */ 15 | void build(int idx, int l, int r) { 16 | 17 | // current range has a single element (leaf node) 18 | if (l == r) { 19 | seg[idx] = arr[l]; 20 | return; 21 | } 22 | 23 | // current range has two or more elements, hence divide into half and recur 24 | int mid = (l + r) / 2; 25 | 26 | build(2 * idx, l, mid); 27 | build(2 * idx + 1, mid + 1, r); 28 | 29 | // any node (except leaf) contains the sum of its left and right child 30 | seg[idx] = seg[2 * idx] + seg[2 * idx + 1]; 31 | } 32 | 33 | /* Find sum of all elements in the range [l, r] */ 34 | int query(int idx, int curr_l, int curr_r, int l, int r) { 35 | 36 | // no overlap 37 | if (curr_l > r || curr_r < l) 38 | return 0; 39 | 40 | // complete overlap 41 | if (curr_l >= l && curr_r <= r) 42 | return seg[idx]; 43 | 44 | // partial overlap 45 | int mid = (curr_l + curr_r) / 2; 46 | 47 | int left = query(2 * idx, curr_l, mid, l, r); 48 | int right = query(2 * idx + 1, mid + 1, curr_r, l, r); 49 | 50 | return left + right; 51 | } 52 | 53 | int main() { 54 | 55 | int n; 56 | cin >> n; 57 | 58 | for (int i = 1; i <= n; ++i) { 59 | cin >> arr[i]; 60 | } 61 | 62 | build(1, 1, n); 63 | 64 | int q; 65 | cin >> q; 66 | 67 | while (q--) { 68 | int l, r; 69 | cin >> l >> r; 70 | 71 | cout << query(1, 1, n, l, r) << '\n'; 72 | } 73 | 74 | return 0; 75 | } 76 | 77 | /* 78 | ~ Time Complexity: 79 | build() -> O(n) 80 | query() -> O(log n) 81 | ~ Space Complexity: O(4*n) 82 | */ 83 | -------------------------------------------------------------------------------- /Segment Tree/MaximumQuery_NoUpdate.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Title : Answer Maximum queries (Find the maximum of all elements in a given range) 3 | * Author : Tridib Samanta 4 | **/ 5 | 6 | #include 7 | using namespace std; 8 | 9 | const int MAXN = 1e5 + 5; 10 | 11 | int arr[MAXN]; 12 | int seg[4 * MAXN]; 13 | 14 | /* Construct the Segment Tree */ 15 | void build(int idx, int l, int r) { 16 | 17 | // current range has a single element (leaf node) 18 | if (l == r) { 19 | seg[idx] = arr[l]; 20 | return; 21 | } 22 | 23 | // current range has two or more elements, hence divide into half and recur 24 | int mid = (l + r) / 2; 25 | 26 | build(2 * idx, l, mid); 27 | build(2 * idx + 1, mid + 1, r); 28 | 29 | // any node (except leaf) contains the maximum between its left and right child 30 | seg[idx] = max(seg[2 * idx], seg[2 * idx + 1]); 31 | } 32 | 33 | /* Find maximum of all elements in the range [l, r] */ 34 | int query(int idx, int curr_l, int curr_r, int l, int r) { 35 | 36 | // no overlap 37 | if (curr_l > r || curr_r < l) 38 | return INT_MIN; 39 | 40 | // complete overlap 41 | if (curr_l >= l && curr_r <= r) 42 | return seg[idx]; 43 | 44 | // partial overlap 45 | int mid = (curr_l + curr_r) / 2; 46 | 47 | int left = query(2 * idx, curr_l, mid, l, r); 48 | int right = query(2 * idx + 1, mid + 1, curr_r, l, r); 49 | 50 | return max(left, right); 51 | } 52 | 53 | int main() { 54 | 55 | int n; 56 | cin >> n; 57 | 58 | for (int i = 1; i <= n; ++i) { 59 | cin >> arr[i]; 60 | } 61 | 62 | build(1, 1, n); 63 | 64 | int q; 65 | cin >> q; 66 | 67 | while (q--) { 68 | 69 | int l, r; 70 | cin >> l >> r; 71 | 72 | cout << query(1, 1, n, l, r) << '\n'; 73 | } 74 | 75 | return 0; 76 | } 77 | 78 | /* 79 | ~ Time Complexity: 80 | build() -> O(n) 81 | query() -> O(log n) 82 | ~ Space Complexity: O(4*n) 83 | */ 84 | -------------------------------------------------------------------------------- /Segment Tree/MinimumQuery_NoUpdate.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Title : Answer Minimum queries (Find the minimum of all elements in a given range) 3 | * Author : Tridib Samanta 4 | **/ 5 | 6 | #include 7 | using namespace std; 8 | 9 | const int MAXN = 1e5 + 5; 10 | 11 | int arr[MAXN]; 12 | int seg[4 * MAXN]; 13 | 14 | /* Construct the Segment Tree */ 15 | void build(int idx, int l, int r) { 16 | 17 | // current range has a single element (leaf node) 18 | if (l == r) { 19 | seg[idx] = arr[l]; 20 | return; 21 | } 22 | 23 | // current range has two or more elements, hence divide into half and recur 24 | int mid = (l + r) / 2; 25 | 26 | build(2 * idx, l, mid); 27 | build(2 * idx + 1, mid + 1, r); 28 | 29 | // any node (except leaf) contains the minimum between its left and right child 30 | seg[idx] = min(seg[2 * idx], seg[2 * idx + 1]); 31 | } 32 | 33 | /* Find minimum of all elements in the range [l, r] */ 34 | int query(int idx, int curr_l, int curr_r, int l, int r) { 35 | 36 | // no overlap 37 | if (curr_l > r || curr_r < l) 38 | return INT_MAX; 39 | 40 | // complete overlap 41 | if (curr_l >= l && curr_r <= r) 42 | return seg[idx]; 43 | 44 | // partial overlap 45 | int mid = (curr_l + curr_r) / 2; 46 | 47 | int left = query(2 * idx, curr_l, mid, l, r); 48 | int right = query(2 * idx + 1, mid + 1, curr_r, l, r); 49 | 50 | return min(left, right); 51 | } 52 | 53 | int main() { 54 | 55 | int n; 56 | cin >> n; 57 | 58 | for (int i = 1; i <= n; ++i) { 59 | cin >> arr[i]; 60 | } 61 | 62 | build(1, 1, n); 63 | 64 | int q; 65 | cin >> q; 66 | 67 | while (q--) { 68 | 69 | int l, r; 70 | cin >> l >> r; 71 | 72 | cout << query(1, 1, n, l, r) << '\n'; 73 | } 74 | 75 | return 0; 76 | } 77 | 78 | /* 79 | ~ Time Complexity: 80 | build() -> O(n) 81 | query() -> O(log n) 82 | ~ Space Complexity: O(4*n) 83 | */ 84 | -------------------------------------------------------------------------------- /Stack/MinStack.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Title : Design a stack that supports push, pop, top, and retrieving the minimum element in constant time. 3 | * Author : Tridib Samanta 4 | **/ 5 | 6 | #include 7 | using namespace std; 8 | 9 | class MinStack { 10 | public: 11 | 12 | stack s; 13 | int minElement; 14 | 15 | MinStack() { 16 | while (!s.empty()) 17 | s.pop(); 18 | 19 | minElement = -1; 20 | } 21 | 22 | void push(int x) { 23 | 24 | if (s.empty()) { 25 | s.push(x); 26 | minElement = x; 27 | } 28 | else { 29 | if (x < minElement) { 30 | s.push(2 * x - minElement); 31 | minElement = x; 32 | } 33 | else 34 | s.push(x); 35 | } 36 | } 37 | 38 | void pop() { 39 | 40 | if (s.empty()) 41 | return; 42 | 43 | if (s.top() < minElement) 44 | minElement = 2 * minElement - s.top(); 45 | 46 | s.pop(); 47 | } 48 | 49 | int top() { 50 | 51 | if (s.empty()) 52 | return -1; 53 | 54 | if (s.top() > minElement) 55 | return s.top(); 56 | 57 | return minElement; 58 | } 59 | 60 | int getMin() { 61 | return minElement; 62 | } 63 | }; 64 | 65 | int main() { 66 | 67 | MinStack s; 68 | 69 | s.push(3); 70 | s.push(5); 71 | cout << "Minimum Element : " << s.getMin() << '\n'; 72 | s.push(2); 73 | s.push(1); 74 | cout << "Minimum Element : " << s.getMin() << '\n'; 75 | s.pop(); 76 | cout << "Minimum Element : " << s.getMin() << '\n'; 77 | s.pop(); 78 | cout << "Top Element : " << s.top() << '\n'; 79 | 80 | return 0; 81 | } 82 | 83 | /* 84 | ~ Time Complexity 85 | ~ push() : O(1) 86 | ~ pop() : O(1) 87 | ~ top() : O(1) 88 | ~ getMin() : O(1) 89 | 90 | ~ Auxiliary Space : O(1) 91 | */ 92 | -------------------------------------------------------------------------------- /DS/BinaryTree_PostorderTraversal.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Postorder Traversal of a Binary Tree 3 | 4 | Example - 5 | F 6 | / \ 7 | D J 8 | / \ / \ 9 | B E G K 10 | / \ \ 11 | A C I 12 | 13 | Postorder Traversal - A C B E D I G K J F 14 | */ 15 | 16 | #include 17 | #include 18 | using namespace std; 19 | 20 | struct Node { 21 | char data; 22 | Node* left; 23 | Node* right; 24 | }; 25 | 26 | Node* GetNewNode(char data) { 27 | Node* newNode = new Node(); 28 | newNode->data = data; 29 | newNode->left = newNode->right = NULL; 30 | return newNode; 31 | } 32 | 33 | Node* Insert(Node* root, char data) { 34 | if(root == NULL) 35 | root = GetNewNode(data); 36 | else if(data <= root->data) 37 | root->left = Insert(root->left, data); 38 | else 39 | root->right = Insert(root->right, data); 40 | return root; 41 | } 42 | 43 | void PostorderTraversal(Node* root) { 44 | if(root == NULL) 45 | return; 46 | PostorderTraversal(root->left); 47 | PostorderTraversal(root->right); 48 | printf("%c ", root->data); 49 | } 50 | 51 | int main() { 52 | Node* root = NULL; //Empty tree 53 | int c; 54 | do { 55 | printf("1. Insert element\n2. Display tree (Postorder) \n"); 56 | printf("Enter your choice ? \n"); 57 | int ch; 58 | scanf("%d",&ch); 59 | switch(ch) { 60 | case 1: 61 | { 62 | char data; 63 | printf("Enter the node value ?\n"); 64 | fflush(stdin); 65 | data = getchar(); 66 | root = Insert(root,data); 67 | break; 68 | } 69 | case 2: 70 | { 71 | printf("Tree is : "); 72 | PostorderTraversal(root); 73 | printf("\n"); 74 | break; 75 | } 76 | default: 77 | printf("Incorrect choice !\n"); 78 | } 79 | printf("Want to continue ? (1. Yes 2. No)\n"); 80 | scanf("%d",&c); 81 | } while(c == 1); 82 | } 83 | 84 | -------------------------------------------------------------------------------- /DS/BinaryTree_Height.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | struct BstNode { 6 | int data; 7 | struct BstNode* left; 8 | struct BstNode* right; 9 | }; 10 | 11 | struct BstNode* GetNewNode(int data) { 12 | struct BstNode* newNode = (struct BstNode*)malloc(sizeof(struct BstNode)); 13 | newNode->data = data; 14 | newNode->left = newNode->right = NULL; 15 | return newNode; 16 | } 17 | 18 | struct BstNode* Insert(struct BstNode* root, int data) { 19 | if(root == NULL) 20 | root = GetNewNode(data); 21 | else if(data <= root->data) 22 | root->left = Insert(root->left, data); 23 | else 24 | root->right = Insert(root->right, data); 25 | 26 | return root; 27 | } 28 | 29 | int max(int left, int right) { 30 | if(left > right) 31 | return left; 32 | else 33 | return right; 34 | } 35 | 36 | int FindHeight(struct BstNode* root) { 37 | if(root == NULL) 38 | return -1; 39 | return max(FindHeight(root->left),FindHeight(root->right)) + 1; 40 | } 41 | 42 | int main() { 43 | struct BstNode* root = NULL; 44 | int c; 45 | do { 46 | printf("1. Insert element\n2. Find height\n"); 47 | printf("Enter your choice ? \n"); 48 | int ch; 49 | scanf("%d",&ch); 50 | switch(ch) { 51 | case 1: 52 | { 53 | int data; 54 | printf("Enter the element to be inserted ?\n"); 55 | scanf("%d",&data); 56 | root = Insert(root,data); 57 | break; 58 | } 59 | case 2: 60 | { 61 | if(FindHeight(root) == -1) 62 | printf("Empty Tree !\n"); 63 | else 64 | printf("Height of the tree is = %d\n",FindHeight(root)); 65 | break; 66 | } 67 | default: 68 | printf("Incorrect choice !\n"); 69 | } 70 | printf("Want to continue ? (1. Yes 2. No)\n"); 71 | scanf("%d",&c); 72 | } while(c == 1); 73 | 74 | return 0; 75 | } 76 | -------------------------------------------------------------------------------- /Binary Indexed Tree/RangeSumQuery_RangeUpdate.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Title : Range Sum Queries allowing range updates 3 | * Author : Tridib Samanta 4 | **/ 5 | 6 | #include 7 | using namespace std; 8 | 9 | const int MAXN = 1e5 + 5; 10 | 11 | int n; 12 | int arr[MAXN]; 13 | int bit1[MAXN], bit2[MAXN]; 14 | 15 | void update(bool flag, int i, int x) { 16 | for (; i <= n; i += (i & -i)) { 17 | (flag) ? bit2[i] += x : bit1[i] += x; 18 | } 19 | } 20 | 21 | void range_update(int l, int r, int x) { 22 | update(0, l, x); 23 | update(0, r + 1, -x); 24 | update(1, l, x * (l - 1)); 25 | update(1, r + 1, -x * r); 26 | } 27 | 28 | int sum(bool flag, int i) { 29 | int ans = 0; 30 | for (; i > 0; i -= (i & -i)) 31 | ans += (flag) ? bit2[i] : bit1[i]; 32 | return ans; 33 | } 34 | 35 | int prefix_sum(int i) { 36 | return sum(0, i) * i - sum(1, i); 37 | } 38 | 39 | int range_sum(int l, int r) { 40 | return prefix_sum(r) - prefix_sum(l - 1); 41 | } 42 | 43 | int main() { 44 | 45 | cin >> n; 46 | 47 | for (int i = 1; i <= n; ++i) { 48 | cin >> arr[i]; 49 | } 50 | 51 | for (int i = 1; i <= n; ++i) { 52 | range_update(i, i, arr[i]); 53 | } 54 | 55 | int q; 56 | cin >> q; 57 | 58 | while (q--) { 59 | 60 | // Type 1: range_update(l, r, value) -> add value to arr[l..r] 61 | // Type 2: range_sum(l, r) -> sum of elements from arr[l..r]; 62 | 63 | int type; 64 | cin >> type; 65 | 66 | if (type == 1) { 67 | int l, r, val; 68 | cin >> l >> r >> val; 69 | 70 | range_update(l, r, val); 71 | } 72 | else if (type == 2) { 73 | int l, r; 74 | cin >> l >> r; 75 | 76 | cout << range_sum(l, r) << '\n'; 77 | } 78 | } 79 | 80 | return 0; 81 | } 82 | 83 | /* 84 | ~ Time Complexity: 85 | range_update() -> O(log n) 86 | range_sum() -> O(log n) 87 | ~ Space Complexity: O(n) 88 | */ 89 | -------------------------------------------------------------------------------- /Trie/CountNumberOfWords_Trie.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Title : Count the number of words in a Trie 3 | * Author : Tridib Samanta 4 | **/ 5 | 6 | #include 7 | using namespace std; 8 | 9 | const int ALPHABET_SIZE = 26; 10 | 11 | struct TrieNode { 12 | TrieNode *child[ALPHABET_SIZE]; 13 | bool isEndOfWord; 14 | }; 15 | 16 | TrieNode* createTrieNode() { 17 | 18 | TrieNode *newTrieNode = new TrieNode(); 19 | 20 | newTrieNode -> isEndOfWord = false; 21 | 22 | for (int i = 0; i < ALPHABET_SIZE; ++i) { 23 | newTrieNode -> child[i] = NULL; 24 | } 25 | 26 | return newTrieNode; 27 | } 28 | 29 | void insertWord(TrieNode *root, string word) { 30 | 31 | TrieNode *curr = root; 32 | 33 | for (int i = 0; i < word.length(); ++i) { 34 | 35 | int index = word[i] - 'a'; 36 | 37 | if (curr -> child[index] == NULL) 38 | curr -> child[index] = createTrieNode(); 39 | 40 | curr = curr -> child[index]; 41 | } 42 | 43 | curr -> isEndOfWord = true; 44 | } 45 | 46 | int countWordsInTrie(TrieNode *root) { 47 | 48 | int cnt = 0; 49 | 50 | if (root -> isEndOfWord == true) 51 | ++cnt; 52 | 53 | for (int i = 0; i < ALPHABET_SIZE; ++i) { 54 | if (root -> child[i] != NULL) 55 | cnt += countWordsInTrie(root -> child[i]); 56 | } 57 | 58 | return cnt; 59 | } 60 | 61 | int main() { 62 | 63 | TrieNode *root = createTrieNode(); 64 | 65 | string words[] = {"sea", "see", "seat", "seam", "seal", "sat", "saw", "same"}; 66 | 67 | int n = sizeof(words) / sizeof(words[0]); 68 | 69 | for (int i = 0; i < n; ++i) { 70 | insertWord(root, words[i]); 71 | } 72 | 73 | int wordCount = countWordsInTrie(root); 74 | cout << "Number of words in the trie: " << wordCount; 75 | 76 | return 0; 77 | } 78 | 79 | /* 80 | ~ Time Complexity : O(length of each word * ALPHABET_SIZE * total number of words) 81 | ~ Space Complexity : O(length of the longest word) 82 | */ 83 | -------------------------------------------------------------------------------- /DS/BinaryTree_PreorderTraversal.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Preorder Traversal of a Binary Tree 3 | 4 | Example - 5 | F 6 | / \ 7 | D J 8 | / \ / \ 9 | B E G K 10 | / \ \ 11 | A C I 12 | 13 | Preorder Traversal - F D B A C E J G I K 14 | */ 15 | 16 | #include 17 | #include 18 | using namespace std; 19 | 20 | struct Node { 21 | char data; 22 | Node* left; 23 | Node* right; 24 | }; 25 | 26 | Node* GetNewNode(char data) { 27 | Node* newNode = new Node(); 28 | newNode->data = data; 29 | newNode->left = newNode->right = NULL; 30 | return newNode; 31 | } 32 | 33 | Node* Insert(Node* root, char data) { 34 | if(root == NULL) 35 | root = GetNewNode(data); 36 | else if(data <= root->data) 37 | root->left = Insert(root->left,data); 38 | else 39 | root->right = Insert(root->right,data); 40 | return root; 41 | } 42 | 43 | void PreorderTraversal(Node* root) { 44 | if(root == NULL) return; 45 | printf("%c ",root->data); 46 | PreorderTraversal(root->left); 47 | PreorderTraversal(root->right); 48 | } 49 | 50 | int main() { 51 | Node* root = NULL; //Empty tree 52 | int c; 53 | do { 54 | printf("1. Insert element\n2. Display tree (Preorder) \n"); 55 | printf("Enter your choice ? \n"); 56 | int ch; 57 | scanf("%d",&ch); 58 | switch(ch) { 59 | case 1: 60 | { 61 | char data; 62 | printf("Enter the node value ?\n"); 63 | fflush(stdin); 64 | data = getchar(); 65 | root = Insert(root,data); 66 | break; 67 | } 68 | case 2: 69 | { 70 | printf("Tree is : "); 71 | PreorderTraversal(root); 72 | printf("\n"); 73 | break; 74 | } 75 | default: 76 | printf("Incorrect choice !\n"); 77 | } 78 | printf("Want to continue ? (1. Yes 2. No)\n"); 79 | scanf("%d",&c); 80 | } while(c == 1); 81 | } 82 | -------------------------------------------------------------------------------- /Stack/PrefixEvaluation.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Title : Prefix Evaluation 3 | * Author : Tridib Samanta 4 | **/ 5 | 6 | #include 7 | #include 8 | using namespace std; 9 | 10 | int evaluatePrefix(string exp) { 11 | stack S; 12 | for(int i = exp.length() - 1; i >= 0 ; --i) { 13 | if (exp[i] == ' ') 14 | continue; 15 | else if (exp[i] == '+' || exp[i] == '-' || exp[i] == '*' || exp[i] == '/') { 16 | int result = 0; 17 | int operand1 = S.top(); S.pop(); 18 | int operand2 = S.top(); S.pop(); 19 | if (exp[i] == '+') 20 | result = operand1 + operand2; 21 | else if (exp[i] == '-') 22 | result = operand1 - operand2; 23 | else if (exp[i] == '*') 24 | result = operand1 * operand2; 25 | else 26 | result = operand1 / operand2; 27 | S.push(result); 28 | } 29 | else if (exp[i] >= '0' && exp[i] <= '9') { 30 | int rev_operand = 0, operand = 0; 31 | while(i >= 0 && (exp[i] >= '0' && exp[i] <= '9')) { 32 | rev_operand = (rev_operand * 10) + (exp[i] - '0'); 33 | --i; 34 | } 35 | ++i; 36 | while (rev_operand != 0) { 37 | int rem = rev_operand % 10; 38 | operand = (operand * 10) + rem; 39 | rev_operand /= 10; 40 | } 41 | S.push(operand); 42 | } 43 | } 44 | return S.top(); 45 | } 46 | 47 | int main() { 48 | string exp; 49 | cout << "Enter the prefix expression : "; 50 | getline(cin, exp); 51 | int res = evaluatePrefix(exp); 52 | cout << "Result = " << res << '\n'; 53 | return 0; 54 | } 55 | 56 | // N.B. : The input expression values must be separated by blank spaces. This code takes care of multi-digit numbers too. 57 | 58 | /* 59 | ~ Time Complexity : O(n), since we are scanning the input only once. 60 | ~ Space Complexity : O(n), for the stack. 61 | */ 62 | -------------------------------------------------------------------------------- /Graph/PrintEulerCycle_DirectedGraph.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Title : Print Euler Cycle(Circuit) for directed eulerian graph (Hierholzer's Algorithm) 3 | * Author : Tridib Samanta 4 | **/ 5 | 6 | #include 7 | using namespace std; 8 | 9 | class Graph { 10 | private: 11 | int totalVertices; 12 | vector > adj; 13 | public: 14 | Graph(int V); 15 | void addEdge(int src, int dest); 16 | void printEulerCycle(); 17 | }; 18 | 19 | Graph::Graph(int V) { 20 | totalVertices = V; 21 | adj.resize(V); 22 | } 23 | 24 | void Graph::addEdge(int src, int dest) { 25 | adj[src].emplace_back(dest); 26 | } 27 | 28 | void Graph::printEulerCycle() { 29 | 30 | stack currPath; 31 | vector eulerCycle; 32 | 33 | currPath.push(0); 34 | 35 | while(!currPath.empty()) { 36 | 37 | int currV = currPath.top(); 38 | 39 | if (adj[currV].size() > 0) { 40 | 41 | int adjV = adj[currV].back(); 42 | adj[currV].pop_back(); 43 | 44 | currPath.push(adjV); 45 | } 46 | else { 47 | eulerCycle.emplace_back(currV); 48 | currPath.pop(); 49 | } 50 | } 51 | 52 | cout << "Euler Cycle is : "; 53 | for (int i = eulerCycle.size() - 1; i >= 0; --i) 54 | cout << eulerCycle[i] << ' '; 55 | } 56 | 57 | int main() { 58 | 59 | int vertices; 60 | cout << "Enter the total number of vertices : "; 61 | cin >> vertices; 62 | 63 | Graph g(vertices); 64 | 65 | int edges; 66 | cout << "Enter the total number of edges : "; 67 | cin >> edges; 68 | 69 | cout << "Enter " << edges << " edges : "; 70 | for (int i = 0; i < edges; ++i) { 71 | int src, dest; 72 | cin >> src >> dest; 73 | g.addEdge(src, dest); 74 | } 75 | 76 | g.printEulerCycle(); 77 | 78 | return 0; 79 | } 80 | 81 | /* 82 | ~ Time Complexity : O(V + E) 83 | ~ Space Complexity : O(V + E) 84 | 85 | where, 86 | V -> Number of vertices and E -> Number of edges, in the graph. 87 | */ 88 | -------------------------------------------------------------------------------- /Tree/CheckSameElements_BinarySearchTree.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Title : Check if two BST's contain the same set of elements 3 | * Author : Tridib Samanta 4 | **/ 5 | 6 | #include 7 | using namespace std; 8 | 9 | struct Node { 10 | int data; 11 | Node *left, *right; 12 | 13 | Node (int value) { 14 | data = value; 15 | left = right = NULL; 16 | } 17 | }; 18 | 19 | Node* insertNode(Node *root, int data) { 20 | if (root == NULL) 21 | return new Node(data); 22 | if (data < root -> data) 23 | root -> left = insertNode(root -> left, data); 24 | else if (data > root -> data) 25 | root -> right = insertNode(root -> right, data); 26 | return root; 27 | } 28 | 29 | void inorder(Node *root, vector &v) { 30 | if(!root) 31 | return; 32 | inorder(root -> left, v); 33 | v.emplace_back(root -> data); 34 | inorder(root -> right, v); 35 | } 36 | 37 | bool performCheck(Node *root1, Node *root2) { 38 | 39 | if (!root1 && !root2) 40 | return true; 41 | 42 | if (!root1 || !root2) 43 | return false; 44 | 45 | vector v1, v2; 46 | 47 | inorder(root1, v1); 48 | inorder(root2, v2); 49 | 50 | return (v1 == v2); 51 | } 52 | 53 | int main() { 54 | 55 | Node *root1 = NULL; 56 | 57 | root1 = insertNode(root1, 15); root1 = insertNode(root1, 10); 58 | root1 = insertNode(root1, 5); root1 = insertNode(root1, 12); 59 | root1 = insertNode(root1, 20); root1 = insertNode(root1, 25); 60 | 61 | Node *root2 = NULL; 62 | 63 | root2 = insertNode(root2, 15); root2 = insertNode(root2, 12); 64 | root2 = insertNode(root2, 20); root2 = insertNode(root2, 5); 65 | root2 = insertNode(root2, 10); root2 = insertNode(root2, 25); 66 | 67 | if (performCheck(root1, root2)) 68 | cout << "The BST's have same elements \n"; 69 | else 70 | cout << "The BST's do not have same elements \n"; 71 | 72 | return 0; 73 | } 74 | 75 | /* 76 | ~ Time Complexity : O(max(m, n)) 77 | ~ Space Complexity : O(max(m, n)) 78 | */ 79 | -------------------------------------------------------------------------------- /DS/BinarySearchTree_Validation.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | using namespace std; 6 | 7 | struct Node { 8 | int data; 9 | Node* left; 10 | Node* right; 11 | }; 12 | 13 | Node* GetNewNode(int data) { 14 | Node* newNode = new Node(); 15 | newNode->data = data; 16 | newNode->left = newNode->right = NULL; 17 | return newNode; 18 | } 19 | 20 | // Function to insert Node according to level order. 21 | Node* Insert(Node* root, int data) { 22 | if(root == NULL) { 23 | root = GetNewNode(data); 24 | return root; 25 | } 26 | queue Q; 27 | Q.push(root); 28 | while(!Q.empty()) { 29 | Node* temp = Q.front(); 30 | Q.pop(); 31 | if(temp->left != NULL) 32 | Q.push(temp->left); 33 | else { 34 | temp->left = GetNewNode(data); 35 | return root; 36 | } 37 | if(temp->right != NULL) 38 | Q.push(temp->right); 39 | else { 40 | temp->right = GetNewNode(data); 41 | return root; 42 | } 43 | } 44 | } 45 | 46 | bool IsBstUtil(Node* root, int minValue, int maxValue) { 47 | if(root == NULL) 48 | return true; 49 | if(root->data > minValue && root->data <= maxValue 50 | && IsBstUtil(root->left, minValue, root->data) 51 | && IsBstUtil(root->right, root->data, maxValue)) 52 | return true; 53 | else 54 | return false; 55 | } 56 | 57 | bool IsBinarySearchTree(Node* root) { 58 | return IsBstUtil(root, INT_MIN, INT_MAX); 59 | } 60 | 61 | int main() { 62 | Node* root = NULL; 63 | root = Insert(root, 7); 64 | root = Insert(root, 4); 65 | root = Insert(root, 9); 66 | root = Insert(root, 4); //Inserting duplicate value 67 | root = Insert(root, 6); 68 | root = Insert(root, 9); 69 | root = Insert(root, 10); 70 | if(IsBinarySearchTree(root) == true) 71 | printf("Tree is a Binary Search Tree\n"); 72 | else 73 | printf("Tree is not a Binary Search Tree\n"); 74 | } 75 | 76 | -------------------------------------------------------------------------------- /DS/Graph_AdjacencyListImplementation_Directed.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | struct AdjListNode { 6 | int data; 7 | AdjListNode* next; 8 | }; 9 | 10 | struct AdjList { 11 | AdjListNode *head; 12 | }; 13 | 14 | struct Graph{ 15 | int vertices; 16 | AdjList *arr; 17 | }; 18 | 19 | //Function to create a new adjacency list node 20 | 21 | AdjListNode* newAdjListNode(int data) { 22 | AdjListNode* newNode = new AdjListNode(); 23 | newNode->data = data; 24 | newNode->next = NULL; 25 | return newNode; 26 | } 27 | 28 | // Function to create a graph of desired number of vertices 29 | 30 | Graph* createGraph(int vertices) { 31 | Graph* graph = new Graph(); 32 | graph->vertices = vertices; 33 | graph->arr = new AdjList[vertices]; 34 | for(int i = 0; i < vertices; i++) 35 | graph->arr[i].head = NULL; 36 | return graph; 37 | } 38 | 39 | // Function to add an edge to a directed graph 40 | 41 | void addEdge(Graph* graph, int source, int destination) { 42 | AdjListNode* tempNode = newAdjListNode(destination); 43 | tempNode->next = graph->arr[source].head; 44 | graph->arr[source].head = tempNode; 45 | } 46 | 47 | // Function to display the adjacency list contents of the graph 48 | 49 | void printGraph(Graph* graph) { 50 | for(int i = 0; i < graph->vertices; ++i) { 51 | AdjListNode* root = graph->arr[i].head; 52 | cout << "Edge from vertex "<< i << " :\n"; 53 | while(root != NULL) { 54 | cout << "(" << i << " -> " << root->data << ") "; 55 | root = root->next; 56 | } 57 | cout << "\n"; 58 | } 59 | } 60 | 61 | 62 | int main() { 63 | 64 | int totalVertices = 5; 65 | 66 | Graph* graph = createGraph(totalVertices); 67 | 68 | addEdge(graph, 0, 1); 69 | addEdge(graph, 0, 4); 70 | addEdge(graph, 1, 2); 71 | addEdge(graph, 1, 3); 72 | addEdge(graph, 1, 4); 73 | addEdge(graph, 2, 3); 74 | addEdge(graph, 3, 4); 75 | 76 | cout << "Graph is - \n"; 77 | printGraph(graph); 78 | 79 | } 80 | -------------------------------------------------------------------------------- /Arrays/SpirallyTraverseMatrix.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Title : Spirally traverse a matrix 3 | * Author : Tridib Samanta 4 | **/ 5 | 6 | #include 7 | using namespace std; 8 | 9 | int main() 10 | { 11 | int m, n; 12 | cout << "Enter the number of rows : "; 13 | cin >> m; 14 | cout << "Enter the number of columns : "; 15 | cin >> n; 16 | 17 | cout << "Enter " << (m * n) << " elements : "; 18 | int arr[m][n]; 19 | for (int i = 0; i < m; ++i) { 20 | for (int j = 0; j < n; ++j ) { 21 | cin >> arr[i][j]; 22 | } 23 | } 24 | 25 | cout << "Matrix in spiral order : "; 26 | 27 | int k = 0; // starting row index 28 | int l = 0; // starting column index 29 | 30 | while (k < m && l < n) { 31 | 32 | // Print the topmost row from left to right 33 | for (int i = l; i < n; ++i) 34 | cout << arr[k][i] << ' '; 35 | // Topmost row printing done, so increment the row index 36 | ++k; 37 | 38 | // Print the rightmost column from top to bottom 39 | for (int i = k; i < m; ++i) 40 | cout << arr[i][n - 1] << ' '; 41 | // Rightmost column printing done, so decrement the column index 42 | --n; 43 | 44 | // Check for remaining rows 45 | if (k < m) { 46 | 47 | // Print the bottom row from right to left 48 | for (int i = n - 1; i >= l; --i) 49 | cout << arr[m - 1][i] << ' '; 50 | // Bottom row printing done, so decrement the row index 51 | --m; 52 | 53 | } 54 | 55 | // Check for remamining columns 56 | if (l < n) { 57 | 58 | // Print the leftmost column from bottom to top 59 | for (int i = m - 1; i >= k; --i) 60 | cout << arr[i][l] << ' '; 61 | // Leftmost column printing done, so increment the column index 62 | ++l; 63 | 64 | } 65 | 66 | } 67 | 68 | cout << '\n'; 69 | 70 | return 0; 71 | } 72 | 73 | /* 74 | ~ Time Complexity : O(m*n) 75 | ~ Space Complexity : O(1) 76 | */ 77 | -------------------------------------------------------------------------------- /DS/BinarySearchTree_C.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | struct BstNode { 6 | int data; 7 | struct BstNode* left; 8 | struct BstNode* right; 9 | }; 10 | 11 | struct BstNode* GetNewNode(int data) { 12 | struct BstNode* newNode = (struct BstNode*)malloc(sizeof(struct BstNode)); 13 | newNode->data = data; 14 | newNode->left = newNode->right = NULL; 15 | return newNode; 16 | } 17 | 18 | struct BstNode* Insert(struct BstNode* root, int data) { 19 | if(root == NULL) 20 | root = GetNewNode(data); 21 | else if(data <= root->data) 22 | root->left = Insert(root->left, data); 23 | else 24 | root->right = Insert(root->right, data); 25 | 26 | return root; 27 | } 28 | 29 | bool Search(struct BstNode* root, int data) { 30 | if(root == NULL) 31 | return false; 32 | else if(root->data == data) 33 | return true; 34 | else if(data <= root->data) 35 | return Search(root->left,data); 36 | else 37 | return Search(root->right,data); 38 | } 39 | 40 | int main() { 41 | struct BstNode* root = NULL; 42 | int c; 43 | do { 44 | printf("1. Insert element\n2. Search element\n"); 45 | printf("Enter your choice ? \n"); 46 | int ch; 47 | scanf("%d",&ch); 48 | switch(ch) { 49 | case 1: 50 | { 51 | int data; 52 | printf("Enter the element to be inserted ?\n"); 53 | scanf("%d",&data); 54 | root = Insert(root,data); 55 | break; 56 | } 57 | case 2: 58 | { 59 | int number; 60 | printf("Enter the element to be searched ?\n"); 61 | scanf("%d",&number); 62 | if(Search(root,number)) 63 | printf("Element found\n"); 64 | else 65 | printf("Element not found\n"); 66 | break; 67 | } 68 | default: 69 | printf("Incorrect choice !\n"); 70 | } 71 | printf("Want to continue ? (1. Yes 2. No)\n"); 72 | scanf("%d",&c); 73 | } while(c == 1); 74 | 75 | return 0; 76 | } 77 | -------------------------------------------------------------------------------- /DS/DepthFirstSearch_using_STL_Iterative.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | class Graph { 8 | int vertex; // No. of vertices 9 | list *adjList; // Adjacent lists pointer 10 | 11 | public: 12 | Graph(int V); // Constructor 13 | void addEdge(int source, int destination); // Add edges to the graph 14 | void dfs(int startingVertex); // Compute the DFS 15 | }; 16 | 17 | // Initialization and creating the adjacent list for 'V' vertices 18 | Graph::Graph(int V) { 19 | this->vertex = V; 20 | adjList = new list[V]; 21 | } 22 | 23 | // Adding the edge to source node's adj list 24 | void Graph::addEdge(int src, int dest) { 25 | adjList[src].push_back(dest); 26 | } 27 | 28 | // Implement DFS 29 | void Graph::dfs(int startingVertex) { 30 | 31 | bool *visited = new bool[vertex]; 32 | for(int i = 0; i < vertex; i++) 33 | visited[i] = false; 34 | 35 | stack s; 36 | s.push(startingVertex); 37 | visited[startingVertex] = true; 38 | 39 | while(!s.empty()) { 40 | int currentVertex = s.top(); 41 | cout << currentVertex << " "; 42 | s.pop(); 43 | 44 | list::iterator itr; 45 | for (itr = adjList[currentVertex].begin(); itr != adjList[currentVertex].end(); itr++) { 46 | if (!visited[*itr]) { 47 | visited[*itr] = true; 48 | s.push(*itr); 49 | } 50 | } 51 | } 52 | } 53 | 54 | int main() { 55 | Graph g(7); 56 | 57 | g.addEdge(0, 2); 58 | g.addEdge(0, 1); 59 | g.addEdge(1, 4); 60 | g.addEdge(1, 3); 61 | g.addEdge(2, 6); 62 | g.addEdge(2, 5); 63 | 64 | cout << "Depth First Traversal (DFS) of the graph starting from vertex 1 : " << endl; 65 | g.dfs(0); 66 | } 67 | 68 | /* 69 | Example graph - 70 | 71 | 0 72 | / \ 73 | 1 2 74 | / \ / \ 75 | 3 4 5 6 76 | 77 | DFS - 0 1 3 4 2 5 6 78 | 79 | Time Complexity - O(V + E), where V is the number of vertex and E is the number of edges 80 | */ 81 | -------------------------------------------------------------------------------- /DS/Queue_ArrayImplementation.c: -------------------------------------------------------------------------------- 1 | /* Circular Array Implementation of Queue */ 2 | 3 | #include 4 | #define MAX_SIZE 10 5 | 6 | int A[MAX_SIZE]; 7 | int front = -1; 8 | int rear = -1; 9 | 10 | void Enqueue(int element) { 11 | if((rear+1) % MAX_SIZE == front) { 12 | printf("Queue is full ! Insertion cannot be performed\n"); 13 | return; 14 | } 15 | else if(IsEmpty()) { 16 | front = rear = 0; 17 | } 18 | else { 19 | rear = (rear+1) % MAX_SIZE; 20 | } 21 | A[rear] = element; 22 | printf("Element successfully inserted into the Queue\n"); 23 | } 24 | 25 | void Dequeue() { 26 | if(IsEmpty()) { 27 | printf("Queue is empty ! Deletion cannot be performed\n"); 28 | return; 29 | } 30 | else if(front == rear) { 31 | front = rear = -1; 32 | printf("Element successfully deleted from the Queue\n"); 33 | return; 34 | } 35 | else { 36 | front = (front+1) % MAX_SIZE; 37 | printf("Element successfully deleted from the Queue\n"); 38 | return; 39 | } 40 | } 41 | 42 | int IsEmpty() { 43 | if(front == -1 && rear == -1) 44 | return 1; 45 | return 0; 46 | } 47 | 48 | int Front() { 49 | if(front == -1) { 50 | printf("Queue is empty !\n"); 51 | return -1; 52 | } 53 | return A[front]; 54 | } 55 | 56 | void Print() { 57 | if(IsEmpty()) { 58 | printf("Queue is empty !\n"); 59 | return; 60 | } 61 | printf("Queue is : "); 62 | int i,count = (rear + MAX_SIZE - front) % MAX_SIZE + 1; 63 | for(i = 0; i < count; i++) { 64 | int index = (front + i) % MAX_SIZE; 65 | printf("%d ",A[index]); 66 | } 67 | printf("\n"); 68 | } 69 | 70 | int main() { 71 | Dequeue(); Print(); 72 | Enqueue(15); Print(); 73 | Enqueue(23); Print(); 74 | Enqueue(31); Print(); 75 | Enqueue(47); Print(); 76 | Dequeue(); Print(); 77 | Dequeue(); Print(); 78 | Enqueue(53); Print(); 79 | 80 | int front_element = Front(); 81 | printf("Front element = %d\n",front_element); 82 | 83 | return 0; 84 | } 85 | -------------------------------------------------------------------------------- /DS/BreadthFirstSearch_using_STL.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | class Graph { 7 | int vertex; // No. of vertices 8 | list *adjList; // Pointer to an array containing adjacent lists 9 | 10 | public: 11 | Graph(int V); // Constructor 12 | void addEdge(int source, int destination); // Add edges to the graph 13 | void bfs(int startingVertex); // Compute the BFS 14 | }; 15 | 16 | // Initialization and creating the adjList for 'V' vertices 17 | Graph::Graph(int V) { 18 | this->vertex = V; 19 | adjList = new list[V]; 20 | } 21 | 22 | // Adding the edge to source node's adj list 23 | void Graph::addEdge(int src, int dest) { 24 | adjList[src].push_back(dest); 25 | } 26 | 27 | // Implement BFS 28 | void Graph::bfs(int startingVertex) { 29 | 30 | bool *visited = new bool[vertex]; 31 | for(int i = 0; i < vertex; i++) 32 | visited[i] = false; 33 | 34 | list q; 35 | 36 | visited[startingVertex] = true; 37 | q.push_back(startingVertex); 38 | 39 | list::iterator i; 40 | 41 | while(!q.empty()) { 42 | int currentVertex = q.front(); 43 | cout << currentVertex << " "; 44 | q.pop_front(); 45 | 46 | for (i = adjList[currentVertex].begin(); i != adjList[currentVertex].end(); i++) { 47 | if (visited[*i] == false) { 48 | visited[*i] == true; 49 | q.push_back(*i); 50 | } 51 | } 52 | } 53 | } 54 | 55 | int main() { 56 | Graph g(7); 57 | 58 | g.addEdge(1, 2); 59 | g.addEdge(1, 4); 60 | g.addEdge(1, 5); 61 | g.addEdge(2, 3); 62 | g.addEdge(2, 6); 63 | g.addEdge(2, 7); 64 | 65 | cout << "Breadth First Traversal (BFS) of the graph starting from vertex 1 : " << endl; 66 | g.bfs(1); 67 | } 68 | 69 | /* 70 | Example graph - 71 | 72 | 1- - - - - 2- - - 7 73 | / \ / \ 74 | / \ / \ 75 | 4 5 3 6 76 | 77 | BFS - 1 2 4 5 3 6 7 78 | 79 | Time Complexity - O(V + E), where V is the number of vertex and E is the number of edges 80 | */ 81 | -------------------------------------------------------------------------------- /Tree/ExpressionTree.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Title : Expression Tree 3 | * Author : Tridib Samanta 4 | **/ 5 | 6 | #include 7 | using namespace std; 8 | 9 | struct ExpTreeNode { 10 | char data; 11 | ExpTreeNode *left, *right; 12 | 13 | ExpTreeNode(char value) { 14 | data = value; 15 | left = right = NULL; 16 | } 17 | }; 18 | 19 | void inorderTraversal(ExpTreeNode *root) { 20 | if (!root) 21 | return; 22 | inorderTraversal(root -> left); 23 | cout << root -> data << ' '; 24 | inorderTraversal(root -> right); 25 | } 26 | 27 | bool checkOperator(char c) { 28 | return (c == '+' || c == '-' || c == '*' || c == '/' || c == '^') ? true : false; 29 | } 30 | 31 | ExpTreeNode * buildExpTree(string postfix, int len) { 32 | 33 | stack s; 34 | 35 | for (int i = 0; i < len; ++i) { 36 | 37 | if (!checkOperator(postfix[i])) { 38 | ExpTreeNode *opnd = new ExpTreeNode(postfix[i]); 39 | s.push(opnd); 40 | } 41 | else { 42 | ExpTreeNode *optr = new ExpTreeNode(postfix[i]); 43 | 44 | ExpTreeNode *opnd1 = s.top(); s.pop(); 45 | ExpTreeNode *opnd2 = s.top(); s.pop(); 46 | 47 | optr -> left = opnd2; 48 | optr -> right = opnd1; 49 | 50 | s.push(optr); 51 | } 52 | } 53 | 54 | ExpTreeNode *root = s.top(); 55 | s.pop(); 56 | 57 | return root; 58 | } 59 | 60 | int main() { 61 | 62 | ExpTreeNode *root = NULL; 63 | 64 | /* 65 | Postfix Expression - ABC*+D/ 66 | Infix Expression - (A+B*C)/D 67 | 68 | / 69 | / \ 70 | + D 71 | / \ 72 | A * 73 | / \ 74 | B C 75 | */ 76 | 77 | string postfix = "ABC*+D/"; 78 | int len = postfix.length(); 79 | 80 | root = buildExpTree(postfix, len); 81 | 82 | printf("Inorder traversal (Infix expression) : "); 83 | inorderTraversal(root); 84 | cout << '\n'; 85 | 86 | return 0; 87 | } 88 | 89 | /* 90 | ~ Time Complexity : O(n) 91 | ~ Space Complexity : O(n) 92 | */ 93 | -------------------------------------------------------------------------------- /Tree/RemoveHalfNodes_BinaryTree.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Title : Remove all the half-nodes in a Binary Tree 3 | * Author : Tridib Samanta 4 | **/ 5 | 6 | #include 7 | using namespace std; 8 | 9 | struct Node { 10 | int data; 11 | Node *left, *right; 12 | 13 | Node(int x) { 14 | data = x; 15 | left = right = NULL; 16 | } 17 | }; 18 | 19 | Node* insertNode(Node *root, int data) { 20 | if (!root) 21 | return new Node(data); 22 | if (data < root -> data) 23 | root -> left = insertNode(root -> left, data); 24 | else if (data > root -> data) 25 | root -> right = insertNode(root -> right, data); 26 | return root; 27 | } 28 | 29 | void inorderTraversal(Node *root) { 30 | if (!root) 31 | return; 32 | inorderTraversal(root -> left); 33 | cout << root -> data << ' '; 34 | inorderTraversal(root -> right); 35 | } 36 | 37 | Node *removeHalfNodes(Node *root) { 38 | 39 | if (!root) 40 | return NULL; 41 | 42 | root -> left = removeHalfNodes(root -> left); 43 | root -> right = removeHalfNodes(root ->right); 44 | 45 | if (root -> left == NULL && root -> right == NULL) 46 | return root; 47 | 48 | if (root -> left == NULL) { 49 | Node *temp = root -> right; 50 | delete root; 51 | return temp; 52 | } 53 | if (root -> right == NULL) { 54 | Node *temp = root -> left; 55 | delete root; 56 | return temp; 57 | } 58 | 59 | return root; 60 | } 61 | 62 | int main() 63 | { 64 | Node *root = NULL; 65 | 66 | root = insertNode(root, 15); root = insertNode(root, 12); root = insertNode(root, 20); 67 | root = insertNode(root, 25); root = insertNode(root, 5); root = insertNode(root, 10); 68 | 69 | cout << "Before removing the half nodes tree is : "; 70 | inorderTraversal(root); 71 | cout << endl; 72 | 73 | root = removeHalfNodes(root); 74 | 75 | cout << "After removing the half nodes tree is : "; 76 | inorderTraversal(root); 77 | cout << endl; 78 | 79 | return 0; 80 | } 81 | 82 | /* 83 | ~ Time Complexity : O(n) 84 | ~ Space Complexity : O(n) 85 | */ 86 | -------------------------------------------------------------------------------- /Tree/ConstructBinaryTree_InorderPostorder.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Title : Construct a Binary Tree from its Inorder & Postorder Traversals 3 | * Author : Tridib Samanta 4 | **/ 5 | 6 | #include 7 | using namespace std; 8 | 9 | struct Node { 10 | char data; 11 | Node *left; 12 | Node *right; 13 | 14 | Node(int x) { 15 | data = x; 16 | left = right = NULL; 17 | } 18 | }; 19 | 20 | void preorderTraversal(Node *root) { 21 | if (root == NULL) 22 | return; 23 | cout << root -> data << ' '; 24 | preorderTraversal(root -> left); 25 | preorderTraversal(root -> right); 26 | } 27 | 28 | int searchNode(string inorder, int startIndex, int endIndex, char value) { 29 | for (int i = startIndex; i <= endIndex; ++i) 30 | if (inorder[i] == value) 31 | return i; 32 | } 33 | 34 | Node *buildBinaryTree(string inorder, string postorder, int startIndex, int endIndex) { 35 | 36 | static int postorderIndex = inorder.length() - 1; 37 | 38 | if (startIndex > endIndex) 39 | return NULL; 40 | 41 | Node *newNode = new Node(postorder[postorderIndex]); 42 | --postorderIndex; 43 | 44 | if (startIndex == endIndex) 45 | return newNode; 46 | 47 | int nodeIdx = searchNode(inorder, startIndex, endIndex, newNode -> data); 48 | 49 | newNode -> right = buildBinaryTree(inorder, postorder, nodeIdx + 1, endIndex); 50 | newNode -> left = buildBinaryTree(inorder, postorder, startIndex, nodeIdx - 1); 51 | 52 | return newNode; 53 | } 54 | 55 | int main() { 56 | 57 | string inorder; 58 | cout << "Enter the inorder traversal list : "; 59 | cin >> inorder; 60 | 61 | string postorder; 62 | cout << "Enter the postorder traversal list : "; 63 | cin >>postorder; 64 | 65 | int len = inorder.length(); 66 | Node *root = buildBinaryTree(inorder, postorder, 0, len - 1); 67 | 68 | cout << "Preorder traversal of the constructed tree is : "; 69 | preorderTraversal(root); 70 | cout << '\n'; 71 | 72 | return 0; 73 | } 74 | 75 | /* 76 | ~ Time Complexity : O(h) 77 | ~ Space Complexity : O(h) 78 | where 'h' is the height of the tree. 79 | */ 80 | -------------------------------------------------------------------------------- /DS/DepthFirstSearch_using_STL_Recursive.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | class Graph { 8 | int vertex; // No. of vertices 9 | list *adjList; // Adjacent lists pointer 10 | 11 | public: 12 | Graph(int V); // Constructor 13 | void addEdge(int source, int destination); // Add edges to the graph 14 | void dfs(int startingVertex); // Initialize visited list to false and call dfsUtil 15 | void dfsUtil(int startingVertex, bool visited[]); // Recursive function to compute dfs 16 | }; 17 | 18 | // Initialization and creating the adjacent list for 'V' vertices 19 | Graph::Graph(int V) { 20 | this->vertex = V; 21 | adjList = new list[V]; 22 | } 23 | 24 | // Adding the edge to source node's adj list 25 | void Graph::addEdge(int src, int dest) { 26 | adjList[src].push_back(dest); 27 | } 28 | 29 | // Recursive function to compute the dfs 30 | void Graph::dfsUtil(int currentVertex, bool visited[]) { 31 | visited[currentVertex] = true; 32 | cout << currentVertex << " "; 33 | list::iterator itr; 34 | for (itr = adjList[currentVertex].begin(); itr != adjList[currentVertex].end(); ++itr) 35 | if (!visited[*itr]) 36 | dfsUtil(*itr, visited); 37 | } 38 | 39 | // Initialize all visited vertex to false and pass the starting vertex to dfsUtil function 40 | void Graph::dfs(int startVertex) { 41 | bool *visited = new bool[vertex]; 42 | for (int i = 0; i < vertex; i++) 43 | visited[i] = false; 44 | dfsUtil(startVertex, visited); 45 | } 46 | 47 | int main() { 48 | Graph g(7); 49 | 50 | g.addEdge(0, 1); 51 | g.addEdge(0, 2); 52 | g.addEdge(1, 3); 53 | g.addEdge(1, 4); 54 | g.addEdge(2, 5); 55 | g.addEdge(2, 6); 56 | 57 | cout << "Depth First Traversal (DFS) of the graph starting from vertex 0 : " << endl; 58 | g.dfs(0); 59 | } 60 | 61 | /* 62 | Example graph - 63 | 64 | 0 65 | / \ 66 | 1 2 67 | / \ / \ 68 | 3 4 5 6 69 | 70 | DFS - 0 1 3 4 2 5 6 71 | 72 | Time Complexity - O(V + E), where V is the number of vertex and E is the number of edges 73 | */ 74 | -------------------------------------------------------------------------------- /Queue/InterleaveQueue.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Title : Interleave the first half of a queue with the second half 3 | * Author : Tridib Samanta 4 | **/ 5 | 6 | #include 7 | using namespace std; 8 | 9 | void interleaveQueue(queue &q) { 10 | 11 | // If there are odd number of elements in the queue 12 | if (q.size() % 2 != 0) { 13 | cout << "Enter even number of elements\n"; 14 | return; 15 | } 16 | 17 | // Initialize an auxiliary stack 18 | stack s; 19 | 20 | int halfSize = q.size() / 2; 21 | 22 | // Push first half of elements from the queue to the stack 23 | for(int i = 0; i < halfSize; ++i) { 24 | s.push(q.front()); 25 | q.pop(); 26 | } 27 | 28 | // Enqueue all the stack elements to the queue 29 | while(!s.empty()) { 30 | q.push(s.top()); 31 | s.pop(); 32 | } 33 | 34 | // Enqueue and dequeue the first half of the queue to the same queue 35 | for (int i = 0; i < halfSize; ++i) { 36 | q.push(q.front()); 37 | q.pop(); 38 | } 39 | 40 | // Push the first half of the queue into the stack 41 | for (int i = 0; i < halfSize; ++i) { 42 | s.push(q.front()); 43 | q.pop(); 44 | } 45 | 46 | // Enqueue the top element from the stack and pop it, enqueue the front element of the queue and dequeue it 47 | // Continue to do this unless the stack is void 48 | while(!s.empty()) { 49 | q.push(s.top()); 50 | s.pop(); 51 | q.push(q.front()); 52 | q.pop(); 53 | } 54 | 55 | } 56 | 57 | int main() { 58 | 59 | int n; 60 | cout << "Enter the size of the queue = "; 61 | cin >> n; 62 | 63 | queue q; 64 | 65 | cout << "Enter the queue elements : "; 66 | int element = 0; 67 | for (int i = 0; i < n; ++i) { 68 | cin >> element; 69 | q.push(element); 70 | } 71 | 72 | interleaveQueue(q); 73 | 74 | cout << "Interleaved Queue is : "; 75 | for(int i = 0; i < n; ++i) { 76 | cout << q.front() << ' '; 77 | q.pop(); 78 | } 79 | 80 | return 0; 81 | } 82 | 83 | /* 84 | ~ Time Complexity : O(n) 85 | ~ Space Complexity : O(n) 86 | */ 87 | -------------------------------------------------------------------------------- /Tree/AncestorsPrint_BinaryTree.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Title : Print all ancestors of a node in a Binary Tree 3 | * Author : Tridib Samanta 4 | **/ 5 | 6 | #include 7 | using namespace std; 8 | 9 | struct Node { 10 | int data; 11 | Node *left, *right; 12 | 13 | Node (int x) { 14 | data = x; 15 | left = right = NULL; 16 | } 17 | }; 18 | 19 | Node* insertNode(Node *root, int data) { 20 | if (root == NULL) { 21 | root = new Node(data); 22 | return root; 23 | } 24 | if (data <= root -> data) 25 | root -> left = insertNode(root -> left, data); 26 | else 27 | root -> right = insertNode(root -> right, data); 28 | return root; 29 | } 30 | 31 | void inorderTraversal(Node *root) { 32 | if (root == NULL) 33 | return; 34 | inorderTraversal(root -> left); 35 | cout << root -> data << ' '; 36 | inorderTraversal(root -> right); 37 | } 38 | 39 | bool printAllAncestors(Node* root, int target) { 40 | 41 | if (root == NULL) 42 | return false; 43 | 44 | if (root -> data == target) 45 | return true; 46 | 47 | if (printAllAncestors(root -> left, target) || printAllAncestors(root -> right, target)) { 48 | cout << root -> data << ' '; 49 | return true; 50 | } 51 | 52 | return false; 53 | } 54 | 55 | int main() { 56 | 57 | Node *root = NULL; 58 | 59 | root = insertNode(root, 10); 60 | root = insertNode(root, 15); 61 | root = insertNode(root, 7); 62 | root = insertNode(root, 9); 63 | root = insertNode(root, 11); 64 | root = insertNode(root, 4); 65 | 66 | /* 67 | 10 68 | / \ 69 | 7 15 70 | / \ / 71 | 4 9 11 72 | */ 73 | 74 | cout << "Tree : "; 75 | inorderTraversal(root); 76 | cout << '\n'; 77 | 78 | int target = 11; 79 | cout << "Ancestors of " << target << " is : "; 80 | printAllAncestors(root, target); 81 | cout << '\n'; 82 | 83 | return 0; 84 | } 85 | 86 | /* 87 | ~ Time Complexity : O(n) 88 | ~ Space Complexity : O(h), for recursive call stack. 89 | where 'n' is the number of nodes & 'h' is the height of the tree. 90 | */ 91 | -------------------------------------------------------------------------------- /DS/BinarySearchTree_Validation_InorderTraversal.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | using namespace std; 6 | 7 | struct Node { 8 | int data; 9 | Node* left; 10 | Node* right; 11 | }; 12 | 13 | Node* GetNewNode(int data) { 14 | Node* newNode = new Node(); 15 | newNode->data = data; 16 | newNode->left = newNode->right = NULL; 17 | return newNode; 18 | } 19 | 20 | // Function to insert Node according to level order. 21 | Node* Insert(Node* root, int data) { 22 | if(root == NULL) { 23 | root = GetNewNode(data); 24 | return root; 25 | } 26 | queue Q; 27 | Q.push(root); 28 | while(!Q.empty()) { 29 | Node* temp = Q.front(); 30 | Q.pop(); 31 | if(temp->left != NULL) 32 | Q.push(temp->left); 33 | else { 34 | temp->left = GetNewNode(data); 35 | return root; 36 | } 37 | if(temp->right != NULL) 38 | Q.push(temp->right); 39 | else { 40 | temp->right = GetNewNode(data); 41 | return root; 42 | } 43 | } 44 | } 45 | 46 | bool IsBstUtil(Node* root, long long int &prev) 47 | { 48 | if(root) { 49 | if(!IsBstUtil(root->left, prev)) 50 | return false; 51 | //Check for current node is greater than or equal to previous node. 52 | //Use - root->data < prev if tree has duplicate nodes. 53 | if(root->data <= prev) 54 | return false; 55 | prev = root->data; 56 | return IsBstUtil(root->right, prev); 57 | } 58 | return true; 59 | } 60 | 61 | bool IsBinarySearchTree(Node* root){ 62 | long long int prev = LLONG_MIN; 63 | return IsBstUtil(root, prev); 64 | } 65 | 66 | int main() { 67 | Node* root = NULL; 68 | root = Insert(root, 7); 69 | root = Insert(root, 4); 70 | root = Insert(root, 9); 71 | root = Insert(root, 3); 72 | root = Insert(root, 6); 73 | root = Insert(root, 8); 74 | root = Insert(root, 10); 75 | if(IsBinarySearchTree(root) == true) 76 | printf("Tree is a Binary Search Tree\n"); 77 | else 78 | printf("Tree is not a Binary Search Tree\n"); 79 | } 80 | 81 | -------------------------------------------------------------------------------- /Graph/TopologicalSorting.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Title : Topological Sorting 3 | * Author : Tridib Samanta 4 | **/ 5 | 6 | #include 7 | using namespace std; 8 | 9 | class Graph { 10 | private: 11 | int totalVertices; 12 | vector *adj; 13 | void topologicalSortUtil(int v, bool visited[], stack &s); 14 | public: 15 | Graph(int v); 16 | void addEdge(int src, int dest); 17 | void topologicalSort(); 18 | }; 19 | 20 | Graph :: Graph(int v) { 21 | totalVertices = v; 22 | adj = new vector [totalVertices]; 23 | } 24 | 25 | void Graph :: addEdge(int src, int dest) { 26 | adj[src].emplace_back(dest); 27 | } 28 | 29 | void Graph :: topologicalSortUtil(int v, bool visited[], stack &s) { 30 | 31 | visited[v] = true; 32 | 33 | vector :: iterator i; 34 | for (i = adj[v].begin(); i != adj[v].end(); ++i) 35 | if (!visited[*i]) 36 | topologicalSortUtil(*i, visited, s); 37 | 38 | s.push(v); 39 | } 40 | 41 | void Graph :: topologicalSort() { 42 | 43 | stack s; 44 | 45 | bool *visited = new bool[totalVertices]; 46 | for (int i = 0; i < totalVertices; ++i) 47 | visited[i] = false; 48 | 49 | for (int i = 0; i < totalVertices; ++i) 50 | if (!visited[i]) 51 | topologicalSortUtil(i, visited, s); 52 | 53 | delete[] visited; 54 | 55 | while(!s.empty()) { 56 | cout << s.top() << ' '; 57 | s.pop(); 58 | } 59 | } 60 | 61 | int main() { 62 | 63 | int vertices; 64 | cout << "Enter the total number of vertices : "; 65 | cin >> vertices; 66 | 67 | Graph g(vertices); 68 | 69 | int E; 70 | cout << "Enter the total number of edges : "; 71 | cin >> E; 72 | 73 | cout << "Enter " << E << " edges : "; 74 | int src, dest; 75 | for (int i = 0; i < E; ++i) { 76 | cin >> src >> dest; 77 | g.addEdge(src, dest); 78 | } 79 | 80 | cout << "Topological Ordering : "; 81 | g.topologicalSort(); 82 | 83 | return 0; 84 | } 85 | 86 | /* 87 | ~ Time Complexity : O(V + E) 88 | ~ Auxiliary Space : O(V) 89 | 90 | where, 91 | V -> Number of vertices and E -> Number of edges, in the graph. 92 | */ 93 | 94 | -------------------------------------------------------------------------------- /Arrays/SearchElement_RotatedSortedArray.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Title : Search for an element in a rotated sorted array 3 | * Author : Tridib Samanta 4 | **/ 5 | 6 | #include 7 | using namespace std; 8 | 9 | int findElement(vector &nums, int target) { 10 | 11 | int low = 0, high = nums.size() - 1; 12 | 13 | while (low <= high) { 14 | 15 | int mid = low + (high - low) / 2; 16 | 17 | // If element at index 'mid' is equal to target 18 | if (nums[mid] == target) 19 | return mid; 20 | 21 | // If right segment is sorted 22 | if (nums[mid] <= nums[high]) { 23 | 24 | // If target is probably in the right sorted segment 25 | if (target > nums[mid] && target <= nums[high]) 26 | low = mid + 1; 27 | // Else target is probably in the left unsorted segment 28 | else 29 | high = mid - 1; 30 | } 31 | // Else left segment is sorted 32 | else if (nums[low] <= nums[mid]) { 33 | 34 | // If target is probably in the left sorted segment 35 | if (target >= nums[low] && target < nums[mid]) 36 | high = mid - 1; 37 | // Else target is probably in the right unsorted segment 38 | else 39 | low = mid + 1; 40 | } 41 | } 42 | // target is not present in the array 43 | return -1; 44 | } 45 | 46 | int main() { 47 | 48 | int n; 49 | cout << "Enter the number of elements: "; 50 | cin >> n; 51 | 52 | vector nums; 53 | 54 | cout << "Enter " << n << " elements: "; 55 | for (int i = 0; i < n; ++i) { 56 | int element; 57 | cin >> element; 58 | nums.emplace_back(element); 59 | } 60 | 61 | int target; 62 | cout << "Enter the element to be searched: "; 63 | cin >> target; 64 | 65 | int targetIndex = findElement(nums, target); 66 | 67 | if (targetIndex == -1) 68 | cout << target << " is not present in the array" << '\n'; 69 | else 70 | cout << target << " is present at index " << targetIndex << '\n'; 71 | 72 | return 0; 73 | } 74 | 75 | /* 76 | * Time Complexity : O(log n) 77 | * Space Complexity : O(1) 78 | */ 79 | -------------------------------------------------------------------------------- /Graph/DepthFirstSearch.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Title : Depth First Search (DFS) for a graph 3 | * Author : Tridib Samanta 4 | **/ 5 | 6 | #include 7 | using namespace std; 8 | 9 | class Graph { 10 | private: 11 | int totalVertices; 12 | vector *adj; 13 | void dfsUtil(int v, bool visited[]); 14 | 15 | public: 16 | Graph(int V); 17 | void addEdge(int src, int dest); 18 | void dfs(int start); 19 | }; 20 | 21 | Graph::Graph(int V) { 22 | totalVertices = V; 23 | adj = new vector[V]; 24 | } 25 | 26 | void Graph::addEdge(int src, int dest) { 27 | adj[src].emplace_back(dest); 28 | } 29 | 30 | void Graph::dfsUtil(int v, bool visited[]) { 31 | visited[v] = true; 32 | cout << v << ' '; 33 | vector :: iterator i; 34 | for (i = adj[v].begin(); i != adj[v].end(); ++i) 35 | if (!visited[*i]) 36 | dfsUtil(*i, visited); 37 | } 38 | 39 | void Graph::dfs(int start) { 40 | 41 | bool *visited = new bool[totalVertices]; 42 | for (int i = 0; i < totalVertices; ++i) 43 | visited[i] = false; 44 | 45 | dfsUtil(start, visited); 46 | // Handles the case when graph as more than one component. (disconnected graph) 47 | for (int i = 0; i < totalVertices; ++i) 48 | if (visited[i] == false) 49 | dfsUtil(i, visited); 50 | } 51 | 52 | int main() { 53 | 54 | int vertices; 55 | cout << "Enter the total number of vertices : "; 56 | cin >> vertices; 57 | 58 | Graph g(vertices); 59 | 60 | int E; 61 | cout << "Enter the total number of edges : "; 62 | cin >> E; 63 | 64 | cout << "Enter " << E << " edges (Source Vertex -> Destination Vertex) : "; 65 | int src, dest; 66 | for (int i = 0; i < E; ++i) { 67 | cin >> src >> dest; 68 | g.addEdge(src, dest); 69 | } 70 | 71 | int startVertex; 72 | cout << "Enter the starting vertex for traversal : "; 73 | cin >> startVertex; 74 | 75 | cout << "Depth First Search / Traversal (DFS) is : "; 76 | g.dfs(startVertex); 77 | 78 | return 0; 79 | } 80 | 81 | /* 82 | ~ Time Complexity : O(V + E) 83 | ~ Space Complexity : O(V) 84 | 85 | where, 86 | V -> Number of vertices and E -> Number of edges, in the graph. 87 | */ 88 | -------------------------------------------------------------------------------- /Tree/ConstructBinaryTree_InorderPreorder.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Title : Construct a Binary Tree from its Inorder & Preorder Traversals 3 | * Author : Tridib Samanta 4 | **/ 5 | 6 | #include 7 | using namespace std; 8 | 9 | class Node { 10 | public: 11 | char data; 12 | Node *left; 13 | Node *right; 14 | }; 15 | 16 | Node* getNewNode(char value) { 17 | Node *newNode = new Node(); 18 | newNode -> data = value; 19 | newNode -> left = newNode -> right = NULL; 20 | return newNode; 21 | } 22 | 23 | void postorderTraversal(Node *root) { 24 | if (root == NULL) 25 | return; 26 | postorderTraversal(root -> left); 27 | postorderTraversal(root -> right); 28 | cout << root -> data << ' '; 29 | } 30 | 31 | int searchNode(string inorder, int startIndex, int endIndex, char value) { 32 | for (int i = startIndex; i <= endIndex; ++i) 33 | if (inorder[i] == value) 34 | return i; 35 | } 36 | 37 | Node *buildBinaryTree(string inorder, string preorder, int startIndex, int endIndex) { 38 | 39 | static int preorderIndex = 0; 40 | 41 | if (startIndex > endIndex) 42 | return NULL; 43 | 44 | Node *newNode = getNewNode(preorder[preorderIndex]); 45 | ++preorderIndex; 46 | 47 | if (startIndex == endIndex) 48 | return newNode; 49 | 50 | int nodeIdx = searchNode(inorder, startIndex, endIndex, newNode -> data); 51 | 52 | newNode -> left = buildBinaryTree(inorder, preorder, startIndex, nodeIdx - 1); 53 | newNode -> right = buildBinaryTree(inorder, preorder, nodeIdx + 1, endIndex); 54 | 55 | return newNode; 56 | } 57 | 58 | int main() { 59 | 60 | string inorder; 61 | cout << "Enter the inorder traversal list : "; 62 | cin >> inorder; 63 | 64 | string preorder; 65 | cout << "Enter the preorder traversal list : "; 66 | cin >>preorder; 67 | 68 | int len = inorder.length(); 69 | Node *root = buildBinaryTree(inorder, preorder, 0, len - 1); 70 | 71 | cout << "Postorder traversal of the constructed tree is : "; 72 | postorderTraversal(root); 73 | cout << '\n'; 74 | 75 | return 0; 76 | 77 | } 78 | 79 | /* 80 | ~ Time Complexity : O(h) 81 | ~ Space Complexity : O(h) 82 | where 'h' is the height of the tree. 83 | */ 84 | 85 | -------------------------------------------------------------------------------- /Stack/LargestRectangleHistogram.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Title : Largest Rectangle in Histogram 3 | * Author : Tridib Samanta 4 | **/ 5 | 6 | #include 7 | using namespace std; 8 | 9 | int getMaxArea(int height[], int n) { 10 | 11 | // To store indexes of the height array 12 | // The indexes are stored in ascending order of their heights 13 | stack S; 14 | 15 | int tempTop = -1, maxArea = 0, currArea = 0, i = 0; 16 | 17 | while (i < n) { 18 | 19 | // If stack is empty or current height is equal or higher than the height at stack top index, 20 | // push current height index into the stack. 21 | if (S.empty() || height[i] >= height[S.top()]) 22 | S.push(i++); 23 | 24 | // If the current height is smaller than the height at stack top index, 25 | // calculate area with respect to the height at stack top index and pop the index 26 | // Continue this process until a height is found which is smaller than or equals current height, 27 | // if no such height is there, then we reach empty stack and push the current height index. 28 | else { 29 | tempTop = S.top(); 30 | S.pop(); 31 | 32 | currArea = height[tempTop] * (S.empty() ? i : (i - S.top() - 1)); 33 | 34 | if (currArea > maxArea) 35 | maxArea = currArea; 36 | } 37 | } 38 | 39 | // If stack is not empty then calculate area w.r.t. each of the height indexes in the stack and pop. 40 | while (!S.empty()) { 41 | tempTop = S.top(); 42 | S.pop(); 43 | 44 | currArea = height[tempTop] * (S.empty() ? i : i - S.top() - 1); 45 | 46 | if (currArea > maxArea) 47 | maxArea = currArea; 48 | } 49 | 50 | // Return the maximum rectangular area in histogram 51 | return maxArea; 52 | 53 | } 54 | 55 | int main() { 56 | int n; 57 | cout << "Enter the number of bars in the histogram : "; 58 | cin >> n; 59 | int arr[n]; 60 | cout << "Enter the height of " << n << " bars : "; 61 | for (int i = 0; i < n; ++i) 62 | cin >> arr[i]; 63 | cout << "Largest rectangular area = " << getMaxArea(arr, n) << '\n'; 64 | return 0; 65 | } 66 | 67 | /* 68 | ~ Time Complexity : O(n) 69 | ~ Space Complexity : O(n) 70 | */ 71 | -------------------------------------------------------------------------------- /DS/LinkedList_DeleteNodeAtNthPosition.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | struct Node { 5 | int data; 6 | struct Node * next; 7 | }; 8 | 9 | struct Node * head; //Global head pointer 10 | 11 | void Insert(int data, int pos_insert); 12 | void Print(); 13 | void Delete(int pos_delete); 14 | 15 | int main() { 16 | head=NULL; //empty list 17 | int nodes_insert,nodes_delete,i,data_insert,pos_insert,pos_delete; 18 | printf("How many nodes you want to insert ?\n"); 19 | scanf("%d",&nodes_insert); 20 | for(i=0;idata=data; 42 | temp1->next=NULL; 43 | if(n==1) { 44 | temp1->next=head; 45 | head=temp1; 46 | return; 47 | } 48 | struct Node * temp2 = head; 49 | int i; 50 | for(i=0;inext; 52 | } 53 | temp1->next=temp2->next; 54 | temp2->next=temp1; 55 | } 56 | 57 | void Print() { 58 | if(head==NULL) 59 | printf("\nHey ! The list is empty.\n"); 60 | return; 61 | struct Node * temp = head; 62 | printf("The list is - \n"); 63 | while(temp!=NULL) { 64 | printf("%d ",temp->data); 65 | temp=temp->next; 66 | } 67 | printf("\n"); 68 | } 69 | 70 | void Delete(int n) { 71 | struct Node * temp1 = head; 72 | if(n==1) { 73 | head=temp1->next; 74 | free(temp1); 75 | return; 76 | } 77 | int i; 78 | for(i=0;inext; //(n-1)th Node 80 | } 81 | struct Node * temp2 = temp1->next; // nth Node 82 | temp1->next = temp2->next; // (n+1)th Node 83 | free(temp2); 84 | } 85 | -------------------------------------------------------------------------------- /Tree/KthLargestElement_BinarySearchTree.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Title : Kth largest element in a Binary Search Tree 3 | * Author : Tridib Samanta 4 | **/ 5 | 6 | #include 7 | using namespace std; 8 | 9 | struct Node { 10 | int data; 11 | Node *left, *right; 12 | 13 | Node (int value) { 14 | data = value; 15 | left = right = NULL; 16 | } 17 | }; 18 | 19 | Node* insertNode(Node *root, int data) { 20 | if (root == NULL) 21 | return new Node(data); 22 | if (data < root -> data) 23 | root -> left = insertNode(root -> left, data); 24 | else if (data > root -> data) 25 | root -> right = insertNode(root -> right, data); 26 | return root; 27 | } 28 | 29 | void inorderTraversal(Node *root) { 30 | if(root == NULL) 31 | return; 32 | inorderTraversal(root -> left); 33 | cout << root -> data << ' '; 34 | inorderTraversal(root -> right); 35 | } 36 | 37 | Node* KthLargestElementUtil(Node *root, int &k) { 38 | 39 | if (root == NULL) 40 | return NULL; 41 | 42 | Node* right = KthLargestElementUtil(root -> right, k); 43 | 44 | if (right != NULL) 45 | return right; 46 | 47 | if (--k == 0) 48 | return root; 49 | 50 | return KthLargestElementUtil(root -> left, k); 51 | } 52 | 53 | int KthLargestElement(Node *root, int k) { 54 | 55 | Node *res = KthLargestElementUtil(root, k); 56 | 57 | if (res == NULL) 58 | return INT_MIN; 59 | else 60 | return res -> data; 61 | } 62 | 63 | int main() { 64 | 65 | Node *root = NULL; 66 | 67 | root = insertNode(root, 5); root = insertNode(root, 3); 68 | root = insertNode(root, 6); root = insertNode(root, 2); 69 | root = insertNode(root, 4); root = insertNode(root, 1); 70 | 71 | cout << "Tree : "; 72 | inorderTraversal(root); 73 | cout << '\n'; 74 | 75 | int k; 76 | cout << "Enter the value of k : "; 77 | cin >> k; 78 | 79 | int res = KthLargestElement(root, k); 80 | 81 | if (res == INT_MIN) 82 | cout << "No. of nodes in BST is less than K !"; 83 | else 84 | cout << "Kth Largest element is : " << res; 85 | 86 | return 0; 87 | } 88 | 89 | /* 90 | ~ Time Complexity : O(n) 91 | ~ Auxiliary Space Complexity : O(1) 92 | */ 93 | -------------------------------------------------------------------------------- /Tree/KthSmallestElement_BinarySearchTree.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Title : Kth smallest element in a Binary Search Tree 3 | * Author : Tridib Samanta 4 | **/ 5 | 6 | #include 7 | using namespace std; 8 | 9 | struct Node { 10 | int data; 11 | Node *left, *right; 12 | 13 | Node (int value) { 14 | data = value; 15 | left = right = NULL; 16 | } 17 | }; 18 | 19 | Node* insertNode(Node *root, int data) { 20 | if (root == NULL) 21 | return new Node(data); 22 | if (data < root -> data) 23 | root -> left = insertNode(root -> left, data); 24 | else if (data > root -> data) 25 | root -> right = insertNode(root -> right, data); 26 | return root; 27 | } 28 | 29 | void inorderTraversal(Node *root) { 30 | if(root == NULL) 31 | return; 32 | inorderTraversal(root -> left); 33 | cout << root -> data << ' '; 34 | inorderTraversal(root -> right); 35 | } 36 | 37 | Node* KthSmallestElementUtil(Node *root, int &k) { 38 | 39 | if (root == NULL) 40 | return NULL; 41 | 42 | Node* left = KthSmallestElementUtil(root -> left, k); 43 | 44 | if (left != NULL) 45 | return left; 46 | 47 | if (--k == 0) 48 | return root; 49 | 50 | return KthSmallestElementUtil(root -> right, k); 51 | } 52 | 53 | int KthSmallestElement(Node *root, int k) { 54 | 55 | Node *res = KthSmallestElementUtil(root, k); 56 | 57 | if (res == NULL) 58 | return INT_MIN; 59 | else 60 | return res -> data; 61 | } 62 | 63 | int main() { 64 | 65 | Node *root = NULL; 66 | 67 | root = insertNode(root, 5); root = insertNode(root, 3); 68 | root = insertNode(root, 6); root = insertNode(root, 2); 69 | root = insertNode(root, 4); root = insertNode(root, 1); 70 | 71 | cout << "Tree : "; 72 | inorderTraversal(root); 73 | cout << '\n'; 74 | 75 | int k; 76 | cout << "Enter the value of k : "; 77 | cin >> k; 78 | 79 | int res = KthSmallestElement(root, k); 80 | 81 | if (res == INT_MIN) 82 | cout << "No. of nodes in BST is less than K !"; 83 | else 84 | cout << "Kth smallest element is : " << res; 85 | 86 | return 0; 87 | } 88 | 89 | /* 90 | ~ Time Complexity : O(n) 91 | ~ Auxiliary Space Complexity : O(1) 92 | */ 93 | -------------------------------------------------------------------------------- /Sorts/MergeSort.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Title : Merge Sort 3 | * Author : Tridib Samanta 4 | **/ 5 | 6 | #include 7 | using namespace std; 8 | 9 | void mergeArrays(int *arr, int *L, int L_len, int *R, int R_len) { 10 | 11 | int i = 0, j = 0, k = 0; 12 | 13 | while (i < L_len && j < R_len) { 14 | 15 | if (L[i] < R[j]) 16 | arr[k++] = L[i++]; 17 | else 18 | arr[k++] = R[j++]; 19 | } 20 | 21 | while (i < L_len) 22 | arr[k++] = L[i++]; 23 | 24 | while (j < R_len) 25 | arr[k++] = R[j++]; 26 | } 27 | 28 | void mergeSort(int arr[], int n) { 29 | 30 | if (n < 2) 31 | return; 32 | 33 | int mid = n / 2; 34 | 35 | int* L = new int[mid]; 36 | int* R = new int[n - mid]; 37 | 38 | for (int i = 0; i < mid; ++i) 39 | L[i] = arr[i]; 40 | 41 | for (int i = mid; i < n; ++i) 42 | R[i - mid] = arr[i]; 43 | 44 | mergeSort(L, mid); 45 | 46 | mergeSort(R, n - mid); 47 | 48 | mergeArrays(arr, L, mid, R, n - mid); 49 | 50 | delete L; 51 | delete R; 52 | 53 | } 54 | 55 | void displayArray(int arr[], int n) { 56 | cout << "The array elements are - "; 57 | for (int i = 0; i < n; ++i) 58 | cout << arr[i] << " "; 59 | cout << "\n"; 60 | } 61 | 62 | int main() { 63 | 64 | int n; 65 | cout << "Enter the size of the array - "; 66 | cin >> n; 67 | 68 | int arr[n]; 69 | cout << "Enter the " << n << " array elements - "; 70 | for (int i = 0; i < n; ++i) 71 | cin >> arr[i]; 72 | 73 | cout << "\nBefore sorting\n"; 74 | displayArray(arr, n); 75 | 76 | mergeSort(arr, n); 77 | 78 | cout << "\nAfter sorting\n"; 79 | displayArray(arr, n); 80 | 81 | return 0; 82 | } 83 | 84 | /* 85 | * Time Complexity : O(n log n) 86 | * Auxiliary Space : O(n) 87 | */ 88 | 89 | /* 90 | Additional Notes - 91 | 1. Useful for sorting linked lists in O(n log n) time and in O(1) extra space 92 | 2. Stable, i.e., does not change the relative order of elements with equal keys 93 | 3. NOT in-place (only requires a constant amount - O(1) of additional memory space) 94 | 4. Algorithmic Paradigm - Divide and Conquer 95 | 5. Efficient than other simple quadratic (i.e., O(n^2)) algorithms, such as selection sort or bubble sort 96 | */ 97 | -------------------------------------------------------------------------------- /DS/BinaryTree_LevelOrderTraversal.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | 6 | struct Node { 7 | char data; 8 | Node* left; 9 | Node* right; 10 | }; 11 | 12 | Node* GetNewNode(char data) { 13 | Node* newNode = new Node(); 14 | newNode->data = data; 15 | newNode->left = newNode->right = NULL; 16 | return newNode; 17 | } 18 | 19 | Node* Insert(Node* root, char data) { 20 | if(root == NULL) 21 | root = GetNewNode(data); 22 | else if(data <= root->data) 23 | root->left = Insert(root->left,data); 24 | else 25 | root->right = Insert(root->right,data); 26 | return root; 27 | } 28 | 29 | void LevelOrder(Node* root) { 30 | if(root == NULL) { 31 | printf("Tree is empty !\n"); 32 | return; 33 | } 34 | queue Q; 35 | Q.push(root); 36 | printf("Elements in the tree are : "); 37 | //As long as there is at-least one discovered node in queue 38 | while(!Q.empty()) { 39 | //Print data of front node address (discovered node) 40 | Node* current = Q.front(); 41 | printf("%c ",current->data); 42 | //Remove the visited (printed) node address 43 | Q.pop(); 44 | //Push the immediate left child node address 45 | if(current->left != NULL) 46 | Q.push(current->left); 47 | //Push the immediate right child node address 48 | if(current->right != NULL) 49 | Q.push(current->right); 50 | } 51 | printf("\n"); 52 | } 53 | 54 | int main() { 55 | Node* root = NULL; //Empty tree 56 | int c; 57 | do { 58 | printf("1. Insert element\n2. Display tree\n"); 59 | printf("Enter your choice ? \n"); 60 | int ch; 61 | scanf("%d",&ch); 62 | switch(ch) { 63 | case 1: 64 | { 65 | char data; 66 | printf("Enter the node value ?\n"); 67 | fflush(stdin); 68 | data = getchar(); 69 | root = Insert(root,data); 70 | break; 71 | } 72 | case 2: 73 | { 74 | LevelOrder(root); 75 | break; 76 | } 77 | default: 78 | printf("Incorrect choice !\n"); 79 | } 80 | printf("Want to continue ? (1. Yes 2. No)\n"); 81 | scanf("%d",&c); 82 | } while(c == 1); 83 | } 84 | -------------------------------------------------------------------------------- /Tree/RootToNodePath_BinaryTree.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Title : Print path from root to a node in a Binary Tree 3 | * Author : Tridib Samanta 4 | **/ 5 | 6 | #include 7 | using namespace std; 8 | 9 | struct Node { 10 | int data; 11 | Node *left, *right; 12 | 13 | Node (int x) { 14 | data = x; 15 | left = right = NULL; 16 | } 17 | }; 18 | 19 | Node* insertNode(Node *root, int data) { 20 | if (root == NULL) { 21 | root = new Node(data); 22 | return root; 23 | } 24 | if (data <= root -> data) 25 | root -> left = insertNode(root -> left, data); 26 | else 27 | root -> right = insertNode(root -> right, data); 28 | return root; 29 | } 30 | 31 | void inorderTraversal(Node *root) { 32 | if (root == NULL) 33 | return; 34 | inorderTraversal(root -> left); 35 | cout << root -> data << ' '; 36 | inorderTraversal(root -> right); 37 | } 38 | 39 | vector path; //Global list for storing the path 40 | 41 | bool printPath(Node *root, int target) { 42 | 43 | if (root == NULL) 44 | return false; 45 | 46 | if (root -> data == target || printPath(root -> left, target) || printPath(root -> right, target)) { 47 | path.emplace_back(root -> data); 48 | return true; 49 | } 50 | 51 | return false; 52 | } 53 | 54 | int main() { 55 | 56 | Node *root = NULL; 57 | 58 | root = insertNode(root, 10); 59 | root = insertNode(root, 15); 60 | root = insertNode(root, 7); 61 | root = insertNode(root, 9); 62 | root = insertNode(root, 11); 63 | root = insertNode(root, 4); 64 | 65 | /* 66 | 10 67 | / \ 68 | 7 15 69 | / \ / 70 | 4 9 11 71 | */ 72 | 73 | cout << "Tree : "; 74 | inorderTraversal(root); 75 | cout << '\n'; 76 | 77 | int target = 11; 78 | cout << "Path from " << root -> data << " to " << target << " is : "; 79 | printPath(root, target); 80 | 81 | vector :: reverse_iterator i; 82 | for (i = path.rbegin(); i != path.rend(); ++i) 83 | cout << *i << ' '; 84 | cout << '\n'; 85 | 86 | return 0; 87 | } 88 | 89 | /* 90 | ~ Time Complexity : O(n) 91 | ~ Space Complexity : O(h) 92 | where 'n' is the number of nodes & 'h' is the height of the tree. 93 | */ 94 | -------------------------------------------------------------------------------- /Graph/ConnectedComponents_UndirectedGraph.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Title : Connected components in an undirected graph 3 | * Author : Tridib Samanta 4 | **/ 5 | 6 | #include 7 | using namespace std; 8 | 9 | class Graph { 10 | private: 11 | int totalVertices; 12 | vector *adj; 13 | void connectedComponentsUtil(int s, bool visited[]); 14 | public: 15 | Graph(int v); 16 | int countCC = 0; 17 | void addEdge(int src, int dest); 18 | void findConnectedComponents(); 19 | }; 20 | 21 | Graph :: Graph(int v) { 22 | totalVertices = v; 23 | adj = new vector [totalVertices]; 24 | } 25 | 26 | void Graph :: addEdge(int src, int dest) { 27 | adj[src].emplace_back(dest); 28 | adj[dest].emplace_back(src); 29 | } 30 | 31 | void Graph :: findConnectedComponents() { 32 | bool *visited = new bool[totalVertices]; 33 | for (int i = 0; i < totalVertices; ++i) 34 | visited[i] = false; 35 | for (int i = 0; i < totalVertices; ++i) { 36 | if (!visited[i]) { 37 | connectedComponentsUtil(i, visited); 38 | ++countCC; 39 | cout << '\n'; 40 | } 41 | } 42 | delete[] visited; 43 | } 44 | 45 | void Graph :: connectedComponentsUtil(int s, bool visited[]) { 46 | visited[s] = true; 47 | cout << s << ' '; 48 | vector :: iterator i; 49 | for (i = adj[s].begin(); i != adj[s].end(); ++i) 50 | if (!visited[*i]) 51 | connectedComponentsUtil(*i, visited); 52 | } 53 | 54 | int main() { 55 | 56 | int vertices; 57 | cout << "Enter the total number of vertices : "; 58 | cin >> vertices; 59 | 60 | Graph g(vertices); 61 | 62 | int E; 63 | cout << "Enter the total number of edges : "; 64 | cin >> E; 65 | 66 | cout << "Enter " << E << " edges : "; 67 | int src, dest; 68 | for (int i = 0; i < E; ++i) { 69 | cin >> src >> dest; 70 | g.addEdge(src, dest); 71 | } 72 | 73 | cout << "Connected components in the undirected graph : "; 74 | g.findConnectedComponents(); 75 | 76 | cout << "Number of connected components = " << g.countCC << '\n'; 77 | 78 | return 0; 79 | } 80 | 81 | /* 82 | ~ Time Complexity : O(V + E) 83 | ~ Auxiliary Space : O(V) 84 | 85 | where, 86 | V -> Number of vertices and E -> Number of edges, in the graph. 87 | */ 88 | -------------------------------------------------------------------------------- /Tree/MaximumPathSum_BinaryTree.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Title : Maximum Path Sum in a Binary Tree 3 | * Author : Tridib Samanta 4 | **/ 5 | 6 | #include 7 | using namespace std; 8 | 9 | struct Node { 10 | int data; 11 | Node *left, *right; 12 | 13 | Node(int x) { 14 | data = x; 15 | left = right = NULL; 16 | } 17 | }; 18 | 19 | Node* insertNode(Node *root, int data) { 20 | if (root == NULL) { 21 | root = new Node(data); 22 | return root; 23 | } 24 | queue q; 25 | q.push(root); 26 | while (!q.empty()) { 27 | Node *temp = q.front(); 28 | q.pop(); 29 | if (temp -> left != NULL) 30 | q.push(temp -> left); 31 | else { 32 | temp -> left = new Node(data); 33 | return root; 34 | } 35 | if (temp -> right != NULL) 36 | q.push(temp -> right); 37 | else { 38 | temp -> right = new Node(data); 39 | return root; 40 | } 41 | } 42 | } 43 | 44 | void inorderTraversal(Node *root) { 45 | if (!root) 46 | return; 47 | inorderTraversal(root -> left); 48 | cout << root -> data << ' '; 49 | inorderTraversal(root -> right); 50 | } 51 | 52 | int maxPathSumUtil(Node *root, int &res) { 53 | 54 | if (!root) 55 | return 0; 56 | 57 | int left = maxPathSumUtil(root -> left, res); 58 | int right = maxPathSumUtil(root -> right, res); 59 | 60 | int max1 = max(root -> data, max(left, right) + root -> data); 61 | int max2 = max(max1, left + right + root -> data); 62 | 63 | res = max(res, max2); 64 | 65 | return max1; 66 | } 67 | 68 | int maxPathSum(Node *root) { 69 | 70 | int res = INT_MIN; 71 | maxPathSumUtil(root, res); 72 | 73 | return res; 74 | } 75 | 76 | int main() 77 | { 78 | Node *root = NULL; 79 | 80 | root = insertNode(root, 10); root = insertNode(root, 8); root = insertNode(root, 2); 81 | root = insertNode(root, -3); root = insertNode(root, 5); 82 | 83 | cout << "Tree is : "; 84 | inorderTraversal(root); 85 | cout << endl; 86 | 87 | int maxSum = maxPathSum(root); 88 | cout << "Maximum Path Sum is : " << maxSum << '\n'; 89 | 90 | return 0; 91 | } 92 | 93 | /* 94 | ~ Time Complexity : O(n) 95 | ~ Space Complexity : O(n) 96 | */ 97 | -------------------------------------------------------------------------------- /Graph/DetectCycle_UndirectedGraph_Approach1.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Title : Detect Cycle in an Undirected Graph (Using DFS) 3 | * Author : Tridib Samanta 4 | **/ 5 | 6 | #include 7 | using namespace std; 8 | 9 | class Graph { 10 | private: 11 | int totalVertices; 12 | vector *adj; 13 | bool detectCycleUtil(int v, bool visited[], int parent); 14 | public: 15 | Graph(int v); 16 | void addEdge(int src, int dest); 17 | bool detectCycle(); 18 | }; 19 | 20 | Graph :: Graph(int v) { 21 | totalVertices = v; 22 | adj = new vector [totalVertices]; 23 | } 24 | 25 | void Graph :: addEdge(int src, int dest) { 26 | adj[src].emplace_back(dest); 27 | adj[dest].emplace_back(src); 28 | } 29 | 30 | bool Graph :: detectCycleUtil(int v, bool visited[], int parent) { 31 | 32 | visited[v] = true; 33 | 34 | vector :: iterator i; 35 | for (i = adj[v].begin(); i != adj[v].end(); ++i) { 36 | 37 | if (!visited[*i]) { 38 | if (detectCycleUtil(*i, visited, v)) 39 | return true; 40 | } 41 | else if (*i != parent) 42 | return true; 43 | } 44 | return false; 45 | } 46 | 47 | bool Graph :: detectCycle() { 48 | 49 | bool *visited = new bool[totalVertices]; 50 | for (int i = 0; i < totalVertices; ++i) 51 | visited[i] = false; 52 | 53 | for (int i = 0; i < totalVertices; ++i) 54 | if (!visited[i] && detectCycleUtil(i, visited, -1)) 55 | return true; 56 | 57 | return false; 58 | } 59 | 60 | int main() { 61 | 62 | int vertices; 63 | cout << "Enter the total number of vertices : "; 64 | cin >> vertices; 65 | 66 | Graph g(vertices); 67 | 68 | int E; 69 | cout << "Enter the total number of edges : "; 70 | cin >> E; 71 | 72 | cout << "Enter " << E << " edges : "; 73 | int src, dest; 74 | for (int i = 0; i < E; ++i) { 75 | cin >> src >> dest; 76 | g.addEdge(src, dest); 77 | } 78 | 79 | if (g.detectCycle()) 80 | cout << "Graph contains cycle\n"; 81 | else 82 | cout << "Graph doesn't contain cycle\n"; 83 | 84 | return 0; 85 | } 86 | 87 | /* 88 | ~ Time Complexity : O(V + E) 89 | ~ Space Complexity : O(V) 90 | 91 | where, 92 | V -> Number of vertices and E -> Number of edges, in the graph. 93 | */ 94 | -------------------------------------------------------------------------------- /Linked Lists/RotateKPlacesLeft_LinkedList.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Title : Rotate a linked list to the left (anti-clockwise) by k places 3 | * Author : Tridib Samanta 4 | **/ 5 | 6 | #include 7 | using namespace std; 8 | 9 | struct Node { 10 | int data; 11 | Node *next; 12 | 13 | Node(int val) { 14 | data = val; 15 | next = NULL; 16 | } 17 | }; 18 | 19 | Node* insertNode(Node* head, int data) { 20 | 21 | Node *newNode = new Node(data); 22 | 23 | if (!newNode) { 24 | cout << "Memory Error !" << '\n'; 25 | return head; 26 | } 27 | 28 | newNode -> next = head; 29 | head = newNode; 30 | 31 | return head; 32 | } 33 | 34 | void printList(Node* head) { 35 | 36 | if (head == NULL) { 37 | cout << "Empty List !" << '\n'; 38 | return; 39 | } 40 | 41 | Node *temp = head; 42 | 43 | while (temp != NULL) { 44 | cout << temp -> data << ' '; 45 | temp = temp -> next; 46 | } 47 | } 48 | 49 | Node* rotateLeft(Node* head, int k) { 50 | 51 | if (head == NULL) 52 | return NULL; 53 | 54 | int nodeCount = 1; 55 | Node* curr = head; 56 | 57 | while (curr -> next != NULL) { 58 | ++nodeCount; 59 | curr = curr -> next; 60 | } 61 | 62 | k = k % nodeCount; 63 | 64 | if (k == 0) 65 | return head; 66 | 67 | curr -> next = head; 68 | 69 | while (k--) { 70 | curr = curr -> next; 71 | } 72 | 73 | head = curr -> next; 74 | curr -> next = NULL; 75 | 76 | return head; 77 | } 78 | 79 | int main() { 80 | 81 | Node *head = NULL; 82 | 83 | head = insertNode(head, 5); 84 | head = insertNode(head, 4); 85 | head = insertNode(head, 3); 86 | head = insertNode(head, 2); 87 | head = insertNode(head, 1); 88 | 89 | cout << "List is : "; 90 | printList(head); 91 | cout << '\n'; 92 | 93 | int k; 94 | cout << "Enter the value of k : "; 95 | cin >> k; 96 | 97 | cout << "Modified list is : "; 98 | head = rotateLeft(head, k); 99 | printList(head); 100 | cout << '\n'; 101 | 102 | return 0; 103 | } 104 | 105 | /* 106 | ~ Time Complexity : O(n) 107 | ~ Space Complexity : O(1) 108 | */ 109 | -------------------------------------------------------------------------------- /DS/Graph_AdjacencyListImplementation_in_C.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | struct AdjListNode { 5 | int data; 6 | struct AdjListNode* next; 7 | }; 8 | 9 | struct AdjList { 10 | struct AdjListNode* head; 11 | }; 12 | 13 | struct Graph { 14 | int vertices; 15 | struct AdjList* arr; 16 | }; 17 | 18 | struct AdjListNode* newAdjListNode(int data) { 19 | struct AdjListNode* newNode = (struct AdjListNode*) malloc(sizeof(struct AdjListNode)); 20 | newNode->data = data; 21 | newNode->next = NULL; 22 | return newNode; 23 | }; 24 | 25 | struct Graph* createGraph(int vertices) { 26 | struct Graph* graph = (struct Graph*) malloc(sizeof(struct Graph)); 27 | graph->vertices = vertices; 28 | graph->arr = (struct AdjList*) malloc(vertices * sizeof(struct AdjList)); 29 | int i; 30 | for(i = 0; i < vertices; i++) 31 | graph->arr[i].head = NULL; 32 | return graph; 33 | } 34 | 35 | void addEdge(struct Graph* graph, int source, int destination) { 36 | struct AdjListNode* tempNode = newAdjListNode(destination); 37 | tempNode->next = graph->arr[source].head; 38 | graph->arr[source].head = tempNode; 39 | tempNode = newAdjListNode(source); 40 | tempNode->next = graph->arr[destination].head; 41 | graph->arr[destination].head = tempNode; 42 | } 43 | 44 | void printGraph(struct Graph* graph) { 45 | int i; 46 | for(i = 0; i < graph->vertices; i++) { 47 | struct AdjListNode* root = graph->arr[i].head; 48 | printf("Edge from vertex %d :\n",i); 49 | while(root != NULL) { 50 | printf("(%d -> %d)", i, root->data); 51 | root = root->next; 52 | } 53 | printf("\n"); 54 | } 55 | } 56 | 57 | int main() { 58 | 59 | int vertices, edges; 60 | printf("Enter the total number of vertices in the graph = "); 61 | scanf("%d", &vertices); 62 | 63 | struct Graph* graph = createGraph(vertices); 64 | 65 | printf("Enter the total number of edges in the graph = "); 66 | scanf("%d", &edges); 67 | 68 | int i, source, destination; 69 | for(i = 1; i <= edges; i++) { 70 | printf("Enter the source vertex and destination vertex of edge %d - \n", i); 71 | scanf("%d%d", &source, &destination); 72 | addEdge(graph, source, destination); 73 | } 74 | 75 | printf("Graph is - \n"); 76 | printGraph(graph); 77 | } 78 | -------------------------------------------------------------------------------- /Linked Lists/RotateKPlacesRight_LinkedList.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Title : Rotate a linked list to the right (clockwise) by k places 3 | * Author : Tridib Samanta 4 | **/ 5 | 6 | #include 7 | using namespace std; 8 | 9 | struct Node { 10 | int data; 11 | Node *next; 12 | 13 | Node(int val) { 14 | data = val; 15 | next = NULL; 16 | } 17 | }; 18 | 19 | Node* insertNode(Node* head, int data) { 20 | 21 | Node *newNode = new Node(data); 22 | 23 | if (!newNode) { 24 | cout << "Memory Error !" << '\n'; 25 | return head; 26 | } 27 | 28 | newNode -> next = head; 29 | head = newNode; 30 | 31 | return head; 32 | } 33 | 34 | void printList(Node* head) { 35 | 36 | if (head == NULL) { 37 | cout << "Empty List !" << '\n'; 38 | return; 39 | } 40 | 41 | Node *temp = head; 42 | 43 | while (temp != NULL) { 44 | cout << temp -> data << ' '; 45 | temp = temp -> next; 46 | } 47 | } 48 | 49 | Node* rotateRight(Node* head, int k) { 50 | 51 | if (head == NULL) 52 | return NULL; 53 | 54 | int nodeCount = 1; 55 | Node* curr = head; 56 | 57 | while (curr -> next != NULL) { 58 | ++nodeCount; 59 | curr = curr -> next; 60 | } 61 | 62 | k = k % nodeCount; 63 | 64 | if (k == 0) 65 | return head; 66 | 67 | curr -> next = head; 68 | 69 | k = nodeCount - k; 70 | 71 | while (k--) { 72 | curr = curr -> next; 73 | } 74 | 75 | head = curr -> next; 76 | curr -> next = NULL; 77 | 78 | return head; 79 | } 80 | 81 | int main() { 82 | 83 | Node *head = NULL; 84 | 85 | head = insertNode(head, 5); 86 | head = insertNode(head, 4); 87 | head = insertNode(head, 3); 88 | head = insertNode(head, 2); 89 | head = insertNode(head, 1); 90 | 91 | cout << "List is : "; 92 | printList(head); 93 | cout << '\n'; 94 | 95 | int k; 96 | cout << "Enter the value of k : "; 97 | cin >> k; 98 | 99 | cout << "Modified list is : "; 100 | head = rotateRight(head, k); 101 | printList(head); 102 | cout << '\n'; 103 | 104 | return 0; 105 | } 106 | 107 | /* 108 | ~ Time Complexity : O(n) 109 | ~ Space Complexity : O(1) 110 | */ 111 | --------------------------------------------------------------------------------