├── .gitignore ├── Arrays ├── Add1ToNo.cpp ├── antiDiagonals.cpp ├── arrayManipulation.cpp ├── duplicateInArray.cpp ├── dynamicArray.cpp ├── firstMissingInteger.cpp ├── hotelBookingPossible.cpp ├── hourGlassSum.cpp ├── insertionSort.cpp ├── largestNumber.cpp ├── leftRotation.cpp ├── maxAbsDifference.cpp ├── maxContigSubarray.cpp ├── maxDistance.cpp ├── maxUnsortedSubArray.cpp ├── mergeOverlappingInterval.cpp ├── mergeSort.cpp ├── nextPermutation.cpp ├── pascalTriangle.cpp ├── quickSort.cpp ├── rotateMatrix.cpp ├── setMatrixZeros.cpp ├── sparseArrays.cpp ├── spiralMatrix2.cpp └── waveArray.cpp ├── C++ ├── comparatorSort.cpp ├── eraseVector.cpp ├── iterateMap.cpp ├── iterateVectWithoutItr.cpp ├── lowerBound.cpp ├── manipulators.cpp ├── maps.cpp ├── pointerTo2dArray.cpp ├── queue.cpp ├── reverseVector.cpp ├── sets.cpp ├── sortVector.cpp ├── stack.cpp ├── stringAppend.cpp ├── stringErase.cpp ├── stringFind.cpp ├── stringStream.cpp ├── strings.cpp └── variableSizedArrays.cpp ├── Dynamic Programming ├── 01knapsack.cpp ├── booleanParenthization.cpp ├── coinChange1.cpp ├── coinChange2.cpp ├── countOfSubsetSum.cpp ├── countSubsetsOfGivenDiff.cpp ├── equalSumPartition.cpp ├── longestCommonSubsequence.cpp ├── longestCommonSubstring.cpp ├── longestPalndSubsequence.cpp ├── longestRepeatingSubsequence.cpp ├── matrixchainmultiplication.cpp ├── minDelForPalindromicString.cpp ├── minInsDelforAToB.cpp ├── minSubsetSumDiff.cpp ├── palindromePartitioning.cpp ├── rodCutting.cpp ├── scrambledString.cpp ├── seqPatternMatching.cpp ├── shortestCommonSupersequence.cpp ├── subsetSum.cpp └── unboundedKnapsack.cpp ├── Linked Lists ├── compare.cpp ├── cycleDetection.cpp ├── delDuplFrmSortedList.cpp ├── deleteNode.cpp ├── getNode.cpp ├── insertInSortedDoublyList.cpp ├── insertNodeAtHead.cpp ├── insertNodeAtPosition.cpp ├── insertNodeAtTail.cpp ├── mergePointOf2Lists.cpp ├── mergeSortedLists.cpp ├── reverseDoubly.cpp ├── reversePrint.cpp ├── reverseSingly.cpp └── traverseList.cpp ├── Math ├── allFactors.cpp ├── excelColNo.cpp ├── excelColTitle.cpp ├── gcd.cpp ├── gridUniquePath.cpp ├── oddOccuringNo.cpp ├── powOf2Integers.cpp ├── rearrangeArray.cpp ├── sieveOfEratosthenes.cpp ├── sortedPermutationRank.cpp ├── sumOfPairwiseHammingDist.cpp ├── trailingZeroInFactorial.cpp └── verifyPrime.cpp ├── README.md ├── Recursion ├── allSubsetsofString.cpp ├── delMidofStack.cpp ├── generateParantheses.cpp ├── josephus.cpp ├── kthGrammar.cpp ├── letterCasePermutation.cpp ├── nBitBinaryNo.cpp ├── permutationWithCaseChange.cpp ├── permutationWithSpaces.cpp ├── reverseStack.cpp ├── sortArray.cpp └── towerOfHanoi.cpp ├── Strings ├── Atoi.cpp ├── KmpPatternSearch.cpp ├── LastWordLength.cpp ├── addBinaryStrings.cpp ├── countAndSay.cpp ├── integerToRoman.cpp ├── justifiedText.cpp ├── longestCommonPrefix.cpp ├── minCharForPalindromeStr.cpp ├── multiplyStrings.cpp ├── powerOf2.cpp ├── prettyJson.cpp ├── reverseTheString.cpp ├── romanToInteger.cpp ├── subString.cpp └── validIpAddresses.cpp └── Trees ├── binaryTreeHeight.cpp ├── bstInsertion.cpp ├── inOrder.cpp ├── lcabst.cpp ├── levelOrder.cpp ├── postOrder.cpp ├── preOrder.cpp ├── search.cpp ├── topView.cpp └── verticalOrder.cpp /.gitignore: -------------------------------------------------------------------------------- 1 | .vscode -------------------------------------------------------------------------------- /Arrays/Add1ToNo.cpp: -------------------------------------------------------------------------------- 1 | // https://www.interviewbit.com/problems/add-one-to-number/ 2 | 3 | vector Solution::plusOne(vector &A) 4 | { 5 | int i, carry; 6 | vector B; 7 | for (int i = A.size() - 1; i != -1; i--) 8 | { 9 | // Initialize carry and add 1 to the last element 10 | if (i == A.size() - 1) 11 | { 12 | carry = 0; 13 | A[i] = A[i] + 1; 14 | } 15 | // Add 0 and carry for all other elements 16 | if (i != A.size() - 1) 17 | { 18 | A[i] = A[i] + 0 + carry; 19 | carry = 0; 20 | } 21 | // Check value and set carry in a separate case 22 | if (A[i] > 9) 23 | { 24 | carry++; 25 | A[i] = 0; 26 | } 27 | } 28 | // If carry is 1 after the loop then insert 1 at the beginning 29 | if (carry != 0) 30 | { 31 | A.insert(A.begin(), 1); 32 | } 33 | // Check for leading 0's if any 34 | int ind = -1; 35 | for (int i = 0; i < A.size(); i++) 36 | { 37 | if (A[i] != 0) 38 | { 39 | ind = i; 40 | break; 41 | } 42 | } 43 | if (ind != -1 && A.size() != 1) 44 | { 45 | for (int i = 0; i < A.size() - ind; i++) 46 | { 47 | B.push_back(A[ind + i]); 48 | } 49 | return B; 50 | } 51 | else 52 | { 53 | return A; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /Arrays/antiDiagonals.cpp: -------------------------------------------------------------------------------- 1 | // https://www.interviewbit.com/problems/anti-diagonals/ 2 | 3 | vector > Solution::diagonal(vector > &A) { 4 | vector> B; 5 | int row, col; 6 | for(int i=0; i C; 9 | if(i == 0 || j == A.size() - 1) { 10 | int row = i, col = j; 11 | while(row < A.size() && col >= 0) { 12 | C.push_back(A[row][col]); 13 | row++; 14 | col--; 15 | } 16 | B.push_back(C); 17 | C.clear(); 18 | } 19 | } 20 | } 21 | return B; 22 | } -------------------------------------------------------------------------------- /Arrays/arrayManipulation.cpp: -------------------------------------------------------------------------------- 1 | // https://www.hackerrank.com/challenges/crush/problem 2 | 3 | long arrayManipulation(int n, vector> queries) { 4 | vector A(n,0); 5 | long len = queries.size(); 6 | for(long i=0; isum) 20 | { 21 | sum = x; 22 | } 23 | } 24 | return sum; 25 | } -------------------------------------------------------------------------------- /Arrays/duplicateInArray.cpp: -------------------------------------------------------------------------------- 1 | // https://www.interviewbit.com/problems/find-duplicate-in-array/ 2 | 3 | int Solution::repeatedNumber(const vector &A) { 4 | int n = A.size() - 1; 5 | int sq = sqrt(n); 6 | int range = (n / sq) + 1; 7 | int count[range] = {0}; 8 | 9 | // Dividing the array in blocks of size root n and updating count of elements 10 | for (int i = 0; i <= n; i++) 11 | { 12 | count[(A[i] - 1) / sq]++; 13 | } 14 | 15 | // select last block as default block 16 | int selected_block = range - 1; 17 | for (int i = 0; i < range - 1; i++) 18 | { 19 | if (count[i] > sq) 20 | { 21 | selected_block = i; 22 | break; 23 | } 24 | } 25 | unordered_map m; 26 | for (int i = 0; i <= n; i++) 27 | { 28 | if ( ((selected_block * sq) < A[i]) && 29 | (A[i] <= ((selected_block + 1) * sq))) 30 | { 31 | m[A[i]]++; 32 | if (m[A[i]] > 1) 33 | return A[i]; 34 | } 35 | } 36 | 37 | return -1; 38 | 39 | } 40 | -------------------------------------------------------------------------------- /Arrays/dynamicArray.cpp: -------------------------------------------------------------------------------- 1 | // https://www.hackerrank.com/challenges/dynamic-array/problem 2 | 3 | vector dynamicArray(int n, vector> queries) { 4 | vector> seq(n); 5 | int lastAnswer = 0; 6 | vector sol; 7 | for(int i = 0; i < queries.size(); i++) { 8 | if(queries[i][0] == 1) { 9 | seq[(queries[i][1] ^ lastAnswer) % n].push_back(queries[i][2]); 10 | } 11 | else { 12 | lastAnswer = seq[(queries[i][1] ^ lastAnswer) % n] 13 | [queries[i][2] % seq[(queries[i][1] ^ lastAnswer) % n].size()]; 14 | sol.push_back(lastAnswer); 15 | } 16 | } 17 | return sol; 18 | } -------------------------------------------------------------------------------- /Arrays/firstMissingInteger.cpp: -------------------------------------------------------------------------------- 1 | // https://www.interviewbit.com/problems/first-missing-integer/ 2 | 3 | // O(n) time and O(1) extra space solution 4 | 5 | void sep(vector &A) 6 | { 7 | int j = 0; 8 | for(int i = 0; i < A.size(); i++) { 9 | if(A[i] <= 0) { 10 | int t = A[i]; 11 | A[i] = A[j]; 12 | A[j] = t; 13 | j++; 14 | } 15 | } 16 | A.erase(A.begin(), A.begin() + j); 17 | } 18 | 19 | int Solution::firstMissingPositive(vector &A) { 20 | sep(A); 21 | int i; 22 | for(i=0;i 0) { 25 | A[abs(A[i]) - 1] = - A[abs(A[i]) - 1]; 26 | } 27 | } 28 | for(i=0;i0) 31 | return i+1; 32 | } 33 | return A.size()+1; 34 | } -------------------------------------------------------------------------------- /Arrays/hotelBookingPossible.cpp: -------------------------------------------------------------------------------- 1 | // https://www.interviewbit.com/problems/hotel-bookings-possible/ 2 | 3 | // sorts vector of pairs by 1st value of pair by default, add marker and calculate 4 | // active users 5 | bool Solution::hotel(vector &arrive, vector &depart, int K) { 6 | vector>ans; 7 | for (int i=0; i K){ 21 | return false; 22 | } 23 | } 24 | return true; 25 | } 26 | -------------------------------------------------------------------------------- /Arrays/hourGlassSum.cpp: -------------------------------------------------------------------------------- 1 | // https://www.hackerrank.com/challenges/2d-array/problem 2 | 3 | int hourglassSum(vector> arr) { 4 | int hourglassSum = INT_MIN; 5 | for(int i = 0; i < arr.size() - 2; i++) { 6 | for(int j = 0; j < arr[0].size() - 2; j++) { 7 | hourglassSum = max(hourglassSum, arr[i][j] + arr[i][j+1] + arr[i][j+2] 8 | + arr[i+1][j+1] + arr[i+2][j] + arr[i+2][j+1] + arr[i+2][j+2]); 9 | } 10 | } 11 | return hourglassSum; 12 | } -------------------------------------------------------------------------------- /Arrays/insertionSort.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | void insertionSort(int arr[], int length); 7 | void printArray(int array[], int size); 8 | 9 | int main() 10 | { 11 | int array[6] = {5, 1, 6, 2, 4, 3}; 12 | insertionSort(array, 6); 13 | return 0; 14 | } 15 | 16 | void insertionSort(int arr[], int length) 17 | { 18 | int i, j, key; 19 | for (i = 1; i < length; i++) 20 | { 21 | key = arr[i]; 22 | j = i - 1; 23 | 24 | while (j >= 0 && arr[j] > key) 25 | { 26 | arr[j + 1] = arr[j]; 27 | j--; 28 | } 29 | arr[j + 1] = key; 30 | } 31 | cout << "Sorted Array: "; 32 | printArray(arr, length); 33 | } 34 | 35 | void printArray(int array[], int size) 36 | { 37 | int j; 38 | for (j = 0; j < size; j++) 39 | { 40 | cout << " " << array[j]; 41 | } 42 | cout << endl; 43 | } -------------------------------------------------------------------------------- /Arrays/largestNumber.cpp: -------------------------------------------------------------------------------- 1 | // https://www.interviewbit.com/problems/largest-number/ 2 | 3 | bool myCompare(string X, string Y) { 4 | string XY = X.append(Y); 5 | string YX = Y.append(X); 6 | 7 | return XY.compare(YX) > 0; 8 | } 9 | 10 | string Solution::largestNumber(const vector &A) { 11 | vector b; 12 | for(int i=0; i< A.size(); i++) { 13 | b.push_back(to_string(A[i])); 14 | } 15 | sort(b.begin(), b.end(), myCompare); 16 | string ans=""; 17 | for(int i=0; i rotateLeft(int d, vector arr) { 4 | int n = arr.size(); 5 | // d = d % n; 6 | for(int i = 0; i < d; i++) { 7 | int temp = arr[0], j; 8 | for (j = 0; j < n - 1; j++) 9 | arr[j] = arr[j + 1]; 10 | 11 | arr[j] = temp; 12 | } 13 | return arr; 14 | } -------------------------------------------------------------------------------- /Arrays/maxAbsDifference.cpp: -------------------------------------------------------------------------------- 1 | int Solution::maxArr(vector &A) 2 | { 3 | // express abs difference using modulus properties for different cases 4 | int max1 = INT_MIN, min1 = INT_MAX; 5 | int max2 = INT_MIN, min2 = INT_MAX; 6 | 7 | for (int i = 0; i < A.size(); i++) 8 | { 9 | max1 = max(max1, A[i] + i); 10 | min1 = min(min1, A[i] + i); 11 | max2 = max(max2, A[i] - i); 12 | min2 = min(min2, A[i] - i); 13 | } 14 | return max(max1 - min1, max2 - min2); 15 | } -------------------------------------------------------------------------------- /Arrays/maxContigSubarray.cpp: -------------------------------------------------------------------------------- 1 | // https://www.interviewbit.com/problems/max-sum-contiguous-subarray/ 2 | 3 | // Popularly known as Kadane's algorithm 4 | 5 | int Solution::maxSubArray(const vector &A) 6 | { 7 | int max_so_far = INT_MIN, max_ending_here = 0; 8 | for (int i = 0; i < A.size(); i++) 9 | { 10 | max_ending_here = max_ending_here + A[i]; 11 | if (max_so_far < max_ending_here) 12 | max_so_far = max_ending_here; 13 | // Adding a postive or negative value to a negative no would 14 | // further decrease the sum so reset it to 0 and start fresh 15 | if (max_ending_here < 0) 16 | max_ending_here = 0; 17 | } 18 | return max_so_far; 19 | } 20 | -------------------------------------------------------------------------------- /Arrays/maxDistance.cpp: -------------------------------------------------------------------------------- 1 | // https://www.interviewbit.com/problems/max-distance/ 2 | 3 | int Solution::maximumGap(const vector &A) { 4 | int n = A.size(); 5 | vector maxFromEnd(n+1, INT_MIN); 6 | for(int i = A.size() - 1; i >= 0; i--) { 7 | maxFromEnd[i] = max(maxFromEnd[i+1], A[i]); 8 | } 9 | int result = 0; 10 | for(int i = 0; i < A.size(); i++) { 11 | int low = i + 1, high = A.size() - 1, ans = i; 12 | while(low <= high) { 13 | int mid = (low + high) / 2; 14 | if(A[i] <= maxFromEnd[mid]) { 15 | ans = max(ans, mid); 16 | low = mid + 1; 17 | } 18 | else { 19 | high = mid - 1; 20 | } 21 | } 22 | result = max(result, ans - i); 23 | } 24 | return result; 25 | } 26 | -------------------------------------------------------------------------------- /Arrays/maxUnsortedSubArray.cpp: -------------------------------------------------------------------------------- 1 | // https://www.interviewbit.com/problems/maximum-unsorted-subarray/ 2 | 3 | // traverse array from start and find index where not sorted 4 | // check if sorted, then return -1 5 | // traverse array from end and find index where not sorted 6 | // calculate max and min within the range 7 | // traverse from 0 to start-1 to check for first element less than min 8 | // traverse from n-1 to end+1 to check if element is less than max 9 | 10 | vector Solution::subUnsort(vector &A) { 11 | int n = A.size(); 12 | vector B; 13 | int s = 0, e = n-1; 14 | for(s=0; s < n-1; s++) { 15 | if(A[s] > A[s+1]) { 16 | break; 17 | } 18 | } 19 | if(s == n-1) { 20 | B.push_back(-1); 21 | return B; 22 | } 23 | for(e = n-1; e > 0; e--) { 24 | if(A[e] < A[e-1]) { 25 | break; 26 | } 27 | } 28 | int max=A[s], min=A[s]; 29 | for(int i=s+1; i<=e; i++) { 30 | if(A[i] < min) { 31 | min = A[i]; 32 | } 33 | if(A[i] > max) { 34 | max = A[i]; 35 | } 36 | } 37 | for(int i=0; i min) { 39 | s = i; 40 | break; 41 | } 42 | } 43 | for(int i=n-1; i>e; i--) { 44 | if(A[i] < max) { 45 | e = i; 46 | break; 47 | } 48 | } 49 | B.push_back(s); 50 | B.push_back(e); 51 | return B; 52 | } 53 | 54 | -------------------------------------------------------------------------------- /Arrays/mergeOverlappingInterval.cpp: -------------------------------------------------------------------------------- 1 | // https://www.interviewbit.com/problems/merge-overlapping-intervals/ 2 | 3 | struct Interval { 4 | int start; 5 | int end; 6 | Interval() : start(0), end(0) {} 7 | Interval(int s, int e) : start(s), end(e) {} 8 | }; 9 | 10 | bool mycomp(Interval x, Interval y) 11 | { 12 | return (x.start < y.start); 13 | } 14 | 15 | vector Solution::merge(vector &A) { 16 | int n = A.size(); 17 | sort(A.begin(), A.end() , mycomp); 18 | int index = 0; 19 | for (int i=1; i= A[i].start) 22 | { 23 | A[index].end = max(A[index].end, A[i].end); 24 | A[index].start = min(A[index].start, A[i].start); 25 | } 26 | else { 27 | index++; 28 | A[index] = A[i]; 29 | } 30 | } 31 | vector B; 32 | for(int i = 0; i<= index; i++){ 33 | B.push_back(A[i]); 34 | } 35 | return B; 36 | } 37 | -------------------------------------------------------------------------------- /Arrays/mergeSort.cpp: -------------------------------------------------------------------------------- 1 | void merge(int *Arr, int start, int mid, int end) 2 | { 3 | // create a temp array 4 | int temp[end - start + 1]; 5 | 6 | // crawlers for both intervals and for temp 7 | int i = start, j = mid + 1, k = 0; 8 | 9 | // traverse both arrays and in each iteration add smaller of both elements in temp 10 | while (i <= mid && j <= end) 11 | { 12 | if (Arr[i] <= Arr[j]) 13 | { 14 | temp[k] = Arr[i]; 15 | k += 1; 16 | i += 1; 17 | } 18 | else 19 | { 20 | temp[k] = Arr[j]; 21 | k += 1; 22 | j += 1; 23 | } 24 | } 25 | 26 | // add elements left in the first interval 27 | while (i <= mid) 28 | { 29 | temp[k] = Arr[i]; 30 | k += 1; 31 | i += 1; 32 | } 33 | 34 | // add elements left in the second interval 35 | while (j <= end) 36 | { 37 | temp[k] = Arr[j]; 38 | k += 1; 39 | j += 1; 40 | } 41 | 42 | // copy temp to original interval 43 | for (i = start; i <= end; i += 1) 44 | { 45 | Arr[i] = temp[i - start] 46 | } 47 | } 48 | 49 | // Arr is an array of integer type 50 | // start and end are the starting and ending index of current interval of Arr 51 | 52 | void mergeSort(int *Arr, int start, int end) 53 | { 54 | 55 | if (start < end) 56 | { 57 | int mid = (start + end) / 2; 58 | mergeSort(Arr, start, mid); 59 | mergeSort(Arr, mid + 1, end); 60 | merge(Arr, start, mid, end); 61 | } 62 | } -------------------------------------------------------------------------------- /Arrays/nextPermutation.cpp: -------------------------------------------------------------------------------- 1 | // https://www.interviewbit.com/problems/next-permutation/ 2 | 3 | vector Solution::nextPermutation(vector &A) { 4 | int i,temp,small,big; 5 | for(i = A.size() - 1; i > 0; i--) { 6 | if(A[i] > A[i-1]) { 7 | break; 8 | } 9 | } 10 | if(i == 0) { 11 | sort(A.begin(), A.end()); 12 | return A; 13 | } 14 | small = i - 1; 15 | big = i; 16 | temp = i; 17 | for(int i = A.size() - 1; i > big; i--) { 18 | if(A[i] < A[temp] && A[i] > A[small]) { 19 | temp = i; 20 | } 21 | } 22 | int t = A[temp]; 23 | A[temp] = A[small]; 24 | A[small] = t; 25 | small++; 26 | sort(A.begin()+small, A.end()); 27 | return A; 28 | } 29 | -------------------------------------------------------------------------------- /Arrays/pascalTriangle.cpp: -------------------------------------------------------------------------------- 1 | // https://www.interviewbit.com/problems/pascal-triangle/ 2 | 3 | vector > Solution::solve(int A) { 4 | vector> pascal (A); 5 | for (int line = 0; line < A; line++) 6 | { 7 | for (int i = 0; i <= line; i++) 8 | { 9 | pascal[line].push_back(1); 10 | } 11 | } 12 | for (int line = 1; line < A; line++) 13 | { 14 | int C = 1; 15 | for (int i = 1; i <= line; i++) 16 | { 17 | pascal[line][i] = C * (line - i + 1) / i; 18 | C = pascal[line][i]; 19 | } 20 | } 21 | return pascal; 22 | } 23 | -------------------------------------------------------------------------------- /Arrays/quickSort.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | // Swapping two values 5 | void swap(int *a, int *b) 6 | { 7 | int temp; 8 | temp = *a; 9 | *a = *b; 10 | *b = temp; 11 | } 12 | 13 | // Partitioning the array on the basis of values at high as pivot value 14 | int Partition(int a[], int low, int high) 15 | { 16 | int pivot, index, i; 17 | index = low; 18 | pivot = high; 19 | 20 | // Getting index of the pivot 21 | for (i = low; i < high; i++) 22 | { 23 | if (a[i] < a[pivot]) 24 | { 25 | swap(&a[i], &a[index]); 26 | index++; 27 | } 28 | } 29 | // Swapping value at high and at the index obtained 30 | swap(&a[pivot], &a[index]); 31 | 32 | return index; 33 | } 34 | 35 | // Random selection of pivot. 36 | int RandomPivotPartition(int a[], int low, int high) 37 | { 38 | int pvt, n, temp; 39 | n = rand(); 40 | // Randomizing the pivot value in the given subpart of array 41 | pvt = low + n % (high - low + 1); 42 | 43 | // Swapping pivot value from high, so pivot value will be taken as a pivot while partitioning 44 | swap(&a[high], &a[pvt]); 45 | 46 | return Partition(a, low, high); 47 | } 48 | 49 | int QuickSort(int a[], int low, int high) 50 | { 51 | int pindex; 52 | if (low < high) 53 | { 54 | // Partitioning array using randomized pivot 55 | pindex = RandomPivotPartition(a, low, high); 56 | // Recursively implementing QuickSort. 57 | QuickSort(a, low, pindex - 1); 58 | QuickSort(a, pindex + 1, high); 59 | } 60 | return 0; 61 | } 62 | 63 | int main() 64 | { 65 | int n, i; 66 | cout << "\nEnter the number of data elements to be sorted: "; 67 | cin >> n; 68 | 69 | int arr[n]; 70 | for (i = 0; i < n; i++) 71 | { 72 | cout << "Enter element " << i + 1 << ": "; 73 | cin >> arr[i]; 74 | } 75 | 76 | QuickSort(arr, 0, n - 1); 77 | 78 | // Printing the sorted data 79 | cout << "\nSorted Data "; 80 | for (i = 0; i < n; i++) 81 | cout << "->" << arr[i]; 82 | 83 | return 0; 84 | } 85 | -------------------------------------------------------------------------------- /Arrays/rotateMatrix.cpp: -------------------------------------------------------------------------------- 1 | // https://www.interviewbit.com/problems/rotate-matrix/ 2 | 3 | // Rotate array in form of squares dividing matrix into squares or circles 4 | // to solve without extra space 5 | 6 | void Solution::rotate(vector > &A) { 7 | int N = A.size(); 8 | for (int i = 0; i < N / 2; i++) { 9 | for (int j = i; j < N - i - 1; j++) { 10 | int temp = A[i][j]; 11 | A[i][j] = A[N - 1 - j][i]; 12 | A[N - 1 - j][i] = A[N - 1 - i][N - 1 - j]; 13 | A[N - 1 - i][N - 1 - j] = A[j][N - 1 - i]; 14 | A[j][N - 1 - i] = temp; 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Arrays/setMatrixZeros.cpp: -------------------------------------------------------------------------------- 1 | // https://www.interviewbit.com/problems/set-matrix-zeros/ 2 | 3 | // First check row 1 and col 1 and then rest of the matrix. 4 | // If any element in the rest of the matrix is 0 then make 1st element 5 | // of that row and col as 0. Then check if 1st element of a row or 6 | // col is 0 then make that complete row and col as 0 7 | 8 | void Solution::setZeroes(vector > &A) { 9 | int m = A.size(), n = A[0].size(); 10 | int r1=0, c1=0; 11 | for(int i=0; i matchingStrings(vector strings, vector queries) { 4 | vector results; 5 | for(int i = 0; i < queries.size(); i++) { 6 | int count = 0; 7 | for(int j = 0; j < strings.size(); j++) { 8 | if(queries[i] == strings[j]) { 9 | count++; 10 | } 11 | } 12 | results.push_back(count); 13 | } 14 | return results; 15 | } -------------------------------------------------------------------------------- /Arrays/spiralMatrix2.cpp: -------------------------------------------------------------------------------- 1 | // https://www.interviewbit.com/problems/spiral-order-matrix-ii/ 2 | 3 | // track top, bottom, left and right 4 | vector> Solution::generateMatrix(int A) { 5 | int n = A; 6 | int t=0,l=0,r=n-1,b=n-1; 7 | int d=0,count=1; 8 | vector>a(n,vector(n)); 9 | while(t<=b && l<=r){ 10 | if(d==0){ 11 | for(int i=l;i<=r;i++){ 12 | a[t][i]=count; 13 | count++; 14 | } 15 | d=1; 16 | t++; 17 | } 18 | else if(d==1){ 19 | for(int i=t;i<=b;i++){ 20 | a[i][r]=count; 21 | count++; 22 | } 23 | d=2; 24 | r--; 25 | } 26 | else if(d==2){ 27 | for(int i=r;i>=l;i--){ 28 | a[b][i]=count; 29 | count++; 30 | } 31 | d=3; 32 | b--; 33 | } 34 | else if(d==3){ 35 | for(int i=b;i>=t;i--){ 36 | a[i][l]=count; 37 | count++; 38 | } 39 | d=0; 40 | l++; 41 | } 42 | } 43 | return a; 44 | } 45 | -------------------------------------------------------------------------------- /Arrays/waveArray.cpp: -------------------------------------------------------------------------------- 1 | // https://www.interviewbit.com/problems/wave-array/ 2 | 3 | vector Solution::wave(vector &A) { 4 | int n = A.size(); 5 | sort(A.begin(), A.end()); 6 | for(int i=0;i 2 | using namespace std; 3 | 4 | struct Interval 5 | { 6 | int start, end; 7 | }; 8 | 9 | bool comparatorFunction(Interval I1, Interval I2) 10 | { 11 | return (I1.start < I2.start); 12 | } 13 | 14 | int main() 15 | { 16 | Interval arr[] = {{6, 8}, {3, 5}, {2, 7}}; 17 | sort(arr, arr + 3, comparatorFunction); 18 | for (int i = 0; i < 3; i++) 19 | { 20 | cout << arr[i].start << " " << arr[i].end << endl; 21 | } 22 | } -------------------------------------------------------------------------------- /C++/eraseVector.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | using namespace std; 7 | 8 | int main() 9 | { 10 | int n, x, a, b; 11 | cin >> n; 12 | vector arr(n); 13 | for (int i = 0; i < n; i++) 14 | { 15 | cin >> arr[i]; 16 | } 17 | cin >> x; 18 | cin >> a >> b; 19 | arr.erase(arr.begin() + x - 1); 20 | arr.erase(arr.begin() + a - 1, arr.begin() + b - 1); 21 | cout << arr.size() << endl; 22 | for (int i = 0; i < arr.size(); i++) 23 | { 24 | cout << arr[i] << " "; 25 | } 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /C++/iterateMap.cpp: -------------------------------------------------------------------------------- 1 | // Different ways to iterate over a map in C++ 2 | 3 | // Similar way for unordered_map 4 | 5 | #include 6 | using namespace std; 7 | 8 | int main() { 9 | int arr[] = {1, 1, 2, 1, 1, 3, 4, 3}; 10 | int n = sizeof(arr) / sizeof(arr[0]); 11 | 12 | map m; 13 | for(int i = 0; i < n; i++) { 14 | m[arr[i]]++; 15 | } 16 | 17 | for(auto i : m) { 18 | cout<first<<" "<second; 24 | cout< 2 | using namespace std; 3 | 4 | int main() 5 | { 6 | 7 | vector arr = { 1, 2, 3, 4 }; 8 | 9 | // Traversing the vector using 10 | // values directly 11 | for (auto it : arr) { 12 | 13 | // Print the values 14 | cout << it << ' '; 15 | } 16 | 17 | // For updating values in a vector without using iterators 18 | // traverse the values stored in vector using reference and updated the value 19 | for (auto& it : arr) { 20 | it *= 2; 21 | } 22 | 23 | for (auto& it : arr) { 24 | cout << it << ' '; 25 | } 26 | 27 | return 0; 28 | } -------------------------------------------------------------------------------- /C++/lowerBound.cpp: -------------------------------------------------------------------------------- 1 | // https://www.hackerrank.com/challenges/cpp-lower-bound/problem 2 | 3 | #include 4 | using namespace std; 5 | 6 | int customSearch(vector &arr, int num) 7 | { 8 | int first = 0, last = arr.size() - 1, mid, found = 0; 9 | while (first <= last && found == 0) 10 | { 11 | mid = (first + last) / 2; 12 | if (arr[mid] == num && (mid == 0 || num > arr[mid - 1])) 13 | { 14 | found = 1; 15 | break; 16 | } 17 | if (num > arr[mid]) 18 | { 19 | first = mid + 1; 20 | } 21 | else 22 | { 23 | last = mid - 1; 24 | } 25 | } 26 | if (found == 0) 27 | { 28 | return found; 29 | } 30 | else 31 | { 32 | return mid + 1; 33 | } 34 | } 35 | 36 | int main() 37 | { 38 | int n, i, q, result; 39 | cin >> n; 40 | vector a(n); 41 | vector::iterator pos; 42 | for (i = 0; i < n; i++) 43 | { 44 | cin >> a[i]; 45 | } 46 | cin >> q; 47 | vector number(q); 48 | for (i = 0; i < q; i++) 49 | { 50 | cin >> number[i]; 51 | } 52 | for (i = 0; i < q; i++) 53 | { 54 | result = customSearch(a, number[i]); 55 | if (result == 0) 56 | { 57 | pos = lower_bound(a.begin(), a.end(), number[i]); 58 | cout << "No " << pos - a.begin() + 1 << endl; 59 | } 60 | else 61 | { 62 | cout << "Yes " << result << endl; 63 | } 64 | } 65 | } -------------------------------------------------------------------------------- /C++/manipulators.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | int main() 6 | { 7 | int T; 8 | cin >> T; 9 | cout << setiosflags(ios::uppercase); 10 | cout << setw(0xf) << internal; 11 | while (T--) 12 | { 13 | double A, B, C; 14 | cin >> A >> B >> C; 15 | 16 | cout << left << hex << showbase << nouppercase; 17 | cout << (long long)A << endl; 18 | 19 | cout.precision(2); 20 | cout << showpos << fixed << setfill('_') << setw(15) << right; 21 | cout << B << endl; 22 | 23 | cout.precision(9); 24 | cout << noshowpos << uppercase << scientific; 25 | cout << C << endl; 26 | } 27 | return 0; 28 | } -------------------------------------------------------------------------------- /C++/maps.cpp: -------------------------------------------------------------------------------- 1 | // https://www.hackerrank.com/challenges/cpp-maps/problem 2 | 3 | #include 4 | using namespace std; 5 | 6 | int main() 7 | { 8 | int q, i, type, marks; 9 | string name; 10 | char space; 11 | map m; 12 | map::iterator pos; 13 | cin >> q; 14 | for (i = 0; i < q; i++) 15 | { 16 | cin >> type >> name; 17 | if (type == 1) 18 | { 19 | cin >> marks; 20 | m[name] += marks; 21 | } 22 | else if (type == 2) 23 | { 24 | m.erase(name); 25 | } 26 | else 27 | { 28 | pos = m.find(name); 29 | if (pos != m.end()) 30 | { 31 | cout << pos->second << endl; 32 | } 33 | else 34 | { 35 | cout << 0 << endl; 36 | } 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /C++/pointerTo2dArray.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int main() 4 | { 5 | int a[2][3] = {0}; 6 | int(*p)[3] = a; 7 | cout << a[0] << endl; 8 | cout << *a << endl; 9 | cout << a << endl; 10 | cout << &a[0][0] << endl; 11 | cout << p << endl; 12 | for (int i = 0; i < 2; i++) 13 | { 14 | for (int j = 0; j < 3; j++) 15 | { 16 | cout << a[i][j] << " "; 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /C++/queue.cpp: -------------------------------------------------------------------------------- 1 | // Queues operate in FIFO (first in first out). Elements are inserted at the end 2 | // and are deleted from the front. 3 | 4 | // push() adds element at the end and pop() deletes the first element of 5 | // the queue 6 | 7 | #include 8 | using namespace std; 9 | 10 | void showq(queue gq) { 11 | queue g = gq; 12 | while(!g.empty()) { 13 | cout<<" "< gquiz; 20 | gquiz.push(10); 21 | gquiz.push(20); 22 | gquiz.push(30); 23 | showq(gquiz); 24 | } 25 | 26 | // 10 20 30 -------------------------------------------------------------------------------- /C++/reverseVector.cpp: -------------------------------------------------------------------------------- 1 | // Complete the reverseArray function below. 2 | 3 | vector reverseArray(vector a) { 4 | for(int i = 0, j = a.size() - 1; i <= j ; i++, j--) { 5 | swap(a[i], a[j]); 6 | } 7 | return a; 8 | } -------------------------------------------------------------------------------- /C++/sets.cpp: -------------------------------------------------------------------------------- 1 | // https://www.hackerrank.com/challenges/cpp-sets/problem 2 | 3 | #include 4 | using namespace std; 5 | 6 | int main() 7 | { 8 | int q, i, x, y; 9 | set s; 10 | set::iterator pos; 11 | cin >> q; 12 | for (i = 0; i < q; i++) 13 | { 14 | cin >> x >> y; 15 | if (x == 1) 16 | { 17 | s.insert(y); 18 | } 19 | else if (x == 2) 20 | { 21 | s.erase(y); 22 | } 23 | else 24 | { 25 | pos = s.find(y); 26 | if (pos != s.end()) 27 | { 28 | cout << "Yes" << endl; 29 | } 30 | else 31 | { 32 | cout << "No" << endl; 33 | } 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /C++/sortVector.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | using namespace std; 7 | 8 | int main() 9 | { 10 | int n; 11 | cin >> n; 12 | vector a(n); 13 | for (int i = 0; i < n; i++) 14 | { 15 | cin >> a[i]; 16 | } 17 | sort(a.begin(), a.end()); 18 | for (int i = 0; i < n; i++) 19 | { 20 | cout << a[i] << " "; 21 | } 22 | return 0; 23 | } 24 | -------------------------------------------------------------------------------- /C++/stack.cpp: -------------------------------------------------------------------------------- 1 | // Stacks follow LIFO(Last In First Out) where element is added on top and deleted from top 2 | 3 | #include 4 | using namespace std; 5 | 6 | void showstack(stack s) { 7 | while(!s.empty()) { 8 | cout< s; 15 | s.push(10); 16 | s.push(20); 17 | s.push(30); 18 | showstack(s); 19 | } 20 | 21 | // 30 20 10 -------------------------------------------------------------------------------- /C++/stringAppend.cpp: -------------------------------------------------------------------------------- 1 | // Different ways to use std::string::append() in C++ 2 | 3 | string str1, str2; 4 | 5 | // Appends str2 in str1 6 | str1.append(str2); 7 | 8 | // Appends 5 characters from 0th index of str2 to str1 9 | str1.append(str2, 0, 5); 10 | 11 | // Appends "GeeksforGeeks" in str1 12 | str1.append("GeeksforGeeks"); 13 | 14 | // Appends first 5 characters from "GeeksforGeeks" to str1 15 | str1.append("GeeksforGeeks", 5); 16 | 17 | // Appends 10 occurrences of '$' to str1 18 | str1.append(10, '$'); 19 | 20 | // Appends all characters of the range [beg, end) 21 | str1.append(str2.begin() + 5, str2.end()); -------------------------------------------------------------------------------- /C++/stringErase.cpp: -------------------------------------------------------------------------------- 1 | // Different ways to use std::string::erase() in C++ 2 | 3 | // Deletes all characters 4 | str.erase(); 5 | 6 | // Deletes all characters starting from index 2 7 | str.erase(2); 8 | 9 | // Deletes 4 characters from index number 1 10 | str.erase(1, 4); 11 | 12 | // deletes character at 4th index 13 | str.erase(str.begin() + 4); 14 | 15 | // Erases all characters of the range [beg, end) 16 | str.erase(str.begin() + 0, str.end() - 6); -------------------------------------------------------------------------------- /C++/stringFind.cpp: -------------------------------------------------------------------------------- 1 | // https://www.geeksforgeeks.org/string-find-in-cpp/ 2 | 3 | #include 4 | #include 5 | 6 | using namespace std; 7 | 8 | int main() 9 | { 10 | string str = "geeksforgeeks a computer science"; 11 | string str1 = "geeks"; 12 | 13 | // Find first occurrence of "geeks" 14 | // Syntax 1 15 | // if the sub-string is not found it returns string::npos 16 | // string::npos is static member with value as the highest 17 | // possible for the size_t data structure 18 | 19 | size_t found = str.find(str1); 20 | if (found != string::npos) 21 | cout << "First occurrence is " << found << endl; 22 | 23 | // Find next occurrence of "geeks". Note here we pass 24 | // "geeks" as C style string. 25 | // Syntax 2 26 | 27 | char arr[] = "geeks"; 28 | found = str.find(arr, found+1); 29 | if (found != string::npos) 30 | cout << "Next occurrence is " << found << endl; 31 | 32 | return 0; 33 | } 34 | 35 | // Output 36 | // First occurrence is 0 37 | // Next occurrence is 8 -------------------------------------------------------------------------------- /C++/stringStream.cpp: -------------------------------------------------------------------------------- 1 | // stringstream ss("23,4,56"); 2 | // char ch; 3 | // int a, b, c; 4 | // ss >> a >> ch >> b >> ch >> c; // a = 23, b = 4, c = 56 5 | 6 | #include 7 | #include 8 | #include 9 | using namespace std; 10 | 11 | vector parseInts(string str) 12 | { 13 | stringstream parse(str); 14 | char ch; 15 | int a; 16 | vector arr; 17 | while (parse >> a) 18 | { 19 | parse >> ch; 20 | arr.push_back(a); 21 | } 22 | return arr; 23 | } 24 | 25 | int main() 26 | { 27 | string str; 28 | cin >> str; 29 | vector integers = parseInts(str); 30 | for (int i = 0; i < integers.size(); i++) 31 | { 32 | cout << integers[i] << endl; 33 | } 34 | return 0; 35 | } -------------------------------------------------------------------------------- /C++/strings.cpp: -------------------------------------------------------------------------------- 1 | // Problem link: https://www.hackerrank.com/challenges/c-tutorial-strings/problem 2 | 3 | #include 4 | #include 5 | using namespace std; 6 | 7 | int main() 8 | { 9 | string a, b; 10 | char t; 11 | cin >> a >> b; 12 | string c = a + b; 13 | cout << a.size() << " " << b.size() << endl; 14 | cout << c << endl; 15 | t = a[0]; 16 | a[0] = b[0]; 17 | b[0] = t; 18 | cout << a << " " << b; 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /C++/variableSizedArrays.cpp: -------------------------------------------------------------------------------- 1 | // vectors are same as dynamic arrays with the ability to resize automatically 2 | // Problem link - https://www.hackerrank.com/challenges/variable-sized-arrays/problem 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | using namespace std; 10 | 11 | int main() 12 | { 13 | // get length of array 'a' and number of queries 14 | int n, q; 15 | cin >> n >> q; 16 | 17 | // create vector of vectors 18 | vector> a(n); 19 | 20 | // fill each 2D vector i with k_i values 21 | for (int i = 0; i < n; i++) 22 | { 23 | // get the length k of the vector at a[i] 24 | int k; 25 | cin >> k; 26 | 27 | // fill the vector with k values 28 | a[i].resize(k); 29 | for (int j = 0; j < k; j++) 30 | { 31 | cin >> a[i][j]; 32 | } 33 | } 34 | 35 | // run queries on a 36 | for (int q_num = 0; q_num < q; q_num++) 37 | { 38 | // get i, j as the 'query' to get a value from a 39 | int i, j; 40 | cin >> i >> j; 41 | cout << a[i][j] << endl; 42 | } 43 | 44 | return 0; 45 | } -------------------------------------------------------------------------------- /Dynamic Programming/01knapsack.cpp: -------------------------------------------------------------------------------- 1 | // 0-1 Knapsack problem 2 | 3 | // Input - weights (int wt[]), values (int val[]), capacity of knapsack (int W), Size of array (int n) 4 | // Output - maximum profit (int) 5 | 6 | // Recursive approach 7 | 8 | int knapsack(int wt[], int val[], int W, int n) { 9 | if(n == 0 || w == 0) { 10 | return 0; 11 | } 12 | if(wt[n-1] <= W) { 13 | return max(val[n-1] + knapsack(wt, val, W - wt[n-1], n-1), knapsack(wt, val, W, n-1)); 14 | } 15 | else if(wt[n-1] > W) { 16 | return knapsack(wt, val, W, n-1); 17 | } 18 | } 19 | 20 | // Memoization (Recursive call + storage in matrix) 21 | 22 | // Create matrix (int t[n+1][w+1]) with variables that are changing (n, w), size of matrix from constraints given in question 23 | // Initialize the matrix with -1 24 | 25 | int t[102][1002]; 26 | memset(t, -1, sizeof(t)); 27 | int knapsack(int wt[], int val[], int W, int n) { 28 | if(n == 0 || w == 0) { 29 | return 0; 30 | } 31 | if(t[n][w] != -1) { 32 | return t[n][w]; 33 | } 34 | if(wt[n-1] <= W) { 35 | return t[n][w] = max(val[n-1] + knapsack(wt, val, W - wt[n-1], n-1), knapsack(wt, val, W, n-1)); 36 | } 37 | else if(wt[n-1] > W) { 38 | return t[n][w] = knapsack(wt, val, W, n-1); 39 | } 40 | } 41 | 42 | // Tabulation (Eliminates recursive calls, only matrix) 43 | 44 | int knapsack(int wt[], int val[], int w, int n) { 45 | int t[n+1][w+1]; 46 | 47 | // Initializaton of matrix (same as base condition in recursion) 48 | 49 | for(int i=0; i 5 | using namespace std; 6 | 7 | // Recursive 8 | 9 | int solve(string s, int i, int j, bool isTrue) { 10 | if(i > j) { 11 | return false; 12 | } 13 | 14 | if(i == j) { 15 | if(isTrue == true) { 16 | return s[i] == 'T'; 17 | } 18 | else { 19 | return s[i] == 'F'; 20 | } 21 | } 22 | 23 | int ans = 0; 24 | 25 | for(int k = i+1; k <= j-1; k+=2) { 26 | int lt = solve(s, i, k-1, true); 27 | int lf = solve(s, i, k-1, false); 28 | int rt = solve(s, k+1, j, true); 29 | int rf = solve(s, k+1, j, false); 30 | 31 | if(s[k] == '&') { 32 | if(isTrue == true) { 33 | ans = ans + lt*rt; 34 | } 35 | else { 36 | ans = ans + lt*rf + lf*rt + lf*rf; 37 | } 38 | } 39 | 40 | else if(s[k] == '|') { 41 | if(isTrue == true) { 42 | ans = ans + lt*rt + lt*rf + lf*rt; 43 | } 44 | else { 45 | ans = ans + lf*rf; 46 | } 47 | } 48 | 49 | else if(s[k] == '^') { 50 | if(isTrue == true) { 51 | ans = ans + lt*rf + lf*rt; 52 | } 53 | else { 54 | ans = ans + lf*rf + lt*rt; 55 | } 56 | } 57 | } 58 | 59 | return ans; 60 | } 61 | 62 | int main() { 63 | string s; 64 | cin >> s; 65 | cout<< solve(s, 0, s.size()-1, true); 66 | } 67 | 68 | // Memoization with map 69 | 70 | unordered_map mp; 71 | 72 | int solve(string s, int i, int j, bool isTrue) { 73 | if(i > j) { 74 | return false; 75 | } 76 | 77 | if(i == j) { 78 | if(isTrue == true) { 79 | return s[i] == 'T'; 80 | } 81 | else { 82 | return s[i] == 'F'; 83 | } 84 | } 85 | 86 | string temp = to_string(i); 87 | temp.push_back(' '); 88 | temp.append(to_string(j)); 89 | temp.push_back(' '); 90 | temp.append(to_string(isTrue)); 91 | 92 | if(mp.find(temp) != mp.end()) { 93 | return mp[temp]; 94 | } 95 | 96 | int ans = 0; 97 | 98 | for(int k = i+1; k <= j-1; k+=2) { 99 | int lt = solve(s, i, k-1, true); 100 | int lf = solve(s, i, k-1, false); 101 | int rt = solve(s, k+1, j, true); 102 | int rf = solve(s, k+1, j, false); 103 | 104 | if(s[k] == '&') { 105 | if(isTrue == true) { 106 | ans = ans + lt*rt; 107 | } 108 | else { 109 | ans = ans + lt*rf + lf*rt + lf*rf; 110 | } 111 | } 112 | 113 | else if(s[k] == '|') { 114 | if(isTrue == true) { 115 | ans = ans + lt*rt + lt*rf + lf*rt; 116 | } 117 | else { 118 | ans = ans + lf*rf; 119 | } 120 | } 121 | 122 | else if(s[k] == '^') { 123 | if(isTrue == true) { 124 | ans = ans + lt*rf + lf*rt; 125 | } 126 | else { 127 | ans = ans + lf*rf + lt*rt; 128 | } 129 | } 130 | } 131 | 132 | return mp[temp] = ans; 133 | } 134 | 135 | int main() { 136 | string s; 137 | cin >> s; 138 | mp.clear(); 139 | cout<< solve(s, 0, s.size()-1, true); 140 | } 141 | 142 | -------------------------------------------------------------------------------- /Dynamic Programming/coinChange1.cpp: -------------------------------------------------------------------------------- 1 | // Input - int coin[] (Array of coin values), int sum, int n (size of array) 2 | // Output - No. of ways in which sum can be generated by selecting coins 3 | // Similar to count of subset sum with variation according to unbounded knapsack 4 | 5 | int coinChange(int coin[], int sum, int n) { 6 | int t[n+1][sum+1]; 7 | 8 | for(int i = 0; i < n+1; i++) { 9 | for(int j = 0; j < sum+1; j++) { 10 | if(i == 0) { 11 | t[i][j] = 0; 12 | } 13 | if(j == 0) { 14 | t[i][j] = 1; 15 | } 16 | } 17 | } 18 | 19 | for(int i = 1; i < n+1; i++) { 20 | for(int j = 1; j < sum+1; j++) { 21 | if(coin[i-1] <= j) { 22 | t[i][j] = t[i][j-coin[i-1]] + t[i-1][j]; 23 | } 24 | else { 25 | t[i][j] = t[i-1][j]; 26 | } 27 | } 28 | } 29 | 30 | return t[n][sum]; 31 | } -------------------------------------------------------------------------------- /Dynamic Programming/coinChange2.cpp: -------------------------------------------------------------------------------- 1 | // Input - int coin[], int n(size of coin array), int sum 2 | // Output - Min. no of coins required to make that sum 3 | 4 | int coinChange(int coin[], int sum, int n) { 5 | int t[n+1][sum+1]; 6 | 7 | // Initialization of first row and first coloumn 8 | 9 | for(int i = 0; i < n+1; i++) { 10 | for(int j = 0; j < sum+1; j++) { 11 | if(j == 0) { 12 | t[i][j] = 0; 13 | } 14 | if(i == 0) { 15 | t[i][j] = INT_MAX - 1; 16 | } 17 | } 18 | } 19 | 20 | // Initialization of second row 21 | 22 | for(int j = 1; j < sum+1; j++) { 23 | if(j % coin[0] != 0) { 24 | t[1][j] = INT_MAX - 1; 25 | } 26 | else { 27 | t[1][j] = j / coin[0]; 28 | } 29 | } 30 | 31 | for(int i = 2; i < n+1; i++) { 32 | for(int j = 1; j < sum+1; j++) { 33 | if(coin[i-1] <= j) { 34 | t[i][j] = min(1 + t[i][j-coin[i-1]], t[i-1][j]); 35 | } 36 | else { 37 | t[i][j] = t[i-1][j]; 38 | } 39 | } 40 | } 41 | 42 | if(t[n][sum] != INT_MAX - 1) { 43 | return t[n][sum]; 44 | } 45 | else { 46 | return -1; 47 | } 48 | } -------------------------------------------------------------------------------- /Dynamic Programming/countOfSubsetSum.cpp: -------------------------------------------------------------------------------- 1 | // Input - Array, Sum, Size of array 2 | // Output - No. of subsets of given sum 3 | 4 | int countOfSubsetSum(int arr[], int sum, int n) { 5 | int t[n+1][sum+1]; 6 | 7 | for(int i = 0; i < n+1; i++) { 8 | for(int j = 0; j < sum+1; j++) { 9 | if(i == 0) { 10 | t[i][j] = 0; 11 | } 12 | if(j == 0) { 13 | t[i][j] = 1; 14 | } 15 | } 16 | } 17 | 18 | for(int i = 1; i < n+1; i++) { 19 | for(int j = 1; j < sum+1; j++) { 20 | if(arr[i-1] <= j) { 21 | t[i][j] = t[i-1][j-arr[i-1]] + t[i-1][j]; 22 | } 23 | else { 24 | t[i][j] = t[i-1][j]; 25 | } 26 | } 27 | } 28 | 29 | return t[n][sum]; 30 | } -------------------------------------------------------------------------------- /Dynamic Programming/countSubsetsOfGivenDiff.cpp: -------------------------------------------------------------------------------- 1 | // Input - int arr[], int n, int diff(Difference) 2 | // Output - No. of subsets whose difference of sums is equal to given difference (diff) 3 | 4 | // s1 - s2 = diff; 5 | // s1 + s2 = sum; 6 | // 2s1 = diff + sum; 7 | // s1 = (diff + sum) / 2; 8 | 9 | int countSubsetsOfGivenDiff(int arr[], int diff, int n) { 10 | int sum = 0; 11 | 12 | for(int i = 0; i < n; i++) { 13 | sum += arr[i]; 14 | } 15 | 16 | s1 = (diff + sum) / 2; 17 | 18 | int t[n+1][s1+1]; 19 | 20 | for(int i = 0; i < n+1; i++) { 21 | for(int j = 0; j < s1+1; j++) { 22 | if(i == 0) { 23 | t[i][j] = 0; 24 | } 25 | if(j == 0) { 26 | t[i][j] = 1; 27 | } 28 | } 29 | } 30 | 31 | for(int i = 1; i < n+1; i++) { 32 | for(int j = 1; j < s1+1; j++) { 33 | if(arr[i-1] <= j) { 34 | t[i][j] = t[i-1][j-arr[i-1]] + t[i-1][j]; 35 | } 36 | else { 37 | t[i][j] = t[i-1][j]; 38 | } 39 | } 40 | } 41 | 42 | return t[n][s1]; 43 | } -------------------------------------------------------------------------------- /Dynamic Programming/equalSumPartition.cpp: -------------------------------------------------------------------------------- 1 | // Input - Array (int arr[]), Size of array (int n) 2 | // Output - True/False (If array can be divided into partitions of equal sum) 3 | 4 | bool subsetSum(int arr[], int sum, int n) { 5 | int t[n+1][sum+1]; 6 | 7 | // Initialization 8 | 9 | for(int i = 0; i < n+1; i++) { 10 | for(int j = 0; j < sum + 1; j++) { 11 | if(i == 0) { 12 | t[i][j] = false; 13 | } 14 | if(j == 0) { 15 | t[i][j] = true; 16 | } 17 | } 18 | } 19 | 20 | for(int i = 1; i < n+1; i++) { 21 | for(int j = 1; j < sum+1; j++) { 22 | if(arr[i-1] <= j) { 23 | t[i][j] = t[i-1][j-arr[i-1]] || t[i-1][j]; 24 | } 25 | else { 26 | t[i][j] = t[i-1][j]; 27 | } 28 | } 29 | } 30 | 31 | return t[n][sum]; 32 | } 33 | 34 | bool equalSumPartition(int arr[], int n) { 35 | int sum = 0; 36 | for(int i = 0; i < n; i++) { 37 | sum += arr[i]; 38 | } 39 | if(sum % 2 != 0) { 40 | return false; 41 | } 42 | else { 43 | return subsetSum(arr, sum / 2, n); 44 | } 45 | } -------------------------------------------------------------------------------- /Dynamic Programming/longestCommonSubsequence.cpp: -------------------------------------------------------------------------------- 1 | // Input - string X, string Y, int n, int m (n, m are size of strings) 2 | // Output - Length of longest common subsequence 3 | 4 | // Recursive approach 5 | 6 | int lcs(string X, string Y, int n, int m) { 7 | if(n == 0 || m == 0) { 8 | return 0; 9 | } 10 | if(X[n-1] == Y[m-1]) { 11 | return 1 + lcs(X, Y, n-1, m-1); 12 | } 13 | else { 14 | return max(lcs(X, Y, n, m-1), lcs(X, Y, n-1, m)); 15 | } 16 | } 17 | 18 | // Memoization 19 | 20 | int t[n+1][m+1]; 21 | memset(t, -1, sizeof(t)); 22 | int lcs(string X, string Y, int m, int n) { 23 | if(n == 0 || m == 0) { 24 | return 0; 25 | } 26 | if(t[m][n] != -1) { 27 | return t[m][n]; 28 | } 29 | if(X[m-1] == Y[n-1]) { 30 | return t[m][n] = 1 + lcs(X, Y, m-1, n-1); 31 | } 32 | else { 33 | return t[m][n] = max(lcs(X, Y, m, n-1), lcs(X, Y, m-1, n)); 34 | } 35 | } 36 | 37 | // Tabulation 38 | 39 | int lcs(string X, string Y, int m, int n) { 40 | int t[m+1][n+1]; 41 | 42 | for(int i = 0; i < m+1; i++) { 43 | for(int j = 0; j < n+1; j++) { 44 | if(i == 0 || j == 0) { 45 | t[i][j] = 0; 46 | } 47 | } 48 | } 49 | 50 | for(int i = 1; i < m+1; i++) { 51 | for(int j = 1; j < n+1; j++) { 52 | if(X[i-1] == Y[j-1]) { 53 | t[i][j] = 1 + t[i-1][j-1]; 54 | } 55 | else { 56 | t[i][j] = max(t[i][j-1], t[i-1][j]); 57 | } 58 | } 59 | } 60 | 61 | return t[m][n]; 62 | } 63 | 64 | // Print longest common subsequence 65 | 66 | void printLcs(string X, string Y, int m, int n) { 67 | int t[m+1][n+1]; 68 | 69 | for(int i = 0; i < m+1; i++) { 70 | for(int j = 0; j < n+1; j++) { 71 | if(i == 0 || j == 0) { 72 | t[i][j] = 0; 73 | } 74 | } 75 | } 76 | 77 | for(int i = 1; i < m+1; i++) { 78 | for(int j = 1; j < n+1; j++) { 79 | if(X[i-1] == Y[j-1]) { 80 | t[i][j] = 1 + t[i-1][j-1]; 81 | } 82 | else { 83 | t[i][j] = max(t[i][j-1], t[i-1][j]); 84 | } 85 | } 86 | } 87 | 88 | int i = m, j = n; 89 | string s = ""; 90 | 91 | while(i > 0 && j > 0) { 92 | if(X[i-1] == Y[j-1]) { 93 | s.push_back(X[i-1]); 94 | i--; 95 | j--; 96 | } 97 | else { 98 | if(t[i][j-1] > t[i-1][j]) { 99 | j--; 100 | } 101 | else { 102 | i--; 103 | } 104 | } 105 | } 106 | 107 | reverse(s.begin(), s.end()); 108 | 109 | cout<= j) { 8 | return 0; 9 | } 10 | 11 | int minimum = INT_MAX; 12 | 13 | for(int k = i; k <= j-1; k++) { 14 | int tempans = solve(arr, i, k) + solve(arr, k+1, j) + arr[i-1]*arr[k]*arr[j]; 15 | if(tempans < minimum) { 16 | minimum = tempans; 17 | } 18 | } 19 | 20 | return minimum; 21 | } 22 | 23 | int main() { 24 | solve(arr, 1, n-1); 25 | } 26 | 27 | // Memoized 28 | 29 | int t[1001][1001]; // From constraints 30 | 31 | memset(t, -1, sizeof(t)); 32 | 33 | int solve(int arr[], int i, int j) { 34 | if(i >= j) { 35 | return 0; 36 | } 37 | 38 | int minimum = INT_MAX; 39 | 40 | if(t[i][j] != -1) { 41 | return t[i][j]; 42 | } 43 | 44 | for(int k = i; k <= j-1; k++) { 45 | int tempans = solve(arr, i, k) + solve(arr, k+1, j) + arr[i-1]*arr[k]*arr[j]; 46 | if(tempans < minimum) { 47 | minimum = tempans; 48 | } 49 | } 50 | 51 | return t[i][j] = minimum; 52 | } 53 | 54 | int main() { 55 | solve(arr, 1, n-1); 56 | } -------------------------------------------------------------------------------- /Dynamic Programming/minDelForPalindromicString.cpp: -------------------------------------------------------------------------------- 1 | // Minimum deletion from a string to get a palindromic string 2 | // Minimum insertion in a string to make it a palindromic string 3 | 4 | int lcs(string X, string Y) { 5 | int t[X.size()+1][Y.size()+1]; 6 | 7 | for(int i = 0; i < X.size()+1; i++) { 8 | for(int j = 0; j < Y.size()+1; j++) { 9 | if(i == 0 || j == 0) { 10 | t[i][j] = 0; 11 | } 12 | } 13 | } 14 | 15 | for (int i = 1; i < X.size()+1; i++) 16 | { 17 | for (int j = 1; j < Y.size()+1; j++) 18 | { 19 | if(X[i-1] == Y[j-1]) { 20 | t[i][j] = 1 + t[i-1][j-1]; 21 | } 22 | else { 23 | t[i][j] = max(t[i][j-1], t[i-1][j]); 24 | } 25 | } 26 | } 27 | 28 | return t[X.size()][Y.size()]; 29 | } 30 | 31 | int minDelforPalindromicString(string X) { 32 | string Y = X; 33 | reverse(Y.begin(), Y.end()); 34 | return X.length() - lcs(X, Y); 35 | } -------------------------------------------------------------------------------- /Dynamic Programming/minInsDelforAToB.cpp: -------------------------------------------------------------------------------- 1 | // Minimum insertion and deletion to convert string A to string B 2 | 3 | int lcs(string X, string Y, int m, int n) { 4 | int t[m+1][n+1]; 5 | 6 | for(int i = 0; i < m+1; i++) { 7 | for(int j = 0; j < n+1; j++) { 8 | if(i == 0 || j == 0) { 9 | t[i][j] = 0; 10 | } 11 | } 12 | } 13 | 14 | for(int i = 1; i < m+1; i++) { 15 | for(int j = 1; j < n+1; j++) { 16 | if(X[i-1] == Y[j-1]) { 17 | t[i][j] = 1 + t[i-1][j-1]; 18 | } 19 | else { 20 | t[i][j] = max(t[i][j-1], t[i-1][j]); 21 | } 22 | } 23 | } 24 | 25 | return t[m][n]; 26 | } 27 | 28 | void minInsertAndDelete(string A, string B, int m, int n) { 29 | cout<<"Deletion "< 5 | using namespace std; 6 | 7 | void subsetSum(int arr[], int sum, int n) { 8 | int t[n+1][sum+1]; 9 | 10 | for(int i = 0; i < n+1; i++) { 11 | for(int j = 0; j < sum+1; j++) { 12 | if(i == 0) { 13 | t[i][j] = false; 14 | } 15 | if(j == 0) { 16 | t[i][j] = true; 17 | } 18 | } 19 | } 20 | 21 | for(int i = 1; i < n+1; i++) { 22 | for(int j = 1; j < sum+1; j++) { 23 | if(arr[i-1] <= j) { 24 | t[i][j] = t[i-1][j-arr[i-1]] || t[i-1][j]; 25 | } 26 | else { 27 | t[i][j] = t[i-1][j]; 28 | } 29 | } 30 | } 31 | } 32 | 33 | int minSubsetSumDiff(int arr[], int n) { 34 | int range = 0; 35 | vector v; 36 | for(int i = 0; i < n; i++) { 37 | range += arr[i]; 38 | } 39 | subsetSum(arr, range, n); 40 | for(int i = 0; i <= range/2; i++) { 41 | if(t[n][i] == true) { 42 | v.push_back(i); 43 | } 44 | } 45 | return range - 2*v[v.size()-1]; 46 | } -------------------------------------------------------------------------------- /Dynamic Programming/palindromePartitioning.cpp: -------------------------------------------------------------------------------- 1 | // Input - string s 2 | // Output - Minimum no of partition required such that every substring of the partition is a palindrome 3 | 4 | // Recursive 5 | 6 | bool isPalindrome(string s, int i, int j) { 7 | for(int a = i, b = j; a < b; a++, b--) { 8 | if(s[a] != s[b]) { 9 | return false; 10 | } 11 | } 12 | 13 | return true; 14 | } 15 | 16 | int palindromePartitioning(string s, int i, int j) { 17 | if(i >= j) { 18 | return 0; 19 | } 20 | if(isPalindrome(s, i, j)) { 21 | return 0; 22 | } 23 | int ans = INT_MAX; 24 | for(int k = i; k <= j-1; k++) { 25 | int temp = 1 + palindromePartitioning(s, i, k) + palindromePartitioning(s, k+1, j); 26 | if(temp < ans) { 27 | ans = temp; 28 | } 29 | } 30 | return ans; 31 | } 32 | 33 | int main() { 34 | string s; 35 | cin >> s; 36 | return palindromePartitioning(s, 0, s.size()-1); 37 | } 38 | 39 | // Memoization with Optimization 40 | 41 | class Solution { 42 | public: 43 | bool isPalindrome(string s, int i, int j) { 44 | for(int a = i, b = j; a < b; a++, b--) { 45 | if(s[a] != s[b]) { 46 | return false; 47 | } 48 | } 49 | 50 | return true; 51 | } 52 | int t[2001][2001]; 53 | int helper(string s, int i, int j) { 54 | if(i >= j) { 55 | return 0; 56 | } 57 | if(t[i][j] != -1) { 58 | return t[i][j]; 59 | } 60 | if(isPalindrome(s, i, j)) { 61 | return 0; 62 | } 63 | int ans = INT_MAX; 64 | for(int k=i; k <= j-1; k++) { 65 | int left, right; 66 | if(t[i][k] != -1) { 67 | left = t[i][k]; 68 | } 69 | else { 70 | left = helper(s, i, k); 71 | t[i][k] = left; 72 | } 73 | if(t[k+1][j] != -1) { 74 | right = t[k+1][j]; 75 | } 76 | else { 77 | right = helper(s, k+1, j); 78 | t[k+1][j] = right; 79 | } 80 | int temp = 1 + left + right; 81 | if(temp < ans) { 82 | ans = temp; 83 | } 84 | } 85 | 86 | return t[i][j] = ans; 87 | } 88 | int minCut(string s) { 89 | memset(t, -1, sizeof(t)); 90 | return helper(s, 0, s.size()-1); 91 | } 92 | }; -------------------------------------------------------------------------------- /Dynamic Programming/rodCutting.cpp: -------------------------------------------------------------------------------- 1 | // Variation of unbounded knapsack problem 2 | 3 | // Input - int length[], int price[], int n (length of rod) 4 | // Output - Max profit by cutting rod 5 | // int t[size+1][length+1] where size = size of array and length = length of rod 6 | 7 | int rodCutting(int length[], int price[], int n) { 8 | int t[n+1][n+1]; 9 | 10 | for(int i = 0; i < n+1; i++) { 11 | for(int j = 0; j < n+1; j++) { 12 | if(i == 0 || j == 0) { 13 | t[i][j] = 0; 14 | } 15 | } 16 | } 17 | 18 | for(int i = 1; i < n+1; i++) { 19 | for(int j = 1; j < n+1; j++) { 20 | if(length[i-1] <= j) { 21 | t[i][j] = max(price[i-1] + t[i][j-length[i-1]], t[i-1][j]); 22 | } 23 | else { 24 | t[i][j] = t[i-1][j]; 25 | } 26 | } 27 | } 28 | 29 | return t[n][n]; 30 | } -------------------------------------------------------------------------------- /Dynamic Programming/scrambledString.cpp: -------------------------------------------------------------------------------- 1 | https://leetcode.com/problems/scramble-string 2 | 3 | // Recursion with Memoization 4 | 5 | class Solution { 6 | public: 7 | unordered_map mp; 8 | bool solve(string a, string b) { 9 | if(a == b) { 10 | return true; 11 | } 12 | if(a.length() <= 1) { 13 | return false; 14 | } 15 | string key = a; 16 | key.push_back(' '); 17 | key.append(b); 18 | if(mp.find(key) != mp.end()) { 19 | return mp[key]; 20 | } 21 | int n = a.length(); 22 | bool flag = false; 23 | for(int i = 1; i <= n-1; i++) { 24 | if((solve(a.substr(0, i), b.substr(n-i, i)) && solve(a.substr(i, n-i), b.substr(0, n-i))) || 25 | (solve(a.substr(0, i), b.substr(0, i)) && solve(a.substr(i, n-i), b.substr(i, n-i)))) { 26 | flag = true; 27 | break; 28 | } 29 | } 30 | 31 | return mp[key] = flag; 32 | } 33 | 34 | bool isScramble(string s1, string s2) { 35 | if(s1.length() != s2.length()) { 36 | return false; 37 | } 38 | if(s1.empty() && s2.empty()) { 39 | return true; 40 | } 41 | return solve(s1, s2); 42 | } 43 | }; -------------------------------------------------------------------------------- /Dynamic Programming/seqPatternMatching.cpp: -------------------------------------------------------------------------------- 1 | // Input - string a, string b 2 | // Output - Return true/false if a is a subsequence of b 3 | 4 | int lcs(string X, string Y) { 5 | int m = X.size(); 6 | int n = Y.size(); 7 | int t[m+1][n+1]; 8 | 9 | for(int i = 0; i < m+1; i++) { 10 | for(int j = 0; j < n+1; j++) { 11 | if(i == 0 || j == 0) { 12 | t[i][j] = 0; 13 | } 14 | } 15 | } 16 | 17 | for(int i = 1; i < m+1; i++) { 18 | for(int j = 1; j < n+1; j++) { 19 | if(X[i-1] == Y[j-1]) { 20 | t[i][j] = 1 + t[i-1][j-1]; 21 | } 22 | else { 23 | t[i][j] = max(t[i][j-1], t[i-1][j]); 24 | } 25 | } 26 | } 27 | 28 | return t[m][n]; 29 | } 30 | 31 | bool seqPatternMatching(string a, string b) { 32 | if(lcs(a, b) == a.size()) { 33 | return true; 34 | } 35 | else { 36 | return false; 37 | } 38 | } -------------------------------------------------------------------------------- /Dynamic Programming/shortestCommonSupersequence.cpp: -------------------------------------------------------------------------------- 1 | // Length of shortest common supersequence 2 | 3 | int lcs(string X, string Y, int m, int n) { 4 | int t[m+1][n+1]; 5 | 6 | for(int i = 0; i < m+1; i++) { 7 | for(int j = 0; j < n+1; j++) { 8 | if(i == 0 || j == 0) { 9 | t[i][j] = 0; 10 | } 11 | } 12 | } 13 | 14 | for(int i = 1; i < m+1; i++) { 15 | for(int j = 1; j < n+1; j++) { 16 | if(X[i-1] == Y[j-1]) { 17 | t[i][j] = 1 + t[i-1][j-1]; 18 | } 19 | else { 20 | t[i][j] = max(t[i][j-1], t[i-1][j]); 21 | } 22 | } 23 | } 24 | 25 | return t[m][n]; 26 | } 27 | 28 | int shortestCommonSuperSequence(string X, string Y, int m, int n) { 29 | return m + n - lcs(X, Y, m, n); 30 | } 31 | 32 | // Print shortest common supersequence 33 | // Similar to printing longest common subsequence 34 | 35 | class Solution { 36 | public: 37 | string shortestCommonSupersequence(string str1, string str2) { 38 | int t[str1.size()+1][str2.size()+1]; 39 | 40 | for(int i = 0; i < str1.size(); i++) { 41 | for(int j = 0; j < str2.size()+1; j++) { 42 | if(i == 0 || j == 0) { 43 | t[i][j] = 0; 44 | } 45 | } 46 | } 47 | 48 | for(int i = 1; i < str1.size()+1; i++) { 49 | for(int j = 1; j < str2.size()+1; j++) { 50 | if(str1[i-1] == str2[j-1]) { 51 | t[i][j] = 1 + t[i-1][j-1]; 52 | } 53 | else { 54 | t[i][j] = max(t[i][j-1], t[i-1][j]); 55 | } 56 | } 57 | } 58 | 59 | int i = str1.size(), j = str2.size(); 60 | 61 | string s = ""; 62 | 63 | while(i > 0 && j > 0) { 64 | if(str1[i-1] == str2[j-1]) { 65 | s.push_back(str1[i-1]); 66 | i--; 67 | j--; 68 | } 69 | else { 70 | if(t[i][j-1] > t[i-1][j]) { 71 | s.push_back(str2[j-1]); 72 | j--; 73 | } 74 | else { 75 | s.push_back(str1[i-1]); 76 | i--; 77 | } 78 | } 79 | } 80 | 81 | while(i > 0) { 82 | s.push_back(str1[i-1]); 83 | i--; 84 | } 85 | 86 | while(j > 0) { 87 | s.push_back(str2[j-1]); 88 | j--; 89 | } 90 | 91 | reverse(s.begin(), s.end()); 92 | 93 | return s; 94 | } 95 | }; -------------------------------------------------------------------------------- /Dynamic Programming/subsetSum.cpp: -------------------------------------------------------------------------------- 1 | // Input - int arr[], int sum, int n (size of arr) 2 | // Output - T/F (subset whose sum is equal to given sum) 3 | 4 | // Similar to 01knapsack as choice is there to choose elements from array 5 | 6 | bool subsetSum(int arr[], int sum, int n) { 7 | int t[n+1][sum+1]; 8 | 9 | // Initialization 10 | 11 | for(int i = 0; i < n + 1; i++) { 12 | for(int j = 0; j < sum + 1; j++) { 13 | if(i == 0) { 14 | t[i][j] = false; 15 | } 16 | if(j == 0) { 17 | t[i][j] = true; 18 | } 19 | } 20 | } 21 | 22 | for(int i = 1; i < n + 1; i++) { 23 | for(int j = 1; j < sum + 1; j++) { 24 | if(arr[i - 1] <= j) { 25 | t[i][j] = t[i - 1][j - arr[i - 1]] || t[i - 1][j]; 26 | } 27 | else { 28 | t[i][j] = t[i - 1][j]; 29 | } 30 | } 31 | } 32 | 33 | return t[n][sum]; 34 | } -------------------------------------------------------------------------------- /Dynamic Programming/unboundedKnapsack.cpp: -------------------------------------------------------------------------------- 1 | // 1 item can be taken multiple times 2 | // Similar to 0-1 knapsack with some variations 3 | 4 | int unboundedKnapsack(int val[], int wt[], int w, int n) { 5 | int t[n+1][w+1]; 6 | 7 | for(int i = 0; i < n+1; i++) { 8 | for(int j = 0; j < w+1; j++) { 9 | if(i == 0 || j == 0) { 10 | t[i][j] = 0; 11 | } 12 | } 13 | } 14 | 15 | for(int i = 1; i < n+1; i++) { 16 | for(int j = 1; j < w+1; j++) { 17 | if(wt[i-1] <= j) { 18 | t[i][j] = max(val[i-1] + t[i][j-wt[i-1]], t[i-1][j]); 19 | } 20 | else { 21 | t[i][j] = t[i-1][j]; 22 | } 23 | } 24 | } 25 | 26 | return t[n][w]; 27 | } -------------------------------------------------------------------------------- /Linked Lists/compare.cpp: -------------------------------------------------------------------------------- 1 | // https://www.hackerrank.com/challenges/compare-two-linked-lists/problem 2 | 3 | bool compare_lists(SinglyLinkedListNode* head1, SinglyLinkedListNode* head2) { 4 | while(head1 != NULL && head2 != NULL) { 5 | if(head1->data != head2->data) { 6 | return false; 7 | } 8 | head1 = head1->next; 9 | head2 = head2->next; 10 | } 11 | if(head1 == NULL && head2 == NULL) { 12 | return true; 13 | } 14 | else { 15 | return false; 16 | } 17 | } -------------------------------------------------------------------------------- /Linked Lists/cycleDetection.cpp: -------------------------------------------------------------------------------- 1 | // https://www.hackerrank.com/challenges/detect-whether-a-linked-list-contains-a-cycle/problem 2 | 3 | // Floyd's cycle finding algorithm 4 | 5 | bool has_cycle(SinglyLinkedListNode* head) { 6 | if(head == NULL) { 7 | return 0; 8 | } 9 | SinglyLinkedListNode* slow = head; 10 | SinglyLinkedListNode* fast = head; 11 | while(fast != NULL && fast->next != NULL) { 12 | slow = slow->next; 13 | fast = fast->next->next; 14 | if(slow == fast) { 15 | return 1; 16 | } 17 | } 18 | return 0; 19 | } 20 | 21 | // Hashing O(n) 22 | 23 | bool detectLoop(SinglyLinkedListNode* h) { 24 | unordered_set s; 25 | while(h != NULL) { 26 | if(s.find(h) != s.end()) { 27 | return 1; 28 | } 29 | s.insert(h); 30 | h = h->next; 31 | } 32 | return 0; 33 | } -------------------------------------------------------------------------------- /Linked Lists/delDuplFrmSortedList.cpp: -------------------------------------------------------------------------------- 1 | // https://www.hackerrank.com/challenges/delete-duplicate-value-nodes-from-a-sorted-linked-list/problem 2 | 3 | SinglyLinkedListNode* removeDuplicates(SinglyLinkedListNode* head) { 4 | if(head == NULL || head->next == NULL) { 5 | return head; 6 | } 7 | else 8 | { 9 | SinglyLinkedListNode* current = head; 10 | while(current->next != NULL) 11 | { 12 | if(current->data != current->next->data) 13 | current=current->next; 14 | else 15 | { 16 | current->next=current->next->next; 17 | } 18 | } 19 | return head; 20 | } 21 | } -------------------------------------------------------------------------------- /Linked Lists/deleteNode.cpp: -------------------------------------------------------------------------------- 1 | // https://www.hackerrank.com/challenges/delete-a-node-from-a-linked-list/problem 2 | 3 | class SinglyLinkedListNode { 4 | public: 5 | int data; 6 | SinglyLinkedListNode* next; 7 | 8 | SinglyLinkedListNode(int node_data) { 9 | this->data = node_data; 10 | this->next = nullptr; 11 | } 12 | }; 13 | 14 | SinglyLinkedListNode* deleteNode(SinglyLinkedListNode* head, int position) { 15 | if(position != 0) { 16 | SinglyLinkedListNode* t = head; 17 | for(int i = 0; i < position - 1; i++) { 18 | head = head->next; 19 | } 20 | head->next = head->next->next; 21 | return t; 22 | } 23 | head = head->next; 24 | return head; 25 | } -------------------------------------------------------------------------------- /Linked Lists/getNode.cpp: -------------------------------------------------------------------------------- 1 | // https://www.hackerrank.com/challenges/get-the-value-of-the-node-at-a-specific-position-from-the-tail/problem 2 | 3 | int getNode(SinglyLinkedListNode* head, int positionFromTail) { 4 | SinglyLinkedListNode* t = head; 5 | int count = 0; 6 | while(head != NULL) { 7 | count++; 8 | head = head->next; 9 | } 10 | head = t; 11 | int index = count - positionFromTail; 12 | count = 0; 13 | while(head != NULL) { 14 | count++; 15 | if(index == count) { 16 | return head->data; 17 | } 18 | head = head->next; 19 | } 20 | return 0; 21 | } -------------------------------------------------------------------------------- /Linked Lists/insertInSortedDoublyList.cpp: -------------------------------------------------------------------------------- 1 | // https://www.hackerrank.com/challenges/insert-a-node-into-a-sorted-doubly-linked-list/problem 2 | 3 | class DoublyLinkedListNode { 4 | public: 5 | int data; 6 | DoublyLinkedListNode* prev; 7 | DoublyLinkedListNode* next; 8 | 9 | DoublyLinkedListNode(int node_data) { 10 | this->data = node_data; 11 | this->prev = nullptr; 12 | this->next = nullptr; 13 | } 14 | }; 15 | 16 | DoublyLinkedListNode* sortedInsert(DoublyLinkedListNode* head, int data) { 17 | DoublyLinkedListNode* temp = new DoublyLinkedListNode(data); 18 | DoublyLinkedListNode* t = head; 19 | if(head->data >= data) { 20 | temp->next = head; 21 | head->prev = temp; 22 | t = temp; 23 | return t; 24 | } 25 | while(head != NULL) { 26 | if(head->data >= data) { 27 | head->prev->next = temp; 28 | temp->prev = head->prev; 29 | head->prev = temp; 30 | temp->next = head; 31 | return t; 32 | } 33 | if(head->next == NULL) { 34 | head->next = temp; 35 | temp->prev = head; 36 | return t; 37 | } 38 | head = head->next; 39 | } 40 | return t; 41 | } -------------------------------------------------------------------------------- /Linked Lists/insertNodeAtHead.cpp: -------------------------------------------------------------------------------- 1 | // https://www.hackerrank.com/challenges/insert-a-node-at-the-head-of-a-linked-list/problem 2 | 3 | class SinglyLinkedListNode { 4 | public: 5 | int data; 6 | SinglyLinkedListNode *next; 7 | 8 | SinglyLinkedListNode(int node_data) { 9 | this->data = node_data; 10 | this->next = nullptr; 11 | } 12 | }; 13 | 14 | SinglyLinkedListNode* insertNodeAtHead(SinglyLinkedListNode* llist, int data) { 15 | SinglyLinkedListNode* temp = new SinglyLinkedListNode(data); 16 | temp->next = llist; 17 | return temp; 18 | } -------------------------------------------------------------------------------- /Linked Lists/insertNodeAtPosition.cpp: -------------------------------------------------------------------------------- 1 | // https://www.hackerrank.com/challenges/insert-a-node-at-a-specific-position-in-a-linked-list/problem 2 | 3 | class SinglyLinkedListNode { 4 | public: 5 | int data; 6 | SinglyLinkedListNode *next; 7 | 8 | SinglyLinkedListNode(int node_data) { 9 | this->data = node_data; 10 | this->next = nullptr; 11 | } 12 | }; 13 | 14 | SinglyLinkedListNode* insertNodeAtPosition(SinglyLinkedListNode* head, int data, int position) { 15 | SinglyLinkedListNode* temp = new SinglyLinkedListNode(data); 16 | SinglyLinkedListNode* t = head; 17 | for(int i = 0; i < position - 1; i++) { 18 | head = head->next; 19 | } 20 | temp->next = head->next; 21 | head->next = temp; 22 | return t; 23 | } -------------------------------------------------------------------------------- /Linked Lists/insertNodeAtTail.cpp: -------------------------------------------------------------------------------- 1 | // https://www.hackerrank.com/challenges/insert-a-node-at-the-tail-of-a-linked-list/problem 2 | 3 | SinglyLinkedListNode* insertNodeAtTail(SinglyLinkedListNode* head, int data) { 4 | SinglyLinkedListNode* t = head; 5 | if(head != NULL) { 6 | while(head->next != NULL) { 7 | head = head->next; 8 | } 9 | SinglyLinkedListNode* temp = new SinglyLinkedListNode(data); 10 | head->next = temp; 11 | temp->next = NULL; 12 | return t; 13 | } 14 | else { 15 | SinglyLinkedListNode* temp = new SinglyLinkedListNode(data); 16 | head = temp; 17 | temp->next = NULL; 18 | return head; 19 | } 20 | } -------------------------------------------------------------------------------- /Linked Lists/mergePointOf2Lists.cpp: -------------------------------------------------------------------------------- 1 | // https://www.hackerrank.com/challenges/find-the-merge-point-of-two-joined-linked-lists/problem 2 | 3 | int findMergeNode(SinglyLinkedListNode* head1, SinglyLinkedListNode* head2) { 4 | SinglyLinkedListNode* t = head2; 5 | while(head1 != NULL) { 6 | head2 = t; 7 | while(head2 != NULL) { 8 | if(head1 == head2) { 9 | return head1->data; 10 | } 11 | head2 = head2->next; 12 | } 13 | head1 = head1->next; 14 | } 15 | return 0; 16 | } -------------------------------------------------------------------------------- /Linked Lists/mergeSortedLists.cpp: -------------------------------------------------------------------------------- 1 | // https://www.hackerrank.com/challenges/merge-two-sorted-linked-lists/problem 2 | 3 | SinglyLinkedListNode* mergeLists(SinglyLinkedListNode* head1, SinglyLinkedListNode* head2) { 4 | SinglyLinkedListNode* head, *t; 5 | if(head1->data <= head2->data) { 6 | t = head1; 7 | head = head1; 8 | head1 = head1->next; 9 | } 10 | else { 11 | t = head2; 12 | head = head2; 13 | head2 = head2->next; 14 | } 15 | while(head1 != NULL && head2 != NULL) { 16 | if(head1->data <= head2->data) { 17 | head->next = head1; 18 | head = head->next; 19 | head1 = head1->next; 20 | } 21 | else { 22 | head->next = head2; 23 | head = head->next; 24 | head2 = head2->next; 25 | } 26 | } 27 | while(head1 != NULL) { 28 | head->next = head1; 29 | head = head->next; 30 | head1 = head1->next; 31 | } 32 | while(head2 != NULL) { 33 | head->next = head2; 34 | head = head->next; 35 | head2 = head2->next; 36 | } 37 | return t; 38 | } -------------------------------------------------------------------------------- /Linked Lists/reverseDoubly.cpp: -------------------------------------------------------------------------------- 1 | // https://www.hackerrank.com/challenges/reverse-a-doubly-linked-list/problem 2 | 3 | DoublyLinkedListNode* reverse(DoublyLinkedListNode* head) { 4 | DoublyLinkedListNode* current = head; 5 | DoublyLinkedListNode* prev = NULL, *next = NULL; 6 | while(current != NULL) { 7 | next = current->next; 8 | current->next = prev; 9 | current->prev = next; 10 | prev = current; 11 | current = next; 12 | } 13 | head = prev; 14 | return head; 15 | } -------------------------------------------------------------------------------- /Linked Lists/reversePrint.cpp: -------------------------------------------------------------------------------- 1 | // https://www.hackerrank.com/challenges/print-the-elements-of-a-linked-list-in-reverse/problem 2 | 3 | void reversePrint(SinglyLinkedListNode* head) { 4 | vector temp; 5 | while(head != NULL) { 6 | temp.insert(temp.begin(), head->data); 7 | head = head->next; 8 | } 9 | for(int i = 0; i < temp.size(); i++) { 10 | cout<next; 8 | current->next = prev; 9 | prev = current; 10 | current = next; 11 | } 12 | head = prev; 13 | return head; 14 | } -------------------------------------------------------------------------------- /Linked Lists/traverseList.cpp: -------------------------------------------------------------------------------- 1 | // https://www.hackerrank.com/challenges/print-the-elements-of-a-linked-list/problem 2 | 3 | // Arrow operator 4 | // pointer_name -> variable_name 5 | 6 | void printLinkedList(SinglyLinkedListNode* head) { 7 | while(head != NULL) { 8 | cout<data<next; 10 | } 11 | } -------------------------------------------------------------------------------- /Math/allFactors.cpp: -------------------------------------------------------------------------------- 1 | // All factors of a no in O(sqrt(n)) 2 | 3 | vector Solution::allFactors(int A) { 4 | vector ret; 5 | for(int i=1;i=1;i--){ 10 | if(A%i==0) 11 | ret.push_back(A/i); 12 | } 13 | return ret; 14 | } 15 | -------------------------------------------------------------------------------- /Math/excelColNo.cpp: -------------------------------------------------------------------------------- 1 | // https://www.interviewbit.com/problems/excel-column-number/ 2 | 3 | int Solution::titleToNumber(string A) { 4 | unordered_map m; 5 | int count = 1; 6 | int solution = 0; 7 | for(char i = 'A'; i <= 'Z'; i++) { 8 | m.insert({i, count}); 9 | count++; 10 | } 11 | for(int i = A.size() - 1,j = 0; i >= 0; i--) { 12 | solution += m[A[i]] * pow(26, j); 13 | j++; 14 | } 15 | return solution; 16 | } 17 | -------------------------------------------------------------------------------- /Math/excelColTitle.cpp: -------------------------------------------------------------------------------- 1 | // https://www.interviewbit.com/problems/excel-column-title/ 2 | 3 | string Solution::convertToTitle(int A) { 4 | char str[50]; 5 | int i = 0; 6 | 7 | while (A > 0) { 8 | int rem = A % 26; 9 | 10 | // If remainder is 0, then a 'Z' must be there in output 11 | if (rem == 0) { 12 | str[i++] = 'Z'; 13 | A = (A / 26) - 1; 14 | } 15 | else // If remainder is non-zero 16 | { 17 | str[i++] = (rem - 1) + 'A'; 18 | A = A / 26; 19 | } 20 | } 21 | str[i] = '\0'; 22 | 23 | reverse(str, str + strlen(str)); 24 | return str; 25 | } 26 | -------------------------------------------------------------------------------- /Math/gcd.cpp: -------------------------------------------------------------------------------- 1 | // https://www.interviewbit.com/problems/greatest-common-divisor/ 2 | 3 | // GCD of two numbers doesn’t change if smaller number is subtracted from a bigger number. 4 | 5 | int Solution::gcd(int A, int B) { 6 | if (B == 0) 7 | return A; 8 | return gcd(B, A % B); 9 | } 10 | 11 | -------------------------------------------------------------------------------- /Math/gridUniquePath.cpp: -------------------------------------------------------------------------------- 1 | // https://www.interviewbit.com/problems/grid-unique-paths/ 2 | 3 | // We have to take m + n - 2 steps in total. You have to take (m - 1) steps 4 | // going down and (n-1) steps going right. 5 | 6 | // Let 0 denote a down step and 1 denote a right step. 7 | 8 | // We need to find out the number of strings of length m + n - 2 which 9 | // have exactly m - 1 zeroes and n - 1 ones. 10 | // So, the answer becomes Choose(m+n-2, n - 1). 11 | 12 | int Solution::uniquePaths(int A, int B) { 13 | int m = A; 14 | int n = B; 15 | int path = 1; 16 | for(int i = n; i < m+n-1; i++) { 17 | path *= i; 18 | path /= i-n+1; 19 | } 20 | return path; 21 | } 22 | -------------------------------------------------------------------------------- /Math/oddOccuringNo.cpp: -------------------------------------------------------------------------------- 1 | // https://www.geeksforgeeks.org/bitwise-operators-in-c-cpp/ 2 | 3 | // Given a set of numbers where all elements occur even number 4 | // of times except one number, find the odd occurring number 5 | 6 | int findOdd(int arr[], int n) { 7 | int res = 0, i; 8 | for(i=0; i 1) { 11 | return 1; 12 | } 13 | } 14 | return 0; 15 | } 16 | -------------------------------------------------------------------------------- /Math/rearrangeArray.cpp: -------------------------------------------------------------------------------- 1 | // https://www.interviewbit.com/problems/rearrange-array/ 2 | 3 | // An array element is needed that can store two different values at the same time. 4 | // To achieve this every element at ith index is incremented by (A[A[i]] % n)*n. 5 | // After the increment operation of first step, 6 | // every element holds both old values and new values. Old value can be obtained by 7 | // A[i]%n and a new value can be obtained by A[i]/n. 8 | 9 | // Time - O(n), Space - O(1) 10 | 11 | void Solution::arrange(vector &A) { 12 | int n = A.size(); 13 | for (int i=0; i < n; i++) 14 | A[i] += (A[A[i]]%n)*n; 15 | 16 | for (int i=0; i Solution::sieve(int A) { 8 | vector primes(A+1, 1); 9 | vector B; 10 | primes[0] = 0; 11 | primes[1] = 0; 12 | for(int i = 2; i <= sqrt(A); i++) { 13 | if(primes[i] == 1) { 14 | for(int j = 2; i*j <= A; j++) { 15 | primes[i*j] = 0; 16 | } 17 | } 18 | } 19 | for(int i =0; i <= A; i++) { 20 | if(primes[i] == 1) { 21 | B.push_back(i); 22 | } 23 | } 24 | sort(B.begin(), B.end()); 25 | return B; 26 | } 27 | -------------------------------------------------------------------------------- /Math/sortedPermutationRank.cpp: -------------------------------------------------------------------------------- 1 | // https://www.interviewbit.com/problems/sorted-permutation-rank/ 2 | 3 | // O(n^2) 4 | 5 | int mod = 1000003; 6 | 7 | int fact(int n) { 8 | return (n<=1)?1:(n*fact(n-1)) %mod; 9 | } 10 | 11 | int Solution::findRank(string A) { 12 | int rank=1; 13 | for(int i=0;iA[j])c++; 17 | } 18 | rank=(rank+(c*fact(A.size()-1-i))%mod)%mod; 19 | } 20 | return rank; 21 | } 22 | 23 | // O(n) by creating auxillary array, will not work with duplicate elements 24 | 25 | int fact(int n) 26 | { 27 | return (n <= 1) ? 1 : n * fact(n - 1); 28 | } 29 | 30 | void populateAndIncreaseCount(int* count, char* str) 31 | { 32 | int i; 33 | for (i = 0; str[i]; ++i){ 34 | ++count[str[i]]; 35 | } 36 | for (i = 1; i < 256; ++i) 37 | count[i] += count[i - 1]; 38 | } 39 | 40 | void updatecount(int* count, char ch) 41 | { 42 | int i; 43 | for (i = ch; i < 256; ++i) 44 | --count[i]; 45 | } 46 | 47 | int findRank(char* str) 48 | { 49 | int len = strlen(str); 50 | int mul = fact(len); 51 | int rank = 1, i; 52 | 53 | int count[256] = { 0 }; 54 | 55 | populateAndIncreaseCount(count, str); 56 | 57 | for (i = 0; i < len; ++i) { 58 | mul /= len - i; 59 | rank += count[str[i] - 1] * mul; 60 | updatecount(count, str[i]); 61 | } 62 | 63 | return rank; 64 | } 65 | -------------------------------------------------------------------------------- /Math/sumOfPairwiseHammingDist.cpp: -------------------------------------------------------------------------------- 1 | // https://www.interviewbit.com/problems/sum-of-pairwise-hamming-distance/ 2 | 3 | // Every pair has one element which has set bit at ith position 4 | // and second element having unset bit at ith position contributes 5 | // exactly 1 to sum, therefore total permutation count 6 | // will be count*(n-count) multiplied by 2 7 | 8 | int Solution::hammingDistance(const vector &A) { 9 | long long int ans=0,n=A.size(); 10 | long long int count; 11 | for(int i=0; i < 31; i++) { 12 | count = 0; 13 | for(int j=0; j= 1; i *= 5) 6 | count += A / i; 7 | 8 | return count; 9 | } -------------------------------------------------------------------------------- /Math/verifyPrime.cpp: -------------------------------------------------------------------------------- 1 | // https://www.interviewbit.com/problems/verify-prime/ 2 | 3 | int Solution::isPrime(int A) { 4 | int prime = 1; 5 | if(A != 1) { 6 | for(int i=2; i<=sqrt(A); i++) { 7 | if(A % i == 0) { 8 | prime = 0; 9 | break; 10 | } 11 | } 12 | } 13 | else { 14 | prime = 0; 15 | } 16 | return prime; 17 | } 18 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CPP-and-Algorithms 2 | Hello folks! 👋 3 | 4 | I'm maintaining this repo solely for the purpose of brushing up my DS Algo concepts before an interview. 5 | 6 | _This is not a complete guide for interview preparation._ -------------------------------------------------------------------------------- /Recursion/allSubsetsofString.cpp: -------------------------------------------------------------------------------- 1 | // Print all subsets or subsequence or powersets of a string 2 | 3 | // Eg. Input - "ab" Output - "", "a", "b", "ab" 4 | 5 | void solve(string ip, string op) { 6 | if(ip.length() == 0) { 7 | cout<> ip; 22 | string op = ""; 23 | solve(ip, op); 24 | } -------------------------------------------------------------------------------- /Recursion/delMidofStack.cpp: -------------------------------------------------------------------------------- 1 | // Delete middle element of stack using recursion 2 | 3 | // Identify base condition, make input smaller and design the function (hypothesis) 4 | 5 | void solve(stack &s, int k) { 6 | if(k == 1) { 7 | s.pop(); 8 | return; 9 | } 10 | int temp = s.top(); 11 | s.pop(); 12 | solve(s, k - 1); 13 | s.push(temp); 14 | } 15 | 16 | stack midDel(stack s, int size) { 17 | if(s.size() == 0) { 18 | return s; 19 | } 20 | int k = size / 2 + 1; 21 | solve(s, k); 22 | return s; 23 | } -------------------------------------------------------------------------------- /Recursion/generateParantheses.cpp: -------------------------------------------------------------------------------- 1 | // https://leetcode.com/problems/generate-parentheses 2 | 3 | class Solution { 4 | public: 5 | void solve(int open, int close, string op, vector &v) { 6 | if(open == 0 && close == 0) { 7 | v.push_back(op); 8 | return; 9 | } 10 | if(open != 0) { 11 | string op1 = op; 12 | op1.push_back('('); 13 | solve(open - 1, close, op1, v); 14 | } 15 | if(close > open) { 16 | string op2 = op; 17 | op2.push_back(')'); 18 | solve(open, close - 1, op2, v); 19 | } 20 | } 21 | vector generateParenthesis(int n) { 22 | vector v; 23 | int close = n; 24 | int open = n; 25 | string op = ""; 26 | solve(open, close, op, v); 27 | return v; 28 | } 29 | }; -------------------------------------------------------------------------------- /Recursion/josephus.cpp: -------------------------------------------------------------------------------- 1 | // Josephus problem - https://www.youtube.com/watch?v=ULUNeD0N9yI&list=PL_z_8CaSLPWeT1ffjiImo0sYTcnLzo-wY&index=19 2 | 3 | void solve(vector v, int k, int index, int &ans) { 4 | if(v.size() == 1) { 5 | ans = v[0]; 6 | return; 7 | } 8 | index = (index + k) % v.size(); 9 | v.erase(v.begin() + index); 10 | solve(v, k, index, ans); 11 | } 12 | 13 | int main() { 14 | int n, k; 15 | cin >> n >> k; 16 | vector v; 17 | for(int i = 1; i <= n; i++) { 18 | v.push_back(i); 19 | } 20 | k--; 21 | int index = 0; 22 | int ans = -1; 23 | solve(v, k, index, ans); 24 | return ans; 25 | } 26 | 27 | -------------------------------------------------------------------------------- /Recursion/kthGrammar.cpp: -------------------------------------------------------------------------------- 1 | // https://leetcode.com/problems/k-th-symbol-in-grammar/ 2 | 3 | class Solution { 4 | public: 5 | int kthGrammar(int N, int K) { 6 | if(N == 1 && K == 1) { 7 | return 0; 8 | } 9 | int mid = pow(2, N - 1) / 2; 10 | if(K <= mid) { 11 | return kthGrammar(N - 1, K); 12 | } 13 | else { 14 | return !kthGrammar(N - 1, K - mid); 15 | } 16 | } 17 | }; -------------------------------------------------------------------------------- /Recursion/letterCasePermutation.cpp: -------------------------------------------------------------------------------- 1 | // https://leetcode.com/problems/letter-case-permutation 2 | 3 | class Solution { 4 | public: 5 | void solve(string ip, string op, vector &v) { 6 | if(ip.length() == 0) { 7 | v.push_back(op); 8 | return; 9 | } 10 | if(isalpha(ip[0])) { 11 | string op1 = op; 12 | string op2 = op; 13 | op1.push_back(tolower(ip[0])); 14 | op2.push_back(toupper(ip[0])); 15 | ip.erase(ip.begin() + 0); 16 | solve(ip, op1, v); 17 | solve(ip, op2, v); 18 | } 19 | else { 20 | string op1 = op; 21 | op1.push_back(ip[0]); 22 | ip.erase(ip.begin() + 0); 23 | solve(ip, op1, v); 24 | } 25 | } 26 | vector letterCasePermutation(string S) { 27 | string ip = S; 28 | string op = ""; 29 | vector v; 30 | solve(ip, op, v); 31 | return v; 32 | } 33 | }; -------------------------------------------------------------------------------- /Recursion/nBitBinaryNo.cpp: -------------------------------------------------------------------------------- 1 | // Given n, print all n-bit binary no. with no. of 1's >= no. of 0's in all the prefix 2 | 3 | // Draw recursive tree using ip-op method 4 | 5 | void solve(int one, int zero, int n, string op) { 6 | if(n == 0) { 7 | cout< zero) { 14 | string op2 = op; 15 | op2.push_back('0'); 16 | solve(one, zero + 1, n - 1, op2); 17 | } 18 | } 19 | 20 | int main() { 21 | int n; 22 | cin >> n; 23 | string op = ""; 24 | int one = 0, zero = 0; 25 | solve(one, zero, n, op); 26 | } -------------------------------------------------------------------------------- /Recursion/permutationWithCaseChange.cpp: -------------------------------------------------------------------------------- 1 | // Input - ab (assume that input string is always in lower case) 2 | // Output - ab, aB, Ab, AB 3 | 4 | void solve(string ip, string op) { 5 | if(ip.length() == 0) { 6 | cout<> ip; 22 | string op = ""; 23 | solve(ip, op); 24 | } -------------------------------------------------------------------------------- /Recursion/permutationWithSpaces.cpp: -------------------------------------------------------------------------------- 1 | // Given abc as input print a_b_c, a_bc, ab_c, abc as output 2 | 3 | void solve(string ip, string op) { 4 | if(ip.length() == 0) { 5 | cout<> ip; 22 | string op = ""; 23 | op.push_back(ip[0]); 24 | ip.erase(ip.begin() + 0); 25 | solve(ip, op); 26 | } -------------------------------------------------------------------------------- /Recursion/reverseStack.cpp: -------------------------------------------------------------------------------- 1 | // Reverse a stack using recursion 2 | 3 | // Identify base condition, make input smaller and design the function (hypothesis) 4 | 5 | void insert(stack &s, int value) { 6 | if(s.size() == 0) { 7 | s.push(value); 8 | return; 9 | } 10 | 11 | int temp = s.top(); 12 | s.pop(); 13 | insert(s, value); 14 | s.push(temp); 15 | } 16 | 17 | void reverse(stack &s) { 18 | if(s.size() == 1) { 19 | return; 20 | } 21 | int temp = s.top(); 22 | s.pop(); 23 | reverse(s); 24 | insert(s, temp); 25 | } -------------------------------------------------------------------------------- /Recursion/sortArray.cpp: -------------------------------------------------------------------------------- 1 | // sort an array using recursion 2 | 3 | // Similarly sort a stack using recursion 4 | // Identify base condition, make input smaller and design the function (hypothesis) 5 | 6 | void insert(vector &v, val) { 7 | if(v.size() == 0 || val >= v[v.size() - 1]) { 8 | v.push_back(val); 9 | return; 10 | } 11 | int temp = v[v.size() - 1]; 12 | v.pop_back(); 13 | insert(v, val); 14 | v.push_back(temp); 15 | } 16 | 17 | void sort(vector &v) { 18 | if(v.size() == 1) { 19 | return; 20 | } 21 | 22 | int temp = v[v.size() - 1]; 23 | v.pop_back(); 24 | sort(v); 25 | insert(v, temp); 26 | } -------------------------------------------------------------------------------- /Recursion/towerOfHanoi.cpp: -------------------------------------------------------------------------------- 1 | // Solve Tower of Hanoi problem using recursion 2 | 3 | // Print the moves to move all the plates from source to destination pole using helper pole 4 | 5 | // For n disks, 2^(n - 1) moves are required 6 | 7 | // Design the function - solve() moves the plates from source to destination, 1 at a time 8 | // First move n - 1 plates from source to helper pole 9 | // Then move nth plate from source to destination 10 | // Then move n - 1 plates from helper pole to destination pole 11 | 12 | void solve(int source, int destination, int helper, int n) { 13 | if(n == 1) { 14 | cout<<"Move plate 1 from "<= '0' && A[i] <= '9') { 18 | // check overflow 19 | if(base > INT_MAX/10 || (base == INT_MAX/10 && A[i] - '0' > 7)) { 20 | if(sign == 1) { 21 | return INT_MAX; 22 | } 23 | else { 24 | return INT_MIN; 25 | } 26 | } 27 | base = (base * 10) + A[i++] - '0'; 28 | } 29 | return base * sign; 30 | } 31 | -------------------------------------------------------------------------------- /Strings/KmpPatternSearch.cpp: -------------------------------------------------------------------------------- 1 | // https://www.geeksforgeeks.org/kmp-algorithm-for-pattern-searching/ 2 | 3 | #include 4 | 5 | void computeLPSArray(char* pat, int M, int* lps); 6 | 7 | // Prints occurrences of pat[] in txt[] 8 | // lps[i] = the longest proper prefix of pat[0..i] which is also a suffix of pat[0..i] 9 | 10 | void KMPSearch(char* pat, char* txt) 11 | { 12 | int M = strlen(pat); 13 | int N = strlen(txt); 14 | 15 | int lps[M]; 16 | 17 | // Preprocess the pattern (calculate lps[] array) 18 | computeLPSArray(pat, M, lps); 19 | 20 | int i = 0; 21 | int j = 0; 22 | 23 | while(i < N) { 24 | if(pat[j] == txt[i]) { 25 | i++; 26 | j++; 27 | } 28 | if(j == M) { 29 | cout<<"Pattern found at "<< i - j; 30 | j = lps[j - 1]; 31 | } 32 | // mismatch after j matches 33 | else if(i < N && pat[j] != txt[i]) { 34 | // Do not match lps[0..lps[j-1]] characters, 35 | // they will match anyway 36 | if(j != 0) { 37 | j = lps[j - 1]; 38 | } 39 | else { 40 | i++; 41 | } 42 | } 43 | } 44 | } 45 | 46 | // Fills lps[] for given patttern pat[0..M-1] 47 | void computeLPSArray (char *pat, int M, int *lps) { 48 | int len = 0; 49 | lps[0] = 0; // lps[0] is always 0 50 | int i = 1; 51 | 52 | while (i < M) { 53 | if (pat[i] == pat[len]) { 54 | len++; 55 | lps[i] = len; 56 | i++; 57 | } 58 | else 59 | { 60 | if (len != 0) { 61 | len = lps[len - 1]; 62 | } 63 | else 64 | { 65 | lps[i] = 0; 66 | i++; 67 | } 68 | } 69 | } 70 | } 71 | 72 | // Driver program to test above function 73 | int main() 74 | { 75 | char txt[] = "ABABDABACDABABCABAB"; 76 | char pat[] = "ABABCABAB"; 77 | KMPSearch(pat, txt); 78 | return 0; 79 | } -------------------------------------------------------------------------------- /Strings/LastWordLength.cpp: -------------------------------------------------------------------------------- 1 | // https://www.interviewbit.com/problems/length-of-last-word/ 2 | 3 | int Solution::lengthOfLastWord(const string A) { 4 | int count = 0; 5 | bool flag = false; 6 | for (int i = A.length() - 1; i >= 0; i--) { 7 | if ((A[i] >= 'a' && A[i] <= 'z') || (A[i] >= 'A' && A[i] <= 'Z')) { 8 | flag = true; 9 | count++; 10 | } 11 | else { 12 | if (flag == true) 13 | return count; 14 | } 15 | } 16 | return count; 17 | } 18 | -------------------------------------------------------------------------------- /Strings/addBinaryStrings.cpp: -------------------------------------------------------------------------------- 1 | // https://www.interviewbit.com/problems/add-binary-strings/ 2 | 3 | string Solution::addBinary(string A, string B) { 4 | string result = ""; 5 | int s = 0; 6 | int i = A.size() - 1, j = B.size() - 1; 7 | while(i >= 0 || j >= 0 || s == 1) { 8 | s += ((i >= 0)? A[i] - '0' : 0); 9 | s += ((j >= 0)? B[j] - '0' : 0); 10 | 11 | result = char(s%2 + '0') + result; 12 | s /= 2; 13 | i--; 14 | j--; 15 | } 16 | return result; 17 | } 18 | -------------------------------------------------------------------------------- /Strings/countAndSay.cpp: -------------------------------------------------------------------------------- 1 | // https://www.interviewbit.com/problems/count-and-say/ 2 | 3 | string Solution::countAndSay(int A) { 4 | int n = A; 5 | 6 | if(n == 1) { 7 | return "1"; 8 | } 9 | 10 | if(n == 2) { 11 | return "11"; 12 | } 13 | 14 | string str = "11"; 15 | 16 | for(int i=3; i<=n; i++) { 17 | str+="$"; 18 | string tmp = ""; 19 | int len = str.length(); 20 | int count = 1; 21 | for(int j=1; j0) 10 | { 11 | int div = number/num[i]; 12 | number = number%num[i]; 13 | while(div--) 14 | { 15 | sol += sym[i]; 16 | } 17 | i--; 18 | } 19 | return sol; 20 | } 21 | -------------------------------------------------------------------------------- /Strings/justifiedText.cpp: -------------------------------------------------------------------------------- 1 | // https://www.interviewbit.com/problems/justified-text/ 2 | 3 | string JoinALineWithSpace( 4 | vector& words, 5 | int start, int end, 6 | int num_spaces) 7 | { 8 | 9 | // Number of words in current line 10 | int num_words_curr_line 11 | = end - start + 1; 12 | 13 | // String to store the justified text 14 | string line; 15 | 16 | for (int i = start; i < end; i++) { 17 | 18 | line += words[i]; 19 | --num_words_curr_line; 20 | 21 | // Count number of current space needed 22 | int num_curr_space 23 | = ceil((double)(num_spaces) 24 | / num_words_curr_line); 25 | 26 | // Insert spaces in string line 27 | line.append(num_curr_space, ' '); 28 | 29 | // Delete the spaces inserted in line 30 | num_spaces -= num_curr_space; 31 | } 32 | 33 | // Insert word to string line 34 | line += words[end]; 35 | line.append(num_spaces, ' '); 36 | 37 | // Return justified text 38 | return line; 39 | } 40 | 41 | // Function that justify the words of 42 | // sentence of length of line L 43 | vector JustifyText( 44 | vector& words, 45 | int L) 46 | { 47 | 48 | int curr_line_start = 0; 49 | int num_words_curr_line = 0; 50 | int curr_line_length = 0; 51 | 52 | // To store the justified text 53 | vector result; 54 | 55 | // Traversing the words array 56 | for (int i = 0; i < words.size(); i++) { 57 | 58 | // curr_line_start is the first word 59 | // in the current line, and i is 60 | // used to identify the last word 61 | ++num_words_curr_line; 62 | 63 | int lookahead_line_length 64 | = curr_line_length 65 | + words[i].size() 66 | + (num_words_curr_line - 1); 67 | 68 | // If by including the words length becomes L, 69 | // then that set of words is justified 70 | // and add the justified text to result 71 | if (lookahead_line_length == L) { 72 | 73 | // Justify the set of words 74 | string ans 75 | = JoinALineWithSpace( 76 | words, 77 | curr_line_start, 78 | i, 79 | i - curr_line_start); 80 | 81 | // Store the justified text in result 82 | result.emplace_back(ans); 83 | 84 | // Start the current line 85 | // with next index 86 | curr_line_start = i + 1; 87 | 88 | // num of words in the current line 89 | // and current line length set to 0 90 | num_words_curr_line = 0; 91 | curr_line_length = 0; 92 | } 93 | 94 | // If by including the words such that 95 | // length of words becomes greater than L, 96 | // then hat set is justified with 97 | // one less word and add the 98 | // justified text to result 99 | else if (lookahead_line_length > L) { 100 | 101 | // Justify the set of words 102 | string ans 103 | = JoinALineWithSpace( 104 | words, 105 | curr_line_start, 106 | i - 1, 107 | L - curr_line_length); 108 | 109 | // Store the justified text in result 110 | result.emplace_back(ans); 111 | 112 | // Current line set to current word 113 | curr_line_start = i; 114 | 115 | // Number of words set to 1 116 | num_words_curr_line = 1; 117 | 118 | // Current line length set 119 | // to current word length 120 | curr_line_length = words[i].size(); 121 | } 122 | 123 | // If length is less than L then, 124 | // add the word to current line length 125 | else { 126 | curr_line_length 127 | += words[i].size(); 128 | } 129 | } 130 | 131 | // Last line is to be left-aligned 132 | if (num_words_curr_line > 0) { 133 | string line 134 | = JoinALineWithSpace( 135 | words, 136 | curr_line_start, 137 | words.size() - 1, 138 | num_words_curr_line - 1); 139 | 140 | line.append( 141 | L - curr_line_length 142 | - (num_words_curr_line - 1), 143 | ' '); 144 | 145 | // Insert the last line 146 | // left-aligned to result 147 | result.emplace_back(line); 148 | } 149 | 150 | // Return result 151 | return result; 152 | } 153 | vector Solution::fullJustify(vector &A, int B) { 154 | vector result = JustifyText(A, B); 155 | return result; 156 | } 157 | -------------------------------------------------------------------------------- /Strings/longestCommonPrefix.cpp: -------------------------------------------------------------------------------- 1 | // https://www.interviewbit.com/problems/longest-common-prefix/ 2 | 3 | string Solution::longestCommonPrefix(vector &A) { 4 | string ans = A[0]; 5 | int n = A.size(); 6 | for(int i=1; i computeLPSArray(string str) 4 | { 5 | int M = str.length(); 6 | vector lps(M); 7 | 8 | int len = 0; 9 | lps[0] = 0; // lps[0] is always 0 10 | int i = 1; 11 | 12 | while (i < M) 13 | { 14 | if (str[i] == str[len]) 15 | { 16 | len++; 17 | lps[i] = len; 18 | i++; 19 | } 20 | else 21 | { 22 | if (len != 0) 23 | { 24 | len = lps[len-1]; 25 | } 26 | else 27 | { 28 | lps[i] = 0; 29 | i++; 30 | } 31 | } 32 | } 33 | return lps; 34 | } 35 | 36 | // Method returns minimum character to be added at 37 | // front to make string palindrome 38 | int getMinCharToAddedToMakeStringPalin(string str) 39 | { 40 | string revStr = str; 41 | reverse(revStr.begin(), revStr.end()); 42 | 43 | // Get concatenation of string, special character 44 | // and reverse string 45 | string concat = str + "$" + revStr; 46 | 47 | // Get LPS array of this concatenated string 48 | vector lps = computeLPSArray(concat); 49 | 50 | // By subtracting last entry of lps vector from 51 | // string length, we will get our result 52 | return (str.length() - lps.back()); 53 | } 54 | 55 | int Solution::solve(string A) { 56 | return getMinCharToAddedToMakeStringPalin(A); 57 | } 58 | -------------------------------------------------------------------------------- /Strings/multiplyStrings.cpp: -------------------------------------------------------------------------------- 1 | // https://www.interviewbit.com/problems/multiply-strings/ 2 | 3 | string Solution::multiply(string A, string B) { 4 | string num1 = A; 5 | string num2 = B; 6 | int len1 = num1.size(); 7 | int len2 = num2.size(); 8 | if (len1 == 0 || len2 == 0) 9 | return "0"; 10 | 11 | // will keep the result number in vector 12 | // in reverse order 13 | vector result(len1 + len2, 0); 14 | 15 | // Below two indexes are used to find positions 16 | // in result. 17 | int i_n1 = 0; 18 | int i_n2 = 0; 19 | 20 | // Go from right to left in num1 21 | for (int i=len1-1; i>=0; i--) 22 | { 23 | int carry = 0; 24 | int n1 = num1[i] - '0'; 25 | 26 | // To shift position to left after every 27 | // multiplication of a digit in num2 28 | i_n2 = 0; 29 | 30 | // Go from right to left in num2 31 | for (int j=len2-1; j>=0; j--) 32 | { 33 | // Take current digit of second number 34 | int n2 = num2[j] - '0'; 35 | 36 | // Multiply with current digit of first number 37 | // and add result to previously stored result 38 | // at current position. 39 | int sum = n1*n2 + result[i_n1 + i_n2] + carry; 40 | 41 | // Carry for next iteration 42 | carry = sum/10; 43 | 44 | // Store result 45 | result[i_n1 + i_n2] = sum % 10; 46 | 47 | i_n2++; 48 | } 49 | 50 | // store carry in next cell 51 | if (carry > 0) 52 | result[i_n1 + i_n2] += carry; 53 | 54 | // To shift position to left after every 55 | // multiplication of a digit in num1. 56 | i_n1++; 57 | } 58 | 59 | // ignore '0's from the right 60 | int i = result.size() - 1; 61 | while (i>=0 && result[i] == 0) 62 | i--; 63 | 64 | // If all were '0's - means either both or 65 | // one of num1 or num2 were '0' 66 | if (i == -1) 67 | return "0"; 68 | 69 | // generate the result string 70 | string s = ""; 71 | 72 | while (i >= 0) 73 | s += to_string(result[i--]); 74 | 75 | return s; 76 | } 77 | -------------------------------------------------------------------------------- /Strings/powerOf2.cpp: -------------------------------------------------------------------------------- 1 | // https://www.interviewbit.com/problems/power-of-2/ 2 | 3 | int Solution::power(string A) { 4 | int n = A.size(), num = 0, j = 0; 5 | if(A == "1" || A == "0") { 6 | return 0; 7 | } 8 | while(j != n-1) { 9 | num = 0; 10 | while(A[j] == '0') { 11 | j++; 12 | } 13 | if((A[n-1] - '0') % 2){ 14 | return 0; 15 | } 16 | for(int i = j; i < n; i++) { 17 | num = num*10 + (A[i] - '0'); 18 | A[i] = (num / 2) + '0'; 19 | num = num % 2; 20 | } 21 | } 22 | return 1; 23 | } 24 | -------------------------------------------------------------------------------- /Strings/prettyJson.cpp: -------------------------------------------------------------------------------- 1 | // https://www.interviewbit.com/problems/pretty-json/ 2 | 3 | vector Solution::prettyJSON(string A) { 4 | string s = A; 5 | vector ans; 6 | string temp = ""; 7 | int tabs = 0; 8 | for(int i = 0; i < s.size(); i++) { 9 | if(s[i] == ' ') { 10 | continue; 11 | } 12 | else if(s[i] == '{' || s[i] == '[') { 13 | if(temp != "") { 14 | ans.push_back(temp); 15 | } 16 | temp = ""; 17 | for(int j=0; j < tabs; j++) { 18 | temp += "\t"; 19 | } 20 | temp += s[i]; 21 | ans.push_back(temp); 22 | temp = ""; 23 | tabs++; 24 | } 25 | else if(s[i] == '}' || s[i] == ']') { 26 | if(temp != "") { 27 | ans.push_back(temp); 28 | } 29 | temp = ""; 30 | for(int j=0; j < tabs - 1; j++) { 31 | temp += "\t"; 32 | } 33 | temp += s[i]; 34 | if(i < s.length() && s[i+1] == ',') { 35 | ++i; 36 | temp += s[i]; 37 | } 38 | ans.push_back(temp); 39 | temp = ""; 40 | tabs--; 41 | } 42 | else { 43 | if(temp == "") { 44 | for(int j=0; j < tabs; j++) { 45 | temp += "\t"; 46 | } 47 | } 48 | temp += s[i]; 49 | if(s[i] == ',') { 50 | ans.push_back(temp); 51 | temp = ""; 52 | } 53 | } 54 | } 55 | return ans; 56 | } 57 | -------------------------------------------------------------------------------- /Strings/reverseTheString.cpp: -------------------------------------------------------------------------------- 1 | // https://www.interviewbit.com/problems/reverse-the-string/ 2 | 3 | string Solution::solve(string A) { 4 | string result = ""; 5 | for(int i = A.length()-1; i>-1; --i) 6 | { 7 | if (A[i] != ' ') 8 | { 9 | int last = i; 10 | int first = i; 11 | while (i>-1 && A[i] != ' ') 12 | --i; 13 | 14 | first = i + 1; 15 | 16 | //append new word 17 | result.append(A.begin()+first, A.begin()+last+1); 18 | 19 | //if not last word then add a space 20 | if (i>0) 21 | { 22 | string str = A.substr(0, i+1); 23 | string temp = ""; 24 | temp.append(i+1, ' '); 25 | if(str != temp) 26 | result += ' '; 27 | } 28 | } 29 | } 30 | return result; 31 | } 32 | -------------------------------------------------------------------------------- /Strings/romanToInteger.cpp: -------------------------------------------------------------------------------- 1 | // https://www.interviewbit.com/problems/roman-to-integer/ 2 | 3 | int Solution::romanToInt(string A) { 4 | unordered_map m; 5 | m.insert({'I', 1}); 6 | m.insert({'V', 5}); 7 | m.insert({'X', 10}); 8 | m.insert({'L', 50}); 9 | m.insert({'C', 100}); 10 | m.insert({'D', 500}); 11 | m.insert({'M', 1000}); 12 | int sum = 0; 13 | if(A.size() != 1) { 14 | for(int i = 0; i < A.size() - 1; i++) { 15 | if(m[A[i]] >= m[A[i+1]]) { 16 | sum += m[A[i]]; 17 | } 18 | else { 19 | sum -= m[A[i]]; 20 | } 21 | if(i == A.size() - 2) { 22 | sum += m[A[i+1]]; 23 | } 24 | } 25 | return sum; 26 | } 27 | else { 28 | return m[A[0]]; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Strings/subString.cpp: -------------------------------------------------------------------------------- 1 | // https://www.interviewbit.com/problems/implement-strstr/ 2 | 3 | // B is sub-string, A is main string 4 | 5 | // This is also a naive pattern searching algorithm. 6 | 7 | // O(m(n-m+1)) 8 | 9 | int Solution::strStr(const string A, const string B) { 10 | int M = B.length(); 11 | int N = A.length(); 12 | 13 | for (int i = 0; i <= N - M; i++) { 14 | int j; 15 | 16 | for (j = 0; j < M; j++) 17 | if (A[i + j] != B[j]) 18 | break; 19 | 20 | if (j == M) 21 | return i; 22 | } 23 | 24 | return -1; 25 | } 26 | -------------------------------------------------------------------------------- /Strings/validIpAddresses.cpp: -------------------------------------------------------------------------------- 1 | // https://www.interviewbit.com/problems/valid-ip-addresses/ 2 | 3 | bool isValid(string A) { 4 | if(A.size() > 1 && A[0] == '0') { 5 | return false; 6 | } 7 | else if(stoi(A) <= 255 && stoi(A) >= 0) { 8 | return true; 9 | } 10 | else { 11 | return false; 12 | } 13 | } 14 | 15 | vector Solution::restoreIpAddresses(string A) { 16 | vector sol; 17 | string result = ""; 18 | if(A.size() > 12 || A.size() < 4) { 19 | return sol; 20 | } 21 | for(int i = 1; i < 4; i++) { 22 | string first = A.substr(0, i); 23 | if(!isValid(first)) { 24 | continue; 25 | } 26 | for(int j = 1; i + j < A.size() && j < 4; j++) { 27 | string second = A.substr(i, j); 28 | if(!isValid(second)) { 29 | continue; 30 | } 31 | for(int k = 1; i + j + k < A.size() && k < 4; k++) { 32 | string third = A.substr(i + j, k); 33 | string fourth = A.substr(i + j + k); 34 | if(isValid(third) && isValid(fourth)) { 35 | result = first + "." + second + "." + third + "." + fourth; 36 | sol.push_back(result); 37 | result = ""; 38 | } 39 | } 40 | } 41 | } 42 | return sol; 43 | } 44 | -------------------------------------------------------------------------------- /Trees/binaryTreeHeight.cpp: -------------------------------------------------------------------------------- 1 | // https://www.hackerrank.com/challenges/tree-height-of-a-binary-tree/problem 2 | 3 | int height(Node* root) { 4 | if (root == NULL) { 5 | return -1; 6 | } 7 | else { 8 | return 1 + max(height(root->left), height(root->right)); 9 | } 10 | } -------------------------------------------------------------------------------- /Trees/bstInsertion.cpp: -------------------------------------------------------------------------------- 1 | // https://www.hackerrank.com/challenges/binary-search-tree-insertion/problem 2 | 3 | // Time Complexity - O(n) for skewed tree 4 | 5 | // A new key is always inserted at the leaf. 6 | 7 | class Node { 8 | public: 9 | int data; 10 | Node* left; 11 | Node* right; 12 | Node(int nodeData) { 13 | data = nodeData; 14 | left = NULL; 15 | right = NULL; 16 | } 17 | }; 18 | 19 | Node* insert(Node* root, int data) { 20 | if(!root) { 21 | return new Node(data); 22 | } 23 | if(data > root->data) { 24 | root->right = insert(root->right, data); 25 | } 26 | if(data < root->data) { 27 | root->left = insert(root->left, data); 28 | } 29 | return root; 30 | } -------------------------------------------------------------------------------- /Trees/inOrder.cpp: -------------------------------------------------------------------------------- 1 | // https://www.hackerrank.com/challenges/tree-inorder-traversal/problem 2 | 3 | class Node { 4 | public: 5 | int data; 6 | Node* left; 7 | Node* right; 8 | Node(int node_data) { 9 | data = node_data; 10 | left = NULL; 11 | right = NULL; 12 | } 13 | }; 14 | 15 | 16 | // Function call happens only once for each node in the tree. For each call of this function 17 | // a maximum of k<=4 operations are performed. Hence, max. of k*n operations lead to O(n). 18 | 19 | void inOrder(Node* root) { 20 | if(root == NULL) { 21 | return; 22 | } 23 | inOrder(root->left); 24 | cout<data<<" "; 25 | inOrder(root->right); 26 | } -------------------------------------------------------------------------------- /Trees/lcabst.cpp: -------------------------------------------------------------------------------- 1 | // lowest common ancestor in binary search tree 2 | // https://www.geeksforgeeks.org/lowest-common-ancestor-in-a-binary-search-tree 3 | 4 | // To find distance between pairs of nodes in a tree, distance between n1 and n2 can be computed 5 | // as the distance from the root to n1, plus the distance from root to n2, minus twice the distance 6 | // from the root to their lowest common ancestor 7 | 8 | // A node is considered a descendant of itself 9 | 10 | // Recursive solution 11 | // Time Complexity - O(h) 12 | // Space Complexity - O(1) if recursive stack space is ignored 13 | 14 | Node* lca(Node* root, int n1, int n2) { 15 | if(root == NULL) { 16 | return NULL; 17 | } 18 | if(root->data > n1 && root->data > n2) { 19 | return lca(root->left, n1, n2); 20 | } 21 | if(root->data < n1 && root->data < n2) { 22 | return lca(root->right, n1, n2); 23 | } 24 | return root; 25 | } 26 | 27 | // Iterative solution 28 | // Time Complexity - O(h) 29 | // Space Complexity - O(1) 30 | 31 | Node* lca(Node* root, int n1, int n2) { 32 | if(root == NULL) { 33 | return; 34 | } 35 | while(root != NULL) { 36 | if(root->data > n1 && root->data > n2) { 37 | root = root->left; 38 | } 39 | else if(root->data < n1 && root->data < n2) { 40 | root = root->right 41 | } 42 | else 43 | break; 44 | } 45 | return root; 46 | } -------------------------------------------------------------------------------- /Trees/levelOrder.cpp: -------------------------------------------------------------------------------- 1 | // Level order traversal is breadth first traversal. 2 | 3 | #include 4 | using namespace std; 5 | 6 | class Node { 7 | public: 8 | int data; 9 | Node* left; 10 | Node* right; 11 | Node(int nodeData) { 12 | data = nodeData; 13 | left = NULL; 14 | right = NULL; 15 | } 16 | }; 17 | 18 | // Method 1 19 | // Time Complexity - For skewed tree, 1 + 2 + 3 + .. + n where n is no. of nodes. O(n^2) in worst case. 20 | // Space Complexity - O(n) in worst case for skewed tree printGivenLevel() uses O(n) space for call stack. 21 | 22 | // Calculate height of the tree 23 | int height(Node* root) { 24 | if(root == NULL) { 25 | return -1; 26 | } 27 | return 1 + max(height(root->left), height(root->right)); 28 | } 29 | 30 | void levelOrder(Node* root) { 31 | int h = height(root); 32 | for(int i = 0; i <= h; i++) { 33 | printGivenLevel(root, i); 34 | } 35 | } 36 | 37 | void printGivenLevel(Node *root, int level) { 38 | if(root == NULL) { 39 | return; 40 | } 41 | if(level == 0) { 42 | cout<data<<" "; 43 | } 44 | else if(level > 0) { 45 | printGivenLevel(root->left, level - 1); 46 | printGivenLevel(root->right, level - 1); 47 | } 48 | } 49 | 50 | // Method 2 (queue) 51 | // Time Complexity - O(n) where n is no. of nodes in the binary tree (each node is visited once) 52 | // Space Complexity - O(n) 53 | 54 | void levelOrder(Node* root) { 55 | if(root == NULL) { 56 | return; 57 | } 58 | 59 | queue q; 60 | q.push(root); 61 | while(q.empty() == false) { 62 | Node* node = q.front(); 63 | cout<data<<" "; 64 | q.pop(); 65 | 66 | if(node->left != NULL) { 67 | q.push(node->left); 68 | } 69 | 70 | if(node->right != NULL) { 71 | q.push(node->right); 72 | } 73 | } 74 | } -------------------------------------------------------------------------------- /Trees/postOrder.cpp: -------------------------------------------------------------------------------- 1 | // https://www.hackerrank.com/challenges/tree-postorder-traversal/problem 2 | 3 | class Node { 4 | public: 5 | int data; 6 | Node* left; 7 | Node* right; 8 | Node(int node_data) { 9 | data = node_data; 10 | left = NULL; 11 | right = NULL; 12 | } 13 | }; 14 | 15 | void postOrder(Node* root) { 16 | if(root == NULL) { 17 | return; 18 | } 19 | postOrder(root->left); 20 | postOrder(root->right); 21 | cout<data<<" "; 22 | } -------------------------------------------------------------------------------- /Trees/preOrder.cpp: -------------------------------------------------------------------------------- 1 | // https://www.hackerrank.com/challenges/tree-preorder-traversal/problem 2 | 3 | class Node { 4 | public: 5 | int data; 6 | Node* left; 7 | Node* right; 8 | Node(int node_data) { 9 | data = node_data; 10 | left = NULL; 11 | right = NULL; 12 | } 13 | }; 14 | 15 | void preOrder(Node* root) { 16 | if(root == NULL) { 17 | return; 18 | } 19 | cout<data<<" "; 20 | preOrder(root->left); 21 | preOrder(root->right); 22 | } -------------------------------------------------------------------------------- /Trees/search.cpp: -------------------------------------------------------------------------------- 1 | // Searching for an element in binary search tree is similar to binary search 2 | 3 | // Time Complexity - O(n), skewed binary tree 4 | 5 | Node* search(Node* root, int key) { 6 | if(root == NULL || root->data == key) { 7 | return root; 8 | } 9 | if(root->data < key) { 10 | return search(root->right, key); 11 | } 12 | return search(root->left, key); 13 | } -------------------------------------------------------------------------------- /Trees/topView.cpp: -------------------------------------------------------------------------------- 1 | // Time Complexity - O(nlogn) as insertion in map has O(log n) and each node is visited once. 2 | 3 | void fillMap(Node* root, int hd, int l, map> &m) { 4 | if(root == NULL) { 5 | return; 6 | } 7 | if(m.count(hd) == 0) { 8 | m[hd] = make_pair(root->data, l); 9 | } 10 | else if(m[hd].second > l){ 11 | m[hd] = make_pair(root->data, l); 12 | } 13 | 14 | fillMap(root->left, hd - 1, l + 1, m); 15 | fillMap(root->right, hd + 1, l + 1, m); 16 | } 17 | 18 | void topView(Node* root) { 19 | if(root == NULL) { 20 | return; 21 | } 22 | map> m; 23 | fillMap(root, 0 , 0, m); 24 | for(auto it = m.begin(); it != m.end(); it++) { 25 | cout<second.first<<" "; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Trees/verticalOrder.cpp: -------------------------------------------------------------------------------- 1 | class Node { 2 | public: 3 | int data; 4 | Node* left; 5 | Node* right; 6 | Node(int node_data) { 7 | data = node_data; 8 | left = NULL; 9 | right = NULL; 10 | } 11 | }; 12 | 13 | // Method 1 14 | // Time Complexity - O(w*n) where w is width of binary tree. In worst case w -> n when we have complete binary tree. 15 | // Hence, O(n*n) 16 | 17 | void findMinMax(Node* node, int* min, int* max, int hd) { 18 | if(node == NULL) { 19 | return; 20 | } 21 | if(hd < *min) { 22 | *min = hd; 23 | } 24 | if(hd > *max) { 25 | *max = hd; 26 | } 27 | findMinMax(node->left, min, max, hd - 1); 28 | findMinMax(node->right, min, max, hd + 1); 29 | } 30 | 31 | void printVerticalLine(Node* node, int lineNo, int hd) { 32 | if(node == NULL) { 33 | return; 34 | } 35 | if(lineNo == hd) { 36 | cout<data<<" "; 37 | } 38 | printVerticalLine(node->left, lineNo, hd - 1); 39 | printVerticalLine(node->right, lineNo, hd + 1); 40 | } 41 | 42 | void verticalOrder(Node* root) { 43 | if(root == NULL) { 44 | return; 45 | } 46 | int min = 0, max = 0; 47 | findMinMax(root, &min, &max, 0); 48 | 49 | for(int lineNo = min; lineNo <= max; lineNo++) { 50 | printVerticalLine(root, lineNo, 0); 51 | } 52 | } 53 | 54 | // Method 2 55 | // Map operations take O(log n) and pre-order traversal is O(n) therefore complexity of the below solution is O(nlog n) 56 | // The below solution may not print nodes in same vertical order as they appear in tree 57 | 58 | void getVerticalOrder(Node* root, int hd, map> &m) { 59 | if(root == NULL) { 60 | return; 61 | } 62 | 63 | m[hd].push_back(root->data); 64 | getVerticalOrder(root->left, hd - 1, m); 65 | getVerticalOrder(root->right, hd + 1, m); 66 | } 67 | 68 | void verticalOrder(Node* root) { 69 | map> m; 70 | int hd = 0; 71 | getVerticalOrder(root, hd, m); 72 | map>::iterator itr; 73 | 74 | for(itr = m.begin(); itr != m.end(); itr++) { 75 | for(int i = 0; i < itr->second.size(); i++) { 76 | cout<second[i]<<" "; 77 | } 78 | cout<