├── .gitignore ├── 01. Time Complexity ├── 1.order_of_growth.md ├── 2.asymptotic_notation.md └── 3.space.md ├── 02. Mathematics ├── 01.CountDigit │ └── countDigit.cpp ├── 02.Palindrome │ └── palindrome.cpp ├── 03.Factorial │ └── fact.cpp ├── 04.CountTrailZero │ └── countTrailZero.cpp ├── 05.GCD │ └── GCD.cpp ├── 06.LCM │ └── LCM.cpp ├── 07.Prime │ └── prime.cpp ├── 08.PrimeFactors │ └── primeFactors.cpp ├── 09.AllDivisiors │ └── allDivisor.cpp ├── 10.SieveOfEratosthenes │ └── primeInRange.cpp ├── 11.Power │ └── power.cpp ├── 12. Exactly 3 Divisor │ └── divisor.cpp └── 13. FastExponent │ └── exponent.cpp ├── 03. Bit Magic ├── 01. Theory │ └── BitwiseOperators.md ├── 02. Operations │ └── Bitwise.cpp ├── 03. CheckKthBit │ └── checkBit.cpp ├── 04. RightMostDiffBit │ └── rightMostDiffBit.cpp ├── 05. CountSetBit │ └── countBit.cpp ├── 06. BitInRange │ └── bitInRange.cpp ├── 07. PowerOfTwo │ └── po2.cpp ├── 08. Missing number │ └── missing.cpp ├── 09. SwapEvenOdd │ └── swap.cpp └── 10. Only odd occuring │ └── odd.cpp ├── 04. Recursion ├── 01. Theory │ └── recursion.md ├── 02. Guess Output │ └── guess.cpp ├── 03. Print Numbers │ └── printNumber.cpp ├── 04. Fact and Fibo │ └── FactnFibo.cpp ├── 05. Palindrome │ └── palindrome.cpp ├── 06. Sum of Digits │ └── sum.cpp ├── 07. Rope cutting │ └── rope.cpp ├── 08. Generate Subset │ └── subset.cpp ├── 09. Tower of Hanoi │ └── toh.cpp └── 10. Josephus │ └── jose.cpp ├── 05. Array ├── 01. Theory │ ├── introduction.md │ └── vector.md ├── 02. Array │ └── operations.cpp ├── 03.Vector │ └── vector.cpp ├── 04. Largest Element │ └── large.cpp ├── 05. Check sorted │ └── check.cpp ├── 06. Reverse │ └── reverse.cpp ├── 07. Remove Duplicate │ └── remove.cpp ├── 08. Segregate │ └── move.cpp ├── 09. Left Rotate │ └── rotate.cpp ├── 10. Right Rotate │ └── rotate.cpp ├── 11. Max difference │ └── maxDiff.cpp ├── 12. Frequency │ └── freq.cpp ├── 13. Stock │ └── stock.cpp ├── 14. Rain Water │ └── rain.cpp ├── 15. Consecutive ones │ └── countOnes.cpp ├── 16. Sub Array │ └── subArray.cpp ├── 17. SubArray sum │ └── sum.cpp ├── 18. Max Even Odd │ └── max.cpp ├── 19. Rearrange Alternately │ └── rearrange.cpp ├── 20. Circular subarray │ └── cSub.cpp ├── 21. Majority │ └── majority.cpp ├── 22. Good pair │ └── good.cpp ├── 23. Max Sum │ └── max.cpp ├── 24. Min Consecutive flips │ └── flips.cpp ├── 25. Sliding Window │ ├── constant.cpp │ └── variable.cpp ├── 26. Subarray │ └── sum.cpp ├── 27. sort rotate │ └── sortedRotated.cpp ├── 28. Subset sum │ └── subsetsum.cpp ├── 29. Max Area │ └── max.cpp └── 30. Absolute Diff │ └── minimize.cpp ├── 06. Searching ├── 01. Binary Search (Iterative) │ └── binary.cpp ├── 02. BInary Search (recursive) │ └── binary.cpp ├── 03. Index of First occurance │ └── index.cpp ├── 04. Index of Last Occurance │ └── index.cpp ├── 05. Freq in sorted array │ └── freq.cpp ├── 06. Sqrt Floor │ └── sqrt.cpp ├── 07. Print all perfect squares │ └── square.cpp ├── 08. Search in sorted rotated array │ └── search.cpp ├── 09. Peak element │ └── peak.cpp ├── 10. Two pointer │ └── pointer.cpp ├── 11. Median in sorted array │ └── median.cpp └── 12. Repeating element │ └── repeat.cpp ├── 07. Sorting ├── 01. Theory │ ├── sort.md │ └── stability.md ├── 02. Bubble Sort │ └── bubble.cpp ├── 03. Selection Sort │ └── selection.cpp ├── 04. Insertion Sort │ └── Insertion.cpp ├── 05. Merge sorted array │ └── merge.cpp ├── 06. Merge function │ └── merge.cpp ├── 07. Merge sort │ └── merge.cpp ├── 08. Union │ └── union.cpp ├── 09. Intersection │ └── intersection.cpp ├── 10. Count Inversion │ └── count.cpp ├── 11. Naive partition │ └── partition.cpp ├── 12. Lomuto partition │ └── partition.cpp ├── 13. Hoare's partition │ └── partition.cpp ├── 14. QuickSort Lomuto │ └── sort.cpp ├── 15. QuickSort Hoare │ └── sort.cpp ├── 16. Kth Smallest │ └── smallest.cpp ├── 17. Chocolate distribution │ └── chocolate.cpp ├── 18. Sort and segregate │ └── sort.cpp ├── 19. Min Difference │ └── min.cpp ├── 20. Mege intervals │ └── merge.cpp └── 21. Max guests │ └── guests.cpp ├── 08. Matrix ├── 01. Introduction │ └── matrix.cpp ├── 02. Array as parameters │ └── parameter.cpp ├── 03. Snake pattern │ └── print.cpp ├── 04. Spiral pattern │ └── spiral.cpp ├── 05. Transpose │ └── transpose.cpp ├── 06. Rotate │ └── rotate.cpp ├── 07. Search │ └── search.cpp ├── 08. Print diagonals │ └── diagonal.cpp └── 09. Sort diagonally │ └── sort.cpp ├── 09. Hashing ├── 01. Theory │ └── theory.md ├── 02. Implementation │ └── implement.cpp ├── 03. Count distinct │ └── count.cpp ├── 04. Print freq │ └── print.cpp ├── 05. Intersection │ └── intersection.cpp ├── 06. Union │ └── union.cpp ├── 07. Find pair │ └── pair.cpp ├── 08. Subarray sum 0 │ └── sum.cpp ├── 09. Count subarray │ └── count.cpp ├── 10. Count 0 and 1 │ └── count.cpp ├── 11. Largest subarray │ └── find.cpp ├── 12. Longest subsequence │ └── longest.cpp ├── 13. Distinct elements │ └── count.cpp ├── 14. More than NbyK │ └── count.cpp ├── 15. Sort by freq │ └── sort.cpp ├── 16. winner │ └── winner.cpp ├── 17. Group Anagram │ └── anagram.cpp └── 18. Smaller Right │ └── smaller.cpp ├── 10. Strings ├── 01. Theory │ └── theory.md ├── 02. Operations │ └── operations.cpp ├── 03. Split and store │ └── string.cpp ├── 04. Letter frequency │ └── freq.cpp ├── 05. Word frequency │ └── freq.cpp ├── 06. Palindrome │ └── palindrome.cpp ├── 07. Subsequence │ ├── checkSubsequence.cpp │ └── printSubsequence.cpp ├── 08. Anagram │ └── anagram.cpp ├── 09. First Repeating │ └── repeat.cpp ├── 10. First non-repeating │ └── nonRepeating.cpp ├── 11. Reverse words │ └── reverse.cpp ├── 12. Naive search │ └── pattern.cpp ├── 13. Improved Naive │ └── search.cpp ├── 14. Rabin Karp Algorithm │ └── rk.cpp ├── 15. KMP algorithm │ ├── 1_lps.cpp │ └── kmp.cpp ├── 16. Check Rotated │ └── check.cpp ├── 17. Anagram search │ └── search.cpp ├── 18. Lexicographic rank │ └── rank.cpp ├── 19. Distinct characters │ └── longest.cpp ├── 20. Pangram │ └── pangram.cpp ├── 21. LargestNumber │ └── largest.cpp └── 22. K distinctChar │ └── kdistinct.cpp ├── 11. Pointers ├── 01. Introduction │ ├── 1. Pointer.md │ ├── 2. Double Pointer.md │ ├── pointer-to-pointer.webp │ └── pointers-in-c.png ├── 02. Basics │ └── pointer.cpp ├── 03 .swap │ └── swap.cpp ├── 04. Pointer to array │ └── array.cpp ├── 05. Pointer to structure │ └── structure.cpp ├── 06. Pointer to function │ └── function.cpp └── 07. Pointer Arithmatic │ └── arithmetic.cpp ├── 12. Linked List ├── 01. Theory │ ├── linkedlist.png │ └── theory.md ├── 02. SLL │ ├── 01. Singly Linked List │ │ ├── link.cpp │ │ ├── list.cpp │ │ └── listlinked.cpp │ ├── 02. Traverse │ │ └── traverse.cpp │ ├── 03. Insert begin │ │ └── insert.cpp │ ├── 04. Insert end │ │ └── insert.cpp │ ├── 05. Delete head │ │ └── delete.cpp │ ├── 06. Delete tail │ │ └── delete.cpp │ ├── 07. Insert at pos │ │ └── insert.cpp │ ├── 08. Search │ │ └── search.cpp │ ├── 09. Reverse │ │ └── reverse.cpp │ └── Master │ │ └── list.cpp ├── 03 DLL │ ├── 01. Doubly Linked List │ │ └── doublyLL.cpp │ ├── 02. Insert begin │ │ └── insert.cpp │ ├── 03. Insert end │ │ └── insert.cpp │ ├── 04. Delete head │ │ └── delete.cpp │ ├── 05. Delete tail │ │ └── delete.cpp │ ├── 06. Insert at pos │ │ └── insert.cpp │ ├── 07 Reverse │ │ └── revDoublyLL.cpp │ ├── 08. Search │ │ └── search.cpp │ └── Master │ │ └── list.cpp ├── 04. SCLL │ ├── 01. Singly Circular LL │ │ └── singlyCircular.cpp │ ├── 02. Traverse │ │ └── traverse.cpp │ ├── 03. Insert begin │ │ └── insert.cpp │ ├── 04. Insert end │ │ └── insert.cpp │ ├── 05. Delete head │ │ └── delete.cpp │ ├── 06. Delete tail │ │ └── delete.cpp │ └── 07. Delete kth node │ │ └── delete.cpp ├── 05. CDLL │ ├── 01. Circular Doubly LL │ │ └── cdll.cpp │ ├── 02. Traverse │ │ └── traverse.cpp │ └── 03. Insert begin │ │ └── insert.cpp └── 06. Questions │ ├── 01. Sorted insert │ └── sorted.cpp │ ├── 02. Middle item │ └── center.cpp │ ├── 03. Nth from end │ └── printnode.cpp │ ├── 04. Reverse │ └── reverse.cpp │ ├── 05. Remove dups │ └── remove.cpp │ ├── 06. Reverse in group │ └── rev.cpp │ ├── 07. Detect loop │ └── detect.cpp │ ├── 08. Cycle detection │ └── floyd.cpp │ ├── 09. Remove loop │ └── remove.cpp │ ├── 10. Segregate node │ ├── byIndex.cpp │ └── segregate.cpp │ ├── 11. Intersection │ └── common.cpp │ ├── 12. Pairwise swap │ └── swap.cpp │ ├── 13. Random ptr │ └── random.cpp │ ├── 14. Merge │ └── merge.cpp │ ├── 15. Palindrome │ └── palindrome.cpp │ ├── 16. Add two number │ └── add.cpp │ ├── 17. Rotate │ └── rotate.cpp │ ├── 18. Merge Sort │ └── mergesort.cpp │ └── 19. Reverse in range │ └── revese.cpp ├── 13. Stack ├── 01. Theory │ └── Theory.md ├── 02. Implementation │ ├── 1_Array.cpp │ ├── 2_Vector.cpp │ └── 3_List.cpp ├── 03. Balanced bracket │ └── balanced.cpp ├── 04. Two stack │ └── twoStack.cpp ├── 05. Stock span │ └── span.cpp ├── 06. Previous greater │ └── prevMax.cpp ├── 07. Next greater │ └── nextMax.cpp ├── 08. Previous smaller │ └── prevMin.cpp ├── 09. Next Smaller │ └── nextMin.cpp ├── 10. Histogram area │ ├── _prerequisite.cpp │ └── maxArea.cpp └── 11. Infix Prefix Posfix │ └── Theory.md ├── 14. Queue ├── 01. Theory │ └── queue.md ├── 02. Implementation │ ├── queueArr.cpp │ └── queueList.cpp └── 03. Generate numbers │ └── generate.cpp ├── 15. Deque ├── 01. Theory │ └── theory.md ├── 02. Implementation │ └── dequeArr.cpp └── 03. Max of subarrayK │ └── max.cpp ├── 16. Greedy ├── 01. Theory │ └── theory.md ├── 02. Minimum Coins │ └── minimum.cpp ├── 03. Activity selection │ └── activity.cpp ├── 04. Fractional Knapsack │ └── knapsack.cpp └── 05. Job sequencing │ └── job.cpp ├── 17. Tree ├── 01. Theory │ └── theory.md ├── 02. Implementation │ └── implement.cpp ├── 03. Traversal │ └── traverse.md ├── 04. Depth First Traversal │ ├── 1_inorder_recursive.cpp │ ├── 2_inorder_iterative.cpp │ ├── 3_preorder_recursive.cpp │ ├── 4_preorder_iterative.cpp │ ├── 5_postorder_recursive.cpp │ └── 6_postorder_iterative.cpp ├── 05. Height │ └── height.cpp ├── 06. Print at K distance │ └── print.cpp ├── 07. Breadth First Traversal │ ├── 1_usingtwoFunction.cpp │ ├── 2_usingQueue.cpp │ ├── 3_NewLineWithNULL.cpp │ └── 4_NewLineWithLoop.cpp ├── 08. Count Nodes │ └── count.cpp ├── 09. Maximum │ └── max.cpp ├── 10. Left View │ └── left.cpp ├── 11 Right view │ └── right.cpp ├── 12. Child Sum │ └── sum.cpp ├── 13. Height Balanced │ └── balanced.cpp ├── 14. Width │ └── width.cpp ├── 15. Convert to DLL │ └── dll.cpp ├── 16. Construct tree │ └── construct.cpp ├── 17. Snake Pattern │ └── snake.cpp ├── 18. Diameter │ └── diameter.cpp ├── 19. Compare │ └── checkEqual.cpp ├── 20. Check Subtree │ └── check.cpp ├── 21. Count Subtree │ └── count.cpp ├── 22. Max Pathsum │ └── maxpath.cpp ├── 23. Mirror Tree │ └── mirror.cpp ├── 24. Vertical width │ └── width.cpp ├── 25. Connect Nodes │ └── connect.cpp ├── 26. List to Tree │ └── tree.cpp ├── 27. Foldable Tree │ └── fold.cpp ├── 28. Check CBT │ └── check.cpp ├── 29. Diagonal Tree │ └── diagonal.cpp ├── 30. Boundary │ └── boundary.cpp └── 31. Built Tree │ └── build.cpp ├── 18. Binary Search Tree ├── 01. Theory │ └── theory.md ├── 02. Implementation │ └── implement.cpp ├── 03. Search │ └── search.cpp ├── 04. Insert │ └── insert.cpp ├── 05. Delete │ └── delete.cpp ├── 06. Floor │ └── floor.cpp ├── 07. Ceil │ └── ceil.cpp ├── 08. Range BST │ └── range.cpp ├── 09. Range Count │ └── range.cpp ├── 10. Pair Sum │ └── pair.cpp ├── 11. Vertical Traversal │ └── vertical.cpp ├── 12. Veritcal Sum │ └── vertical.cpp ├── 13. Top View │ └── top.cpp └── 14. Bottom View │ └── bottom.cpp ├── 19. Graph ├── 01. Theory │ ├── Graph.png │ └── theory.md ├── 02. Implementation │ ├── graph_1_a.cpp │ ├── graph_1_a.png │ ├── graph_1_b.cpp │ ├── graph_1_b.png │ ├── graph_2_a.cpp │ ├── graph_2_a.png │ ├── graph_2_b.cpp │ ├── graph_2_b.png │ └── graph_3.cpp ├── 03. DFS │ ├── 01_dfs.cpp │ ├── 02_dfs.cpp │ ├── 03_dfs_itr.cpp │ └── 04_dfs_naray.cpp ├── 04. Cond Comp │ └── CC.cpp ├── 06. SSSP │ ├── 01_sssp.cpp │ ├── 02_ques.cpp │ └── 03_ques.cpp ├── 07. Bipartite │ ├── 01_bp.cpp │ └── 02_ques.cpp ├── 08. Cycle Detection │ ├── 01_findCycle.cpp │ ├── 02_printCycle.cpp │ └── 03_directed.cpp ├── 09. Problem │ └── codechef.cpp ├── 10. InOut │ └── inout.cpp ├── 11. Diameter │ └── ques.cpp ├── 12. Subtree Size │ └── subtree.cpp ├── 13. BFS │ ├── 01_bfs.cpp │ └── 02_bfs.cpp ├── 14. SSSP │ └── sssp_bfs.cpp ├── 15. Prime Path │ └── prime.cpp ├── 16. Feasible Relations │ └── relations.cpp ├── 17. Social Networking │ └── social.cpp ├── 18. Word Ladder │ └── word.cpp ├── 19. Print paths │ └── print.cpp ├── 20. Bridges │ ├── 01_bridges.cpp │ └── 02_ques.cpp ├── 21. Articulation Points │ └── cutVertices.cpp ├── 22. Topological Sort │ ├── 01_bfstopo.cpp │ ├── 02_dfstopo.cpp │ ├── 03_ques.cpp │ ├── 04_sssp_dag.cpp │ └── 05_cycle.cpp ├── 23. DFS Grid │ ├── 01_dfs.cpp │ └── 02_dfs.cpp ├── 24. Cond Comp │ ├── 01_cc.cpp │ └── 02_cc.cpp ├── 25. BFS │ ├── 01_bfs.cpp │ ├── 02_bfs.cpp │ ├── 03_bfs.cpp │ └── 04_bfs.cpp ├── 26. Min Moves │ └── knight.cpp ├── 27. Kosaraju's Algo │ └── kosaraju.cpp ├── 28. Tarjan's Algo │ └── tarjan.cpp ├── 29. Prim's algo │ └── prim.cpp └── 30. Kruskal's algo │ ├── dsu.cpp │ └── kruskal.cpp ├── README.md └── _Utility ├── 01. Preprocessors └── preprocessor.cpp ├── 02. Builtin functions └── builtInFn.cpp ├── 03. vector └── vector.cpp ├── 04. pair └── pair.cpp ├── 05. set └── set.c++ ├── 06. map └── map.cpp ├── 07. Strings └── strings.cpp ├── 08. List └── list.cpp ├── 09. stack └── stack.cpp └── _images └── demo.png /.gitignore: -------------------------------------------------------------------------------- 1 | # IGNORE EXECUTABLES 2 | *.exe 3 | *.vscode 4 | *.out -------------------------------------------------------------------------------- /01. Time Complexity/1.order_of_growth.md: -------------------------------------------------------------------------------- 1 | ## Order of growth: 2 | 3 | - Order of growth determines the general behaviour of an algorithm when the input size is large. 4 | 5 | ## Limitation of order of growth analysis: 6 | 7 | - The input might never reach to a large value.
8 | - For smaller values of n, generally we don't need order of growth analysis. 9 | 10 | ## Direct way to compare order of growth 11 | 12 | - Ignore lower order terms 13 | - Ignore leading constants 14 | 15 | ## Lower order terms priority : 16 | 17 | - constant < log(log(n)) < n1/3 < n1/2 < n < n2 < n3 < n4 < 2n < nn 18 | -------------------------------------------------------------------------------- /02. Mathematics/01.CountDigit/countDigit.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Count number of digits in a given integer 3 | eg: 7123 has 4 digits 4 | */ 5 | 6 | #include 7 | using namespace std; 8 | 9 | // Iterative soln O(n) 10 | int countDigitsIteratively(long n) 11 | { 12 | // init vars 13 | int count = 0; 14 | 15 | // logic: 16 | while (n) 17 | { 18 | n /= 10; 19 | count++; 20 | } 21 | 22 | // return ans 23 | return count; 24 | } 25 | 26 | // Recursive soln O(n) 27 | int countDigitsRecursively(long n) 28 | { 29 | // base case 30 | if (n == 0) 31 | return 0; 32 | 33 | // recursion 34 | return 1 + countDigitsRecursively(n / 10); 35 | } 36 | 37 | // Best soln O(log n) 38 | int countDigitsEfficiently(long n) 39 | { 40 | return floor(log10(n) + 1); 41 | } 42 | 43 | // Driver code 44 | int main() 45 | { 46 | // Given number 47 | int n = 2179; 48 | 49 | // fn call 50 | cout << countDigitsEfficiently(n); 51 | } -------------------------------------------------------------------------------- /02. Mathematics/02.Palindrome/palindrome.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Check whether a given number is palindrome or not 3 | eg: 212 is a palindrome, 362 is not 4 | */ 5 | 6 | #include 7 | using namespace std; 8 | 9 | // Time complexity O(digit) 10 | bool checkPalindrome(int number) 11 | { 12 | // init vars 13 | int temp = number, remainder, reversed = 0; 14 | 15 | // logic: 16 | while (number) 17 | { 18 | remainder = number % 10; 19 | reversed = reversed * 10 + remainder; 20 | number /= 10; 21 | } 22 | 23 | // return ans 24 | return temp == reversed; 25 | } 26 | 27 | // Driver code 28 | int main() 29 | { 30 | // Given number 31 | int num = 121; 32 | 33 | // fn call 34 | checkPalindrome(num) ? cout << "Palindrome" : cout << "Not a palindrome"; 35 | } -------------------------------------------------------------------------------- /02. Mathematics/03.Factorial/fact.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Find factorial of given number 3 | eg: 4! = 4 * 3 * 2 * 1 = 24 4 | */ 5 | 6 | #include 7 | using namespace std; 8 | 9 | // Iterative factorial. Better approach, Time complexity O(n) 10 | int factIterative(int n) 11 | { 12 | // init vars 13 | int fact = 1; 14 | 15 | // logic: 16 | for (int i = n; i > 0; i--) 17 | fact = fact * i; 18 | 19 | // return ans 20 | return fact; 21 | } 22 | 23 | // Recursive factorial. Time complexity O(n) 24 | int factRecursive(int n) 25 | { 26 | // base case 27 | if (n == 0) 28 | return 1; 29 | 30 | // recursive call 31 | return n * factRecursive(n - 1); 32 | } 33 | 34 | // Driver code 35 | int main() 36 | { 37 | // Given number 38 | int num = 6; 39 | 40 | // fn call 41 | cout << factRecursive(num); 42 | } -------------------------------------------------------------------------------- /02. Mathematics/04.CountTrailZero/countTrailZero.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Count number of trailing zeroes in the factorial 3 | eg 10! = 3628800, number of trailing zeroes = 2 4 | */ 5 | 6 | #include 7 | using namespace std; 8 | 9 | // Count zero after finding factorial (overflow even at small numbers) 10 | int countZeros(int n) 11 | { 12 | // find factorial 13 | int fact = 1; 14 | for (int i = n; i > 0; i--) 15 | fact *= i; 16 | 17 | // logic: 18 | int countZeros = 0; 19 | while (fact % 10 == 0) 20 | { 21 | countZeros++; 22 | fact /= 10; 23 | } 24 | 25 | // return ans 26 | return countZeros; 27 | } 28 | 29 | // Efficient way O(log n) 30 | int countZerosEfficiently(int n) 31 | { 32 | // init var 33 | int count = 0; 34 | 35 | // logic: 36 | for (int i = 5; i <= n; i *= 5) // count 2 and 5 which are the reason for trailing zeros 37 | count += n / i; // sum of floor of n/i 38 | 39 | // answer 40 | return count; 41 | } 42 | 43 | // Driver code 44 | int main() 45 | { 46 | // Given number 47 | int num = 10; 48 | 49 | // fn call 50 | cout << "counted efficiently: " << countZerosEfficiently(num) << "\n"; 51 | } 52 | 53 | /* 54 | NOTES: 55 | * The number of 5's are always less than the number of 2's in a factorial 56 | * Every 5th number is going to have 5 as a prime factor 57 | * For a number n, it will have [n/5] 5's in prime factor where [] is floor fn 58 | * A table of factorials: https://www.mymathtables.com/numbers/100-factorial-tables-chart.html 59 | * Explanation: https://www.youtube.com/watch?v=fx8rUY_iIms 60 | */ -------------------------------------------------------------------------------- /02. Mathematics/05.GCD/GCD.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Find Greatest Common Divisor of two integers 3 | eg: GCD(4,6) = 2 4 | */ 5 | 6 | #include 7 | using namespace std; 8 | 9 | // Naive approach to GCD O(min(x,y)) 10 | int getGCD(int x, int y) 11 | { 12 | // get min of given two numbers 13 | int GCD = min(x, y); 14 | 15 | // if min divides both x and y break and thats the ans otherwise decrease and try again 16 | while (GCD) 17 | { 18 | if (x % GCD == 0 && y % GCD == 0) 19 | break; 20 | GCD--; 21 | } 22 | 23 | // return answer 24 | return GCD; 25 | } 26 | 27 | // Better approach Euclidean algorithm 28 | int euclidAlgorithm(int x, int y) 29 | { 30 | // logic: 31 | while (x != y) 32 | { 33 | if (x > y) 34 | x -= y; 35 | else 36 | y -= x; 37 | } 38 | 39 | // return ans; 40 | return x; 41 | } 42 | 43 | // Best approach optimized Euclidean algorithm 44 | int optimizedEuclid(int a, int b) 45 | { 46 | if (b == 0) 47 | return a; 48 | else 49 | return optimizedEuclid(b, a % b); 50 | } 51 | 52 | // Driver code 53 | int main() 54 | { 55 | // Given numbers 56 | int a = 4, b = 6; 57 | 58 | // fn call 59 | cout << optimizedEuclid(a, b) << "\n"; 60 | } 61 | 62 | /* 63 | NOTES: 64 | * gcd(a,b) * lcm(a,b) = (a*b) 65 | * https://www.youtube.com/watch?v=VWOUh4w_zVI 3:20 66 | */ -------------------------------------------------------------------------------- /02. Mathematics/06.LCM/LCM.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Find Least Common Multiple of two integers 3 | eg: LCM(7,3) = 21 4 | */ 5 | 6 | #include 7 | using namespace std; 8 | 9 | // Similar to GCD O(a*b - max(a,b)) 10 | int getLCM(int x, int y) 11 | { 12 | // init vars 13 | int LCM = max(x, y); 14 | 15 | // logic: 16 | while (1) 17 | { 18 | if (LCM % x == 0 && LCM % y == 0) 19 | return LCM; 20 | LCM++; 21 | } 22 | 23 | // return ans 24 | return LCM; 25 | } 26 | 27 | // Effeicient solution 28 | int getGCD(int a, int b) 29 | { 30 | // base case 31 | if (b == 0) 32 | return a; 33 | 34 | // recursion 35 | else 36 | return getGCD(b, a % b); 37 | } 38 | int getLCMefficiently(int x, int y) 39 | { 40 | return (x * y) / getGCD(x, y); 41 | } 42 | 43 | // Driver code 44 | int main() 45 | { 46 | // Given numbers 47 | int a = 7, b = 3; 48 | 49 | // fn call 50 | cout << getLCMefficiently(a, b) << "\n"; 51 | } 52 | 53 | /* 54 | NOTES: 55 | * gcd(a,b) * lcm(a,b) = (a*b) 56 | * https://www.youtube.com/watch?v=VWOUh4w_zVI 3:20 57 | */ -------------------------------------------------------------------------------- /02. Mathematics/09.AllDivisiors/allDivisor.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Print all divisors of given integer 3 | eg: 50 = [1, 2, 5, 10, 25, 50] 4 | */ 5 | 6 | #include 7 | using namespace std; 8 | 9 | // Naive solution 10 | void printDivisors(int n) 11 | { 12 | for (int i = 1; i <= n; i++) 13 | if (n % i == 0) 14 | cout << i << " "; 15 | } 16 | 17 | // Best solution 18 | void printDivisorEfficiently(int n) 19 | { 20 | 21 | // logic: 22 | for (int i = 1; i * i <= n; i++) 23 | { 24 | if (n % i == 0) 25 | { 26 | cout << i << " "; 27 | // for perfect squares, to prevent printing twice 28 | if (i != n / i) 29 | cout << n / i << " "; 30 | } 31 | } 32 | } 33 | 34 | // Driver code 35 | int main() 36 | { 37 | // Given number 38 | int n = 50; 39 | 40 | // fn call 41 | printDivisorEfficiently(n); 42 | } -------------------------------------------------------------------------------- /02. Mathematics/10.SieveOfEratosthenes/primeInRange.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Print prime number in given range L to R 3 | eg: L = 1, R = 25 => [2, 3, 5, 7, 11, 13, 17, 19, 23] 4 | */ 5 | 6 | #include 7 | using namespace std; 8 | 9 | // To print prime from 1 to n. Time complexity O(n * sqrt n) 10 | void sieveOfEratosthenes(int n) 11 | { 12 | // init vars 13 | vector isPrime(n + 1, true); 14 | 15 | // logic: 16 | for (int i = 2; i * i <= n; i++) 17 | if (isPrime[i]) 18 | for (int j = i * i; j <= n; j += i) 19 | isPrime[j] = false; 20 | 21 | // output 22 | for (int i = 2; i <= n; i++) 23 | if (isPrime[i]) 24 | cout << i << " "; 25 | // https://www.youtube.com/watch?v=nDPo9hsDNvU 26 | } 27 | 28 | // Optimized sieveOfEratosthenes O(n loglog n) 29 | void optimizedSieveOfEratosthenes(int n) 30 | { 31 | // init vars 32 | vector isPrime(n + 1, true); 33 | 34 | // logic: 35 | for (int i = 2; i <= n; i++) 36 | { 37 | if (isPrime[i]) 38 | { 39 | cout << i << " "; 40 | for (int j = i * i; j <= n; j += i) 41 | isPrime[j] = false; 42 | } 43 | } 44 | // https://www.youtube.com/watch?v=eKp56OLhoQs 45 | } 46 | 47 | // Driver code 48 | int main() 49 | { 50 | // Given number 51 | int n = 100; 52 | 53 | // fn call 54 | sieveOfEratosthenes(n); 55 | } -------------------------------------------------------------------------------- /02. Mathematics/11.Power/power.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Calculate base to the power exponent 3 | eg: base = 2, expo = 3 then power = 2^3 = 8 4 | */ 5 | 6 | #include 7 | using namespace std; 8 | 9 | /* 10 | power (x,n) can be written as : 11 | 12 | power(x,n/2) * power(x,n/2) // if n is even 13 | 14 | power(x,n-1)*x // if n is odd 15 | */ 16 | 17 | // Time complexity O(log n) 18 | int power(int x, int n) 19 | { 20 | // base case 21 | if (n == 0) 22 | return 1; 23 | 24 | // init vars: 25 | int temp = power(x, n / 2); 26 | temp *= temp; 27 | 28 | // logic: 29 | if (n % 2 == 0) 30 | return temp; 31 | else 32 | return temp * x; 33 | } 34 | 35 | // Driver code 36 | int main() 37 | { 38 | // Given numbers 39 | int base = 3, expo = 2; 40 | 41 | // fn call 42 | cout << power(base, expo); 43 | } -------------------------------------------------------------------------------- /02. Mathematics/12. Exactly 3 Divisor/divisor.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Given a number, find whether it has exactly 3 divisors or not. 3 | */ 4 | 5 | #include 6 | using namespace std; 7 | 8 | // Check whether number is prime 9 | bool isPrime(int number) 10 | { 11 | // logic: 12 | for (int i = 2; i * i <= number; i++) 13 | if (number % i == 0) 14 | return false; 15 | 16 | // answer 17 | return true; 18 | } 19 | 20 | // Check wheter number has exactly 3 divisors 21 | int exactly3Divisors(int number) 22 | { 23 | // init vars: 24 | int count = 1; 25 | 26 | // base case 27 | if (number <= 3) 28 | return 0; 29 | 30 | // only those number whose sqrt is prime have exactly 3 divisor 31 | for (int i = 3; i <= sqrt(number); i++) 32 | if (isPrime(i) && (i * i) <= number) 33 | count++; 34 | 35 | // return ans 36 | return count; 37 | } 38 | 39 | // Driver code 40 | int main() 41 | { 42 | // Given number 43 | int num = 8219; 44 | 45 | // fn call 46 | cout << exactly3Divisors(num); 47 | } -------------------------------------------------------------------------------- /02. Mathematics/13. FastExponent/exponent.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Fast exponent used in competitive programming 3 | */ 4 | 5 | #include 6 | using namespace std; 7 | 8 | #define LL long long 9 | const LL MOD = 1000000007; 10 | 11 | /* 12 | Remember: (x + y) % mod = (x % mod + y % mod) % mod 13 | Time complexity O(log (y)) 14 | */ 15 | LL fastModuloExponent(LL x, LL y, LL MOD) 16 | { 17 | // init result 18 | LL result = 1; 19 | 20 | // bit masking 21 | while (y > 0) 22 | { 23 | // if last bit is 1 24 | if (y & 1) 25 | result = (result * x) % MOD; 26 | 27 | // square of x 28 | x = (x * x) % MOD; 29 | 30 | // discard rightmost bit 31 | y = y >> 1; 32 | } 33 | 34 | // answer 35 | return result; 36 | } 37 | 38 | // Driver code 39 | int main() 40 | { 41 | // Given numbers 42 | int base = 3, expo = 5; 43 | 44 | // fn call 45 | cout << fastModuloExponent(base, expo, MOD); 46 | } 47 | 48 | /* 49 | eg: Calculate 3 ^ 5 50 | * initialize result = 1 51 | * Convert 5 to binary = 1 0 1 52 | * multiply each bit to successive square of 3 53 | * {(3^2^2 * 1)} * { (3^2 * 0)_skippded_ } * {(3^1 * 1)} = 243 54 | */ -------------------------------------------------------------------------------- /03. Bit Magic/01. Theory/BitwiseOperators.md: -------------------------------------------------------------------------------- 1 | - ## Left shift (<<): 2 | Assuming that the leading y bits of a 32 bit number are zero eg: 0...0010, 3 | The result of (x << y) is: x\*2y . 4 | 5 |

6 | 7 | - ## Right shift (>>): 8 | 9 | The result of (x >> y) is equivalent to: [x/2 y] , where [ ] is floor function. 10 | 11 |

12 | 13 | - ## Negation (~) 14 | 15 | The negation of a number inverts all 0 to 1 or vice versa. 16 | 17 |

18 | 19 | - ## XOR (^) 20 | 21 | Important properties of XOR: 22 | 23 | ``` 24 | x^x = 0 25 | x^0 = x 26 | x^y = y^x 27 | x^(y^z) = (x^y)^z 28 | ``` 29 | 30 |

31 | 32 | - ## NOTE: 33 | 34 | It is not recommended to use left shift, right shift or negation on negative numbers. 35 | 36 | -------------------------------------------------------------------------------- /03. Bit Magic/02. Operations/Bitwise.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Introduction to bitwise operators 3 | */ 4 | #include 5 | using namespace std; 6 | 7 | // Driver code 8 | int main() 9 | { 10 | int x = 5; 11 | int y = 3; 12 | unsigned temp = 5; 13 | int rs = 1; 14 | int ls = 2; 15 | cout << x << " & " << y << " is : " << (x & y) << "\n"; // AND 16 | cout << x << " | " << y << " is : " << (x | y) << "\n"; // OR 17 | cout << x << " ^ " << y << " is : " << (x ^ y) << "\n"; // XOR 18 | cout << x << " >> " << rs << " is : " << (x >> rs) << "\n"; // right shift 19 | cout << x << " << " << ls << " is : " << (x << ls) << "\n"; // left shift 20 | cout << "~" << x << " is : " << (~x) << "\n"; // operates in bit 21 | cout << "!" << x << " is : " << (!x) << "\n"; // operates in number 22 | cout << "Negation of unsigned " << temp << " is : " << (~temp) << "\n"; // operates in bit 23 | } -------------------------------------------------------------------------------- /03. Bit Magic/03. CheckKthBit/checkBit.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Check if kth bit of a number is set (1) or not (0) 3 | eg: 10 (decimal input) => 001010 (binary): check 4th bit => 4th bit is set 4 | */ 5 | 6 | #include 7 | using namespace std; 8 | 9 | // Check kth bit 10 | bool checkSetBitWithLeftShift(int n, int k) 11 | { 12 | // 101 & ( 001 << (3-1) ) = 101 & 100 = 4 (non zero) 13 | if ((n & (1 << (k - 1))) != 0) 14 | return true; 15 | 16 | // answer 17 | return false; 18 | } 19 | 20 | // Same concept, but with right shift 21 | bool checkSetBitWithRightShift(int n, int k) 22 | { 23 | // logic: 24 | if ((n >> (k - 1)) & 1 == 1) 25 | return true; 26 | 27 | // answer 28 | return false; 29 | } 30 | 31 | // Driver code 32 | int main() 33 | { 34 | // Given numbers 35 | int num1 = 10, num2 = 4; 36 | 37 | // fn call 38 | cout << checkSetBitWithLeftShift(num1, num2) << "\n"; 39 | cout << checkSetBitWithRightShift(num1, num2) << "\n"; 40 | } -------------------------------------------------------------------------------- /03. Bit Magic/04. RightMostDiffBit/rightMostDiffBit.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Given two numbers M and N. The task is to find the position of the 3 | rightmost different bit in the binary representation of numbers. 4 | eg: 11, 15 (decimal input) => 1011, 1111 (binary) => 3rd bit is rightmost different bit 5 | */ 6 | 7 | #include 8 | using namespace std; 9 | 10 | // Check kth bit is set or not 11 | bool checkSetBit(int n, int k) 12 | { 13 | // logic: 14 | if ((n & (1 << (k - 1))) != 0) 15 | return true; 16 | 17 | // fn call 18 | return false; 19 | } 20 | 21 | // Driver code 22 | int main() 23 | { 24 | // Input 25 | int A, B, i; 26 | cin >> A >> B; 27 | 28 | // Compare all number one by one, loop for 64 times for 64 bit compiler 29 | for (i = 1; i <= 64; i++) 30 | if (checkSetBit(A, i) != checkSetBit(B, i)) 31 | break; 32 | 33 | // Output 34 | cout << i << " "; 35 | } -------------------------------------------------------------------------------- /03. Bit Magic/05. CountSetBit/countBit.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Count total number of set (1) bit in binary representation of a number 3 | eg: 15 (decimal) => 1111 (binary) => total set bit = 4 4 | */ 5 | 6 | #include 7 | using namespace std; 8 | 9 | // Count set bits Brian Kerningam's algorithm 10 | // Logic: (n & n-1) strikes off (deletes) last set bit 11 | // Time complexity : O(set bit count) 12 | int countSetBit(int n) 13 | { 14 | // init vars 15 | int count = 0; 16 | 17 | // logic: 18 | while (n) 19 | { 20 | // first iteration: 101 & 100 = 100 // second iteration: 100 & 011 = 0 21 | n &= (n - 1); 22 | count++; 23 | } 24 | 25 | // answer 26 | return count; 27 | } 28 | 29 | // Driver code 30 | int main() 31 | { 32 | // Given number 33 | int num = 5; 34 | 35 | // fn call 36 | cout << countSetBit(num); 37 | } -------------------------------------------------------------------------------- /03. Bit Magic/06. BitInRange/bitInRange.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Given a number N. Find the total count of set bits for all numbers from 1 to N (both inclusive) 3 | */ 4 | 5 | #include 6 | using namespace std; 7 | 8 | // Count set bit in range in O(log n) 9 | int countSetBits(int n) 10 | { 11 | // base case 12 | if (n == 0) 13 | return 0; 14 | 15 | // recursive call 16 | int x = floor(log10(n) / log10(2)); 17 | return ((pow(2, x - 1) * x) + (n - pow(2, x) + 1) + countSetBits(n - pow(2, x))); 18 | // https://www.youtube.com/watch?v=g6OxU-hRGtY&t=6s 19 | } 20 | 21 | // Driver code 22 | int main() 23 | { 24 | // Given number 25 | int num = 4; 26 | 27 | // fn call 28 | cout << countSetBits(num); 29 | } -------------------------------------------------------------------------------- /03. Bit Magic/07. PowerOfTwo/po2.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Check if a number is power of 2 or not 3 | eg: 64 => true 4 | 5 | Concept: Power of two has only one bit set 6 | */ 7 | 8 | #include 9 | using namespace std; 10 | 11 | // Assmption n>=0 12 | bool powerOfTwo(int n) 13 | { 14 | // corner case 15 | if (n == 0) 16 | return false; 17 | 18 | // logic: if at any point division gives odd num => not power of 2 19 | while (n != 1) 20 | { 21 | if (n % 2 != 0) 22 | return false; 23 | n /= 2; 24 | } 25 | 26 | // answer 27 | return true; 28 | } 29 | 30 | // Best approach 31 | bool towsPowerUsingBriansAlgorithm(int n) 32 | { 33 | // (n != 0) and (unset the only set bit and check if the number == 0) 34 | return (n != 0) && ((n & (n - 1)) == 0); 35 | } 36 | 37 | // Driver code 38 | int main() 39 | { 40 | // Given number 41 | int num = 16; 42 | 43 | // fn call 44 | cout << powerOfTwo(num) << "\n"; 45 | cout << towsPowerUsingBriansAlgorithm(num) << "\n"; 46 | } -------------------------------------------------------------------------------- /03. Bit Magic/08. Missing number/missing.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Given an array of n numbers that has values in range [1, n+1]. 3 | Every no. appear exactly once. Hence one number is missing. 4 | Find the missing number 5 | 6 | Properties of XOR: 7 | x^x = 0 8 | x^0 = x 9 | x^y = y^x 10 | x^(y^z) = (x^y)^x 11 | */ 12 | #include 13 | using namespace std; 14 | 15 | // Time: O(n) 16 | int findNumber(int arr[], int n) 17 | { 18 | // init variable 19 | int found = 0; 20 | 21 | // XOR of all number in array 22 | for (int i = 0; i < n; i++) 23 | found ^= arr[i]; 24 | 25 | // XOR of all number from 1 to n+1 26 | for (int i = 1; i <= n + 1; i++) 27 | found ^= i; 28 | 29 | // answer 30 | return found; 31 | } 32 | 33 | // Driver code 34 | int main() 35 | { 36 | // Given arr 37 | int arr[] = {1, 4, 3, 2}; 38 | int n = sizeof(arr) / sizeof(arr[0]); 39 | 40 | // fn call 41 | cout << findNumber(arr, n); 42 | } -------------------------------------------------------------------------------- /03. Bit Magic/09. SwapEvenOdd/swap.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Given an unsigned integer N. The task is to swap all odd bits with even bits. 3 | For example, if the given number is 23 (00010111), it should be converted to 43(00101011). 4 | 5 | Algorithm: 6 | Obtain the even bits and shift them to odd position 7 | Obtain the odd bits and shift them to even position 8 | combine these values using | operators 9 | 10 | Theory: 11 | 0xAAAAAAAA = 32 bit number where even bits = 1 and odd bits = 0 12 | where A = 1010 13 | 14 | 0x55555555 = 32 bit number where even bits = 0 and odd bits = 1 15 | where 5 = 0101 16 | */ 17 | 18 | #include 19 | using namespace std; 20 | 21 | // Swap in O(1) 22 | int swap(int n) 23 | { 24 | int evenBits, oddBits, answer; 25 | evenBits = n & 0xAAAAAAAA; // gets value of even position 26 | oddBits = n & 0x55555555; // gets balue of odd position 27 | evenBits >>= 1; // right shift for swap 28 | oddBits <<= 1; // right shift for swap 29 | answer = evenBits | oddBits; // combine both bits 30 | return answer; 31 | // https://www.youtube.com/watch?v=GWLCF808oVI 32 | } 33 | 34 | // Driver code 35 | int main() 36 | { 37 | // Given number 38 | int n = 23; 39 | 40 | // fn call 41 | cout << swap(n); 42 | } -------------------------------------------------------------------------------- /03. Bit Magic/10. Only odd occuring/odd.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Given an array of int where all no. appear even number of times except one no. Find this number. 3 | 4 | Properties of XOR: 5 | x^x = 0 6 | x^0 = x 7 | x^y = y^x 8 | x^(y^z) = (x^y)^x 9 | */ 10 | 11 | #include 12 | using namespace std; 13 | 14 | // Time: O(n) 15 | int findOddOccurance(int arr[], int n) 16 | { 17 | // init vars 18 | int found = 0; 19 | 20 | // logic: 21 | for (int i = 0; i < n; i++) 22 | found ^= arr[i]; 23 | 24 | // answer 25 | return found; 26 | } 27 | 28 | // Driver code 29 | int main() 30 | { 31 | // Given array 32 | int arr[] = {4, 2, 4, 4, 5, 5, 4, 3, 2}; 33 | int n = sizeof(arr) / sizeof(arr[0]); 34 | 35 | // fn call 36 | cout << findOddOccurance(arr, n); 37 | } -------------------------------------------------------------------------------- /04. Recursion/01. Theory/recursion.md: -------------------------------------------------------------------------------- 1 | ## Recursion: 2 | 3 | - Function calling itself directly or indirectly is called recursion and the corresponding function is called recursive function. 4 | 5 | - Types of recursion 6 | - Head recursion 7 | - Tail recursion 8 | 9 |
10 | 11 | ## Recursion structure: 12 | 13 | ``` 14 | ...fun(...){ 15 | base case 16 | ... 17 | 18 | Recursive call (i.e. call to fun()) 19 | with at least one change in parameter 20 | } 21 | 22 | ``` 23 | -------------------------------------------------------------------------------- /04. Recursion/02. Guess Output/guess.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Predict the output of following functions 3 | */ 4 | 5 | #include 6 | using namespace std; 7 | 8 | // Function 1 9 | void firstFun(int n) 10 | { 11 | // base case 12 | if (n == 0) 13 | return; 14 | 15 | // print statement 16 | cout << n << " "; 17 | 18 | // recursion 19 | firstFun(n - 1); 20 | 21 | // print statement 22 | cout << n << " "; 23 | } 24 | 25 | // Function 2 26 | void secondFun(int n) 27 | { 28 | // base case 29 | if (n == 0) 30 | return; 31 | 32 | // recursion 33 | secondFun(n - 1); 34 | 35 | // print statement 36 | cout << n << " "; 37 | 38 | // recursion 39 | secondFun(n - 1); 40 | } 41 | 42 | // Function 3 (gives [log2 n]) 43 | int thirdFun(int n) 44 | { 45 | // base case 46 | if (n == 1) 47 | return 0; 48 | 49 | // recursion 50 | else 51 | return (1 + thirdFun(n / 2)); 52 | } 53 | 54 | // Function 4 (prints binary) 55 | void fourthFun(int n) 56 | { 57 | // base case 58 | if (n == 0) 59 | return; 60 | 61 | // recrusion 62 | fourthFun(n / 2); 63 | 64 | // print statement 65 | cout << (n % 2); 66 | } 67 | 68 | // Driver code 69 | int main() 70 | { 71 | // Function 1 72 | cout << "First function:\n"; 73 | firstFun(3); 74 | cout << "\n"; 75 | 76 | // Function 2 77 | cout << "Second function:\n"; 78 | secondFun(3); 79 | cout << "\n"; 80 | 81 | // Function 3 82 | cout << "Third function:\n"; 83 | cout << thirdFun(16); 84 | cout << "\n"; 85 | 86 | // Function 4 87 | cout << "Fourth function:\n"; 88 | fourthFun(8); 89 | } -------------------------------------------------------------------------------- /04. Recursion/03. Print Numbers/printNumber.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Print number from 1 to N and N to 1 using recursion 3 | */ 4 | 5 | #include 6 | using namespace std; 7 | 8 | // Head reursion (print 1 to N) Time complexity: O(n), Aux space: O(n) 9 | void printNumbers(int n) 10 | { 11 | // base case 12 | if (n == 0) 13 | return; 14 | 15 | // recursion 16 | printNumbers(n - 1); 17 | 18 | // print statement 19 | cout << n << " "; 20 | } 21 | 22 | // Tail recursion (print N to 1) Time complexity: O(n), Aux space: O(n) 23 | void printNumbersInReverse(int n) 24 | { 25 | // base case 26 | if (n == 0) 27 | return; 28 | 29 | // print statement 30 | cout << n << " "; 31 | 32 | // recursion 33 | printNumbersInReverse(n - 1); 34 | } 35 | 36 | // Driver code 37 | int main() 38 | { 39 | // Given number 40 | int num = 10; 41 | 42 | // print 1 to num 43 | printNumbers(num); 44 | cout << "\n"; 45 | 46 | // print num to 1 47 | printNumbersInReverse(num); 48 | } -------------------------------------------------------------------------------- /04. Recursion/04. Fact and Fibo/FactnFibo.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Find fibonacci(n) and factorial(n) using recursion. 3 | eg: fib(9) = 34, fact(9) = 362880 4 | */ 5 | 6 | #include 7 | using namespace std; 8 | 9 | // Factorial 10 | int fact(int n) 11 | { 12 | // base case 13 | if (n == 0) 14 | return 1; 15 | 16 | // fn call 17 | return n * fact(n - 1); 18 | } 19 | 20 | // Fibonacci 21 | int fib(int n) 22 | { 23 | // base case if (n<=1) return n 24 | if (n == 0) 25 | return 0; 26 | if (n == 1) 27 | return 1; 28 | 29 | // fn call 30 | return (fib(n - 1) + fib(n - 2)); 31 | } 32 | 33 | // Driver code 34 | int main() 35 | { 36 | // Given number 37 | int num = 9; 38 | 39 | // fn call 40 | cout << fact(num) << "\n"; 41 | cout << fib(num) << "\n"; 42 | } -------------------------------------------------------------------------------- /04. Recursion/05. Palindrome/palindrome.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Using recursion, check whether given string is palindrome or not 3 | eg: babbab => true 4 | */ 5 | 6 | #include 7 | using namespace std; 8 | 9 | // Check palindrome using recursion 10 | bool checkPalindrome(string str, int start, int end) 11 | { 12 | // base case 13 | if (start >= end) 14 | return true; 15 | // fn call 16 | if (str[start] == str[end]) 17 | return checkPalindrome(str, start + 1, end - 1); 18 | 19 | // if not palindrome 20 | return false; 21 | } 22 | 23 | // Code cleaned 24 | bool isPalindrome(string str, int start, int end) 25 | { 26 | // base case 27 | if (start >= end) 28 | return true; 29 | 30 | // fn call 31 | return ((str[start] == str[end]) && isPalindrome(str, start + 1, end - 1)); 32 | } 33 | 34 | // Driver code 35 | int main() 36 | { 37 | // Given string 38 | string s = "racecar"; 39 | 40 | // fn call 41 | cout << (checkPalindrome(s, 0, s.length() - 1) ? "Palindrome" : "Not Palindrome"); 42 | } -------------------------------------------------------------------------------- /04. Recursion/06. Sum of Digits/sum.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Find sum of digits of a given number using recursion 3 | eg: 253 => 2 + 5 + 3 = 10 4 | */ 5 | 6 | #include 7 | using namespace std; 8 | 9 | // Sum using recursion 10 | int getSum(int n) 11 | { 12 | // base case 13 | if (n == 0) 14 | return 0; 15 | 16 | // logic: 17 | return getSum(n / 10) + (n % 10); 18 | } 19 | 20 | // Driver code 21 | int main() 22 | { 23 | // Given number 24 | int num = 253; 25 | 26 | // fn call 27 | cout << getSum(num); 28 | } -------------------------------------------------------------------------------- /04. Recursion/07. Rope cutting/rope.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Given a rope of length n. Cut this rope into maximum 3 | number of pieces such that every piece has length as 4 | either a, b or c 5 | */ 6 | 7 | #include 8 | using namespace std; 9 | 10 | // Find max rope length 11 | int rope(int n, int a, int b, int c) 12 | { 13 | // base case 14 | if (n == 0) 15 | return 0; 16 | if (n < 0) 17 | return -1; 18 | 19 | // max value of three functions 20 | int max = (rope(n - a, a, b, c) > rope(n - b, a, b, c)) ? (rope(n - a, a, b, c) > rope(n - c, a, b, c) ? rope(n - a, a, b, c) : rope(n - c, a, b, c)) : (rope(n - b, a, b, c) > rope(n - c, a, b, c) ? rope(n - b, a, b, c) : rope(n - c, a, b, c)); 21 | 22 | // if all three of them return -1 23 | if (max == -1) 24 | return -1; 25 | 26 | // return answer 27 | return max + 1; 28 | } 29 | 30 | // Driver code 31 | int main() 32 | { 33 | // Given numbers 34 | int n = 9, a = 2, b = 2, c = 2; 35 | 36 | // fn call 37 | cout << rope(n, a, b, c); 38 | } 39 | -------------------------------------------------------------------------------- /04. Recursion/08. Generate Subset/subset.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Print all possible subset of a given string. 3 | eg: ABC = [" ", "C", "B", "BC", "A", "AC", "AB", "ABC"] 4 | 5 | For a string of length n, total possible subset = 2^n 6 | */ 7 | 8 | #include 9 | using namespace std; 10 | 11 | // Print subset 12 | void printSubset(string &str, string current, int index) 13 | { 14 | // base case 15 | if (index == str.length()) 16 | { 17 | cout << current << " "; 18 | return; 19 | } 20 | 21 | // recursion 22 | printSubset(str, current, index + 1); 23 | printSubset(str, current + str[index], index + 1); 24 | } 25 | 26 | // Driver code 27 | int main() 28 | { 29 | // Given string 30 | string s = "ABC"; 31 | string current = ""; 32 | 33 | // fn call 34 | printSubset(s, current, 0); 35 | } -------------------------------------------------------------------------------- /04. Recursion/09. Tower of Hanoi/toh.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Rules: 3 | 4 | 1. Only one disc at a time 5 | 2. No larger disc above smaller at any step 6 | 3. Only the top disc of the tower can be moved 7 | 8 | For 1 disc 9 | * Move disc 1 from A to C 10 | 11 | For 2 discs 12 | * Move disc 1 from A to B 13 | * Move disc 2 from A to C 14 | * Move disc 1 from B to C 15 | 16 | For 3 discs 17 | * Move disc 1 from A to C 18 | * Move disc 2 from A to B 19 | * Move disc 1 from C to B 20 | * Move disc 3 from A to C 21 | * Move disc 1 from B to A 22 | * Move disc 2 from B to C 23 | * Move disc 1 from A to C 24 | */ 25 | 26 | #include 27 | using namespace std; 28 | 29 | // Tower of Hanoi 30 | void ToH(int n, char A, char B, char C) 31 | { 32 | // base case 33 | if (n == 1) 34 | { 35 | cout << "Move 1 from " << A << " to " << C << endl; 36 | return; 37 | } 38 | 39 | // recursion 40 | ToH(n - 1, A, C, B); 41 | cout << "Move " << n << " from " << A << " to " << C << endl; 42 | ToH(n - 1, B, A, C); 43 | } 44 | 45 | // Driver code 46 | int main() 47 | { 48 | // Given number 49 | int num = 3; 50 | 51 | // fn call 52 | ToH(num, 'A', 'B', 'C'); 53 | } -------------------------------------------------------------------------------- /04. Recursion/10. Josephus/jose.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Numberphile: https://www.youtube.com/watch?v=uCsD3ZGzMgE 3 | 4 | There are n people standing in a circle. Find the 5 | position of the survivor after repeatedly killing 6 | kth person in a circular manner. 7 | */ 8 | 9 | #include 10 | using namespace std; 11 | 12 | // Return survivor O(n) 13 | int josephus(int n, int k) 14 | { 15 | // base case 16 | if (n == 1) 17 | return 0; 18 | 19 | // fn call 20 | return (josephus(n - 1, k) + k) % n; 21 | } 22 | 23 | // Driver code 24 | int main() 25 | { 26 | // Given number 27 | int n = 5, k = 3; 28 | 29 | // fn call 30 | cout << josephus(n, k); 31 | } -------------------------------------------------------------------------------- /05. Array/01. Theory/introduction.md: -------------------------------------------------------------------------------- 1 | ## Definition: 2 | 3 | - Store similar data type in contiguous memory location. 4 | 5 | ## Advantages: 6 | 7 | - ### Element access: 8 | - We can access any array element at O(1) time 9 | - An element at index 'x' is: address of first element + (size of data) \* x 10 | - ### Cache friendliness: 11 | - It's a type of memory which is closest to CUP. Speed of access cache: < Ram < Harddisk 12 | - Idealy we want every item that our programm is accessing to be there in the cache. 13 | - When processor access an item, they prefetch and store nearby elements in cache according to cache limit. 14 | - Caching doen't work with other data structures like linked list. 15 | -------------------------------------------------------------------------------- /05. Array/01. Theory/vector.md: -------------------------------------------------------------------------------- 1 | ## Vectors: 2 | 3 | - Vectors are object of vector class. They function similar to array with added benifits. 4 | 5 | ## Advantages of vector over array: 6 | 7 | - Dynamic size 8 | - Rich library function like: find, erase, insert etc 9 | - Easy to know size eg: myVector.size() (in array we've to do: sizeof(arr)/sizeof(arr[0])) 10 | - Can be returned from a function (array are always received as pointers) 11 | - Copying a vector is very easy eg: myVect_1 = myVect_2 12 | -------------------------------------------------------------------------------- /05. Array/05. Check sorted/check.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Check if array is sorted in non-decreasing order or not 3 | eg: [1, 2, 8, 8, 52] => true 4 | */ 5 | 6 | #include 7 | using namespace std; 8 | 9 | // Check if sorted 10 | bool checkSorted(int arr[], int size) 11 | { 12 | // logic: 13 | for (int i = 0; i < size - 1; i++) 14 | if (arr[i] > arr[i + 1]) 15 | return false; 16 | 17 | // answer 18 | return true; 19 | } 20 | 21 | // Driver code 22 | int main() 23 | { 24 | // Given array 25 | int arr[] = {1, 2, 8, 8, 52}; 26 | int size = sizeof(arr) / sizeof(arr[0]); 27 | 28 | // Output 29 | bool isSorted = checkSorted(arr, size); 30 | isSorted ? cout << "Sorted" : cout << "Not sorted"; 31 | } -------------------------------------------------------------------------------- /05. Array/06. Reverse/reverse.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Reverse an array 3 | eg: [1,2,3,4,5] => [5,4,3,2,1] 4 | */ 5 | 6 | #include 7 | using namespace std; 8 | 9 | // Reverse array 10 | void reverseArr(int *arr, int size) 11 | { 12 | // init vars 13 | int low = 0, high = size - 1, temp; 14 | 15 | // logic: 16 | while (low < high) 17 | { 18 | swap(arr[low], arr[high]); 19 | low++; 20 | high--; 21 | } 22 | } 23 | 24 | // Driver code 25 | int main() 26 | { 27 | // Given array 28 | int arr[] = {1, 2, 3, 4, 5, 6, 7}; 29 | int size = sizeof(arr) / sizeof(arr[0]); 30 | 31 | // fn call 32 | reverseArr(arr, size); 33 | 34 | // Output 35 | for (int i = 0; i < size; i++) 36 | cout << arr[i] << " "; 37 | } -------------------------------------------------------------------------------- /05. Array/08. Segregate/move.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Move a value to the front / back maintaining order 3 | eg: [1,2,0,3,1,0] => [1,2,3,1,0,0] (move 0 to end) 4 | */ 5 | 6 | #include 7 | using namespace std; 8 | 9 | // Move all occurances of val to end O(n) 10 | void segregateBack(int *arr, int size, int val) 11 | { 12 | // A pointer to value 13 | int pointer = 0; 14 | 15 | // segregate elements to end 16 | for (int i = 0; i < size; i++) 17 | { 18 | if (arr[i] != val) 19 | { 20 | swap(arr[i], arr[pointer]); 21 | pointer++; 22 | } 23 | } 24 | } 25 | 26 | // Move all occurances of val to front O(n) 27 | void segregateFront(int *arr, int size, int val) 28 | { 29 | // pointer to value 30 | int pointer = size - 1; 31 | 32 | // segregate elements to front 33 | for (int i = size - 1; i >= 0; i--) 34 | { 35 | if (arr[i] != val) 36 | { 37 | swap(arr[i], arr[pointer]); 38 | pointer--; 39 | } 40 | } 41 | } 42 | 43 | // Utility fn to print 44 | void print(int *arr, int size) 45 | { 46 | for (int i = 0; i < size; i++) 47 | cout << arr[i] << " "; 48 | cout << "\n"; 49 | } 50 | 51 | // Driver code 52 | int main() 53 | { 54 | // Given array 55 | int arr[] = {8, 5, 0, 10, 0, 7, 0, 10, 0, 10}; 56 | int size = sizeof(arr) / sizeof(arr[0]); 57 | 58 | // Output given array 59 | cout << "----------before----------\n"; 60 | print(arr, size); 61 | 62 | // Function call 63 | segregateFront(arr, size, 10); 64 | 65 | // Output after segregation 66 | cout << "----------after----------\n"; 67 | print(arr, size); 68 | } -------------------------------------------------------------------------------- /05. Array/09. Left Rotate/rotate.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Left rotate array by k units 3 | eg: [1,2,3,4,5] => [3,4,5,1,2] (rotate left by 2 unit) 4 | */ 5 | 6 | #include 7 | using namespace std; 8 | 9 | // Reverse array from low to high 10 | void reverse(int *arr, int low, int high) 11 | { 12 | while (low <= high) 13 | { 14 | swap(arr[low], arr[high]); 15 | low++; 16 | high--; 17 | } 18 | } 19 | 20 | // Rotate left by k units 21 | void rotateLeftByK(int *arr, int size, int k) 22 | { 23 | // if k > size 24 | k %= size; 25 | 26 | // rotate left logic 27 | reverse(arr, 0, k - 1); 28 | reverse(arr, k, size - 1); 29 | reverse(arr, 0, size - 1); 30 | } 31 | 32 | // Utility fn 33 | void print(int *arr, int size) 34 | { 35 | for (int i = 0; i < size; i++) 36 | cout << arr[i] << " "; 37 | cout << "\n"; 38 | } 39 | 40 | // Driver code 41 | int main() 42 | { 43 | // Given array 44 | int arr[] = {1, 2, 3, 4, 5}; 45 | int size = sizeof(arr) / sizeof(arr[0]); 46 | int k = 6; 47 | 48 | // fn call 49 | rotateLeftByK(arr, size, k); 50 | 51 | // Output 52 | print(arr, size); 53 | } -------------------------------------------------------------------------------- /05. Array/11. Max difference/maxDiff.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Find the maximum of arr[j] - arr[i] where j>i. 3 | eg: [2, 3, 10, 6, 4, 8, 1], maxDiff = 10 - 2 = 6 4 | */ 5 | 6 | #include 7 | using namespace std; 8 | 9 | // Modified Kadane's algorithm 10 | int maxDiff(int arr[], int size) 11 | { 12 | // init vars: 13 | int res = arr[1] - arr[0], minVal = arr[0]; 14 | 15 | // logic: 16 | for (int j = 1; j < size; j++) 17 | { 18 | res = max(res, arr[j] - minVal); 19 | minVal = min(minVal, arr[j]); 20 | } 21 | 22 | // answer 23 | return res; 24 | } 25 | 26 | // Different way to write same logic 27 | int maxDifference(int arr[], int size) 28 | { 29 | // can also be written as 30 | int max = arr[1] - arr[0], minValue = arr[0]; 31 | 32 | // logic: 33 | for (int j = 1; j < size; j++) 34 | { 35 | if (arr[j] - minValue > max) 36 | { 37 | max = arr[j] - minValue; // update max 38 | minValue = arr[j]; // update min value 39 | } 40 | } 41 | 42 | // answer 43 | return max; 44 | } 45 | 46 | // Driver code 47 | int main() 48 | { 49 | // Given array 50 | int arr[] = {2, 3, 10, 6, 4, 8, 1}; 51 | int size = sizeof(arr) / sizeof(arr[0]); 52 | 53 | // fn call 54 | cout << maxDiff(arr, size); 55 | } -------------------------------------------------------------------------------- /05. Array/12. Frequency/freq.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Count frequency of each element in sorted array 3 | eg: [10, 11, 11, 13] 4 | => freq 10 = 1 5 | => freq 11 = 2 6 | => freq 13 = 1 7 | */ 8 | 9 | #include 10 | using namespace std; 11 | 12 | // Calculate frequency of each element 13 | void printFrequency(int *arr, int size) 14 | { 15 | // init var: 16 | int freq = 1; 17 | 18 | // logic: 19 | for (int i = 0; i < size; i++) 20 | { 21 | if (arr[i] == arr[i + 1]) 22 | freq++; 23 | else 24 | { 25 | cout << "frequency of " << arr[i] << " is: " << freq << "\n"; 26 | freq = 1; 27 | } 28 | } 29 | } 30 | 31 | // Driver code 32 | int main() 33 | { 34 | // Given arrary 35 | int arr[] = {10, 10, 10, 10}; 36 | int size = sizeof(arr) / sizeof(arr[0]); 37 | 38 | // Output 39 | printFrequency(arr, size); 40 | } -------------------------------------------------------------------------------- /05. Array/13. Stock/stock.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Given stock prices for upcoming days. You can buy a stock in any day and 3 | sell the stock in any upcoming day. Maximize the profit. 4 | eg: [1,5,3,1,2,8] 5 | => buy on 1 sell on 5, profit = 4 6 | => buy on 1 sell on 8, profit = 7 {(2-1) + (8-2)} 7 | => total profit = 11 8 | */ 9 | 10 | #include 11 | using namespace std; 12 | 13 | // Time Complexity: O(n) 14 | int maxProfit(int *arr, int size) 15 | { 16 | // init vars: 17 | int profit = 0; 18 | 19 | // if price going down => ignore, if price going up sum 20 | for (int i = 1; i < size; i++) 21 | if (arr[i] > arr[i - 1]) 22 | profit += (arr[i] - arr[i - 1]); 23 | 24 | // answer 25 | return profit; 26 | } 27 | 28 | // Driver code 29 | int main() 30 | { 31 | // Given array 32 | int arr[] = {1, 5, 3, 1, 2, 8}; 33 | int size = sizeof(arr) / sizeof(arr[0]); 34 | 35 | // fn call 36 | cout << maxProfit(arr, size); 37 | } -------------------------------------------------------------------------------- /05. Array/15. Consecutive ones/countOnes.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Find longest consecutive ones 3 | eg: [1,1,1,0,0,1,1,0,1] => 3 4 | */ 5 | 6 | #include 7 | using namespace std; 8 | 9 | // Time: O(n) 10 | int countOnes(int arr[], int size) 11 | { 12 | // init vars 13 | int result = 0, currentCount = 0; 14 | 15 | // logic: 16 | for (int i = 0; i < size; i++) 17 | { 18 | if (arr[i] == 0) 19 | currentCount = 0; 20 | else 21 | { 22 | currentCount++; 23 | result = max(result, currentCount); 24 | } 25 | } 26 | 27 | // answer 28 | return result; 29 | } 30 | 31 | // Driver code 32 | int main() 33 | { 34 | // Given array 35 | int arr[] = {1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1}; 36 | int size = sizeof(arr) / sizeof(arr[0]); 37 | 38 | // fn call 39 | cout << countOnes(arr, size) << "\n"; 40 | } -------------------------------------------------------------------------------- /05. Array/16. Sub Array/subArray.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Subarrays are arrays within another array. 3 | Subarrays contains contiguous elements whereas subsequences are not. 4 | Substrings are similar to subarray but for strings. 5 | 6 | A subbarray is a contiguous part of array. 7 | An array that is inside another array. 8 | For example, consider the array [1, 2, 3, 4], 9 | There are 10 non-empty sub-arrays. (maintaining the order of elements). 10 | The subbarays are (1), (2), (3), (4), (1,2), (2,3), (3,4), (1,2,3), (2,3,4) and (1,2,3,4). 11 | In general, for an array/string of size n, there are n*(n+1)/2 non-empty subarrays/subsrings. 12 | */ 13 | 14 | #include 15 | using namespace std; 16 | 17 | // Print all non-empty subarray 18 | void print(int arr[], int n) 19 | { 20 | for (int i = 0; i < n; i++) 21 | { 22 | for (int j = i; j < n; j++) 23 | { 24 | for (int k = i; k <= j; k++) 25 | cout << arr[k] << " "; 26 | cout << "\n"; 27 | } 28 | } 29 | } 30 | 31 | // Driver code 32 | int main() 33 | { 34 | // Given array 35 | int arr[] = {1, 2, 3, 4}; 36 | int n = sizeof(arr) / sizeof(arr[0]); 37 | 38 | // fn call 39 | print(arr, n); 40 | } -------------------------------------------------------------------------------- /05. Array/17. SubArray sum/sum.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Find maximum sub-array sum. 3 | eg: [1,-2,3, 0] => 3 {(3) or (3+0)} 4 | */ 5 | 6 | #include 7 | using namespace std; 8 | 9 | // Kadane's algorithm Time: O(n) 10 | int maxSumEfficiently(int arr[], int size) 11 | { 12 | // init vars: 13 | int res = arr[0], maxEnd = arr[0]; 14 | 15 | // logic: 16 | for (int i = 1; i < size; i++) 17 | { 18 | maxEnd = max(maxEnd + arr[i], arr[i]); 19 | res = max(res, maxEnd); 20 | } 21 | 22 | // answer 23 | return res; 24 | } 25 | 26 | // Driver code 27 | int main() 28 | { 29 | // Given array 30 | int arr[] = {-5, 1, -2, 3, -1, 2, -2}; 31 | int size = sizeof(arr) / sizeof(arr[0]); 32 | 33 | // fn call 34 | cout << maxSumEfficiently(arr, size) << "\n"; 35 | } -------------------------------------------------------------------------------- /05. Array/18. Max Even Odd/max.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Calculate longest even odd sequence. 3 | eg: [11,22,33,44,24] => 4 (11,22,33,44) 4 | */ 5 | 6 | #include 7 | using namespace std; 8 | 9 | // Extension of kaden's algorithm 10 | int maxEvenOdd(int arr[], int size) 11 | { 12 | // init vars: 13 | int res = 1; 14 | int currentLength = 1; 15 | 16 | // logic: 17 | for (int i = 1; i < size; i++) 18 | { 19 | if ((arr[i] % 2 == 0 && arr[i - 1] % 2 != 0) || (arr[i] % 2 != 0 && arr[i - 1] % 2 == 0)) 20 | { 21 | currentLength++; 22 | res = max(res, currentLength); 23 | } 24 | else 25 | currentLength = 1; 26 | } 27 | 28 | // answer 29 | return res; 30 | } 31 | 32 | // Driver code 33 | int main() 34 | { 35 | // Given array 36 | int arr[] = {10, 12, 14, 7, 8, 9, 10, 2}; 37 | int size = sizeof(arr) / sizeof(arr[0]); 38 | 39 | // fn call 40 | cout << maxEvenOdd(arr, size) << "\n"; 41 | } -------------------------------------------------------------------------------- /05. Array/22. Good pair/good.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Given an numsay of integers nums. 3 | A pair (i,j) is called good if nums[i] == nums[j] and i < j. 4 | Return the number of good pairs. 5 | */ 6 | 7 | #include 8 | using namespace std; 9 | 10 | /* 11 | Count how many times each number appears. 12 | If a number appears n times, then n * (n – 1) // 2 13 | good pairs can be made with this number. 14 | */ 15 | 16 | // Time: O(n) 17 | int countGoodPair(vector &nums) 18 | { 19 | // create a vector of size maxElement + 1 and init with all 0 20 | int max = *max_element(nums.begin(), nums.end()); 21 | vector freq(max + 1, 0); 22 | 23 | // count frequency of each element in nums 24 | for (int i = 0; i < nums.size(); i++) 25 | freq[nums[i]]++; 26 | 27 | // logic: If a number appears n times, then n * (n – 1) / 2 good pairs 28 | int result = 0; 29 | for (int i = 0; i < freq.size(); i++) 30 | result += (freq[i] * (freq[i] - 1) / 2); 31 | 32 | // answer 33 | return result; 34 | } 35 | 36 | // Driver code 37 | int main() 38 | { 39 | // Given vector 40 | vector nums{1, 1, 1, 1}; 41 | 42 | // fn call 43 | cout << countGoodPair(nums); 44 | } -------------------------------------------------------------------------------- /05. Array/23. Max Sum/max.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Given an array(0-based indexing), 3 | you have to find the max sum of i*A[i] 4 | where A[i] is the element at index i in the array. 5 | The only operation allowed is to rotate(clock-wise or counter clock-wise) 6 | the array any number of times. 7 | 8 | Explaination : https://www.youtube.com/watch?v=3YNs_Ggqb-Q&t=32s 9 | */ 10 | 11 | #include 12 | using namespace std; 13 | 14 | // Max sum of (arr[i]*i) O(n) 15 | int maxSum(int arr[], int size) 16 | { 17 | // sum of all element in arr 18 | int temp = 0; 19 | int sum = accumulate(arr, arr + size, temp); 20 | 21 | // find maximum of i*arr[i] from 1 to n-1 for current arr (without rotation) 22 | int maximum = 0; 23 | for (int i = 1; i < size; ++i) 24 | maximum += (i)*arr[i]; 25 | 26 | // init res var 27 | int res = maximum; 28 | 29 | // check for all subsequent rotation and update res 30 | for (int i = 1; i < size; ++i) 31 | { 32 | maximum = maximum - (sum - arr[i - 1]) + (arr[i - 1] * (size - 1)); 33 | res = max(res, maximum); 34 | } 35 | 36 | // answer 37 | return res; 38 | } 39 | 40 | // Driver code 41 | int main() 42 | { 43 | // Given array 44 | int arr[] = {8, 3, 1, 2}; 45 | int n = sizeof(arr) / sizeof(arr[0]); 46 | 47 | // fn call 48 | cout << maxSum(arr, n); 49 | } -------------------------------------------------------------------------------- /05. Array/24. Min Consecutive flips/flips.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Given a binary array, we need to find the minimum of number of 3 | group flips to make all array elements same. In a group flip, 4 | we can flip any set of consecutive 1s or 0s. 5 | */ 6 | 7 | #include 8 | using namespace std; 9 | 10 | // Time complexity: O(n) 11 | void printGroups(int arr[], int size) 12 | { 13 | // Logic: 14 | for (int i = 1; i < size; i++) 15 | { 16 | if (arr[i] != arr[i - 1]) 17 | { 18 | if (arr[i] != arr[0]) 19 | cout << "From " << i << " to "; 20 | else 21 | cout << (i - 1) << "\n"; 22 | } 23 | } 24 | 25 | // Print: 26 | if (arr[size - 1] != arr[0]) 27 | cout << (size - 1) << "\n"; 28 | } 29 | 30 | // Driver code 31 | int main() 32 | { 33 | // Given array 34 | int arr[] = {0, 0, 1, 1, 0, 0, 1, 1, 0}; 35 | int size = sizeof(arr) / sizeof(arr[0]); 36 | 37 | // fn call 38 | printGroups(arr, size); 39 | } -------------------------------------------------------------------------------- /05. Array/25. Sliding Window/constant.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Given an array and a number k, find max sum of k consecutive elements 3 | ** WINDOW SIZE IS CONSTANT ** 4 | https://www.youtube.com/watch?v=jM2dhDPYMQM 5 | */ 6 | 7 | #include 8 | using namespace std; 9 | 10 | // Sliding window of fixed size 11 | int maxSum(int arr[], int size, int k) 12 | { 13 | // initialize variables 14 | int sum = 0, maxim = INT_MIN; 15 | 16 | // calculate sum for first window 17 | for (int i = 0; i < k; i++) 18 | sum += arr[i]; 19 | maxim = sum; 20 | 21 | // calculate sum for subsequent windows 22 | for (int i = k; i < size; i++) 23 | { 24 | sum += (arr[i] - arr[i - k]); 25 | maxim = max(maxim, sum); 26 | } 27 | 28 | // return result 29 | return maxim; 30 | } 31 | 32 | // Driver code 33 | int main() 34 | { 35 | // Given array 36 | int arr[] = {1, 8, 30, -5, 20, 7}; 37 | int size = sizeof(arr) / sizeof(arr[0]); 38 | int k = 3; 39 | 40 | // fn call 41 | cout << maxSum(arr, size, k); 42 | } -------------------------------------------------------------------------------- /05. Array/25. Sliding Window/variable.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Given an array and sum, check whether a subarray contains the sum or not 3 | ** WINDOW SIZE IS VARIABLE ** 4 | https://www.youtube.com/watch?v=jM2dhDPYMQM 5 | */ 6 | 7 | #include 8 | using namespace std; 9 | 10 | // Function to print subarray having a given sum using sliding window technique 11 | void findSubarray(int arr[], int n, int givenSum) 12 | { 13 | // maintains the sum of the current window 14 | int windowSum = 0; 15 | 16 | // maintain a window `[low, high-1]` 17 | int low = 0, high = 0; 18 | 19 | // consider every subarray starting from the `low` index 20 | for (low = 0; low < n; low++) 21 | { 22 | // if the current window's sum is less than the given sum, 23 | // then add elements to the current window from the right 24 | while (windowSum < givenSum && high < n) 25 | { 26 | windowSum += arr[high]; 27 | high++; 28 | } 29 | 30 | // if the current window's sum is equal to the given sum 31 | if (windowSum == givenSum) 32 | { 33 | cout << "Subarray found " << low << " " << high - 1 << "\n"; 34 | return; 35 | } 36 | 37 | // At this point, the current window's sum is more than the given sum. 38 | // Remove the current element (leftmost element) from the window 39 | windowSum -= arr[low]; 40 | } 41 | } 42 | 43 | // Driver code 44 | int main() 45 | { 46 | // Given array 47 | int arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; 48 | int n = sizeof(arr) / sizeof(arr[0]); 49 | int sum = 9; 50 | 51 | // fn call 52 | findSubarray(arr, n, sum); 53 | } -------------------------------------------------------------------------------- /05. Array/26. Subarray/sum.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Given an unsorted array of non-negative integers. Find if there is a subarray 3 | with given sum or not 4 | */ 5 | #include 6 | using namespace std; 7 | 8 | // Sliding window technique 9 | bool isSubSum(int arr[], int size, int sum) 10 | { 11 | // init vars 12 | int currentSum = arr[0], start = 0; 13 | 14 | // logic 15 | for (int end = 1; end < size; end++) 16 | { 17 | // clean previous window 18 | while (currentSum > sum && sum < end - 1) 19 | { 20 | currentSum -= arr[start]; 21 | start++; 22 | } 23 | 24 | // check if currSum is equal 25 | if (currentSum == sum) 26 | return true; 27 | 28 | // increase window 29 | if (end < size) 30 | currentSum += arr[end]; 31 | } 32 | 33 | // answer 34 | return currentSum == sum; 35 | } 36 | 37 | // Driver code 38 | int main() 39 | { 40 | // Given array 41 | int arr[] = {1, 4, 20, 3, 10, 5}; 42 | int size = sizeof(arr) / sizeof(arr[0]); 43 | 44 | // fn call 45 | cout << isSubSum(arr, size, 33); 46 | } -------------------------------------------------------------------------------- /05. Array/28. Subset sum/subsetsum.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Print sum of all subsets of an array 3 | */ 4 | 5 | #include 6 | using namespace std; 7 | 8 | // Function to print sum of all subsets of an array 9 | int subsetSums(int arr[], int n) 10 | { 11 | // there are total 2^n subsets 12 | long long size = 1 << n; 13 | 14 | // consider all numbers from 0 to 2^n - 1 15 | long long sum = 0; 16 | for (long long i = 0; i < size; i++) 17 | { 18 | // init current subset sum 19 | long long currSum = 0; 20 | 21 | // using binary of current i to decide which elements to pick. 22 | for (int j = 0; j < n; j++) 23 | if (i & (1 << j)) 24 | currSum += arr[j]; 25 | 26 | // total sum 27 | sum += currSum; 28 | } 29 | 30 | // answer 31 | return sum; 32 | } 33 | 34 | // Driver code 35 | int main() 36 | { 37 | // Given array 38 | int arr[] = {5, 4, 3}; 39 | int n = sizeof(arr) / sizeof(arr[0]); 40 | 41 | // fn call 42 | cout << subsetSums(arr, n); 43 | } 44 | -------------------------------------------------------------------------------- /05. Array/29. Max Area/max.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Container with most water 3 | https://leetcode.com/problems/container-with-most-water/ 4 | */ 5 | 6 | #include 7 | using namespace std; 8 | 9 | // Find max area of water 10 | int maxArea(vector &height) 11 | { 12 | // init vars: 13 | int i = 0, j = height.size() - 1, maxArea = INT_MIN; 14 | 15 | // logic: 16 | while (i < j) 17 | { 18 | // init minimum height 19 | int high = min(height[i], height[j]); 20 | 21 | // compute maxArea with current minimum height 22 | maxArea = max(maxArea, high * (j - i)); 23 | 24 | // increment first pointer 25 | while (height[i] <= high && i < j) 26 | i++; 27 | 28 | // decrement second pointer 29 | while (height[j] <= high && i < j) 30 | j--; 31 | } 32 | 33 | // result 34 | return maxArea; 35 | } 36 | 37 | // Driver code 38 | int main() 39 | { 40 | // Given vector 41 | vector arr{1, 8, 6, 2, 5, 4, 8, 3, 7}; 42 | 43 | // fn call 44 | cout << maxArea(arr); 45 | } -------------------------------------------------------------------------------- /05. Array/30. Absolute Diff/minimize.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Minimize the absolute difference of sum of two subsets 3 | https://www.geeksforgeeks.org/minimize-absolute-difference-sum-two-subsets/ 4 | */ 5 | 6 | #include 7 | using namespace std; 8 | 9 | // Minimize absolute diff 10 | void subsetDifference(int n) 11 | { 12 | // summation of n elements 13 | int s = n * (n + 1) / 2; 14 | 15 | // if divisible by 4 16 | if (n % 4 == 0) 17 | { 18 | cout << "First subset sum = " << s / 2 << "\n"; 19 | cout << "Second subset sum = " << s / 2 << "\n"; 20 | cout << "Difference = " << 0 << "\n"; 21 | } 22 | else if (n % 4 == 1 || n % 4 == 2) 23 | { 24 | 25 | cout << "First subset sum = " << s / 2 << "\n"; 26 | cout << "Second subset sum = " << s / 2 + 1 << "\n"; 27 | cout << "Difference = " << 1 << "\n"; 28 | } 29 | else // if n % 4 == 3 30 | { 31 | cout << "First subset sum = " << s / 2 << "\n"; 32 | cout << "Second subset sum = " << s / 2 << "\n"; 33 | cout << "Difference = " << 0 << "\n"; 34 | } 35 | } 36 | 37 | // Driver code 38 | int main() 39 | { 40 | int t; 41 | cout << "Number of testcases : "; 42 | cin >> t; 43 | while (t--) 44 | { 45 | int n; 46 | cout << "Enter number : "; 47 | cin >> n; 48 | subsetDifference(n); 49 | } 50 | return 0; 51 | } 52 | -------------------------------------------------------------------------------- /06. Searching/01. Binary Search (Iterative)/binary.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Program to demonstrate binary search using iteration. 3 | */ 4 | 5 | #include 6 | using namespace std; 7 | 8 | // Binary search iterative 9 | int binarySearch(int arr[], int size, int element) 10 | { 11 | // init low and high 12 | int low = 0, high = size - 1; 13 | 14 | // logic: 15 | while (low <= high) 16 | { 17 | // initialize mid 18 | int mid = (low + high) / 2; 19 | 20 | // base case 21 | if (arr[mid] == element) 22 | return mid; 23 | 24 | // element greater than mid 25 | else if (arr[mid] < element) 26 | low = mid + 1; 27 | 28 | // element smaller than mid 29 | else 30 | high = mid - 1; 31 | } 32 | 33 | // if not found 34 | return -1; 35 | } 36 | 37 | // Driver code 38 | int main() 39 | { 40 | // Given array 41 | int arr[] = {10, 20, 30, 40, 50, 60, 70, 80, 90, 100}; 42 | int size = sizeof(arr) / sizeof(arr[0]); 43 | 44 | /* ============= Binary search in array (return index) =============== */ 45 | cout << "Binary search in array:" << binarySearch(arr, size, 80) << "\n"; 46 | 47 | /* ============= Binary search in vectors (return true or false) =============== */ 48 | vector vrr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; 49 | cout << "Binary search in vector: " << binary_search(vrr.begin(), vrr.end(), 9) << "\n"; 50 | } -------------------------------------------------------------------------------- /06. Searching/02. BInary Search (recursive)/binary.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Program to demonstrate binary search using recursion. 3 | */ 4 | 5 | #include 6 | using namespace std; 7 | 8 | // Binary search recursive 9 | int binarySearch(int arr[], int size, int element, int low, int high) 10 | { 11 | // base case 12 | if (low > high) 13 | return -1; 14 | 15 | // calculate mid each time 16 | int mid = (low + high) / 2; 17 | 18 | // logic: 19 | if (arr[mid] == element) 20 | return mid; 21 | else if (arr[mid] > element) 22 | return binarySearch(arr, size, element, low, mid - 1); 23 | else 24 | return binarySearch(arr, size, element, mid + 1, high); 25 | } 26 | 27 | // Driver code 28 | int main() 29 | { 30 | // Given array 31 | int arr[] = {10, 20, 30, 40, 50, 60, 70, 80, 90, 100}; 32 | int size = sizeof(arr) / sizeof(arr[0]); 33 | 34 | // fn call 35 | cout << binarySearch(arr, size, 70, 0, 10); 36 | } -------------------------------------------------------------------------------- /06. Searching/06. Sqrt Floor/sqrt.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Given an integer, find floor of its square root. 3 | eg: 10 => 3 4 | */ 5 | 6 | #include 7 | using namespace std; 8 | 9 | // Find square root 10 | int binarySerach(int num) 11 | { 12 | // int vars: 13 | int low = 1, high = num, ans = -1; 14 | 15 | // logic: 16 | while (low <= high) 17 | { 18 | // compute mid 19 | int mid = (low + high) / 2; 20 | 21 | // store current sq 22 | int mySqrt = (mid * mid); 23 | 24 | // if found 25 | if (mySqrt == num) 26 | return mid; 27 | 28 | // if greater 29 | else if (mySqrt > num) 30 | high = mid - 1; 31 | 32 | // save curr ans and look for higher value 33 | else 34 | { 35 | low = mid + 1; 36 | ans = mid; 37 | } 38 | } 39 | 40 | // answer 41 | return ans; 42 | } 43 | 44 | // Driver code 45 | int main() 46 | { 47 | // Given number 48 | int num = 27; 49 | 50 | // fn call 51 | cout << binarySerach(num); 52 | } -------------------------------------------------------------------------------- /06. Searching/07. Print all perfect squares/square.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Print all perfect squares from 1 to n 3 | */ 4 | 5 | #include 6 | using namespace std; 7 | #define ll long long 8 | 9 | // Using binary search to print all perfect square in range 1 to n, Time: O(log n) 10 | bool checkPerfectSquare(ll num) 11 | { 12 | // init vars 13 | ll low = 1, high = num, ans = -1; 14 | 15 | // logic: 16 | while (low <= high) 17 | { 18 | // compute mid 19 | ll mid = (low + high) / 2; 20 | 21 | // if mid * mid = num, mid is square root of num 22 | if (mid * mid == num) 23 | return mid; 24 | 25 | // otherwise go to left half 26 | else if (mid * mid > num) 27 | high = mid - 1; 28 | 29 | // if mid * mid < num, go for right half, meanwhile store this mid 30 | else 31 | { 32 | low = mid + 1; 33 | ans = mid; 34 | } 35 | } 36 | 37 | // final check whether ans is square root of num 38 | if (ans * ans == num) 39 | return true; 40 | 41 | // if not return false 42 | return false; 43 | } 44 | 45 | // Driver code 46 | int main() 47 | { 48 | // Given num 49 | int num = 100; 50 | 51 | // Output 52 | for (ll i = 1; i <= num; i++) 53 | if (checkPerfectSquare(i)) 54 | cout << i << " "; 55 | } -------------------------------------------------------------------------------- /06. Searching/10. Two pointer/pointer.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Given a sorted array and a sum. Find if there is a pair with given sum 3 | */ 4 | #include 5 | using namespace std; 6 | 7 | // Find first sum pair in O(n) time 8 | pair findPair(int arr[], int size, int sum) 9 | { 10 | // low and high vars for two pointer 11 | int low = 0, high = size - 1; 12 | 13 | // logic: 14 | while (low <= high) 15 | { 16 | // calculate curent sum and store it 17 | int currSum = arr[low] + arr[high]; 18 | 19 | // if current sum = given sum , print the pair 20 | if (currSum == sum) 21 | return make_pair(arr[low], arr[high]); 22 | 23 | // if currSum > sum, reduce high 24 | else if (currSum > sum) 25 | high -= 1; 26 | 27 | // otherwise increase low 28 | else 29 | low += 1; 30 | } 31 | 32 | // if no pair found 33 | return make_pair(-1, -1); 34 | } 35 | 36 | // Driver code 37 | int main() 38 | { 39 | // Given array 40 | int arr[] = {2, 3, 4, 9, 11}; 41 | int size = sizeof(arr) / sizeof(arr[0]); 42 | int sum = 20; 43 | 44 | // fn call 45 | pair p1 = findPair(arr, size, sum); 46 | cout << p1.first << " " << p1.second; 47 | } -------------------------------------------------------------------------------- /07. Sorting/01. Theory/stability.md: -------------------------------------------------------------------------------- 1 | ## General idea of stability 2 | 3 | - If two items have same value then they should appear in the same order as they appeard in original data.
4 | 5 | - Given name of student and their marks:
6 | arr[] = [("Anil", 50), ("Ayan", 80), ("Piyush, 50), ("Ramesh", 80)]
7 | 8 | - stable algorithm: (maintain alphabetical order and increasing order of marks)
9 | arr[] = [("Anil", 50), ("Piyush, 50), ("Ayan", 80), ("Ramesh", 80)]
10 | 11 | - unstable algorithm: (only care about increasing order of marks)
12 | May produce any combination. But ensures increasing order of marks 13 | 14 | ## Need of stability 15 | 16 | - Stability is important when we have objects of multiple forms.
17 | 18 | - When we have only int array for eg, we don't need stability. 19 | 20 | | Stable sorting algorithm | Unstable sorting Algorithm | 21 | | ------------------------ | -------------------------- | 22 | | Bubble sort | Selection sort | 23 | | Merge sort | Quick sort | 24 | | Insertion sort | Heap sort | 25 | -------------------------------------------------------------------------------- /07. Sorting/02. Bubble Sort/bubble.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * O(n^2) algorithm 3 | * Stable 4 | */ 5 | 6 | #include 7 | using namespace std; 8 | 9 | // Bubble sort 10 | void bubbleSort(int arr[], int size) 11 | { 12 | // normal 13 | for (int i = 0; i < size - 1; i++) 14 | for (int j = 0; j < size - i - 1; j++) 15 | if (arr[j] > arr[j + 1]) 16 | swap(arr[j], arr[j + 1]); 17 | 18 | return; 19 | 20 | // optimized 21 | for (int i = 0; i < size - 1; i++) 22 | { 23 | bool swapped = false; 24 | for (int j = 0; j < size - i - 1; j++) 25 | { 26 | if (arr[j] > arr[j + 1]) 27 | { 28 | swap(arr[j], arr[j + 1]); 29 | swapped = true; 30 | } 31 | } 32 | if (swapped == false) 33 | break; 34 | } 35 | 36 | return; 37 | } 38 | 39 | // Driver code 40 | int main() 41 | { 42 | // Given array 43 | int arr[] = {8, 2, 1, 9, 10}; 44 | int size = sizeof(arr) / sizeof(arr[0]); 45 | 46 | // fn call 47 | bubbleSort(arr, size); 48 | 49 | // output 50 | for (auto x : arr) 51 | cout << x << " "; 52 | } -------------------------------------------------------------------------------- /07. Sorting/03. Selection Sort/selection.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * O(n^2) algorithm 3 | * Does less memory write as compared to Quick sort, Merge sort, insertion sort etc 4 | * In terms of less memory write cycle sort is best 5 | * Not stable 6 | * In place 7 | * Basic idea for heap sort 8 | */ 9 | 10 | #include 11 | using namespace std; 12 | 13 | // Selection sort 14 | void selectionSort(int *arr, int size) 15 | { 16 | // logic: 17 | for (int i = 0; i < size - 1; i++) 18 | { 19 | // min will sotre index of min element 20 | int min_index = i; 21 | 22 | // find index of min element 23 | for (int j = i + 1; j < size; j++) 24 | if (arr[j] < arr[min_index]) 25 | min_index = j; 26 | 27 | // swap current index (i) with min element 28 | swap(arr[i], arr[min_index]); 29 | } 30 | } 31 | 32 | // Driver code 33 | int main() 34 | { 35 | // Given array 36 | int arr[] = {10, 5, 8, 20, 2, 18}; 37 | int size = sizeof(arr) / sizeof(arr[0]); 38 | 39 | // fn call 40 | selectionSort(arr, size); 41 | 42 | // output 43 | for (auto x : arr) 44 | cout << x << " "; 45 | } -------------------------------------------------------------------------------- /07. Sorting/04. Insertion Sort/Insertion.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * O(n^2) algorithm 3 | * O(n) in Best Case 4 | * Stable and In place 5 | * Used for small arrays (TimSort and IntraSort) 6 | */ 7 | 8 | #include 9 | using namespace std; 10 | 11 | // Insertion Sort 12 | void insertionSort(int *arr, int size) 13 | { 14 | // logic: 15 | for (int i = 1; i < size; i++) 16 | { 17 | // current element is key 18 | int key = arr[i]; 19 | 20 | // make room to insert the key 21 | int j = i - 1; 22 | while (j >= 0 && arr[j] > key) 23 | { 24 | arr[j + 1] = arr[j]; 25 | j--; 26 | } 27 | 28 | // insert key in correct position 29 | arr[j + 1] = key; 30 | } 31 | } 32 | 33 | // Driver code 34 | int main() 35 | { 36 | // Given array 37 | int arr[] = {20, 5, 40, 60, 10, 30}; 38 | int size = sizeof(arr) / sizeof(arr[0]); 39 | 40 | // fn call 41 | insertionSort(arr, size); 42 | 43 | // output 44 | for (auto x : arr) 45 | cout << x << " "; 46 | } -------------------------------------------------------------------------------- /07. Sorting/05. Merge sorted array/merge.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Given two sorted array merge them such that the 3 | resultant array is sorted. Print resultant array 4 | */ 5 | 6 | #include 7 | using namespace std; 8 | 9 | // Merge two sorted array 10 | void merge(int arr[], int brr[], int m, int n) 11 | { 12 | // init vars 13 | int i = 0, j = 0; 14 | 15 | // logic of merge 16 | while (i < m && j < n) 17 | { 18 | if (arr[i] <= brr[j]) 19 | cout << arr[i++] << " "; 20 | else 21 | cout << brr[j++] << " "; 22 | } 23 | 24 | // print remaining elements (only one loop is executed) 25 | while (i < m) 26 | cout << arr[i++] << " "; 27 | while (j < n) 28 | cout << brr[j++] << " "; 29 | } 30 | 31 | // Driver code 32 | int main() 33 | { 34 | // Given array 35 | int arr[] = {1, 4, 7}; 36 | int brr[] = {2, 3, 6}; 37 | int m = sizeof(arr) / sizeof(arr[0]); 38 | int n = sizeof(brr) / sizeof(brr[0]); 39 | 40 | // fn call 41 | merge(arr, brr, m, n); 42 | } -------------------------------------------------------------------------------- /07. Sorting/06. Merge function/merge.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Given an array 'arr' and indices 'low', 'mid' and 'high' 3 | sort them and merge them back to original array 4 | 5 | Input 6 | arr[] = [1, 2, 4, 1000, 2000, 4000, 2000, 3000, 2, 3, 4] 7 | low = 3, mid = 5, high = 7 8 | 9 | Output 10 | arr[] = [1 2 4 1000 2000 2000 3000 4000 2 3 4] 11 | */ 12 | 13 | #include 14 | using namespace std; 15 | 16 | // Merge function of merge sort 17 | void merge(int arr[], int low, int mid, int high) 18 | { 19 | // init vars 20 | int n1 = mid - low + 1, n2 = high - mid; 21 | int left[n1], right[n2]; 22 | 23 | // fill left array 24 | for (int i = 0; i < n1; i++) 25 | left[i] = arr[low + i]; 26 | 27 | // fill right array 28 | for (int i = 0; i < n2; i++) 29 | right[i] = arr[mid + i + 1]; 30 | 31 | // merge logic 32 | int i = 0, j = 0, k = low; 33 | while (i < n1 && j < n2) 34 | { 35 | if (left[i] <= right[j]) 36 | arr[k++] = left[i++]; 37 | else 38 | arr[k++] = right[j++]; 39 | } 40 | 41 | // remaining elements 42 | while (i < n1) 43 | arr[k++] = left[i++]; 44 | while (j < n2) 45 | arr[k++] = right[j++]; 46 | } 47 | 48 | // Driver code 49 | int main() 50 | { 51 | // Given array 52 | int arr[] = {20, 6, 14, 1000, 2000, 4000, 2000, 3000, 52, 3, 9}; 53 | int n = sizeof(arr) / sizeof(arr[0]); 54 | int low = 3, mid = 5, high = 7; 55 | 56 | // fn call (merge from index 3 to 7) 57 | merge(arr, low, mid, high); 58 | 59 | // Output 60 | for (auto x : arr) 61 | cout << x << " "; 62 | } -------------------------------------------------------------------------------- /07. Sorting/07. Merge sort/merge.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Time: O(nlogn) 3 | * Stable 4 | */ 5 | 6 | #include 7 | using namespace std; 8 | 9 | // Merge array 10 | void merge(int arr[], int low, int mid, int high) 11 | { 12 | // init vars 13 | int n1 = mid - low + 1, n2 = high - mid; 14 | int left[n1], right[n2]; 15 | 16 | // fill left array 17 | for (int i = 0; i < n1; i++) 18 | left[i] = arr[low + i]; 19 | 20 | // fill right array 21 | for (int i = 0; i < n2; i++) 22 | right[i] = arr[mid + i + 1]; 23 | 24 | // merge logic 25 | int i = 0, j = 0, k = low; 26 | while (i < n1 && j < n2) 27 | { 28 | if (left[i] <= right[j]) 29 | arr[k++] = left[i++]; 30 | else 31 | arr[k++] = right[j++]; 32 | } 33 | 34 | // remaining elements 35 | while (i < n1) 36 | arr[k++] = left[i++]; 37 | while (j < n2) 38 | arr[k++] = right[j++]; 39 | } 40 | 41 | // Merge sort 42 | void mergeSort(int arr[], int left, int right) 43 | { 44 | 45 | if (right > left) 46 | { 47 | int mid = left + (right - left) / 2; 48 | mergeSort(arr, left, mid); 49 | mergeSort(arr, mid + 1, right); 50 | merge(arr, left, mid, right); 51 | } 52 | } 53 | 54 | // Driver code; 55 | int main() 56 | { 57 | // Given array 58 | int arr[] = {10, 5, 30, 15, 7}; 59 | int n = sizeof(arr) / sizeof(arr[0]); 60 | 61 | // fn call 62 | mergeSort(arr, 0, n - 1); 63 | 64 | // Output 65 | for (auto x : arr) 66 | cout << x << " "; 67 | } -------------------------------------------------------------------------------- /07. Sorting/09. Intersection/intersection.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Given two sorted array. Print their intersection. 3 | eg: a1[] = [1,2,3,4,5], a2[] = [1,2,3]; 4 | intersection = [1,2,3] 5 | */ 6 | 7 | #include 8 | using namespace std; 9 | 10 | // Function to return a list containing the intersection of the two arrays. 11 | vector printIntersection(int arr1[], int arr2[], int N, int M) 12 | { 13 | // sort 14 | sort(arr1, arr1 + N); 15 | sort(arr2, arr2 + M); 16 | 17 | // initialize variables: 18 | vector answer; 19 | int i = 0, j = 0; 20 | 21 | // logic: 22 | while (i < N && j < M) 23 | { 24 | // handle duplicates 25 | if (i > 0 && arr1[i] == arr1[i - 1]) 26 | { 27 | i++; 28 | continue; 29 | } 30 | 31 | // intersection logic: 32 | if (arr1[i] < arr2[j]) 33 | i++; 34 | else if (arr1[i] > arr2[j]) 35 | j++; 36 | else 37 | { 38 | answer.push_back(arr1[i]); 39 | i++; 40 | j++; 41 | } 42 | } 43 | 44 | // answer 45 | return answer; 46 | } 47 | 48 | // Driver code 49 | int main() 50 | { 51 | // Given array 52 | int arr1[] = {1, 2, 3, 4}; 53 | int arr2[] = {2, 4, 6, 7, 8}; 54 | int n = sizeof(arr1) / sizeof(arr1[0]); 55 | int m = sizeof(arr2) / sizeof(arr2[0]); 56 | 57 | // Output 58 | vector answer = printIntersection(arr1, arr2, n, m); 59 | for (auto x : answer) 60 | cout << x << " "; 61 | } -------------------------------------------------------------------------------- /07. Sorting/11. Naive partition/partition.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Partition given array around pivot 3 | * Stable 4 | */ 5 | 6 | #include 7 | using namespace std; 8 | 9 | // Naive partition for quicksort (retains stability) 10 | void partition(int arr[], int low, int high, int pivot) 11 | { 12 | // init vars 13 | int temp[high - low + 1], index = 0; 14 | 15 | // copy smaller or equal elements: 16 | for (int i = low; i <= high; i++) 17 | { 18 | if (arr[i] <= arr[pivot]) 19 | { 20 | temp[index] = arr[i]; 21 | index++; 22 | } 23 | } 24 | 25 | // copy larger elements 26 | for (int i = low; i <= high; i++) 27 | { 28 | if (arr[i] > arr[pivot]) 29 | { 30 | temp[index] = arr[i]; 31 | index++; 32 | } 33 | } 34 | 35 | // copy back to original array 36 | for (int i = low; i <= high; i++) 37 | arr[i] = temp[i - low]; 38 | } 39 | 40 | // Driver code 41 | int main() 42 | { 43 | // given array 44 | int arr[] = {5, 13, 6, 9, 12, 11, 8}; 45 | int n = sizeof(arr) / sizeof(arr[0]); 46 | 47 | // fn call 48 | partition(arr, 0, n - 1, n - 1); 49 | 50 | // Output 51 | for (int x : arr) 52 | cout << x << " "; 53 | } -------------------------------------------------------------------------------- /07. Sorting/12. Lomuto partition/partition.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Partition around last element 3 | * Unstable 4 | */ 5 | 6 | #include 7 | using namespace std; 8 | 9 | // Lumato partition for quicksort 10 | int lomutoPartition(int arr[], int low, int high) 11 | { 12 | // init vars 13 | int pivot = arr[high]; // assuming pivot is last element 14 | int i = low - 1; 15 | 16 | // logic: 17 | for (int j = low; j <= high - 1; j++) 18 | { 19 | if (arr[j] < pivot) 20 | { 21 | i++; 22 | swap(arr[i], arr[j]); 23 | } 24 | } 25 | 26 | // insert pivot at correct position 27 | swap(arr[i + 1], arr[high]); 28 | 29 | // answer 30 | return i + 1; 31 | } 32 | 33 | // Driver code 34 | int main() 35 | { 36 | // Given array 37 | int arr[] = {10, 80, 30, 90, 40, 50, 70}; 38 | int n = sizeof(arr) / sizeof(arr[0]); 39 | 40 | // fn call 41 | lomutoPartition(arr, 0, n - 1); 42 | 43 | // Output 44 | for (int x : arr) 45 | cout << x << " "; 46 | } -------------------------------------------------------------------------------- /07. Sorting/13. Hoare's partition/partition.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Partiton around first element 3 | * Unstable 4 | */ 5 | 6 | #include 7 | using namespace std; 8 | 9 | // Hoare partition for quicksort 10 | int hoarePartition(int arr[], int low, int high) 11 | { 12 | // init vars 13 | int pivot = arr[low]; // assuming pivot is first element 14 | int i = low - 1, j = high + 1; 15 | 16 | // logic: 17 | while (1) 18 | { 19 | // increase i 20 | do 21 | { 22 | i++; 23 | } while (arr[i] < pivot); 24 | 25 | // decrease j 26 | do 27 | { 28 | j--; 29 | } while (arr[j] > pivot); 30 | 31 | // base case 32 | if (i >= j) 33 | return j; 34 | 35 | // if base case is false swap i and j 36 | swap(arr[i], arr[j]); 37 | } 38 | } 39 | 40 | // Driver code 41 | int main() 42 | { 43 | // Given array 44 | int arr[] = {5, 3, 8, 4, 2, 7, 1, 10}; 45 | int n = sizeof(arr) / sizeof(arr[0]); 46 | 47 | // fn call 48 | hoarePartition(arr, 0, n - 1); 49 | 50 | // Output 51 | for (int x : arr) 52 | cout << x << " "; 53 | } -------------------------------------------------------------------------------- /07. Sorting/14. QuickSort Lomuto/sort.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Worst case O(n^2) 3 | * Unstable 4 | */ 5 | 6 | #include 7 | using namespace std; 8 | 9 | // Quicksort using lomuto partition 10 | int lomutoPartition(int arr[], int low, int high) 11 | { 12 | // init vars 13 | int pivot = arr[high]; // assuming pivot is last element 14 | int i = low - 1; 15 | 16 | // logic: 17 | for (int j = low; j <= high - 1; j++) 18 | { 19 | if (arr[j] < pivot) 20 | { 21 | i++; 22 | swap(arr[i], arr[j]); 23 | } 24 | } 25 | 26 | // insert pivot at correct position 27 | swap(arr[i + 1], arr[high]); 28 | 29 | // answer 30 | return i + 1; 31 | } 32 | 33 | // Quick sort 34 | void QuickSort(int arr[], int low, int high) 35 | { 36 | if (high > low) 37 | { 38 | int pivotIndex = lomutoPartition(arr, low, high); 39 | QuickSort(arr, low, pivotIndex - 1); 40 | QuickSort(arr, pivotIndex + 1, high); 41 | } 42 | } 43 | 44 | // Driver code 45 | int main() 46 | { 47 | // Given array 48 | int arr[] = {8, 4, 7, 9, 3, 10, 5}; 49 | int n = sizeof(arr) / sizeof(arr[0]); 50 | 51 | // fn call 52 | QuickSort(arr, 0, n - 1); 53 | 54 | // Output 55 | for (int x : arr) 56 | cout << x << " "; 57 | } -------------------------------------------------------------------------------- /07. Sorting/15. QuickSort Hoare/sort.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Worst case O(n^2) 3 | * Unstable 4 | */ 5 | 6 | #include 7 | using namespace std; 8 | 9 | // Quicksort using hoare partition 10 | int hoarePartition(int arr[], int low, int high) 11 | { 12 | // init vars 13 | int pivot = arr[low]; // assuming pivot is first element 14 | int i = low - 1, j = high + 1; 15 | 16 | // logic: 17 | while (1) 18 | { 19 | // increase i 20 | do 21 | { 22 | i++; 23 | } while (arr[i] < pivot); 24 | 25 | // decrease j 26 | do 27 | { 28 | j--; 29 | } while (arr[j] > pivot); 30 | 31 | // base case 32 | if (i >= j) 33 | return j; 34 | 35 | // if base case is false swap i and j 36 | swap(arr[i], arr[j]); 37 | } 38 | } 39 | 40 | // QuickSort 41 | void QuickSort(int arr[], int low, int high) 42 | { 43 | if (high > low) 44 | { 45 | int pivotIndex = hoarePartition(arr, low, high); 46 | QuickSort(arr, low, pivotIndex); 47 | QuickSort(arr, pivotIndex + 1, high); 48 | } 49 | } 50 | 51 | // Driver code 52 | int main() 53 | { 54 | // Given array 55 | int arr[] = {8, 4, 7, 9, 3, 10, 5}; 56 | int n = sizeof(arr) / sizeof(arr[0]); 57 | 58 | // fn call 59 | QuickSort(arr, 0, n - 1); 60 | 61 | // Output 62 | for (int x : arr) 63 | cout << x << " "; 64 | } -------------------------------------------------------------------------------- /07. Sorting/17. Chocolate distribution/chocolate.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Chocolate distribution problem 3 | https://practice.geeksforgeeks.org/problems/chocolate-distribution-problem3825/1 4 | */ 5 | 6 | #include 7 | using namespace std; 8 | 9 | // Find min of difference betwen min and max in m elements 10 | int minDiff(int arr[], int n, int m) 11 | { 12 | // base case 13 | if (m > n) 14 | return -1; 15 | 16 | // sort given array 17 | sort(arr, arr + n); 18 | 19 | // initialize result 20 | int res = arr[m - 1] - arr[0]; 21 | 22 | // logic: 23 | for (int i = 0; (i + m - 1) < n; i++) 24 | res = min(res, arr[i + m - 1] - arr[i]); 25 | 26 | // answer 27 | return res; 28 | } 29 | 30 | // Driver code 31 | int main() 32 | { 33 | // Given array 34 | int arr[] = {7, 3, 2, 4, 9, 12, 56}; 35 | int n = sizeof(arr) / sizeof(arr[0]); 36 | int m = 3; 37 | 38 | // fn call 39 | cout << minDiff(arr, n, m); 40 | } -------------------------------------------------------------------------------- /07. Sorting/19. Min Difference/min.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Given an array of integers. Find the minimum absolute 3 | difference in this array. 4 | 5 | eg [5,3,2] => min abs(3-5) = 2 6 | */ 7 | 8 | #include 9 | using namespace std; 10 | 11 | // Find min difference of a pair in array 12 | int getMinDiff(int arr[], int n) 13 | { 14 | // sort 15 | sort(arr, arr + n); 16 | 17 | // initialize variables: 18 | int res = INT_MAX; 19 | 20 | // logic 21 | for (int i = 1; i < n; i++) 22 | res = min(res, arr[i] - arr[i - 1]); 23 | 24 | // answer 25 | return res; 26 | } 27 | 28 | // Driver code 29 | int main() 30 | { 31 | // Given array 32 | int arr[] = {5, 3, 8}; 33 | int n = sizeof(arr) / sizeof(arr[0]); 34 | 35 | // fn call 36 | cout << getMinDiff(arr, n); 37 | } -------------------------------------------------------------------------------- /08. Matrix/03. Snake pattern/print.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Given 3 | 1 2 3 4 4 | 5 6 7 8 5 | 9 10 11 12 6 | 13 14 15 16 7 | 8 | Print 9 | 1 2 3 4 10 | 8 7 6 5 11 | 9 10 11 12 12 | 16 15 14 13 13 | */ 14 | 15 | #include 16 | using namespace std; 17 | 18 | // Global const 19 | const int row = 4; 20 | const int column = 4; 21 | 22 | // Print snake pattern 23 | void printSnake(int matrix[row][column]) 24 | { 25 | // logic: 26 | for (int i = 0; i < row; i++) 27 | { 28 | // i is even 29 | if (i % 2 == 0) 30 | { 31 | for (int j = 0; j < column; j++) 32 | cout << matrix[i][j] << " "; 33 | cout << "\n"; 34 | } 35 | // i is odd 36 | else 37 | { 38 | for (int j = column - 1; j >= 0; j--) 39 | cout << matrix[i][j] << " "; 40 | cout << "\n"; 41 | } 42 | } 43 | } 44 | 45 | // Utility fn print normal matrix 46 | void print(int matrix[row][column]) 47 | { 48 | for (int i = 0; i < row; i++) 49 | { 50 | for (int j = 0; j < column; j++) 51 | cout << matrix[i][j] << " "; 52 | cout << "\n"; 53 | } 54 | 55 | cout << "\n"; 56 | } 57 | 58 | // Driver code 59 | int main() 60 | { 61 | // Given matrix 62 | int matrix[row][column] = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}, {13, 14, 15, 16}}; 63 | 64 | // Print given matrix 65 | cout << "Given matrix:\n"; 66 | print(matrix); 67 | 68 | // fn call 69 | cout << "Snake Pattern:\n"; 70 | printSnake(matrix); 71 | } -------------------------------------------------------------------------------- /08. Matrix/07. Search/search.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Given a matrix that is row wise and column wise sorted 3 | Search an element in this matrix 4 | 5 | ALGORITHM: 6 | * Begin from top right 7 | * If target is same, found 8 | * If target is small move left 9 | * If target is greater move down 10 | */ 11 | 12 | #include 13 | using namespace std; 14 | 15 | // Global const 16 | const int ROW = 4, COLUMN = 4; 17 | 18 | // Print index of element 19 | void search(int mat[ROW][COLUMN], int target) 20 | { 21 | // init vars 22 | int low = 0, high = COLUMN - 1; 23 | 24 | // logic: 25 | while (low < ROW && high >= 0) 26 | { 27 | if (mat[low][high] == target) 28 | { 29 | cout << "Found at (" << low << ", " << high << ")"; 30 | return; 31 | } 32 | else if (mat[low][high] > target) 33 | high--; 34 | else 35 | low++; 36 | } 37 | 38 | // if not found 39 | cout << "Not Found"; 40 | } 41 | 42 | // Driver code 43 | int main() 44 | { 45 | // Given array 46 | int arr[ROW][COLUMN] = {{10, 20, 30, 40}, {15, 25, 35, 45}, {27, 29, 35, 45}, {32, 33, 39, 50}}; 47 | int target = 29; 48 | 49 | // fn call 50 | search(arr, target); 51 | } -------------------------------------------------------------------------------- /08. Matrix/08. Print diagonals/diagonal.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Given a matrix print its diagonals 3 | 1, 2, 3, 4 4 | 5, 6, 7, 8 5 | 1, 2, 3, 4 6 | 5, 6, 7, 8 7 | 8 | Principal Diagonal: 1, 6, 3, 8, 9 | Secondary Diagonal: 4, 7, 2, 5, 10 | */ 11 | 12 | #include 13 | using namespace std; 14 | 15 | // Global const 16 | const int row = 100; 17 | const int col = 100; 18 | 19 | // Function to print the Principal Diagonal 20 | void printPrincipalDiagonal(int mat[row][col], int n) 21 | { 22 | // msg 23 | cout << "Principal Diagonal: "; 24 | 25 | // logic: 26 | for (int i = 0; i < n; i++) 27 | { 28 | for (int j = 0; j < n; j++) 29 | { 30 | // Condition for principal diagonal 31 | if (i == j) 32 | cout << mat[i][j] << ", "; 33 | } 34 | } 35 | 36 | // newline 37 | cout << "\n"; 38 | } 39 | 40 | // Function to print the Secondary Diagonal 41 | void printSecondaryDiagonal(int mat[row][col], int n) 42 | { 43 | // msg 44 | cout << "Secondary Diagonal: "; 45 | 46 | // logic: 47 | for (int i = 0; i < n; i++) 48 | { 49 | for (int j = 0; j < n; j++) 50 | { 51 | // Condition for secondary diagonal 52 | if (i == (n - j - 1)) 53 | cout << mat[i][j] << ", "; 54 | } 55 | } 56 | 57 | // newline 58 | cout << "\n"; 59 | } 60 | 61 | // Driver code 62 | int main() 63 | { 64 | // Given array 65 | int array[row][col] = {{1, 2, 3, 4}, 66 | {5, 6, 7, 8}, 67 | {1, 2, 3, 4}, 68 | {5, 6, 7, 8}}; 69 | int size = 4; 70 | 71 | // fn call 72 | printPrincipalDiagonal(array, size); 73 | printSecondaryDiagonal(array, size); 74 | } -------------------------------------------------------------------------------- /09. Hashing/01. Theory/theory.md: -------------------------------------------------------------------------------- 1 | ## Hashing 2 | 3 | - Used to store `key : value` pairs 4 | - Best for `Search, Insert, Delete` operations O(1) 5 | 6 | - Not useful for: 7 | 8 | - Finding closest value 9 | - Sorted data 10 | - Prefix Searching 11 | 12 | - Applications: 13 | - Dictionaries 14 | - Database Indexing 15 | - Cryptography 16 | - Caches 17 | - Symbol table 18 | - Routers 19 | - Getting data from databases 20 | -------------------------------------------------------------------------------- /09. Hashing/03. Count distinct/count.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Count number of distinct elements in an array 3 | eg [1,1,2,3,3,3] => 3 4 | */ 5 | 6 | #include 7 | using namespace std; 8 | 9 | // Count distinct elements 10 | int countDistinct(int arr[], int n) 11 | { 12 | // initialize set and insert all element 13 | unordered_set count(arr, arr + n); 14 | 15 | // size represent number of distinct elements 16 | return count.size(); 17 | } 18 | 19 | // Driver code 20 | int main() 21 | { 22 | // Given array 23 | int arr[] = {1, 1, 1, 2, 3, 3, 4, 5, 1, 1, 2, 3, 4, 4, 9, 9}; 24 | int n = sizeof(arr) / sizeof(arr[0]); 25 | 26 | // fn call 27 | cout << countDistinct(arr, n); 28 | } -------------------------------------------------------------------------------- /09. Hashing/04. Print freq/print.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Print frequency of each element of an array using hashing 3 | eg [1,1,1,2,2,2,2,2] => 1:3, 2:5 4 | */ 5 | 6 | #include 7 | using namespace std; 8 | 9 | // Print frequency 10 | void printFrequency(int arr[], int n) 11 | { 12 | // initialize map 13 | unordered_map frequency; 14 | 15 | // logic: 16 | for (int i = 0; i < n; i++) 17 | frequency[arr[i]]++; 18 | 19 | // print Method 1 20 | cout << "Method 1:\n"; 21 | for (int i = 0; i < frequency.size(); i++) 22 | if (frequency[i]) 23 | cout << i << ": " << frequency[i] << "\n"; 24 | 25 | // print Method 2 26 | cout << "\nMethod 2:\n"; 27 | for (auto val : frequency) 28 | if (val.second) 29 | cout << val.first << ": " << val.second << "\n"; 30 | } 31 | 32 | // Driver code 33 | int main() 34 | { 35 | // Given array 36 | int arr[] = {1, 1, 1, 2, 3, 3, 4, 5, 1, 1, 2, 3, 4, 4, 9, 9}; 37 | int n = sizeof(arr) / sizeof(arr[0]); 38 | 39 | // fn call 40 | printFrequency(arr, n); 41 | } -------------------------------------------------------------------------------- /09. Hashing/05. Intersection/intersection.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Count distinct elements after intersection of two array 3 | eg a1 = [1,2,3], a2 = [2,3,4] = [2,3] => distinct elements = 2 4 | */ 5 | 6 | #include 7 | using namespace std; 8 | 9 | // Count 10 | int countDistinct(int arr1[], int n1, int arr2[], int n2) 11 | { 12 | // init map 13 | unordered_map counter; 14 | 15 | // insert all elements and store their count 16 | for (int i = 0; i < n1; i++) 17 | counter[arr1[i]]++; 18 | for (int i = 0; i < n2; i++) 19 | counter[arr2[i]]++; 20 | 21 | // intersection counting logic: 22 | int count = 0; 23 | for (auto val : counter) 24 | if (val.second > 1) 25 | count++; 26 | 27 | // answer 28 | return count; 29 | } 30 | 31 | // Another optimized approach 32 | int intersection(int arr1[], int n1, int arr2[], int n2) 33 | { 34 | // init set with arr1 35 | unordered_set counter(arr1, arr1 + n1); 36 | 37 | // if element of arr2 is already present, res++ and erase 38 | int res = 0; 39 | for (int i = 0; i < n2; i++) 40 | { 41 | if (counter.find(arr2[i]) != counter.end()) 42 | { 43 | res++; 44 | counter.erase(arr2[i]); 45 | } 46 | } 47 | 48 | // answer 49 | return res; 50 | } 51 | 52 | // Driver code 53 | int main() 54 | { 55 | // Given array 56 | int arr1[] = {10, 15, 20, 5, 30}; 57 | int n1 = sizeof(arr1) / sizeof(arr1[0]); 58 | int arr2[] = {30, 5, 30, 80}; 59 | int n2 = sizeof(arr2) / sizeof(arr2[0]); 60 | 61 | // fn call 62 | cout << countDistinct(arr1, n1, arr2, n2); 63 | } -------------------------------------------------------------------------------- /09. Hashing/06. Union/union.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Count distinct elements after union of two array 3 | eg a1 = [1,2,3], a2 = [2,3,4] = [1,2,3] => distinct elements = 3 4 | */ 5 | 6 | #include 7 | using namespace std; 8 | 9 | // Count 10 | int countDistinct(int arr1[], int n1, int arr2[], int n2) 11 | { 12 | // init set 13 | unordered_set counter(arr1, arr1 + n1); 14 | 15 | // insert all element of arr2 16 | for (int i = 0; i < n2; i++) 17 | counter.insert(arr2[i]); 18 | 19 | // result 20 | return counter.size(); 21 | } 22 | 23 | // Driver code 24 | int main() 25 | { 26 | // Given array 27 | int arr1[] = {10, 15, 20, 5, 30}; 28 | int n1 = sizeof(arr1) / sizeof(arr1[0]); 29 | int arr2[] = {30, 5, 30, 80}; 30 | int n2 = sizeof(arr2) / sizeof(arr2[0]); 31 | 32 | // fn call 33 | cout << countDistinct(arr1, n1, arr2, n2); 34 | } -------------------------------------------------------------------------------- /09. Hashing/07. Find pair/pair.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Find pair with given sum in unsorted array 3 | eg arr = [3,8,4,7,6,1], 9 => (8,1) 4 | */ 5 | 6 | #include 7 | using namespace std; 8 | 9 | // Find pair 10 | pair pairWithSumX(int arr[], int n, int sum) 11 | { 12 | // init set 13 | unordered_set sumFinder(arr, arr + n); 14 | 15 | // logic: 16 | for (auto val : sumFinder) 17 | if (sumFinder.find(sum - val) != sumFinder.end()) 18 | return make_pair(*sumFinder.find(sum - val), val); 19 | 20 | // otherwise 21 | return make_pair(-1, -1); 22 | } 23 | 24 | // Driver code 25 | int main() 26 | { 27 | // Given array 28 | int arr[] = {3, 8, 4, 7, 6, 1}; 29 | int n = sizeof(arr) / sizeof(arr[0]); 30 | 31 | // Given sum 32 | int sum = 9; 33 | 34 | // fn call 35 | pair sumPair = pairWithSumX(arr, n, sum); 36 | cout << sumPair.first << " " << sumPair.second; 37 | } -------------------------------------------------------------------------------- /09. Hashing/08. Subarray sum 0/sum.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Check if there is a subarray with sum = 0 3 | eg [5,3,9,-4,-6,7,-1] => [-6,7,-1] 4 | */ 5 | 6 | #include 7 | using namespace std; 8 | 9 | // Check 10 | bool ZeroSumSubarray(int arr[], int n) 11 | { 12 | // init set 13 | unordered_set prefixSum; 14 | prefixSum.insert(0); 15 | 16 | // init var: 17 | int currentSum = 0; 18 | for (int i = 0; i < n; i++) 19 | { 20 | // update current sum 21 | currentSum += arr[i]; 22 | 23 | // check if sum is there or not 24 | if (prefixSum.find(currentSum) != prefixSum.end()) 25 | return true; 26 | 27 | // insert current sum 28 | prefixSum.insert(currentSum); 29 | } 30 | 31 | // if no such subarray 32 | return false; 33 | } 34 | 35 | // Driver code 36 | int main() 37 | { 38 | // Given array 39 | int arr[] = {5, 3, 9, -4, -6, 7, -1}; 40 | int n = sizeof(arr) / sizeof(arr[0]); 41 | 42 | // fn call 43 | ZeroSumSubarray(arr, n) ? cout << "True" : cout << "False"; 44 | } -------------------------------------------------------------------------------- /09. Hashing/09. Count subarray/count.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Count number of subarray with sum = k 3 | eg: [1,2,7,0,0,0], 10 => [1,2,7], [1,2,7,0], [1,2,7,0,0], [1,2,7,0,0,0] => 4 4 | */ 5 | 6 | #include 7 | using namespace std; 8 | 9 | // Utility fn to print map 10 | void print(unordered_map prefixSum) 11 | { 12 | cout << "\n"; 13 | for (auto m : prefixSum) 14 | cout << m.first << " " << m.second << "\n"; 15 | cout << "\n"; 16 | } 17 | 18 | // Count subarray with sum = k 19 | int subarraySum(vector &nums, int k) 20 | { 21 | // init map: 22 | unordered_map prefixSum; 23 | prefixSum.insert({0, 1}); 24 | 25 | // logic: 26 | int currentSum = 0, count = 0; 27 | for (int i = 0; i < nums.size(); i++) 28 | { 29 | // calculate subarray sum 30 | currentSum += nums[i]; 31 | 32 | // if currSum - k already present increment count 33 | if (prefixSum.find(currentSum - k) != prefixSum.end()) 34 | count += prefixSum[currentSum - k]; 35 | 36 | // insert new value 37 | prefixSum[currentSum]++; 38 | } 39 | 40 | // answer 41 | return count; 42 | } 43 | 44 | // Driver code 45 | int main() 46 | { 47 | // Given vector 48 | vector nums = {1, 2, 7, 0, 0, 0}; 49 | int k = 10; 50 | 51 | // fn call 52 | cout << subarraySum(nums, k); 53 | } -------------------------------------------------------------------------------- /09. Hashing/10. Count 0 and 1/count.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Find the number of subarrays having equal number of 0s and 1s 3 | eg: [1,0,1,1,0,0] => [1,0], [1,1,0,0] => 2 4 | */ 5 | 6 | #include 7 | using namespace std; 8 | 9 | // Count subarray with sum = k 10 | int subarraySumEqualK(vector arr, int k) 11 | { 12 | // init map: 13 | unordered_map prefixSum; 14 | prefixSum.insert({0, 1}); 15 | 16 | // logic: 17 | int currentSum = 0, count = 0; 18 | for (int i = 0; i < arr.size(); i++) 19 | { 20 | // calculate subarray sum 21 | currentSum += arr[i]; 22 | 23 | // if currSum - k already present increment count 24 | if (prefixSum.find(currentSum - k) != prefixSum.end()) 25 | count += prefixSum[currentSum - k]; 26 | 27 | // insert new value 28 | prefixSum[currentSum]++; 29 | } 30 | 31 | // answer 32 | return count; 33 | } 34 | 35 | // Find subarrays having equal 0s and 1s. 36 | long long countSubarrWithEqualZeroAndOne(int arr[], int n) 37 | { 38 | // replace all 0 with -1 in given array 39 | vector replacedWithOne; 40 | 41 | // replaced 42 | for (int i = 0; i < n; i++) 43 | { 44 | if (arr[i] == 0) 45 | replacedWithOne.push_back(-1); 46 | else 47 | replacedWithOne.push_back(1); 48 | } 49 | 50 | // call for subarray with sum k, here k = 0 51 | return subarraySumEqualK(replacedWithOne, 0); 52 | } 53 | 54 | // Driver code 55 | int main() 56 | { 57 | // Given array 58 | int arr[] = {1, 0, 0, 1, 0, 1, 1}; 59 | int n = sizeof(arr) / sizeof(arr[0]); 60 | 61 | // fn call 62 | cout << countSubarrWithEqualZeroAndOne(arr, n); 63 | } -------------------------------------------------------------------------------- /09. Hashing/11. Largest subarray/find.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Find length of largest subarray with given sum 3 | eg: [8,3,1,5,-6,6,2,2], 4 => [-6,6,2,2] => 4 (length) 4 | */ 5 | 6 | #include 7 | using namespace std; 8 | 9 | // Find largest subarray with given sum 10 | int largestSubarrayWithSumX(int arr[], int n, int sum) 11 | { 12 | // init map 13 | unordered_map prefixSum; 14 | 15 | // init vars: 16 | int currSum = 0, result = 0; 17 | 18 | // logic: 19 | for (int i = 0; i < n; i++) 20 | { 21 | // update current sum 22 | currSum += arr[i]; 23 | 24 | // if current sum = given sum 25 | if (currSum == sum) 26 | result = i + 1; 27 | 28 | // if currSum doesn't exist already 29 | if (prefixSum.find(currSum) == prefixSum.end()) 30 | prefixSum.insert({currSum, i}); 31 | 32 | // if found 33 | if (prefixSum.find(currSum - sum) != prefixSum.end()) 34 | result = max(result, i - prefixSum[currSum - sum]); 35 | } 36 | 37 | // answer 38 | return result; 39 | } 40 | 41 | // Driver code 42 | int main() 43 | { 44 | // Given array 45 | int arr[] = {8, 3, 1, 5, -6, 6, 2, 2}; 46 | int n = sizeof(arr) / sizeof(arr[0]); 47 | int sum = 4; 48 | 49 | // fn call 50 | cout << largestSubarrayWithSumX(arr, n, sum); 51 | } -------------------------------------------------------------------------------- /09. Hashing/12. Longest subsequence/longest.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Find length of longest consecutive subsequence 3 | eg [1,9,3,4,2,10,13] => [3,4,10,13] => 4 4 | */ 5 | 6 | #include 7 | using namespace std; 8 | 9 | // Find length of longest consecutive subsequence 10 | int findLongest(int arr[], int n) 11 | { 12 | // init set 13 | unordered_set s(arr, arr + n); 14 | 15 | // init result 16 | int res = 0; 17 | 18 | // logic: 19 | for (int i = 0; i < n; i++) 20 | { 21 | // count subsequence ane update res 22 | if (s.find(arr[i] - 1) == s.end()) 23 | { 24 | int curr = 1; 25 | while (s.find(curr + arr[i]) != s.end()) 26 | curr++; 27 | 28 | res = max(res, curr); 29 | } 30 | } 31 | 32 | // answer 33 | return res; 34 | } 35 | 36 | // Driver code 37 | int main() 38 | { 39 | // Given array 40 | int arr[] = {1, 9, 3, 4, 2, 10, 13}; 41 | int n = sizeof(arr) / sizeof(arr[0]); 42 | 43 | // fn call 44 | cout << findLongest(arr, n); 45 | } -------------------------------------------------------------------------------- /09. Hashing/13. Distinct elements/count.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Print distinct elements in each window of size k 3 | eg: [10,20,20,10,30,40,10], 4 => 2 3 4 3 4 | */ 5 | 6 | #include 7 | using namespace std; 8 | 9 | // Print 10 | void printDistinct(int arr[], int n, int k) 11 | { 12 | // initialize map 13 | map counter; 14 | 15 | // count upto k 16 | for (int i = 0; i < k; i++) 17 | counter[arr[i]]++; 18 | 19 | // print size upto k 20 | cout << counter.size() << " "; 21 | 22 | // for subsequenct window 23 | for (int i = k; i < n; i++) 24 | { 25 | // add current element 26 | counter[arr[i]]++; 27 | 28 | // remove previous element 29 | counter[arr[i - k]]--; 30 | 31 | // if previous element is completely removed erase 32 | if (counter[arr[i - k]] == 0) 33 | counter.erase(arr[i - k]); 34 | 35 | // print current map size 36 | cout << counter.size() << " "; 37 | } 38 | } 39 | 40 | // Driver code 41 | int main() 42 | { 43 | // Given array 44 | int arr[] = {10, 20, 20, 10, 30, 40, 10}; 45 | int n = sizeof(arr) / sizeof(arr[0]); 46 | int k = 4; 47 | 48 | // fn call 49 | printDistinct(arr, n, k); 50 | } -------------------------------------------------------------------------------- /09. Hashing/14. More than NbyK/count.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Print elements with more than n/k occurance 3 | eg: [10,10,20,30,20,10,10], 2 => 10 4 | */ 5 | 6 | #include 7 | using namespace std; 8 | 9 | // Time: O(n), Space: O(n) 10 | void printNbyK(int arr[], int n, int k) 11 | { 12 | unordered_map counter; 13 | for (int i = 0; i < n; i++) 14 | counter[arr[i]]++; 15 | 16 | for (auto val : counter) 17 | if (val.second > n / k) 18 | cout << val.first << " "; 19 | } 20 | 21 | // Driver code 22 | int main() 23 | { 24 | // Given array 25 | int arr[] = {10, 10, 20, 30, 20, 10, 10}; 26 | int n = sizeof(arr) / sizeof(arr[0]); 27 | int k = 2; 28 | 29 | // fn call 30 | printNbyK(arr, n, k); 31 | } -------------------------------------------------------------------------------- /09. Hashing/15. Sort by freq/sort.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Sort an array by frequence of each element (higher freq element first) 3 | eg: [1,2,2,3,3,3,4,4,4,4] => [4,4,4,4,3,3,3,2,2,1] 4 | */ 5 | 6 | #include 7 | using namespace std; 8 | 9 | // Sort array by frequency 10 | vector sortByFreq(int arr[], int n) 11 | { 12 | // create map 13 | unordered_map freq; 14 | 15 | // store frequency 16 | for (int i = 0; i < n; i++) 17 | freq[arr[i]]++; 18 | 19 | // vect of pair 20 | vector> vectPair; 21 | 22 | // store map elements in vector 23 | for (auto &val : freq) 24 | vectPair.push_back(val); 25 | 26 | // sort 27 | sort(begin(vectPair), end(vectPair), [&](pair a, pair b) 28 | { return a.second != b.second ? a.second > b.second : a.first < b.first; }); 29 | 30 | // export answer 31 | vector result; 32 | for (auto &val : vectPair) 33 | while (val.second--) 34 | result.push_back(val.first); 35 | 36 | // return 37 | return result; 38 | } 39 | 40 | // Driver code 41 | int main() 42 | { 43 | // Given array 44 | int arr[] = {1, 2, 2, 3, 3, 3, 4, 4, 4, 4}; 45 | int n = sizeof(arr) / sizeof(arr[0]); 46 | 47 | // Output 48 | vector ans = sortByFreq(arr, n); 49 | for (auto x : ans) 50 | cout << x << " "; 51 | } -------------------------------------------------------------------------------- /09. Hashing/18. Smaller Right/smaller.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Given an array arr[] of N elements. Count maximum number of 3 | distinct smaller elements on right side of any array element. 4 | 5 | eg: 6 | 7 | arr = {10, 6, 9, 7, 20, 19, 21, 18, 17, 16} 8 | output: 4 9 | 10 | Note that 20 has maximum 4 smaller elements on right side 11 | Other elements have less count, for example 10 has 3 smaller 12 | elements on right side. 13 | */ 14 | 15 | #include 16 | using namespace std; 17 | 18 | // Maximum count of smaller elements on right side. 19 | int maxCount(vector &arr) 20 | { 21 | // init 22 | set st; 23 | int res = 0; 24 | 25 | // start from end, insert each element, find max 26 | for (int i = arr.size() - 1; i >= 0; i--) 27 | { 28 | st.insert(arr[i]); 29 | int dist = distance(st.begin(), st.find(arr[i])); 30 | cout << dist << " "; 31 | res = max(res, dist); 32 | } 33 | cout << endl; 34 | 35 | // ans 36 | return res; 37 | } 38 | 39 | // Driver code 40 | int main() 41 | { 42 | // Given vector 43 | vector arr = {10, 6, 9, 7, 20, 19, 21, 18, 17, 16}; 44 | 45 | // fn call 46 | cout << maxCount(arr); 47 | } -------------------------------------------------------------------------------- /10. Strings/01. Theory/theory.md: -------------------------------------------------------------------------------- 1 | ## Definition: 2 | 3 | - In C language, sequence of characters are stroed as character array. 4 | 5 | - C++ has a way to represent sequence of characters as an object of class. 6 | 7 | - This class is called std:: string. 8 | 9 | - String class stores the characters as a sequence of bytes with a functionality of allowing access to single byte character. 10 | 11 | ## Methods: 12 | 13 | 1. getline() 14 | 15 | 2. push_back() 16 | 17 | 3. pop_back() 18 | 19 | 4. capacity() 20 | 21 | 5. resize() 22 | 23 | 6. length() 24 | 25 | 7. shrink_to_fit() 26 | -------------------------------------------------------------------------------- /10. Strings/03. Split and store/string.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Split a string separated by space and store it in vector 3 | eg: str = "This is a word", vect = ["This", "is", "a", "word"] 4 | */ 5 | 6 | #include 7 | using namespace std; 8 | 9 | // Split and store 10 | vector split(string str) 11 | { 12 | // stringstream is used to read from the string as if it were a stream like cin 13 | stringstream cin_s(str); 14 | 15 | // store individual word 16 | string word; 17 | 18 | // store all word in str separated by space 19 | vector result; 20 | 21 | // process each word one by one 22 | while (cin_s >> word) 23 | result.push_back(word); 24 | 25 | // return vector result 26 | return result; 27 | } 28 | 29 | // Driver code 30 | int main() 31 | { 32 | // Given string 33 | string str = "This is a line and a sentence"; 34 | 35 | // fn call 36 | vector words = split(str); 37 | 38 | // Output 39 | for (auto &val : words) 40 | cout << val << " "; 41 | } -------------------------------------------------------------------------------- /10. Strings/04. Letter frequency/freq.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Given a string of lowercase chars. Print sorted chars and their freq 3 | 4 | Dry Run: 5 | * freq[26] = {0,0,0 ... 0} 6 | * Iteration 1: 'g' - 'a' = 7 (value at index 6 = 1) 7 | * Iteration 2: 'e' - 'a' = 5 (value at index 4 = 1) 8 | * Iteration 3: 'e' - 'a' = 5 (value at index 4 = 2) 9 | * Iteration 4: 'k' - 'a' = 11 (value at index 10 = 1) 10 | * Iteration 5: 's' - 'a' = 19 (value at index 18 = 1) 11 | * Traverse array upto index 4 (print 4 + 'a' = 'e' and value = 2) 12 | * Traverse array upto index 6 (print 6 + 'a' = 'g' and value = 1) 13 | * Traverse array upto index 10 (print 10 + 'a' = 'k' and value = 1) 14 | * Traverse array upto index 18 (print 18 + 'a' = 's' and value = 1) 15 | */ 16 | 17 | #include 18 | using namespace std; 19 | 20 | // Utility fn 21 | void print(int arr[], int n) 22 | { 23 | for (int i = 0; i < n; i++) 24 | cout << "Index: " << i << " Value: " << arr[i] << "\n"; 25 | } 26 | 27 | // Driver code 28 | int main() 29 | { 30 | // Given string 31 | string str = "geeks"; 32 | 33 | // Init freq array with 0 34 | int size = 26; 35 | int freq[size] = {}; 36 | 37 | // Store occurance and each char as index 38 | for (int i = 0; i < str.size(); i++) 39 | freq[str[i] - 'a']++; 40 | 41 | // Check freq array at this point 42 | print(freq, size); 43 | 44 | // Output char and its freq 45 | for (int i = 0; i < 26; i++) 46 | if (freq[i]) 47 | cout << (char)(i + 'a') << " " << freq[i] << "\n"; 48 | } -------------------------------------------------------------------------------- /10. Strings/05. Word frequency/freq.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Count total number of words in string 3 | eg: str = "Geeks for Geeks" => Geeks: 2, for: 1 4 | 5 | https://www.geeksforgeeks.org/stringstream-c-applications/ 6 | */ 7 | 8 | #include 9 | using namespace std; 10 | 11 | // Count 12 | void count(string str) 13 | { 14 | // init stringstream 15 | stringstream cin_s(str); 16 | 17 | // to store each word 18 | string word; 19 | 20 | // init count var 21 | int count = 0; 22 | 23 | // read words 24 | while (cin_s >> word) 25 | count++; 26 | 27 | // print result 28 | cout << "Total words in str is: " << count << "\n"; 29 | } 30 | 31 | // Print frequency of each word in a string 32 | void printFreq(string str) 33 | { 34 | // init map 35 | map freqMap; 36 | 37 | // init string stream used for breaking word 38 | stringstream ss(str); 39 | 40 | // to store individual word 41 | string word; 42 | 43 | // extract each word and increment frequency 44 | while (ss >> word) 45 | freqMap[word]++; 46 | 47 | // output 48 | for (auto &val : freqMap) 49 | cout << val.first << " " << val.second << "\n"; 50 | } 51 | 52 | // Driver code 53 | int main() 54 | { 55 | // Given string 56 | string str = "Geeks For Geeks Ide"; 57 | 58 | // fn call 59 | printFreq(str); 60 | count(str); 61 | } 62 | -------------------------------------------------------------------------------- /10. Strings/06. Palindrome/palindrome.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Check whether a string is palindrome or not 3 | eg: str = "aba" => true 4 | */ 5 | 6 | #include 7 | using namespace std; 8 | 9 | // Check palindrome 10 | bool isPalindrome(string str) 11 | { 12 | // init vars: 13 | int low = 0, high = str.size() - 1; 14 | 15 | // logic: 16 | while (low <= high) 17 | if (str[low++] != str[high--]) 18 | return false; 19 | 20 | // answer 21 | return true; 22 | } 23 | 24 | // Driver code 25 | int main() 26 | { 27 | // Given string 28 | string str = "abbbba"; 29 | 30 | // fn call 31 | isPalindrome(str) ? cout << "True" : cout << "False"; 32 | } -------------------------------------------------------------------------------- /10. Strings/07. Subsequence/checkSubsequence.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Check if s2 is subsequence of s1 3 | eg: s1 = "abcde", s2 = "ace" => true 4 | */ 5 | 6 | #include 7 | using namespace std; 8 | 9 | // Check 10 | bool isSubsequence(string s1, string s2) 11 | { 12 | // init pointer to keep track of each char in s2 13 | int ptr = 0; 14 | 15 | // if ch = s1[ptr] move both pointer otherwise only ch 16 | for (auto ch : s1) 17 | if (ch == s2[ptr]) 18 | ptr++; 19 | 20 | // if ptr == s2.size(), every char of s2 appear in s1 21 | return ptr == s2.size(); 22 | } 23 | 24 | // Driver code 25 | int main() 26 | { 27 | // Given string 28 | string s1 = "GEEKSFORGEEKS", s2 = "SKS"; 29 | 30 | // fn call 31 | cout << boolalpha << isSubsequence(s1, s2); 32 | } -------------------------------------------------------------------------------- /10. Strings/07. Subsequence/printSubsequence.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Print all subsequence of given string 3 | */ 4 | 5 | #include 6 | using namespace std; 7 | 8 | // Print subsequence 9 | void subSeq(string ans, string str, int low, int high) 10 | { 11 | // base case 12 | if (low == high) 13 | cout << ans << " "; 14 | // tree recursion 15 | else 16 | { 17 | // don't include 18 | subSeq(ans, str, low + 1, high); 19 | 20 | // add element to ans 21 | ans += str[low]; 22 | 23 | // include ans 24 | subSeq(ans, str, low + 1, high); 25 | } 26 | } 27 | 28 | // Driver code 29 | int main() 30 | { 31 | // Given string 32 | string str = "ABC"; 33 | 34 | // fn call 35 | subSeq("", str, 0, str.size()); 36 | } -------------------------------------------------------------------------------- /10. Strings/08. Anagram/anagram.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Check if string s1 and s2 are anagram (permutation of each other) 3 | eg: s1 = "char", s2 = "rach" => true 4 | */ 5 | 6 | #include 7 | using namespace std; 8 | 9 | const int CHAR = 256; 10 | 11 | // Check anagram (permutation of each other) in lowercase alphabets 12 | bool checkAnagram(string s1, string s2) 13 | { 14 | // initial check 15 | if (s1.size() != s2.size()) 16 | return false; 17 | 18 | // initialize char array of size 256 19 | int count[CHAR] = {0}; 20 | 21 | // increment s1[i]'s count decrement s2[i]'s count: 22 | for (int i = 0; i < s1.size(); i++) 23 | { 24 | count[s1[i]]++; 25 | count[s2[i]]--; 26 | } 27 | 28 | // check 29 | for (int i = 0; i < CHAR; i++) 30 | if (count[i] != 0) 31 | return false; 32 | 33 | // answer 34 | return true; 35 | } 36 | 37 | // Driver code 38 | int main() 39 | { 40 | // Given string 41 | string s1 = "listen", s2 = "silent"; 42 | 43 | // fn call 44 | cout << boolalpha << checkAnagram(s1, s2); 45 | } -------------------------------------------------------------------------------- /10. Strings/12. Naive search/pattern.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Naive pattern searching 3 | */ 4 | 5 | #include 6 | using namespace std; 7 | 8 | // Time: O((n-m+1)*m) 9 | void findPattern(string &str, string &pattern) 10 | { 11 | // init size 12 | int strSize = str.size(), patternSize = pattern.size(); 13 | 14 | // logic: 15 | for (int low = 0; low <= strSize - patternSize; low++) 16 | { 17 | // init end pointer 18 | int high = 0; 19 | 20 | // loop while matching 21 | for (high = 0; high < patternSize; high++) 22 | if (str[low + high] != pattern[high]) 23 | break; 24 | 25 | // if high crossed patternSize 26 | if (high == patternSize) 27 | cout << "Found at index " << low << "\n"; 28 | } 29 | } 30 | 31 | // Driver code 32 | int main() 33 | { 34 | // Given string 35 | string str = "abababcxyabcklabc", pattern = "abc"; 36 | 37 | // fn call 38 | findPattern(str, pattern); 39 | } -------------------------------------------------------------------------------- /10. Strings/13. Improved Naive/search.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Improved Naive pattern searching 3 | */ 4 | 5 | #include 6 | using namespace std; 7 | 8 | // Optimized pattern search 9 | void findPattern(string &str, string &pattern) 10 | { 11 | // init size 12 | int strSize = str.size(), patternSize = pattern.size(); 13 | 14 | // logic: 15 | for (int low = 0; low <= (strSize - patternSize);) 16 | { 17 | // init end pointer 18 | int high = 0; 19 | 20 | // loop untill matching 21 | for (high = 0; high < patternSize; high++) 22 | if (str[low + high] != pattern[high]) 23 | break; 24 | 25 | // if high crossed pattern size 26 | if (high == patternSize) 27 | cout << "Found at index " << low << "\n"; 28 | 29 | // if first character mismatch 30 | if (high == 0) 31 | low++; 32 | // if any subsequent character mismatch 33 | else 34 | low = (low + high); 35 | } 36 | } 37 | 38 | // Driver code 39 | int main() 40 | { 41 | // Given string 42 | string str = "ABCEABEFABCD"; 43 | string pattern = "ABCD"; 44 | 45 | // Optimized naive pattern search 46 | findPattern(str, pattern); 47 | } -------------------------------------------------------------------------------- /10. Strings/14. Rabin Karp Algorithm/rk.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Rabin-Karp Algorithm for Pattern Searching 3 | */ 4 | 5 | #include 6 | using namespace std; 7 | #define d 256 8 | const int q = 101; 9 | 10 | // Find pattern 11 | void RBSearch(string pat, string txt, int M, int N) 12 | { 13 | // compute (d^(M-1))%q 14 | int h = 1; 15 | for (int i = 1; i <= M - 1; i++) 16 | h = (h * d) % q; 17 | 18 | // compute p and to 19 | int p = 0, t = 0; 20 | for (int i = 0; i < M; i++) 21 | { 22 | p = (p * d + pat[i]) % q; 23 | t = (t * d + txt[i]) % q; 24 | } 25 | 26 | for (int i = 0; i <= (N - M); i++) 27 | { 28 | // check for hit 29 | if (p == t) 30 | { 31 | bool flag = true; 32 | for (int j = 0; j < M; j++) 33 | if (txt[i + j] != pat[j]) 34 | { 35 | flag = false; 36 | break; 37 | } 38 | if (flag == true) 39 | cout << "Found pattern at index " << i << "\n"; 40 | } 41 | // compute ti+1 using ti 42 | if (i < N - M) 43 | { 44 | t = ((d * (t - txt[i] * h)) + txt[i + M]) % q; 45 | if (t < 0) 46 | t = t + q; 47 | } 48 | } 49 | } 50 | 51 | // Driver code 52 | int main() 53 | { 54 | // Given strings 55 | string txt = "GEEKS FOR GEEKS", pat = "GEEK"; 56 | 57 | // fn call 58 | RBSearch(pat, txt, 4, 15); 59 | } -------------------------------------------------------------------------------- /10. Strings/16. Check Rotated/check.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Check if two strings are rotation of each other 3 | */ 4 | 5 | #include 6 | using namespace std; 7 | 8 | // Check 9 | bool areRotations(string s1, string s2) 10 | { 11 | return (s1.length() == s2.length()) && ((s1 + s1).find(s2) != string::npos); 12 | } 13 | 14 | int main() 15 | { 16 | // Given string 17 | string s1 = "ABCD", s2 = "CDAB"; 18 | 19 | // fn call 20 | cout << boolalpha << areRotations(s1, s2); 21 | } -------------------------------------------------------------------------------- /10. Strings/17. Anagram search/search.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Check if pattern or it's permutation is present in given text 3 | eg: text = "geeksforgeeks", pattern = "frog" => true 4 | */ 5 | 6 | #include 7 | using namespace std; 8 | 9 | const int CHAR = 256; 10 | 11 | // Check if two array are equal 12 | bool areSame(int countTxt[], int countPat[]) 13 | { 14 | for (int i = 0; i < CHAR; i++) 15 | if (countTxt[i] != countPat[i]) 16 | return false; 17 | 18 | return true; 19 | } 20 | 21 | // Time: O(n*CHAR) 22 | bool isPresent(string &txt, string &pat) 23 | { 24 | // init vars 25 | int countTxt[CHAR] = {0}, countPat[CHAR] = {0}; 26 | 27 | // count frequency of each char in txt and pat upto pat.size() 28 | for (int i = 0; i < pat.size(); i++) 29 | { 30 | countTxt[txt[i]]++; 31 | countPat[pat[i]]++; 32 | } 33 | 34 | // count and check frequency for subsequent window 35 | for (int i = pat.size(); i < txt.size(); i++) 36 | { 37 | // if both array equal 38 | if (areSame(countTxt, countPat)) 39 | return true; 40 | 41 | // slide window 42 | countTxt[txt[i]]++; 43 | countTxt[txt[i - pat.size()]]--; 44 | } 45 | 46 | // if not found 47 | return false; 48 | } 49 | 50 | // Driver code 51 | int main() 52 | { 53 | // Given string 54 | string txt = "geeksforgeeks", pat = "gofr"; 55 | 56 | // fn call 57 | cout << boolalpha << isPresent(txt, pat); 58 | } -------------------------------------------------------------------------------- /10. Strings/18. Lexicographic rank/rank.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Find lexicographic rank of a string 3 | eg: str = "BAC" => rank = 3 4 | 5 | "ABC" 6 | "ACB" 7 | "BAC" (answer) 8 | "BCA" 9 | "CAB" 10 | "CBA" 11 | */ 12 | 13 | #include 14 | using namespace std; 15 | 16 | const int CHAR = 256; 17 | 18 | // factorial of n 19 | int fact(int n) 20 | { 21 | return (n <= 1) ? 1 : n * fact(n - 1); 22 | } 23 | 24 | // Find rank 25 | int lexicographicRank(string &str) 26 | { 27 | // init result 28 | int res = 1; 29 | 30 | // init size 31 | int n = str.size(); 32 | 33 | // factorial of str.size() 34 | int factorial = fact(n); 35 | 36 | // init count array 37 | int count[CHAR] = {0}; 38 | 39 | // logic: 40 | for (int i = 0; i < n; i++) 41 | count[str[i]]++; 42 | 43 | for (int i = 1; i < CHAR; i++) 44 | count[i] += count[i - 1]; 45 | 46 | for (int i = 0; i < n - 1; i++) 47 | { 48 | factorial = factorial / (n - i); 49 | res = res + count[str[i] - 1] * factorial; 50 | 51 | for (int j = str[i]; j < CHAR; j++) 52 | count[j]--; 53 | } 54 | 55 | // return answer 56 | return res; 57 | } 58 | 59 | int main() 60 | { 61 | // Given string 62 | string str = "STRING"; 63 | 64 | // fn call 65 | cout << lexicographicRank(str); 66 | } -------------------------------------------------------------------------------- /10. Strings/19. Distinct characters/longest.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Find length of longest subarray with distinct characters 3 | */ 4 | 5 | #include 6 | using namespace std; 7 | 8 | // Longest subarray 9 | int longestDistinct(string str) 10 | { 11 | // init size and res 12 | int n = str.size(), res = 0; 13 | 14 | // init vector 15 | vector prev(256, -1); 16 | 17 | // logic: 18 | int i = 0; 19 | for (int j = 0; j < n; j++) 20 | { 21 | i = max(i, prev[str[j]] + 1); 22 | int maxEnd = j - i + 1; 23 | res = max(res, maxEnd); 24 | prev[str[j]] = j; 25 | } 26 | 27 | // answer 28 | return res; 29 | } 30 | 31 | // Driver code 32 | int main() 33 | { 34 | // Given string 35 | string str = "geeksforgeeks"; 36 | 37 | // fn call 38 | cout << longestDistinct(str); 39 | } 40 | -------------------------------------------------------------------------------- /10. Strings/20. Pangram/pangram.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Check whether given string is pangram (containing all characters of english alphabet) 3 | eg: str = "The quick brown fox jumps over the lazy dog" => true 4 | */ 5 | 6 | #include 7 | using namespace std; 8 | 9 | const int CHAR = 256; 10 | 11 | // Pangram without using set 12 | bool checkPangram(string &str) 13 | { 14 | // initialize an array of 256 chars with all elements as 0 15 | int mark[CHAR] = {}; 16 | 17 | // init index and size 18 | int index = 0, n = str.size(); 19 | 20 | // logic 21 | for (int i = 0; i < n; i++) 22 | { 23 | // increment mark for each uppercase character 24 | if (str[i] >= 65 && str[i] <= 90) 25 | { 26 | index = str[i] - 65; 27 | mark[index]++; 28 | } 29 | // increment mark for each lowercase character 30 | else if (str[i] >= 97 && str[i] <= 122) 31 | { 32 | index = str[i] - 97; 33 | mark[index]++; 34 | } 35 | } 36 | 37 | // if any mark value is 0 that means a char is missing from a-z 38 | for (int i = 0; i < 26; i++) 39 | if (mark[i] == 0) 40 | return false; 41 | 42 | // if pangram 43 | return true; 44 | } 45 | 46 | // Driver code 47 | int main() 48 | { 49 | // Given string 50 | string s = "Bawds jog, flick quartz, vex nymph"; 51 | 52 | // fn call 53 | cout << boolalpha << checkPangram(s); 54 | } -------------------------------------------------------------------------------- /10. Strings/21. LargestNumber/largest.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Find largest number of n digits with given sum 3 | eg: sum = 12, n = 3 => 930 4 | */ 5 | 6 | #include 7 | using namespace std; 8 | 9 | // Find largest number 10 | string largestNumber(int n, int sum) 11 | { 12 | // init string 13 | string output(n, '0'); 14 | 15 | // logic: 16 | for (int i = 0; i < n; i++) 17 | { 18 | // init current max val 19 | int val = 0; 20 | 21 | // sum > 9 22 | if (sum > 9) 23 | { 24 | val = 9; 25 | sum -= 9; 26 | } 27 | 28 | // sum < 9 29 | else 30 | { 31 | val = sum; 32 | sum = 0; 33 | } 34 | 35 | // construct output string 36 | output[i] = val + '0'; 37 | } 38 | 39 | // if sum has leftovers 40 | if (sum > 0) 41 | return "-1"; 42 | 43 | // answer 44 | return output; 45 | } 46 | 47 | // Driver code 48 | int main() 49 | { 50 | // Given number 51 | int n = 5, sum = 12; 52 | 53 | // fn call 54 | cout << largestNumber(n, sum); 55 | } -------------------------------------------------------------------------------- /11. Pointers/01. Introduction/2. Double Pointer.md: -------------------------------------------------------------------------------- 1 | # Double Pointer: 2 | 3 | - When one pointer variable stores the address of another pointer variable, it is known as Pointer to Pointer variable or Double Pointer. 4 | 5 | - General syntax for double pointer 6 | 7 | ``` 8 | int *p; // normal pointer 9 | int **p1; // double pointer 10 | ``` 11 | 12 | - Program to represent pointer to pointer 13 | 14 | ``` 15 | #include 16 | 17 | int main() { 18 | 19 | int x = 10; 20 | int *p1; // p1 can store the address of variable x 21 | int **p2; // p2 can store address of p1 but not address of 'x' 22 | 23 | p1 = &x; 24 | p2 = &p1; 25 | 26 | // print address of x 27 | cout << (&x) << (p1) << (*p2)<< "\n"; 28 | 29 | // print value of x 30 | cout << (x) << *(p1) << *(*p2) << "\n"; 31 | } 32 | ``` 33 | 34 | 35 | -------------------------------------------------------------------------------- /11. Pointers/01. Introduction/pointer-to-pointer.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nikhilsourav/Data-Structures-and-Algorithms/28cfaeda58597a0f1e266f250e87875d44c22f3d/11. Pointers/01. Introduction/pointer-to-pointer.webp -------------------------------------------------------------------------------- /11. Pointers/01. Introduction/pointers-in-c.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nikhilsourav/Data-Structures-and-Algorithms/28cfaeda58597a0f1e266f250e87875d44c22f3d/11. Pointers/01. Introduction/pointers-in-c.png -------------------------------------------------------------------------------- /11. Pointers/02. Basics/pointer.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Print value and address of variables using single and double pointers 3 | */ 4 | 5 | #include 6 | using namespace std; 7 | 8 | // Driver code 9 | int main() 10 | { 11 | // Initialize variable 12 | int x = 10; 13 | 14 | // Declare inteer pointer 15 | int *p1; // p1 can store the address of variable x 16 | int **p2; // p2 can store address of p1 but not address of 'x' 17 | 18 | // Initialize integer pointer 19 | p1 = &x; 20 | p2 = &p1; 21 | 22 | // Print address of x 23 | cout << (&x) << " " << (p1) << " " << (*p2) << "\n"; 24 | 25 | // Value of x 26 | cout << (x) << *(p1) << *(*p2) << "\n"; 27 | }; -------------------------------------------------------------------------------- /11. Pointers/03 .swap/swap.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Given two numbers swap them with the help of pointers 3 | */ 4 | 5 | #include 6 | using namespace std; 7 | 8 | // Swap two numbers using pointer 9 | void swapByPointer(int *ptr1, int *ptr2) 10 | { 11 | // init temp number 12 | int temp; 13 | 14 | // swap 15 | temp = *ptr1; // store value of ptr1 in temp 16 | *ptr1 = *ptr2; // store value of ptr2 in ptr1 17 | *ptr2 = temp; // store value of temp in ptr2 18 | } 19 | 20 | // Swap two numbers using ref 21 | void swapByRef(int &ptr1, int &ptr2) 22 | { 23 | // init temp number 24 | int temp; 25 | 26 | // swap 27 | temp = ptr1; 28 | ptr1 = ptr2; 29 | ptr2 = temp; 30 | } 31 | 32 | // Driver code 33 | int main() 34 | { 35 | // Given numbers 36 | int num1 = 5, num2 = 7; 37 | 38 | // fn call 39 | swapByPointer(&num1, &num2); 40 | swapByRef(num1, num2); 41 | 42 | // Output 43 | cout << num1 << " " << num2; 44 | } -------------------------------------------------------------------------------- /11. Pointers/04. Pointer to array/array.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Print content of array using pointers 3 | */ 4 | 5 | #include 6 | using namespace std; 7 | 8 | // Driver code 9 | int main() 10 | { 11 | // Given array 12 | int arr[] = {1, 2, 3, 4, 5}; 13 | int n = sizeof(arr) / sizeof(arr[0]); 14 | 15 | // Init pointer 16 | int *ptr = arr; 17 | 18 | // Print array contents using pointer 19 | for (int i = 0; i < n; i++) 20 | cout << (*ptr)++ << " "; 21 | } 22 | 23 | /* 24 | NOTES: 25 | 26 | => we can't decrement pointer once incremented that is p-- won't work. 27 | => arr[i] is same as *(arr + i) 28 | => &arr[i] is same as (arr + i) 29 | => arr[i][j] is same as *(*(arr + i) + j) 30 | => int arr[] = {1, 2, 3}; arr++; ERROR 31 | */ -------------------------------------------------------------------------------- /11. Pointers/05. Pointer to structure/structure.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Introduction to pointer to a structure 3 | 4 | To access members of structure using the structure variable, 5 | we used the dot '.' operator but when we have a pointer 6 | of structure type, we use arrow -> to access structure members. 7 | */ 8 | 9 | #include 10 | using namespace std; 11 | 12 | // Book structure 13 | struct Book 14 | { 15 | string name; 16 | int price; 17 | }; 18 | 19 | // Driver code 20 | int main() 21 | { 22 | // Instance of structure 23 | Book b1 = {"DSA", 799}; // single structure variable 24 | Book *ptr1; // pointer of Structure type 25 | ptr1 = &b1; 26 | 27 | // Output 28 | cout << ptr1->name << " " << ptr1->price << "\n"; 29 | 30 | // Instance of structure 31 | Book b2; 32 | b2.name = "OOPS"; 33 | b2.price = 1299; 34 | 35 | Book *ptr2; 36 | ptr2 = &b2; 37 | 38 | // Output 39 | cout << ptr2->name << " " << ptr2->price << "\n"; 40 | } -------------------------------------------------------------------------------- /11. Pointers/07. Pointer Arithmatic/arithmetic.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Pointer arithmetic 3 | */ 4 | 5 | #include 6 | using namespace std; 7 | 8 | // Driver code 9 | int main() 10 | { 11 | // Given number 12 | int num = 57.86; 13 | 14 | // Init pointer 15 | int *ptr = # 16 | 17 | // Size of int for this compiler 18 | cout << "Integer size: " << sizeof(int) << "\n"; // 8 19 | 20 | // Print ptr, ptr + 1 and ptr -1 21 | cout << "Address ptr is " << ptr << "\n"; // 2014 22 | cout << "Address ptr + 1 is " << ptr + 1 << "\n"; // 2010 23 | cout << "Address ptr - 1 is " << ptr - 1 << "\n"; // 2010 24 | 25 | // ptr + 1 and ptr - 1 contains garbage value 26 | // as we didn't initialize their values 27 | cout << "\nValue of *ptr is " << *ptr << "\n"; 28 | cout << "Value of *(ptr + 1) is " << *(ptr + 1) << "\n"; 29 | cout << "Value of *(ptr - 1) is " << *(ptr - 1) << "\n"; 30 | } -------------------------------------------------------------------------------- /12. Linked List/01. Theory/linkedlist.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nikhilsourav/Data-Structures-and-Algorithms/28cfaeda58597a0f1e266f250e87875d44c22f3d/12. Linked List/01. Theory/linkedlist.png -------------------------------------------------------------------------------- /12. Linked List/01. Theory/theory.md: -------------------------------------------------------------------------------- 1 | ## Definition: 2 | 3 | - A linked list consists of nodes where each node contains a data field and a reference(link) to the next node in the list. 4 | 5 | - The first and last node are called head and tail. Traversal starts from head until tail is encountered which points to NULL. 6 | 7 |
8 | 9 | 10 |
11 | 12 | ## Advantages: 13 | 14 | - Data and reference is stored in a non-contiguous manner. This makes insertion, deletion efficient. 15 | 16 | - Implementation of data structures like queue and dequeue using linked list is simple. 17 | 18 | - Sorting array using merge sort requires O(n) extra space while sorting linked list requires O(1) space. 19 | -------------------------------------------------------------------------------- /12. Linked List/02. SLL/01. Singly Linked List/list.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Linked list implementation using struct 3 | */ 4 | 5 | #include 6 | using namespace std; 7 | 8 | // Node structure 9 | struct Node 10 | { 11 | // data of node (can be int, char, float or custom datatype) 12 | int data; 13 | 14 | // pointer to next node (because datatype of each node = Node) 15 | Node *next; 16 | 17 | // constructor to initialize each Node 18 | Node(int x) 19 | { 20 | data = x; 21 | next = NULL; 22 | } 23 | }; 24 | 25 | // Driver code 26 | int main() 27 | { 28 | // Create three nodes in heap with data initialized by constructor 29 | Node *head = new Node(10); 30 | Node *ptr1 = new Node(20); 31 | Node *ptr2 = new Node(30); 32 | 33 | // Link next pointer of each node to subsequent node 34 | head->next = ptr1; 35 | ptr1->next = ptr2; 36 | 37 | // Output 38 | cout << head->data << " " << head->next << "\n"; 39 | cout << ptr1->data << " " << ptr1->next << "\n"; 40 | cout << ptr2->data << " " << ptr2->next << "\n"; 41 | 42 | // Short implementation 43 | Node *headPtr = new Node(40); 44 | headPtr->next = new Node(50); 45 | headPtr->next->next = new Node(60); 46 | 47 | // Output 48 | cout << headPtr->data << " " << headPtr->next << "\n"; 49 | cout << headPtr->next->data << " " << headPtr->next->next << "\n"; 50 | cout << headPtr->next->next->data << " " << headPtr->next->next->next << "\n"; 51 | } -------------------------------------------------------------------------------- /12. Linked List/02. SLL/05. Delete head/delete.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Delete the head of a linked list 3 | eg: [1->2->3] => [2->3] 4 | */ 5 | 6 | #include 7 | using namespace std; 8 | 9 | // Node class with constructor 10 | class Node 11 | { 12 | public: 13 | int data; 14 | Node *next; 15 | Node(int x) 16 | { 17 | data = x; 18 | next = NULL; 19 | } 20 | }; 21 | 22 | // Delete head node 23 | Node *deleteHead(Node *head) 24 | { 25 | // if list is empty 26 | if (head == NULL) 27 | return NULL; 28 | 29 | // create newHead and point it to next list element 30 | Node *newHead = head->next; 31 | 32 | // delete current head from heap (required in c++) 33 | delete head; 34 | 35 | // rerturn newHead pointer 36 | return newHead; 37 | } 38 | 39 | // Print list 40 | void printList(Node *ptr) 41 | { 42 | while (ptr != NULL) 43 | { 44 | cout << ptr->data << " "; 45 | ptr = ptr->next; 46 | } 47 | cout << "\n"; 48 | } 49 | 50 | // Driver code 51 | int main() 52 | { 53 | // ============ Filled linked list ============= // 54 | // Create new linked list 55 | Node *head = new Node(10); 56 | head->next = new Node(20); 57 | head->next->next = new Node(30); 58 | 59 | // Print given list 60 | printList(head); 61 | 62 | // Update current head 63 | head = deleteHead(head); 64 | 65 | // Print after deletion 66 | printList(head); 67 | } 68 | -------------------------------------------------------------------------------- /12. Linked List/02. SLL/09. Reverse/reverse.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Reverse a linked list 3 | eg: [1->2->3->4] => [4->3->2->1] 4 | 5 | https://www.youtube.com/watch?v=XgABnoJLtG4 6 | */ 7 | 8 | 9 | #include 10 | using namespace std; 11 | 12 | // Node class with constructor 13 | class Node 14 | { 15 | public: 16 | int data; 17 | Node *next; 18 | 19 | // constructor 20 | Node(int x) 21 | { 22 | data = x; 23 | next = NULL; 24 | } 25 | }; 26 | 27 | // Reverse list 28 | Node *reverseList(Node *head) 29 | { 30 | // init before and after pointer 31 | Node *before = NULL, *after = NULL; 32 | 33 | // logic 34 | while (head != NULL) 35 | { 36 | after = head->next; 37 | head->next = before; 38 | before = head; 39 | head = after; 40 | } 41 | 42 | // answer 43 | head = before; 44 | return head; 45 | } 46 | 47 | // Print list 48 | void printList(Node *ptr) 49 | { 50 | // print logic 51 | while (ptr != NULL) 52 | { 53 | cout << ptr->data << " "; 54 | ptr = ptr->next; 55 | } 56 | cout << "\n"; 57 | } 58 | 59 | // Driver code 60 | int main() 61 | { 62 | // Create new linked list 63 | Node *head = new Node(10); 64 | head->next = new Node(20); 65 | head->next->next = new Node(30); 66 | 67 | // Print given list 68 | printList(head); 69 | 70 | // Reverse 71 | head = reverseList(head); 72 | 73 | // Print 74 | printList(head); 75 | } 76 | -------------------------------------------------------------------------------- /12. Linked List/03 DLL/02. Insert begin/insert.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Insert a node at the beginning of the doubly linked list 3 | eg: [1<=>2<=>3], 4 => [4<=>1<=>2<=>3] 4 | */ 5 | 6 | #include 7 | using namespace std; 8 | 9 | // Node class with constructor 10 | class Node 11 | { 12 | public: 13 | Node *prev; 14 | int data; 15 | Node *next; 16 | 17 | // constructor 18 | Node(int x) 19 | { 20 | data = x; 21 | prev = NULL; 22 | next = NULL; 23 | } 24 | }; 25 | 26 | // Insert Node in beginning 27 | Node *insertBegin(Node *head, int val) 28 | { 29 | // create newHead 30 | Node *newHead = new Node(val); 31 | 32 | // link newHead->next to head 33 | newHead->next = head; 34 | 35 | // if list is not empty head->prev = newHead 36 | if (head != NULL) 37 | head->prev = newHead; 38 | 39 | // return newHead pointer 40 | return newHead; 41 | } 42 | 43 | // Print list 44 | void printList(Node *ptr) 45 | { 46 | // print logic 47 | while (ptr != NULL) 48 | { 49 | cout << ptr->data << " "; 50 | ptr = ptr->next; 51 | } 52 | cout << "\n"; 53 | } 54 | 55 | // Driver code 56 | int main() 57 | { 58 | // Create a new linked list in heap 59 | Node *head = new Node(10); 60 | Node *second = new Node(20); 61 | Node *third = new Node(30); 62 | 63 | // Link them 64 | head->next = second; 65 | second->prev = head; 66 | second->next = third; 67 | third->prev = second; 68 | 69 | // Print 70 | printList(head); 71 | 72 | // Insert 73 | head = insertBegin(head, 40); 74 | 75 | // Print 76 | printList(head); 77 | } -------------------------------------------------------------------------------- /12. Linked List/03 DLL/08. Search/search.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Search for an item in a doubly linked list 3 | eg: [1<=>2<=>3], 2 => position = 2 4 | */ 5 | 6 | #include 7 | using namespace std; 8 | 9 | // Node class with constructor 10 | class Node 11 | { 12 | public: 13 | Node *prev; 14 | int data; 15 | Node *next; 16 | 17 | // constructor 18 | Node(int x) 19 | { 20 | data = x; 21 | prev = NULL; 22 | next = NULL; 23 | } 24 | }; 25 | 26 | // Search in list 27 | int search(Node *head, int val) 28 | { 29 | // init position 30 | int pos = 1; 31 | 32 | // init ptr to traverse 33 | Node *ptr = head; 34 | 35 | // traverse and check values 36 | while (ptr != NULL) 37 | { 38 | if (ptr->data == val) 39 | return pos; 40 | else 41 | { 42 | pos++; 43 | ptr = ptr->next; 44 | } 45 | } 46 | 47 | // if not found 48 | return -1; 49 | } 50 | 51 | // Print list 52 | void printList(Node *ptr) 53 | { 54 | // print logic 55 | while (ptr != NULL) 56 | { 57 | cout << ptr->data << " "; 58 | ptr = ptr->next; 59 | } 60 | cout << "\n"; 61 | } 62 | 63 | // Driver code 64 | int main() 65 | { 66 | // Create a new linked list in heap 67 | Node *head = new Node(10); 68 | Node *second = new Node(20); 69 | Node *third = new Node(30); 70 | 71 | // Link them 72 | head->next = second; 73 | second->prev = head; 74 | second->next = third; 75 | third->prev = second; 76 | 77 | // Search list for 30 78 | cout << search(head, 30); 79 | } 80 | -------------------------------------------------------------------------------- /12. Linked List/04. SCLL/01. Singly Circular LL/singlyCircular.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Implementation of singly circular linked list 3 | */ 4 | 5 | #include 6 | using namespace std; 7 | 8 | // Node class with constructor 9 | class Node 10 | { 11 | public: 12 | int data; 13 | Node *next; 14 | Node(int x) 15 | { 16 | data = x; 17 | next = NULL; 18 | } 19 | }; 20 | 21 | // Driver code 22 | int main() 23 | { 24 | // Create a singly circular linked list 25 | Node *head = new Node(10); 26 | head->next = new Node(20); 27 | head->next->next = new Node(30); 28 | head->next->next->next = new Node(40); 29 | head->next->next->next->next = head; // last node point to head 30 | } 31 | 32 | /* 33 | Advantages of circular linked list: 34 | 35 | => whole list can be traversed from any node 36 | => implementation of algorithm like round robin 37 | => Insert at begin / end by only maintaining one tail pointer 38 | 39 | Disadvantages of circular linked list: 40 | 41 | => Implementation of operations becomes complex :( 42 | */ -------------------------------------------------------------------------------- /12. Linked List/04. SCLL/02. Traverse/traverse.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Traverse and print elements of singly circular linked list 3 | */ 4 | 5 | #include 6 | using namespace std; 7 | 8 | // Node class with constructor 9 | class Node 10 | { 11 | public: 12 | int data; 13 | Node *next; 14 | Node(int x) 15 | { 16 | data = x; 17 | next = NULL; 18 | } 19 | }; 20 | 21 | // Print list 22 | void printList_1(Node *head) 23 | { 24 | // if list is empty 25 | if (head == NULL) 26 | return; 27 | 28 | // print logic 29 | Node *ptr = head; 30 | do 31 | { 32 | cout << ptr->data << " "; 33 | ptr = ptr->next; 34 | } while (ptr != head); 35 | 36 | // newline 37 | cout << "\n"; 38 | } 39 | 40 | // Print list 41 | void printList_2(Node *head) 42 | { 43 | // if list is empty 44 | if (head == NULL) 45 | return; 46 | 47 | // print logic 48 | cout << head->data << " "; 49 | for (Node *ptr = head->next; ptr != head; ptr = ptr->next) 50 | cout << ptr->data << " "; 51 | 52 | // newline 53 | cout << "\n"; 54 | } 55 | 56 | // Driver code 57 | int main() 58 | { 59 | // Create a singly circular linked list 60 | Node *head = new Node(10); 61 | head->next = new Node(20); 62 | head->next->next = new Node(30); 63 | head->next->next->next = new Node(40); 64 | head->next->next->next->next = head; // last node point to head 65 | 66 | // Print 67 | printList_2(head); 68 | } 69 | -------------------------------------------------------------------------------- /12. Linked List/05. CDLL/01. Circular Doubly LL/cdll.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Implementation of a circular doubly linked list 3 | */ 4 | 5 | #include 6 | using namespace std; 7 | 8 | // Node class with constructor 9 | struct Node 10 | { 11 | int data; 12 | Node *prev; 13 | Node *next; 14 | Node(int x) 15 | { 16 | data = x; 17 | prev = NULL; 18 | next = NULL; 19 | } 20 | }; 21 | 22 | // Driver code 23 | int main() 24 | { 25 | // Create a circular doubly linked list 26 | Node *head = new Node(10); 27 | Node *second = new Node(20); 28 | Node *third = new Node(30); 29 | 30 | // Link them 31 | head->next = second; 32 | second->next = third; 33 | third->next = head; 34 | second->prev = head; 35 | third->prev = second; 36 | head->prev = third; 37 | } 38 | /* 39 | * CDLL provides all functionality of circular and doubly linked list 40 | 41 | * Access to last node without maintaining extra tail pointer 42 | */ -------------------------------------------------------------------------------- /12. Linked List/05. CDLL/02. Traverse/traverse.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Traverse and print elements of circular doubly linked list 3 | */ 4 | 5 | #include 6 | using namespace std; 7 | 8 | // Node class with constructor 9 | struct Node 10 | { 11 | int data; 12 | Node *prev; 13 | Node *next; 14 | Node(int x) 15 | { 16 | data = x; 17 | prev = NULL; 18 | next = NULL; 19 | } 20 | }; 21 | 22 | // print list 23 | void printlist(Node *head) 24 | { 25 | // if list is empty 26 | if (head == NULL) 27 | return; 28 | 29 | // print logic 30 | Node *ptr = head; 31 | do 32 | { 33 | cout << ptr->data << " "; 34 | ptr = ptr->next; 35 | } while (ptr != head); 36 | 37 | // newline 38 | cout << "\n"; 39 | } 40 | 41 | // Driver code 42 | int main() 43 | { 44 | // create a circular doubly linked list 45 | Node *head = new Node(10); 46 | Node *second = new Node(20); 47 | Node *third = new Node(30); 48 | 49 | // link them 50 | head->next = second; 51 | second->next = third; 52 | third->next = head; 53 | second->prev = head; 54 | third->prev = second; 55 | head->prev = third; 56 | 57 | // print list 58 | printlist(head); 59 | } 60 | -------------------------------------------------------------------------------- /12. Linked List/06. Questions/02. Middle item/center.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Given a singly linked list, find the middle element 3 | if list is even return (n/2 + 1)th element (1 based indexing) 4 | */ 5 | 6 | #include 7 | using namespace std; 8 | 9 | // Node class with constructor 10 | class Node 11 | { 12 | public: 13 | int data; 14 | Node *next; 15 | Node(int x) 16 | { 17 | data = x; 18 | next = NULL; 19 | } 20 | }; 21 | 22 | // Find middle element 23 | int middleElement(Node *head) 24 | { 25 | // if list is empty 26 | if (head == NULL) 27 | return -1; 28 | 29 | // slow (moves 1 node) and fast (moves two node) at a time 30 | Node *slow = head, *fast = head; 31 | 32 | // traverse 33 | while (fast != NULL && fast->next != NULL) 34 | { 35 | slow = slow->next; 36 | fast = fast->next->next; 37 | } 38 | 39 | // return mid element 40 | return slow->data; 41 | } 42 | 43 | // Print 44 | void printList(Node *ptr) 45 | { 46 | while (ptr != NULL) 47 | { 48 | cout << ptr->data << " "; 49 | ptr = ptr->next; 50 | } 51 | cout << "\n"; 52 | } 53 | 54 | // Driver code 55 | int main() 56 | { 57 | // Create linked list 58 | Node *head = new Node(10); 59 | head->next = new Node(20); 60 | head->next->next = new Node(30); 61 | head->next->next->next = new Node(40); 62 | 63 | // Print 64 | printList(head); 65 | 66 | // Print middle element 67 | cout << middleElement(head); 68 | } 69 | -------------------------------------------------------------------------------- /12. Linked List/06. Questions/03. Nth from end/printnode.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Given a singly linked list, find value at nth node from end 3 | 4 | 10->20->30->40->50 5 | n = 3 6 | 7 | output: 30 8 | */ 9 | 10 | #include 11 | using namespace std; 12 | 13 | // Node class with constructor 14 | class Node 15 | { 16 | public: 17 | int data; 18 | Node *next; 19 | Node(int x) 20 | { 21 | data = x; 22 | next = NULL; 23 | } 24 | }; 25 | 26 | // Find nth node from end 27 | int nthFromEnd(Node *head, int x) 28 | { 29 | // if list is empty 30 | if (head == NULL) 31 | return -1; 32 | 33 | // two pointer approach 34 | Node *first = head; 35 | for (int i = 0; i < x; i++) 36 | { 37 | if (first == NULL) 38 | return -1; 39 | first = first->next; 40 | } 41 | Node *second = head; 42 | while (first != NULL) 43 | { 44 | second = second->next; 45 | first = first->next; 46 | } 47 | 48 | // return 49 | return second->data; 50 | } 51 | 52 | // Print 53 | void printList(Node *ptr) 54 | { 55 | while (ptr != NULL) 56 | { 57 | cout << ptr->data << " "; 58 | ptr = ptr->next; 59 | } 60 | cout << "\n"; 61 | } 62 | 63 | // Driver code 64 | int main() 65 | { 66 | // Create linked list 67 | Node *head = new Node(10); 68 | head->next = new Node(20); 69 | head->next->next = new Node(30); 70 | head->next->next->next = new Node(40); 71 | head->next->next->next->next = new Node(50); 72 | 73 | // Print 74 | printList(head); 75 | 76 | // Value of nth node from end 77 | cout << nthFromEnd(head, 3); 78 | } 79 | -------------------------------------------------------------------------------- /12. Linked List/06. Questions/04. Reverse/reverse.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Given a singly linked list, reverse it. 3 | */ 4 | 5 | #include 6 | using namespace std; 7 | 8 | // Node class with constructor 9 | class Node 10 | { 11 | public: 12 | int data; 13 | Node *next; 14 | Node(int x) 15 | { 16 | data = x; 17 | next = NULL; 18 | } 19 | }; 20 | 21 | // Reverse given linked list 22 | Node *reverseList(Node *head) 23 | { 24 | // init before and after pointer 25 | Node *before = NULL, *after = NULL; 26 | 27 | // logic 28 | while (head != NULL) 29 | { 30 | after = head->next; 31 | head->next = before; 32 | before = head; 33 | head = after; 34 | } 35 | 36 | // answer 37 | return before; 38 | } 39 | 40 | // Print 41 | void printList(Node *ptr) 42 | { 43 | while (ptr != NULL) 44 | { 45 | cout << ptr->data << " "; 46 | ptr = ptr->next; 47 | } 48 | cout << "\n"; 49 | } 50 | 51 | // Driver code 52 | int main() 53 | { 54 | // Create linked list 55 | Node *head = new Node(10); 56 | head->next = new Node(20); 57 | head->next->next = new Node(30); 58 | head->next->next->next = new Node(40); 59 | 60 | // Print 61 | printList(head); 62 | 63 | // Reverse list 64 | head = reverseList(head); 65 | 66 | // Print 67 | printList(head); 68 | } 69 | -------------------------------------------------------------------------------- /12. Linked List/06. Questions/08. Cycle detection/floyd.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Given a sorted signly linked list, check whether it has loops 3 | */ 4 | 5 | #include 6 | using namespace std; 7 | 8 | // Node class with constructor 9 | class Node 10 | { 11 | public: 12 | int data; 13 | Node *next; 14 | Node(int x) 15 | { 16 | data = x; 17 | next = NULL; 18 | } 19 | }; 20 | 21 | // Print 22 | void printList(Node *ptr) 23 | { 24 | while (ptr != NULL) 25 | { 26 | cout << ptr->data << " "; 27 | ptr = ptr->next; 28 | } 29 | cout << "\n"; 30 | } 31 | 32 | // Floyd cycle detection 33 | bool hasLoop(Node *head) 34 | { 35 | // init slow and fast 36 | Node *slow = head, *fast = head; 37 | 38 | // loop detection logic 39 | while (fast != NULL && fast->next != NULL) 40 | { 41 | slow = slow->next; 42 | fast = fast->next->next; 43 | if (slow == fast) 44 | return true; 45 | } 46 | 47 | // if no loop 48 | return false; 49 | } 50 | 51 | // Driver code 52 | int main() 53 | { 54 | // Create linked list with loop 55 | Node *head = new Node(10); 56 | head->next = new Node(20); 57 | head->next->next = new Node(30); 58 | head->next->next->next = new Node(40); 59 | head->next->next->next->next = head; 60 | 61 | // Detect loop 62 | cout << boolalpha << hasLoop(head); 63 | } 64 | -------------------------------------------------------------------------------- /13. Stack/01. Theory/Theory.md: -------------------------------------------------------------------------------- 1 | ## Definition: 2 | 3 | - Stack is a linear data structure which follows a particular order in which the operations are performed. The order is LIFO (Last In First Out) 4 | 5 | ## Operations: 6 | 7 | - Push: Adds item in stack 8 | - Pop: Removes item from stack 9 | - Peek: Look at top element 10 | - Top: Returns top element 11 | - Empty: Check if stack is empty 12 | - Time Complexity of all above operations is O(1) 13 | 14 | ## Applications: 15 | 16 | - Symbol balancing 17 | - Infix to Postfix/Prefix 18 | - Redo-Undo in photoshop 19 | - Forward-Backward in browsers 20 | - Used in algorithm: TOH, Tree Traversal, Histogram problem etc 21 | 22 | ## Implementations: 23 | 24 | - Using array/vector 25 | - Using linked list 26 | -------------------------------------------------------------------------------- /13. Stack/02. Implementation/2_Vector.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | // Vector implementation of stack 5 | struct MyStack 6 | { 7 | // init vector 8 | vector v; 9 | 10 | // push operation 11 | void push(int x) 12 | { 13 | v.push_back(x); 14 | } 15 | 16 | // pop operation 17 | int pop() 18 | { 19 | int res = v.back(); 20 | v.pop_back(); 21 | return res; 22 | } 23 | 24 | // last element in stack 25 | int peek() 26 | { 27 | return v.back(); 28 | } 29 | 30 | // stack size 31 | int size() 32 | { 33 | return v.size(); 34 | } 35 | 36 | // check if stack is empty 37 | bool isEmpty() 38 | { 39 | return v.empty(); 40 | } 41 | }; 42 | 43 | // Driver code 44 | int main() 45 | { 46 | // Init stack 47 | MyStack s; 48 | 49 | // Push 3 element 50 | s.push(5); 51 | s.push(10); 52 | s.push(20); 53 | 54 | // Stack methods 55 | cout << s.pop() << "\n"; 56 | cout << s.size() << "\n"; 57 | cout << s.peek() << "\n"; 58 | cout << s.isEmpty() << "\n"; 59 | } 60 | -------------------------------------------------------------------------------- /13. Stack/03. Balanced bracket/balanced.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Given a string containing only '(', ')', '{', '}', '[' and ']' 3 | Check if the string has balanced paranthesis 4 | 5 | eg: str = "()(]" 6 | output: false 7 | 8 | str = "{}[()]" 9 | output: true 10 | */ 11 | 12 | #include 13 | using namespace std; 14 | 15 | // Match two chars as balanced parantheseis 16 | bool matching(char a, char b) 17 | { 18 | return ((a == '(' && b == ')') || (a == '[' && b == ']') || (a == '{' && b == '}')); 19 | } 20 | 21 | // Check if string has balanced paranthesis 22 | bool isBalanced(string str) 23 | { 24 | // init stack 25 | stack stk; 26 | 27 | // logic: 28 | for (int i = 0; i < str.length(); i++) 29 | { 30 | // if str[i] is opening bracket push in stack 31 | if (str[i] == '(' || str[i] == '[' || str[i] == '{') 32 | stk.push(str[i]); 33 | // otherwise check if s.top contains closing bracket 34 | else 35 | { 36 | // if string is like this ')()[]' 37 | if (stk.empty() == true) 38 | return false; 39 | // match top of stack with str[i] 40 | else if (matching(stk.top(), str[i]) == false) 41 | return false; 42 | // if matched pop stack and continue 43 | else 44 | stk.pop(); 45 | } 46 | } 47 | 48 | // if stack is empty => given string is balanced 49 | return (stk.empty() == true); 50 | } 51 | 52 | // Driver code 53 | int main() 54 | { 55 | // Given string 56 | string str = "{()}[]"; 57 | 58 | // fn call 59 | cout << boolalpha << isBalanced(str); 60 | } 61 | -------------------------------------------------------------------------------- /13. Stack/05. Stock span/span.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Given an array of integers representing prices of a stock 3 | on n consecutive days. Find span of stock on each day. 4 | Span on a day is number of consecutive days including 5 | current day and days just before it which have value 6 | equal or smaller. 7 | 8 | eg: [13,15,12,14,16,8,6,4,10,13] => [1,2,1,2,5,1,1,1,4,10] 9 | */ 10 | 11 | #include 12 | using namespace std; 13 | 14 | // Find span of each element 15 | vector printSpan(int arr[], int n) 16 | { 17 | // store answer 18 | vector result; 19 | 20 | // init stack; 21 | stack stk; 22 | 23 | // first element's span is always 1 24 | stk.push(0); 25 | result.push_back(1); 26 | 27 | // logic: 28 | for (int i = 1; i < n; i++) 29 | { 30 | // check if stack empty 31 | while (stk.empty() == false && arr[stk.top()] <= arr[i]) 32 | stk.pop(); 33 | 34 | // calculate span and print 35 | int span = stk.empty() ? i + 1 : i - stk.top(); 36 | result.push_back(span); 37 | 38 | // push current element 39 | stk.push(i); 40 | } 41 | 42 | // return 43 | return result; 44 | } 45 | 46 | // Driver code 47 | int main() 48 | { 49 | // Given array 50 | int arr[] = {18, 12, 13, 14, 11, 16}; 51 | int n = sizeof(arr) / sizeof(arr[0]); 52 | 53 | // fn call 54 | vector ans = printSpan(arr, n); 55 | 56 | // Output 57 | for (auto &val : ans) 58 | cout << val << " "; 59 | } 60 | -------------------------------------------------------------------------------- /13. Stack/06. Previous greater/prevMax.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Given an array of distinct integers, find its previous greater array 3 | (position-wise max and closest on the left side) of every array elements. 4 | This is base for pge, nge, pse, nse 5 | */ 6 | 7 | #include 8 | using namespace std; 9 | #define vi vector 10 | 11 | // Find positionwise greater element in left O(n) 12 | vi printPrevGreater(int arr[], int n) 13 | { 14 | // store answer 15 | vi res; 16 | 17 | // init stack 18 | stack stk; 19 | 20 | // push first element 21 | stk.push(arr[0]); 22 | 23 | // positionwise left greatest for first is always -1 24 | res.push_back(-1); 25 | 26 | // logic: 27 | for (int i = 1; i < n; i++) 28 | { 29 | // pop from stack while stk.top() <= current element 30 | while (stk.empty() == false && stk.top() <= arr[i]) 31 | stk.pop(); 32 | 33 | // if stack is empty after pop => -1 otherwise stk.top() 34 | int val = stk.empty() ? -1 : stk.top(); 35 | 36 | // push res in ans vector 37 | res.push_back(val); 38 | 39 | // push current element 40 | stk.push(arr[i]); 41 | } 42 | 43 | // answer 44 | return res; 45 | } 46 | 47 | // Driver code 48 | int main() 49 | { 50 | // Given array 51 | int arr[] = {15, 10, 18, 12, 4, 6, 2, 8}; 52 | int n = sizeof(arr) / sizeof(arr[0]); 53 | 54 | // fn call 55 | vi ans = printPrevGreater(arr, n); 56 | 57 | // Output 58 | cout << "Previous greator elements:\n"; 59 | for (auto &val : ans) 60 | cout << val << " "; 61 | } 62 | -------------------------------------------------------------------------------- /13. Stack/07. Next greater/nextMax.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Given an array of distinct integers, find its next greater array 3 | (position-wise max and closest on the right side) of every array elements. 4 | */ 5 | 6 | #include 7 | using namespace std; 8 | #define vi vector 9 | 10 | // Find positionwise greater element in right 11 | vi printNextGreater(int arr[], int n) 12 | { 13 | // store answer 14 | vi res; 15 | 16 | // init stack 17 | stack stk; 18 | 19 | // push last element 20 | stk.push(arr[n - 1]); 21 | 22 | // positionwise greatest on right for last is always -1 23 | res.push_back(-1); 24 | 25 | // logic: 26 | for (int i = n - 2; i >= 0; i--) 27 | { 28 | // pop from stack while stk.top() <= current element 29 | while (stk.empty() == false && stk.top() <= arr[i]) 30 | stk.pop(); 31 | 32 | // if stack is empty after pop => -1 otherwise stk.top() 33 | int val = stk.empty() ? -1 : stk.top(); 34 | 35 | // push res in ans vector 36 | res.push_back(val); 37 | 38 | // push current element 39 | stk.push(arr[i]); 40 | } 41 | 42 | // answer is in reverse 43 | reverse(res.begin(), res.end()); 44 | return res; 45 | } 46 | 47 | // Driver code 48 | int main() 49 | { 50 | // Given array 51 | int arr[] = {15, 10, 18, 12, 4, 6, 2, 8}; 52 | int n = sizeof(arr) / sizeof(arr[0]); 53 | 54 | // fn call 55 | vi ans = printNextGreater(arr, n); 56 | 57 | // Output 58 | cout << "Next greator elements:\n"; 59 | for (auto &val : ans) 60 | cout << val << " "; 61 | } 62 | -------------------------------------------------------------------------------- /13. Stack/08. Previous smaller/prevMin.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Given an array of distinct integers, find its previous smaller array 3 | (position-wise min and closest on the left side) of every array elements. 4 | */ 5 | 6 | #include 7 | using namespace std; 8 | #define vi vector 9 | 10 | // Find positionwise Smaller element in left O(n) 11 | vi printPrevSmaller(int arr[], int n) 12 | { 13 | // store answer 14 | vi res; 15 | 16 | // init stack 17 | stack stk; 18 | 19 | // push first element 20 | stk.push(arr[0]); 21 | 22 | // positionwise left smallest for first is always -1 23 | res.push_back(-1); 24 | 25 | // logic: 26 | for (int i = 1; i < n; i++) 27 | { 28 | // pop from stack while stk.top() >= current element 29 | while (stk.empty() == false && stk.top() >= arr[i]) 30 | stk.pop(); 31 | 32 | // if stack is empty after pop => -1 otherwise stk.top() 33 | int val = stk.empty() ? -1 : stk.top(); 34 | 35 | // push res in ans vector 36 | res.push_back(val); 37 | 38 | // push current element 39 | stk.push(arr[i]); 40 | } 41 | 42 | // answer 43 | return res; 44 | } 45 | 46 | // Driver code 47 | int main() 48 | { 49 | // Given array 50 | int arr[] = {15, 10, 18, 12, 4, 6, 2, 8}; 51 | int n = sizeof(arr) / sizeof(arr[0]); 52 | 53 | // fn call 54 | vi ans = printPrevSmaller(arr, n); 55 | 56 | // Output 57 | cout << "Previous smaller elements:\n"; 58 | for (auto &val : ans) 59 | cout << val << " "; 60 | } 61 | -------------------------------------------------------------------------------- /13. Stack/09. Next Smaller/nextMin.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Given an array of distinct integers, find its next smaller array 3 | (position-wise min and closest on the right side) of every array elements. 4 | */ 5 | 6 | #include 7 | using namespace std; 8 | #define vi vector 9 | 10 | // Find positionwise Smaller element in right O(n) 11 | vi printNextSmaller(int arr[], int n) 12 | { 13 | // store answer 14 | vi res; 15 | 16 | // init stack 17 | stack stk; 18 | 19 | // push first element 20 | stk.push(arr[n - 1]); 21 | 22 | // positionwise right smallest for first is always -1 23 | res.push_back(-1); 24 | 25 | // logic: 26 | for (int i = n - 2; i >= 0; i--) 27 | { 28 | // pop from stack while stk.top() >= current element 29 | while (stk.empty() == false && stk.top() >= arr[i]) 30 | stk.pop(); 31 | 32 | // if stack is empty after pop => -1 otherwise stk.top() 33 | int val = stk.empty() ? -1 : stk.top(); 34 | 35 | // push res in ans vector 36 | res.push_back(val); 37 | 38 | // push current element 39 | stk.push(arr[i]); 40 | } 41 | 42 | // answer is in reverse 43 | reverse(res.begin(), res.end()); 44 | return res; 45 | } 46 | 47 | // Driver code 48 | int main() 49 | { 50 | // Given array 51 | int arr[] = {15, 10, 18, 12, 4, 6, 2, 8}; 52 | int n = sizeof(arr) / sizeof(arr[0]); 53 | 54 | // fn call 55 | vi ans = printNextSmaller(arr, n); 56 | 57 | // Output 58 | cout << "Next small elements:\n"; 59 | for (auto &val : ans) 60 | cout << val << " "; 61 | } 62 | -------------------------------------------------------------------------------- /14. Queue/01. Theory/queue.md: -------------------------------------------------------------------------------- 1 | ## Definition: 2 | 3 | - Queues are a type of container adaptors which operate in a first in first out (FIFO) type of arrangement. Elements are inserted at the back (end) and are deleted from the front. 4 | 5 | ## Operations: 6 | 7 | - enQueue: Insert element at the end 8 | - deQueue: Remove element from front 9 | - getFront: Peek front item without deleting 10 | - getRear: Peek rear item without deleting 11 | - size: Size of queue 12 | - isEmpty: Check if queue is empty 13 | 14 | ## Applications: 15 | 16 | - Single resource and multiple consumers 17 | - Synchronization between slow and fast devices 18 | - In operating system (semaphores, FCFS scheduling, spooling, buffer for devices like keyboard) 19 | - In computer networks (routers/switches and mail queues) 20 | - Variations: Deque, Priority Queue, Doubly Ended Priority Queue 21 | 22 | ## Implementations: 23 | 24 | - Using array/vector 25 | - Using linked list 26 | -------------------------------------------------------------------------------- /14. Queue/02. Implementation/queueList.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | // struct for queue node 5 | struct QNode 6 | { 7 | int data; 8 | QNode *next; 9 | QNode(int d) 10 | { 11 | data = d; 12 | next = NULL; 13 | } 14 | }; 15 | 16 | // struct for queue 17 | struct Queue 18 | { 19 | // vars 20 | QNode *front, *rear; 21 | 22 | // constructor 23 | Queue() 24 | { 25 | front = rear = NULL; 26 | } 27 | 28 | // insert 29 | void enQueue(int x) 30 | { 31 | 32 | QNode *temp = new QNode(x); 33 | 34 | if (rear == NULL) 35 | { 36 | front = rear = temp; 37 | return; 38 | } 39 | 40 | rear->next = temp; 41 | rear = temp; 42 | } 43 | 44 | // delete 45 | void deQueue() 46 | { 47 | 48 | if (front == NULL) 49 | return; 50 | 51 | QNode *temp = front; 52 | front = front->next; 53 | 54 | if (front == NULL) 55 | rear = NULL; 56 | 57 | delete (temp); 58 | } 59 | }; 60 | 61 | // Driver code 62 | int main() 63 | { 64 | // Driver code 65 | Queue q; 66 | 67 | // insert 68 | q.enQueue(10); 69 | q.enQueue(20); 70 | q.deQueue(); 71 | q.deQueue(); 72 | q.enQueue(30); 73 | q.enQueue(40); 74 | q.enQueue(50); 75 | q.deQueue(); 76 | 77 | // Peek front and rear items 78 | cout << "Queue Front : " << (q.front)->data << endl; 79 | cout << "Queue Rear : " << (q.rear)->data; 80 | } 81 | -------------------------------------------------------------------------------- /14. Queue/03. Generate numbers/generate.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Given a number n, print first n number (in increasing order) such that all 3 | these numbers have digits in set {5, 6} 4 | */ 5 | 6 | #include 7 | #include 8 | using namespace std; 9 | 10 | // Print first n num with {5, 6} 11 | void printFirstN(int n) 12 | { 13 | // create a queue of string 14 | queue q; 15 | 16 | // init with 5 and 6 17 | q.push("5"); 18 | q.push("6"); 19 | 20 | // logic: 21 | for (int i = 0; i < n; i++) 22 | { 23 | // peek to current front 24 | string curr = q.front(); 25 | 26 | // print current front 27 | cout << curr << " "; 28 | 29 | // pop current front 30 | q.pop(); 31 | 32 | // push 5 and 6 for next itr 33 | q.push(curr + "5"); 34 | q.push(curr + "6"); 35 | } 36 | } 37 | 38 | // Driver code 39 | int main() 40 | { 41 | // Given number 42 | int n = 10; 43 | 44 | // fn call 45 | printFirstN(n); 46 | } 47 | -------------------------------------------------------------------------------- /15. Deque/01. Theory/theory.md: -------------------------------------------------------------------------------- 1 | ## Definition: 2 | 3 | - Deque or Double Ended Queue is a generalized version of Queue data structure that allows insert and delete at both ends 4 | 5 | ## Operations: 6 | 7 | - insertFront(): Adds an item at the front of Deque. 8 | - insertLast(): Adds an item at the rear of Deque. 9 | - deleteFront(): Deletes an item from front of Deque. 10 | - deleteLast(): Deletes an item from rear of Deque. 11 | - getFront(): Gets the front item from queue. 12 | - getRear(): Gets the last item from queue. 13 | - isEmpty(): Checks whether Deque is empty or not. 14 | - isFull(): Checks whether Deque is full or not. 15 | 16 | ## Applications: 17 | 18 | - Can be used as stack and queue 19 | - Support clockwise and anticlockwise rotation in O(1) 20 | - All applications that queue supports 21 | - Problems like [max of all subarray of size k](https://www.geeksforgeeks.org/sliding-window-maximum-maximum-of-all-subarrays-of-size-k/), [0-1 BFS](https://www.geeksforgeeks.org/0-1-bfs-shortest-path-binary-graph/) 22 | 23 | ## Implementations: 24 | 25 | - Using array/vector 26 | - Using linked list 27 | -------------------------------------------------------------------------------- /15. Deque/03. Max of subarrayK/max.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Max of all subarray of size k 3 | */ 4 | 5 | #include 6 | using namespace std; 7 | 8 | // Max of all subarray 9 | void printMax(int arr[], int n, int k) 10 | { 11 | // create a deque 12 | deque dq; 13 | 14 | // initialize deque 15 | for (int i = 0; i < k; ++i) 16 | { 17 | 18 | while (!dq.empty() && arr[i] >= arr[dq.back()]) 19 | dq.pop_back(); 20 | 21 | dq.push_back(i); 22 | } 23 | 24 | // logic: 25 | for (int i = k; i < n; ++i) 26 | { 27 | 28 | cout << arr[dq.front()] << " "; 29 | 30 | while ((!dq.empty()) && dq.front() <= i - k) 31 | dq.pop_front(); 32 | 33 | while ((!dq.empty()) && arr[i] >= arr[dq.back()]) 34 | dq.pop_back(); 35 | 36 | dq.push_back(i); 37 | } 38 | 39 | // print max 40 | cout << arr[dq.front()]; 41 | } 42 | 43 | // Driver code 44 | int main() 45 | { 46 | // Given array 47 | int arr[] = {20, 40, 30, 10, 60}; 48 | int n = sizeof(arr) / sizeof(arr[0]); 49 | int k = 3; 50 | 51 | // fn call 52 | printMax(arr, n, k); 53 | } -------------------------------------------------------------------------------- /16. Greedy/01. Theory/theory.md: -------------------------------------------------------------------------------- 1 | ## Definition: 2 | 3 | - Greedy algorithms are mainly used in optimization problems. 4 | - Optimization problems generally involves maximizing or minimizing something. For eg: shortest path, longest path 5 | - Greedy algorithm makes optimal choice at each step as it attempts to find the overall optimal way to solve the entire problem 6 | 7 |
8 | 9 | ## General structure: 10 | 11 |
12 | 13 | ``` 14 | getOptimal(arr[], n, item) 15 | 16 | 1. Initialize res = 0 17 | 18 | 2. while (all items are not considered) 19 | { 20 | i = selectAnItem() 21 | if(isFeasible(i)) 22 | res = res + i 23 | } 24 | 25 | 3. return res 26 | ``` 27 | 28 | ## Applications: 29 | 30 | - Activity selection 31 | - Fractional knapsack 32 | - Job sequencing 33 | - Prim's algorithm 34 | - Kruskal's algorithm 35 | - Dijkstra's algorithm 36 | - Huffman coding 37 | -------------------------------------------------------------------------------- /17. Tree/01. Theory/theory.md: -------------------------------------------------------------------------------- 1 | ### Tree 2 | 3 | - A tree data structure is defined as a collection of objects or entities known as nodes that are linked together to represent or simulate hierarchy. 4 | 5 | - A tree data structure is a non-linear data structure because it does not store data in a sequential manner. It is a hierarchical structure as elements in a Tree are arranged in multiple levels. 6 | 7 | - In Tree data structure, the topmost node is known as a root node. Each node contains some data, and data can be of any type. 8 | 9 | - Each node contains some data and the link or reference of other nodes that is called children. 10 | 11 | **Representation:** 12 | 13 | ``` 14 | #include 15 | using namespace std; 16 | 17 | // Tree Node 18 | struct Node 19 | { 20 | int key; 21 | Node *left; 22 | Node *right; 23 | Node(int key) 24 | { 25 | this->key = key; 26 | left = NULL; 27 | right = NULL; 28 | } 29 | }; 30 | 31 | // Driver code 32 | int main() 33 | { 34 | /* 35 | 40 36 | / \ 37 | 20 60 38 | / \ / \ 39 | 10 30 50 70 40 | */ 41 | Node *root = new Node(40); 42 | root->left = new Node(20); 43 | root->left->left = new Node(10); 44 | root->left->right = new Node(30); 45 | root->right = new Node(60); 46 | root->right->left = new Node(50); 47 | root->right->right = new Node(70); 48 | } 49 | ``` 50 | -------------------------------------------------------------------------------- /17. Tree/02. Implementation/implement.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | // Tree Node 5 | struct Node 6 | { 7 | int key; 8 | Node *left; 9 | Node *right; 10 | Node(int key) 11 | { 12 | this->key = key; 13 | left = NULL; 14 | right = NULL; 15 | } 16 | }; 17 | 18 | // Driver code 19 | int main() 20 | { 21 | /* 22 | 40 23 | / \ 24 | 20 60 25 | / \ / \ 26 | 10 30 50 70 27 | */ 28 | Node *root = new Node(40); 29 | root->left = new Node(20); 30 | root->left->left = new Node(10); 31 | root->left->right = new Node(30); 32 | root->right = new Node(60); 33 | root->right->left = new Node(50); 34 | root->right->right = new Node(70); 35 | } -------------------------------------------------------------------------------- /17. Tree/03. Traversal/traverse.md: -------------------------------------------------------------------------------- 1 | ## Tree traversal can be classified into two categories: 2 | 3 | **Depth First:** 4 | 5 | - Visit one side, finish it completely then visit other side. Total 3! = 6 type of traversal is possible but we use these three: 6 | 7 | - **Inorder:** Left Root Right (root in between, direction L->R) 8 | - **Preorder:** Root Left Right (root at the beginning, direction L->R) 9 | - **Postorder:** Left Right Root (root at the end, direction L->R) 10 | 11 | **Breadth First or Level Order:** 12 | 13 | - Each node printed from left to right line by line. 14 | 15 |
16 | 17 | **Example:** 18 | 19 | ``` 20 | 10 21 | / \ 22 | 20 30 23 | 24 | Breadth First: 10 20 30 25 | Depth First: 26 | Inorder: 20 10 30 27 | Preorder: 10 20 30 28 | Postorder: 20 30 10 29 | 30 | 31 | 10 32 | / \ 33 | 20 30 34 | / \ \ 35 | 40 50 60 36 | / \ 37 | 70 80 38 | 39 | Breadth First: 10 20 30 40 50 60 70 80 40 | Depth First 41 | Inorder: 70 40 80 20 50 10 30 60 42 | Preorder: 10 20 40 70 80 50 30 60 43 | PostOrder: 70 80 40 50 20 60 30 10 44 | ``` 45 | -------------------------------------------------------------------------------- /17. Tree/05. Height/height.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Find height of binary tree 3 | 4 | eg: 5 | 10 6 | / \ 7 | 20 30 8 | / \ 9 | 40 50 10 | 11 | output: height = 3 12 | */ 13 | #include 14 | using namespace std; 15 | 16 | // Tree node 17 | struct Node 18 | { 19 | int key; 20 | struct Node *left; 21 | struct Node *right; 22 | Node(int k) 23 | { 24 | key = k; 25 | left = NULL; 26 | right = NULL; 27 | } 28 | }; 29 | 30 | // Find height Time: O(n) Auxiliary Space: O(h) 31 | int height(Node *root) 32 | { 33 | if (root == NULL) 34 | return 0; 35 | else 36 | return 1 + max(height(root->left), height(root->right)); 37 | } 38 | 39 | // Driver code 40 | int main() 41 | { 42 | /* 43 | 10 44 | / \ 45 | 20 30 46 | / \ 47 | 40 50 48 | */ 49 | Node *root = new Node(10); 50 | root->left = new Node(20); 51 | root->right = new Node(30); 52 | root->right->left = new Node(40); 53 | root->right->right = new Node(50); 54 | 55 | // print height of tree 56 | cout << height(root); 57 | } -------------------------------------------------------------------------------- /17. Tree/06. Print at K distance/print.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Print all nodes at a distance k from top (top is at distance 0) 3 | 4 | eg: 5 | 10 6 | / \ 7 | 20 30 8 | / \ \ 9 | 40 50 70 10 | \ 11 | 80 12 | 13 | k = 2 14 | output: 40 50 70 15 | */ 16 | #include 17 | using namespace std; 18 | 19 | // Tree node 20 | struct Node 21 | { 22 | int key; 23 | Node *left; 24 | Node *right; 25 | Node(int key) 26 | { 27 | this->key = key; 28 | left = NULL; 29 | right = NULL; 30 | } 31 | }; 32 | 33 | // Time: O(n) Auxiliary Space: O(h) 34 | void print(Node *root, int k) 35 | { 36 | if (root != NULL) 37 | { 38 | print(root->left, k - 1); 39 | if (k == 0) 40 | cout << root->key << " "; 41 | print(root->right, k - 1); 42 | } 43 | } 44 | 45 | // Driver code 46 | int main() 47 | { 48 | /* 49 | 10 50 | / \ 51 | 20 30 52 | / \ \ 53 | 40 50 70 54 | \ 55 | 80 56 | */ 57 | Node *root = new Node(10); 58 | root->left = new Node(20); 59 | root->right = new Node(30); 60 | root->right->right = new Node(70); 61 | root->right->right->right = new Node(80); 62 | root->left->left = new Node(40); 63 | root->left->right = new Node(50); 64 | int k = 2; 65 | 66 | // output 67 | print(root, k); 68 | } -------------------------------------------------------------------------------- /17. Tree/09. Maximum/max.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Find maximum value in a binary tree 3 | 4 | eg: 5 | 6 | 10 7 | / \ 8 | 20 30 9 | / \ \ 10 | 40 50 70 11 | \ 12 | 80 13 | output: 80 14 | */ 15 | 16 | #include 17 | using namespace std; 18 | 19 | // Tree node 20 | struct Node 21 | { 22 | int key; 23 | struct Node *left; 24 | struct Node *right; 25 | Node(int k) 26 | { 27 | key = k; 28 | left = right = NULL; 29 | } 30 | }; 31 | 32 | // Maximum value in tree 33 | int getMax(Node *root) 34 | { 35 | if (root == NULL) 36 | return INT_MIN; 37 | return max(root->key, max(getMax(root->left), getMax(root->right))); 38 | } 39 | 40 | // Driver code 41 | int main() 42 | { 43 | /* 44 | 20 45 | / \ 46 | 80 30 47 | / \ 48 | 40 50 49 | */ 50 | 51 | Node *root = new Node(20); 52 | root->left = new Node(80); 53 | root->right = new Node(30); 54 | root->right->left = new Node(40); 55 | root->right->right = new Node(50); 56 | 57 | // fn call 58 | cout << getMax(root); 59 | } -------------------------------------------------------------------------------- /17. Tree/19. Compare/checkEqual.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Given two binary trees, check if both of them are identical or not. 3 | 4 | eg: 5 | 1 1 6 | / \ / \ 7 | 2 3 2 3 8 | 9 | output: true 10 | 11 | 1 1 12 | / \ / \ 13 | 2 3 3 2 14 | 15 | output: false 16 | */ 17 | 18 | #include 19 | using namespace std; 20 | 21 | // Tree node 22 | struct Node 23 | { 24 | int key; 25 | struct Node *left; 26 | struct Node *right; 27 | Node(int k) 28 | { 29 | key = k; 30 | left = right = NULL; 31 | } 32 | }; 33 | 34 | // Check if two trees are equal 35 | bool checkEqual(Node *r1, Node *r2) 36 | { 37 | if (r1 == NULL and r2 == NULL) 38 | return true; 39 | if (r1 == NULL and r2 != NULL) 40 | return false; 41 | if (r1 != NULL and r2 == NULL) 42 | return false; 43 | if (r1->key != r2->key) 44 | return false; 45 | 46 | return checkEqual(r1->left, r2->left) and checkEqual(r1->right, r2->right); 47 | } 48 | 49 | // Driver code 50 | int main() 51 | { 52 | // Given trees 53 | Node *r1 = new Node(1); 54 | r1->left = new Node(2); 55 | r1->right = new Node(3); 56 | 57 | Node *r2 = new Node(1); 58 | r2->left = new Node(2); 59 | r2->right = new Node(3); 60 | 61 | // fn call 62 | cout << boolalpha << checkEqual(r1, r2); 63 | } -------------------------------------------------------------------------------- /17. Tree/23. Mirror Tree/mirror.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Given root of a binary tree, convert it into its mirror 3 | 4 | 10 10 5 | / \ (mirror) / \ 6 | 20 30 => 30 20 7 | / \ / \ 8 | 40 60 60 40 9 | */ 10 | 11 | #include 12 | using namespace std; 13 | 14 | // Tree node 15 | struct Node 16 | { 17 | int key; 18 | struct Node *left; 19 | struct Node *right; 20 | Node(int k) 21 | { 22 | key = k; 23 | left = right = NULL; 24 | } 25 | }; 26 | 27 | /* 28 | Algorithm: 29 | Swap every node's left and right pointer recursively 30 | */ 31 | void mirror(Node *root) 32 | { 33 | if (root == NULL) 34 | return; 35 | 36 | mirror(root->left); 37 | mirror(root->right); 38 | 39 | swap(root->left, root->right); 40 | } 41 | 42 | // Print tree 43 | void inorder(Node *root) 44 | { 45 | if (root != NULL) 46 | { 47 | inorder(root->left); 48 | cout << root->key << " "; 49 | inorder(root->right); 50 | } 51 | } 52 | 53 | // Driver code 54 | int main() 55 | { 56 | // Given trees 57 | Node *root = new Node(10); 58 | root->left = new Node(20); 59 | root->right = new Node(30); 60 | root->left->left = new Node(40); 61 | root->left->right = new Node(60); 62 | 63 | // fn call 64 | mirror(root); 65 | inorder(root); 66 | } -------------------------------------------------------------------------------- /18. Binary Search Tree/01. Theory/theory.md: -------------------------------------------------------------------------------- 1 | ## Definition: 2 | 3 | The binary search tree is one of the types of binary tree that has the value of all the nodes in the left subtree less than or equal to the root node, and the value of all the nodes in a right subtree are greater than or equal to the value of the root node. 4 | 5 | ## Properties: 6 | 7 | 1. For every node, key in left side are smaller and key in right side are greater 8 | 9 | 2. All keys are typically considered as distinct 10 | 11 | 3. Like linked list, it is linked data structures 12 | 13 | 4. Implementation in C++ as map, set, multimap, multiset 14 | 15 | 5. Search: O(log n), Insert: O(log n), Delete: O(log n), Find closest: O(log n) 16 | -------------------------------------------------------------------------------- /18. Binary Search Tree/02. Implementation/implement.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | // Tree Node 5 | struct Node 6 | { 7 | int key; 8 | Node *left; 9 | Node *right; 10 | Node(int key) 11 | { 12 | this->key = key; 13 | left = NULL; 14 | right = NULL; 15 | } 16 | }; 17 | 18 | // traverse 19 | void print(Node *root) 20 | { 21 | if (root != NULL) 22 | { 23 | print(root->left); 24 | cout << root->key << " "; 25 | print(root->right); 26 | } 27 | } 28 | 29 | // Driver code 30 | int main() 31 | { 32 | /* 33 | 34 | 40 35 | / \ 36 | 20 60 37 | / \ / \ 38 | 10 30 50 70 39 | 40 | */ 41 | Node *root = new Node(40); 42 | root->left = new Node(20); 43 | root->left->left = new Node(10); 44 | root->left->right = new Node(30); 45 | root->right = new Node(60); 46 | root->right->left = new Node(50); 47 | root->right->right = new Node(70); 48 | 49 | // fn call 50 | print(root); 51 | } -------------------------------------------------------------------------------- /18. Binary Search Tree/10. Pair Sum/pair.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Given a binary search tree and a sum. Find whether there 3 | is a pair in the bst whose sum is equal to given sum 4 | 5 | 10 6 | / \ 7 | 8 20 8 | / \ / \ 9 | 4 9 11 30 10 | / 11 | 25 12 | 13 | sum = 33 14 | 15 | output: true 16 | */ 17 | 18 | #include 19 | using namespace std; 20 | 21 | // Tree Node 22 | struct Node 23 | { 24 | int key; 25 | Node *left; 26 | Node *right; 27 | Node(int key) 28 | { 29 | this->key = key; 30 | left = NULL; 31 | right = NULL; 32 | } 33 | }; 34 | 35 | // Check pair sum 36 | bool hasPair(Node *root, int sum, unordered_set &s) 37 | { 38 | if (root == NULL) 39 | return false; 40 | 41 | if (hasPair(root->left, sum, s)) 42 | return true; 43 | 44 | if (s.find(sum - root->key) != s.end()) 45 | return true; 46 | else 47 | s.insert(root->key); 48 | 49 | return hasPair(root->right, sum, s); 50 | } 51 | 52 | // Driver code 53 | int main() 54 | { 55 | /* 56 | 57 | 40 58 | / \ 59 | 20 60 60 | / \ / \ 61 | 10 30 50 70 62 | 63 | */ 64 | Node *root = new Node(40); 65 | root->left = new Node(20); 66 | root->right = new Node(60); 67 | root->left->left = new Node(10); 68 | root->left->right = new Node(30); 69 | root->right->left = new Node(50); 70 | root->right->right = new Node(70); 71 | 72 | int sum = 120; 73 | 74 | // fn call 75 | unordered_set st; 76 | cout << boolalpha << hasPair(root, sum, st); 77 | } -------------------------------------------------------------------------------- /19. Graph/01. Theory/Graph.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nikhilsourav/Data-Structures-and-Algorithms/28cfaeda58597a0f1e266f250e87875d44c22f3d/19. Graph/01. Theory/Graph.png -------------------------------------------------------------------------------- /19. Graph/01. Theory/theory.md: -------------------------------------------------------------------------------- 1 | ## Graph 2 | 3 | - **Definition:** A Graph G is an ordered pair of a set V of vertices and a set E of edges. `G = (V,E)` 4 |
5 | 6 | - Ordered pair is pair of objects where order matter `(v,e) != (e,v) if (a != b)` 7 | - Ordered pair are written under paranthesis `()` 8 | - In our graph definition, first object is always set of vertices and second object is set of edges 9 | - An unordered pair (denoted by `{}`) is a pair of objects where order does not matter `{a,b} = {b,a}` 10 |
11 | 12 | - **Example:** Given a graph with 8 vertices and 10 edges 13 |
14 |

15 | 16 |

17 | 18 | - Each node in a graph must have an identification (name index etc) 19 | - This naming is not indicative of any order. We can give any name to any node 20 | - Set of vertices V = {v1, v2, v3, v4, v5, v6, v7, v8} 21 | - Set of edges E = {{v1,v2}, {v1,v3}, {v1,v4}, {v2,v5}, {v2,v6}, {v3,v7}, {v4,v8}, {v5,v8}, {v6,v8}, {v7,v8}} 22 | - This is an example of undirected graph 23 | -------------------------------------------------------------------------------- /19. Graph/02. Implementation/graph_1_a.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nikhilsourav/Data-Structures-and-Algorithms/28cfaeda58597a0f1e266f250e87875d44c22f3d/19. Graph/02. Implementation/graph_1_a.png -------------------------------------------------------------------------------- /19. Graph/02. Implementation/graph_1_b.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nikhilsourav/Data-Structures-and-Algorithms/28cfaeda58597a0f1e266f250e87875d44c22f3d/19. Graph/02. Implementation/graph_1_b.png -------------------------------------------------------------------------------- /19. Graph/02. Implementation/graph_2_a.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nikhilsourav/Data-Structures-and-Algorithms/28cfaeda58597a0f1e266f250e87875d44c22f3d/19. Graph/02. Implementation/graph_2_a.png -------------------------------------------------------------------------------- /19. Graph/02. Implementation/graph_2_b.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nikhilsourav/Data-Structures-and-Algorithms/28cfaeda58597a0f1e266f250e87875d44c22f3d/19. Graph/02. Implementation/graph_2_b.png -------------------------------------------------------------------------------- /19. Graph/03. DFS/01_dfs.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | https://youtu.be/9_ftWKch6vI?t=1341 3 | */ 4 | #include 5 | using namespace std; 6 | 7 | // Global vars 8 | unordered_map visited; 9 | unordered_map> graph; 10 | 11 | // DFS 12 | void dfs(int vertex) 13 | { 14 | /* 15 | Take action on the vertex 16 | after entering the vertex 17 | */ 18 | visited[vertex] = true; 19 | cout << vertex << " "; 20 | 21 | for (int child: graph[vertex]) 22 | { 23 | /* 24 | Take action on the child 25 | before entering the child 26 | */ 27 | if (visited[child] == 0) 28 | { 29 | dfs(child); 30 | /* 31 | Take action on the child 32 | after entering the child 33 | */ 34 | } 35 | } 36 | /* 37 | Take action on vertex 38 | before exiting the vertex 39 | */ 40 | } 41 | 42 | // Driver code 43 | int main() 44 | { 45 | /* 46 | 47 | 10 48 | / 49 | 20 50 | / \ 51 | 30 40 52 | / \ 53 | 50 60 54 | 55 | 10: 20 56 | 20: 10->30->40 57 | 30: 20 58 | 40: 20->50->60 59 | 50: 40 60 | 60: 40 61 | 62 | */ 63 | 64 | // build graph 65 | graph[10].push_back(20); 66 | 67 | graph[20].push_back(10); 68 | graph[20].push_back(30); 69 | graph[20].push_back(40); 70 | 71 | graph[30].push_back(20); 72 | 73 | graph[40].push_back(20); 74 | graph[40].push_back(50); 75 | graph[40].push_back(60); 76 | 77 | graph[50].push_back(40); 78 | graph[60].push_back(40); 79 | 80 | // fn call 81 | dfs(10); 82 | } -------------------------------------------------------------------------------- /19. Graph/03. DFS/02_dfs.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | // DFS 5 | void dfs(int source, vector adj[], vector &visited) 6 | { 7 | visited[source] = true; 8 | cout << source << " "; 9 | 10 | for (auto child : adj[source]) 11 | if (visited[child] == 0) 12 | dfs(child, adj, visited); 13 | } 14 | 15 | // Driver code 16 | int main() 17 | { 18 | int size = 7; 19 | vector adj[size + 1]; 20 | vector visited(size, false); 21 | 22 | /* 23 | 1---3---5 24 | | | 25 | 2---4 6---7 26 | 27 | 1: [2,3] 28 | 2: [1,4] 29 | 3: [1,4,5] 30 | 4: [2,3] 31 | 5: [3] 32 | 33 | 6: [7] 34 | 7: [6] 35 | */ 36 | 37 | // build graph 38 | adj[1].push_back(2); 39 | adj[1].push_back(3); 40 | 41 | adj[2].push_back(1); 42 | adj[2].push_back(4); 43 | 44 | adj[3].push_back(1); 45 | adj[3].push_back(4); 46 | adj[3].push_back(5); 47 | 48 | adj[4].push_back(3); 49 | adj[4].push_back(2); 50 | 51 | adj[5].push_back(3); 52 | 53 | adj[6].push_back(7); // not connected with previous 54 | adj[7].push_back(6); // not connected with previous 55 | 56 | // traverse all connected components 57 | for (int i = 1; i < visited.size(); i++) 58 | if (visited[i] == false) 59 | dfs(i, adj, visited); 60 | } -------------------------------------------------------------------------------- /19. Graph/03. DFS/04_dfs_naray.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | // DFS 5 | void dfs(int s, vector &vis, vector adj[]) 6 | { 7 | vis[s] = true; 8 | cout << s << " "; 9 | 10 | for (auto child : adj[s]) 11 | if (vis[child] == false) 12 | dfs(child, vis, adj); 13 | } 14 | 15 | // Driver code 16 | int main() 17 | { 18 | int numOfNodes = 11; 19 | vector adj[numOfNodes + 1]; // starting index is 1 20 | vector vis(numOfNodes + 1, false); 21 | 22 | /* 23 | 1 24 | / | \ 25 | 2 3 4 26 | / | \ \ 27 | 5 6 7 8 28 | / | \ 29 | 9 10 11 30 | 31 | 1: [2,3,4] 32 | 2: [1,5,6,7] 33 | 3: [1] 34 | 4: [1,8] 35 | 5: [2] 36 | 6: [2] 37 | 7: [2] 38 | 8: [4,9,10,11] 39 | 9: [8] 40 | 10: [8] 41 | 11: [8] 42 | */ 43 | 44 | // build graph 45 | adj[1].push_back(2); 46 | adj[1].push_back(3); 47 | adj[1].push_back(4); 48 | 49 | adj[2].push_back(1); 50 | adj[2].push_back(5); 51 | adj[2].push_back(6); 52 | adj[2].push_back(7); 53 | 54 | adj[3].push_back(1); 55 | 56 | adj[4].push_back(1); 57 | adj[4].push_back(8); 58 | 59 | adj[5].push_back(2); 60 | adj[6].push_back(2); 61 | adj[7].push_back(2); 62 | 63 | adj[8].push_back(4); 64 | adj[8].push_back(9); 65 | adj[8].push_back(10); 66 | adj[8].push_back(11); 67 | 68 | adj[9].push_back(8); 69 | adj[10].push_back(8); 70 | adj[11].push_back(8); 71 | 72 | // fn call 73 | dfs(1, vis, adj); 74 | } -------------------------------------------------------------------------------- /19. Graph/04. Cond Comp/CC.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Question: 3 | https://www.hackerearth.com/problem/algorithm/connected-components-in-a-graph/ 4 | */ 5 | 6 | #include 7 | using namespace std; 8 | 9 | // DFS 10 | void dfs(int source, vector adj[], vector &visited) 11 | { 12 | visited[source] = true; 13 | for (auto child : adj[source]) 14 | if (visited[child] == 0) 15 | dfs(child, adj, visited); 16 | } 17 | 18 | // Driver code 19 | int main() 20 | { 21 | int size = 8; 22 | vector adj[size]; 23 | vector visited(size, false); 24 | 25 | /* 26 | 1---3---5 27 | | | 28 | 2---4 6---7 29 | 30 | 1: [2,3] 31 | 2: [1,4] 32 | 3: [1,4,5] 33 | 4: [2,3] 34 | 5: [3] 35 | 36 | 6: [7] 37 | 7: [6] 38 | */ 39 | 40 | // build graph 41 | adj[1].push_back(2); 42 | adj[1].push_back(3); 43 | 44 | adj[2].push_back(1); 45 | adj[2].push_back(4); 46 | 47 | adj[3].push_back(1); 48 | adj[3].push_back(4); 49 | adj[3].push_back(5); 50 | 51 | adj[4].push_back(3); 52 | adj[4].push_back(2); 53 | 54 | adj[5].push_back(3); 55 | 56 | adj[6].push_back(7); // not connected with previous 57 | adj[7].push_back(6); // not connected with previous 58 | 59 | // fn call 60 | int count = 0; 61 | for (int i = 1; i < visited.size(); i++) 62 | if (visited[i] == false) 63 | dfs(i, adj, visited), count++; 64 | 65 | cout << count; 66 | } -------------------------------------------------------------------------------- /19. Graph/06. SSSP/01_sssp.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | // Single source shortest path on tree not graph 5 | void dfs( 6 | int source, 7 | vector &visited, 8 | vector adj[], 9 | vector &distArr, 10 | int dist) 11 | { 12 | visited[source] = true; 13 | distArr[source] = dist; 14 | 15 | for (auto child : adj[source]) 16 | if (visited[child] == false) 17 | dfs(child, visited, adj, distArr, dist + 1); 18 | 19 | dist--; 20 | } 21 | 22 | // Driver 23 | int main() 24 | { 25 | int numOfVertices = 6; 26 | vector adj[numOfVertices + 1]; 27 | vector visited(numOfVertices + 1, false); 28 | vector distArr(numOfVertices + 1, 0); 29 | 30 | /* 31 | 1 32 | / 33 | 2 34 | / \ 35 | 3 4 36 | / \ 37 | 5 6 38 | 39 | 1: [2] 40 | 2: [1,3,4] 41 | 3: [2] 42 | 4: [2,5,6] 43 | 5: [5] 44 | 6: [4] 45 | 46 | */ 47 | 48 | // build graph 49 | adj[1].push_back(2); 50 | adj[2].push_back(1); 51 | adj[2].push_back(3); 52 | adj[2].push_back(4); 53 | adj[3].push_back(2); 54 | adj[4].push_back(2); 55 | adj[4].push_back(5); 56 | adj[4].push_back(6); 57 | adj[5].push_back(4); 58 | adj[6].push_back(4); 59 | 60 | // fn call 61 | dfs(1, visited, adj, distArr, 0); 62 | 63 | // print distance array 64 | // index 0 is not used here and distance of 1 from itself is 0 65 | for (auto val : distArr) 66 | cout << val << " "; 67 | } -------------------------------------------------------------------------------- /19. Graph/06. SSSP/03_ques.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | https://www.spoj.com/problems/PT07Y/ 3 | 4 | To ensure a graph is a tree: 5 | 1. There should be only one connected component 6 | 2. Total number of edges = no. of vertices - 1 7 | */ 8 | 9 | #include 10 | using namespace std; 11 | 12 | vector vis(10001, false); 13 | vector adj[10001]; 14 | 15 | // normal dfs 16 | void dfs(int s) 17 | { 18 | vis[s] = true; 19 | for (auto c : adj[s]) 20 | if (vis[c] == false) 21 | dfs(c); 22 | } 23 | 24 | // Driver code 25 | int main() 26 | { 27 | // input total vertex, total edges 28 | int n, m; 29 | cin >> n >> m; 30 | 31 | // input graph 32 | for (int i = 1; i <= m; i++) 33 | { 34 | int u, v; 35 | cin >> u >> v; 36 | adj[u].push_back(v); 37 | adj[v].push_back(u); 38 | } 39 | 40 | // count connected components 41 | int cc = 0; 42 | for (int i = 1; i <= n; i++) 43 | if (vis[i] == false) 44 | dfs(i), cc++; 45 | 46 | // if connected components = 1, total edge = n - 1 47 | if (cc == 1 && m == n - 1) 48 | cout << "YES"; 49 | else 50 | cout << "NO"; 51 | } -------------------------------------------------------------------------------- /19. Graph/07. Bipartite/01_bp.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | #define MAX 10001 4 | 5 | // Global vars 6 | vector vis(MAX, false); 7 | vector gr[MAX]; 8 | vector col(MAX); 9 | 10 | // Check if graph is bipartite 11 | bool isBipartite(int s, int color) 12 | { 13 | vis[s] = true; 14 | col[s] = color; 15 | 16 | for (auto child : gr[s]) 17 | { 18 | if (vis[child] == false) 19 | { 20 | if (isBipartite(child, !color) == false) 21 | return false; 22 | } 23 | else 24 | { 25 | if (col[child] == col[s]) 26 | return false; 27 | } 28 | } 29 | 30 | return true; 31 | } 32 | 33 | // Driver code 34 | int main() 35 | { 36 | /* 37 | 1 38 | / 39 | 2 40 | / \ 41 | 3 - 4 42 | \ 43 | 6 44 | */ 45 | 46 | // build graph 47 | gr[1].push_back(2); 48 | gr[2].push_back(1); 49 | gr[2].push_back(3); 50 | gr[2].push_back(4); 51 | gr[3].push_back(2); 52 | gr[3].push_back(4); 53 | gr[4].push_back(2); 54 | gr[4].push_back(6); 55 | gr[6].push_back(4); 56 | 57 | // fn call 58 | cout << boolalpha << isBipartite(1, 0); 59 | } -------------------------------------------------------------------------------- /19. Graph/08. Cycle Detection/01_findCycle.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | #define MAX 10001 4 | 5 | // Global vars 6 | vector gr[MAX]; 7 | int vis[MAX]; 8 | 9 | // Check cycle 10 | bool hasCycle(int s, int parent) 11 | { 12 | vis[s] = 1; 13 | 14 | for (auto ch : gr[s]) 15 | { 16 | if (vis[ch] == false) 17 | { 18 | if (hasCycle(ch, s) == true) 19 | return true; 20 | } 21 | else 22 | { 23 | if (parent != ch) 24 | return true; 25 | } 26 | } 27 | 28 | return false; 29 | } 30 | 31 | // Driver code 32 | int main() 33 | { 34 | /* 35 | 1 36 | / 37 | 2 38 | / \ 39 | 3 - 4 40 | \ 41 | 6 42 | */ 43 | 44 | // build graph 45 | gr[1].push_back(2); 46 | gr[2].push_back(1); 47 | gr[2].push_back(3); 48 | gr[2].push_back(4); 49 | gr[3].push_back(2); 50 | gr[3].push_back(4); 51 | gr[4].push_back(2); 52 | gr[4].push_back(6); 53 | gr[6].push_back(4); 54 | 55 | // fn call 56 | cout << boolalpha << hasCycle(1, -1); 57 | } -------------------------------------------------------------------------------- /19. Graph/10. InOut/inout.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | #define MAX 10001 4 | 5 | // Global vars 6 | vector gr[MAX]; 7 | bool vis[MAX]; 8 | int in[MAX]; 9 | int out[MAX]; 10 | int timer = 1; 11 | 12 | // DFS 13 | void dfs(int src) 14 | { 15 | vis[src] = true; 16 | in[src] = timer++; 17 | 18 | for (int ch : gr[src]) 19 | if (vis[ch] == false) 20 | dfs(ch); 21 | 22 | out[src] = timer++; 23 | } 24 | 25 | // Driver code 26 | int main() 27 | { 28 | /* 29 | 30 | 1 31 | / 32 | 2 33 | / \ 34 | 3 4 35 | \ 36 | 5 37 | 38 | 1 [2] 39 | 2 [1,3,4] 40 | 3 [2] 41 | 4 [2,5] 42 | 5 [4] 43 | 44 | */ 45 | 46 | // build graph 47 | gr[1].push_back(2); 48 | 49 | gr[2].push_back(1); 50 | gr[2].push_back(3); 51 | gr[2].push_back(4); 52 | 53 | gr[3].push_back(2); 54 | 55 | gr[4].push_back(2); 56 | gr[4].push_back(5); 57 | 58 | gr[5].push_back(4); 59 | 60 | // fn call 61 | dfs(1); 62 | for (int i = 1; i <= 5; i++) 63 | cout << i << ": " << in[i] << " " << out[i] << endl; 64 | } -------------------------------------------------------------------------------- /19. Graph/12. Subtree Size/subtree.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | #define MAX 10001 4 | 5 | // Graph 6 | vector gr[MAX]; 7 | bool vis[MAX]; 8 | int subsize[MAX]; 9 | 10 | // DFS 11 | int dfs(int src) 12 | { 13 | vis[src] = true; 14 | int currsize = 1; 15 | 16 | for (int ch : gr[src]) 17 | if (vis[ch] == false) 18 | currsize += dfs(ch); 19 | 20 | subsize[src] = currsize; 21 | return currsize; 22 | } 23 | 24 | // Driver code 25 | int main() 26 | { 27 | /* 28 | 29 | 1 30 | / 31 | 2 32 | / \ 33 | 3 4 34 | \ 35 | 5 36 | 37 | 1 [2] 38 | 2 [1,3,4] 39 | 3 [2] 40 | 4 [2,5] 41 | 5 [4] 42 | 43 | */ 44 | 45 | // build graph 46 | gr[1].push_back(2); 47 | 48 | gr[2].push_back(1); 49 | gr[2].push_back(3); 50 | gr[2].push_back(4); 51 | 52 | gr[3].push_back(2); 53 | 54 | gr[4].push_back(2); 55 | gr[4].push_back(5); 56 | 57 | gr[5].push_back(4); 58 | 59 | int n = 5; 60 | cout << dfs(1); 61 | } -------------------------------------------------------------------------------- /19. Graph/13. BFS/01_bfs.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | #define MAX 10001 4 | 5 | // Graph 6 | vector gr[MAX]; 7 | bool vis[MAX]; 8 | 9 | // BFS 10 | void bfs(int src) 11 | { 12 | vis[src] = 1; 13 | queue qu; 14 | qu.push(src); 15 | 16 | while (!qu.empty()) 17 | { 18 | int curr = qu.front(); 19 | cout << curr << " "; 20 | qu.pop(); 21 | 22 | for (int ch : gr[curr]) 23 | if (vis[ch] == 0) 24 | vis[ch] = 1, qu.push(ch); 25 | } 26 | } 27 | 28 | // Driver code 29 | int main() 30 | { 31 | /* 32 | 33 | 1 34 | / 35 | 2 36 | / \ 37 | 3 4 38 | \ 39 | 5 40 | 41 | 1 [2] 42 | 2 [1,3,4] 43 | 3 [2] 44 | 4 [2,5] 45 | 5 [4] 46 | 47 | */ 48 | 49 | // build graph 50 | gr[1].push_back(2); 51 | 52 | gr[2].push_back(1); 53 | gr[2].push_back(3); 54 | gr[2].push_back(4); 55 | 56 | gr[3].push_back(2); 57 | 58 | gr[4].push_back(2); 59 | gr[4].push_back(5); 60 | 61 | gr[5].push_back(4); 62 | 63 | bfs(1); 64 | } -------------------------------------------------------------------------------- /19. Graph/13. BFS/02_bfs.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | #define MAX 10001 4 | 5 | // Graph 6 | vector gr[MAX]; 7 | bool vis[MAX]; 8 | 9 | // BFS 10 | void bfs(queue &qu) 11 | { 12 | if (qu.empty()) 13 | return; 14 | 15 | int curr = qu.front(); 16 | cout << curr << " "; 17 | qu.pop(); 18 | 19 | for (int ch : gr[curr]) 20 | if (vis[ch] == 0) 21 | vis[ch] = 1, qu.push(ch); 22 | 23 | bfs(qu); 24 | } 25 | 26 | // Driver code 27 | int main() 28 | { 29 | /* 30 | 31 | 1 32 | / 33 | 2 34 | / \ 35 | 3 4 36 | \ 37 | 5 38 | 39 | 1 [2] 40 | 2 [1,3,4] 41 | 3 [2] 42 | 4 [2,5] 43 | 5 [4] 44 | 45 | */ 46 | 47 | // build graph 48 | gr[1].push_back(2); 49 | 50 | gr[2].push_back(1); 51 | gr[2].push_back(3); 52 | gr[2].push_back(4); 53 | 54 | gr[3].push_back(2); 55 | 56 | gr[4].push_back(2); 57 | gr[4].push_back(5); 58 | 59 | gr[5].push_back(4); 60 | 61 | queue qu; 62 | vis[1] = 1; 63 | qu.push(1); 64 | 65 | bfs(qu); 66 | } -------------------------------------------------------------------------------- /19. Graph/14. SSSP/sssp_bfs.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | #define MAX 10001 4 | 5 | // Global vars 6 | vector gr[MAX]; 7 | bool vis[MAX]; 8 | int dist[MAX]; 9 | 10 | // BFS 11 | void bfs(int src) 12 | { 13 | vis[src] = 1; 14 | dist[src] = 0; 15 | 16 | queue qu; 17 | qu.push(src); 18 | 19 | while (!qu.empty()) 20 | { 21 | int curr = qu.front(); 22 | qu.pop(); 23 | 24 | for (int ch : gr[curr]) 25 | { 26 | if (vis[ch] == 0) 27 | { 28 | vis[ch] = 1; 29 | dist[ch] = dist[curr] + 1; 30 | qu.push(ch); 31 | } 32 | } 33 | } 34 | } 35 | 36 | // Driver code 37 | int main() 38 | { 39 | /* 40 | 41 | 1 42 | / 43 | 2 44 | / \ 45 | 3 4 46 | \ 47 | 5 48 | 49 | 1 [2] 50 | 2 [1,3,4] 51 | 3 [2] 52 | 4 [2,5] 53 | 5 [4] 54 | 55 | */ 56 | 57 | // build graph 58 | gr[1].push_back(2); 59 | 60 | gr[2].push_back(1); 61 | gr[2].push_back(3); 62 | gr[2].push_back(4); 63 | 64 | gr[3].push_back(2); 65 | 66 | gr[4].push_back(2); 67 | gr[4].push_back(5); 68 | 69 | gr[5].push_back(4); 70 | 71 | 72 | // fn call 73 | bfs(1); 74 | 75 | for (int i = 1; i <= 5; i++) 76 | cout << dist[i] << " "; 77 | } -------------------------------------------------------------------------------- /19. Graph/21. Articulation Points/cutVertices.cpp: -------------------------------------------------------------------------------- 1 | // TODO -------------------------------------------------------------------------------- /19. Graph/22. Topological Sort/01_bfstopo.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | #define MAX 10001 4 | 5 | // Graph 6 | vector gr[MAX]; 7 | int indegree[MAX]; 8 | 9 | // Topological sort kahn's algo 10 | vector topsort(int numOfVert) 11 | { 12 | queue qu; 13 | vector res; 14 | 15 | // push indegree[vert] = 0 in qu 16 | for (int i = 1; i <= numOfVert; i++) 17 | if (indegree[i] == 0) 18 | qu.push(i); 19 | 20 | while (!qu.empty()) 21 | { 22 | int cur = qu.front(); 23 | res.push_back(cur); 24 | qu.pop(); 25 | 26 | // edge removal 27 | for (int ch : gr[cur]) 28 | { 29 | indegree[ch]--; 30 | if (indegree[ch] == 0) 31 | qu.push(ch); 32 | } 33 | } 34 | 35 | return res; 36 | } 37 | 38 | // Driver code 39 | int main() 40 | { 41 | /* 42 | 43 | Inputs: 44 | 9 10 45 | 1 2 46 | 3 4 47 | 1 8 48 | 2 9 49 | 2 5 50 | 4 5 51 | 4 8 52 | 5 9 53 | 5 7 54 | 6 7 55 | 56 | */ 57 | 58 | // given graph 59 | int numOfVert, numOfEdge; 60 | int src, dest; 61 | 62 | cout << "Provide inputs:\n"; 63 | cin >> numOfVert >> numOfEdge; 64 | 65 | // u -> v (directed graph) 66 | while (numOfEdge--) 67 | { 68 | cin >> src >> dest; 69 | gr[src].push_back(dest); 70 | indegree[dest]++; 71 | } 72 | 73 | // fn call (cc auto traversed) 74 | vector res = topsort(numOfVert); 75 | 76 | // result 77 | cout << "Topological Sorting:\n"; 78 | for (auto val : res) 79 | cout << val << " "; 80 | } -------------------------------------------------------------------------------- /19. Graph/22. Topological Sort/02_dfstopo.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | #define MAX 10001 4 | 5 | // Graph 6 | vector gr[MAX]; 7 | bool vis[MAX]; 8 | 9 | // Helper 10 | void dfs(int src, stack &stk) 11 | { 12 | vis[src] = 1; 13 | 14 | for (int ch : gr[src]) 15 | if (vis[ch] == 0) 16 | dfs(ch, stk); 17 | 18 | stk.push(src); 19 | } 20 | 21 | // Topological sort using dfs 22 | vector topsort(int numOfVert) 23 | { 24 | stack stk; 25 | vector res; 26 | 27 | // traverse cc 28 | for (int i = 1; i <= numOfVert; i++) 29 | if (vis[i] == 0) 30 | dfs(i, stk); 31 | 32 | // store elements in res 33 | while (!stk.empty()) 34 | res.push_back(stk.top()), stk.pop(); 35 | 36 | return res; 37 | } 38 | 39 | // Driver code 40 | int main() 41 | { 42 | /* 43 | 44 | Inputs: 45 | 9 10 46 | 1 2 47 | 3 4 48 | 1 8 49 | 2 9 50 | 2 5 51 | 4 5 52 | 4 8 53 | 5 9 54 | 5 7 55 | 6 7 56 | 57 | */ 58 | 59 | // given graph 60 | int numOfVert, numOfEdge; 61 | int src, dest; 62 | 63 | cout << "Provide inputs:\n"; 64 | cin >> numOfVert >> numOfEdge; 65 | 66 | // u -> v (directed graph) 67 | while (numOfEdge--) 68 | { 69 | cin >> src >> dest; 70 | gr[src].push_back(dest); 71 | } 72 | 73 | // fn call 74 | vector res; 75 | res = topsort(numOfVert); 76 | 77 | // result 78 | cout << "Topological Sorting:\n"; 79 | for (auto val : res) 80 | cout << val << " "; 81 | } -------------------------------------------------------------------------------- /19. Graph/24. Cond Comp/01_cc.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | // Global vars 5 | int row; 6 | int col; 7 | const int sz = 4; 8 | 9 | int grid[1001][1001]; 10 | bool vis[100][100]; 11 | 12 | int dx[] = {0, 1, 0, -1}; 13 | int dy[] = {1, 0, -1, 0}; 14 | 15 | // Checks if index is valid 16 | bool isValid(int x, int y) 17 | { 18 | if (x < 0 or x > row - 1 or y < 0 or y > col - 1) 19 | return false; 20 | 21 | if (vis[x][y] == 1 or grid[x][y] == 0) 22 | return false; 23 | 24 | return true; 25 | } 26 | 27 | // DFS 28 | void dfs(int x, int y) 29 | { 30 | // visit and print 31 | vis[x][y] = 1; 32 | 33 | // recur for further nodes 34 | for (int i = 0; i < sz; i++) 35 | if (isValid(x + dx[i], y + dy[i])) 36 | dfs(x + dx[i], y + dy[i]); 37 | } 38 | 39 | // Driver code 40 | int main() 41 | { 42 | 43 | /* 44 | Inputs: 45 | 6 6 46 | 0 0 1 0 1 1 47 | 0 1 1 0 0 1 48 | 0 1 0 0 0 0 49 | 1 0 1 1 0 0 50 | 0 0 0 1 0 0 51 | 0 1 1 0 1 1 52 | */ 53 | cin >> row >> col; 54 | for (int i = 0; i < row; i++) 55 | for (int j = 0; j < row; j++) 56 | cin >> grid[i][j]; 57 | 58 | // fn call 59 | int cc = 0; 60 | for (int i = 0; i < row; i++) 61 | for (int j = 0; j < col; j++) 62 | if (vis[i][j] == 0 and grid[i][j] == 1) 63 | dfs(i, j), cc++; 64 | 65 | cout << "\nconnected components: " << cc << endl; 66 | } -------------------------------------------------------------------------------- /19. Graph/28. Tarjan's Algo/tarjan.cpp: -------------------------------------------------------------------------------- 1 | // TODO -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Data Structures & Algorithms 2 | 3 |
4 | 5 | ## About the repository: 6 | 7 | - Contains theories and programming questions related to fundamentals of data structures and algorithms 8 | - Every topic is in sequence and has a separate folder. 9 | - Within each folder, there are various sub-folders with theory and questions related to that topic 10 | - All codes are written in C++ programming language 11 | 12 |
13 | 14 | ## Want to contribute ? 15 | 16 | - If you found any typo / logical error / runtime error or you want to add another topic, feel free to create a pull request. 17 | 18 | - **How to create a pull request ?** 19 | 20 | - step 1:   Fork this repository 21 | - step 2:   Clone this to your local machine 22 | - step 3:   Make a new branch 23 | - step 4:   Make changes 24 | - step 5:   Push it back to your repo 25 | - step 6:   Click compare and pull request 26 | - step 7:   Click create pull request 27 | 28 | - **Are there any rules ?** 29 | 30 | - Nothing strict, just keep the indentation clean 31 | - Use comments wherever necessary 32 | - Follow folder and file structure 33 | - Use appropriate variable names 34 | 35 |
36 | 37 | ## Folder structure example: 38 | 39 |
40 | 41 | 42 | -------------------------------------------------------------------------------- /_Utility/02. Builtin functions/builtInFn.cpp: -------------------------------------------------------------------------------- 1 | // https://www.geeksforgeeks.org/builtin-functions-gcc-compiler/ 2 | 3 | #include 4 | using namespace std; 5 | #define print cout << 6 | 7 | // Driver cdoe 8 | int main() 9 | { 10 | // return no of set bit in an int 11 | int num1 = 7; 12 | __builtin_popcount(num1); 13 | long num2 = 6; 14 | __builtin_popcountl(num2); 15 | long long num3 = 8; 16 | __builtin_popcountll(num3); 17 | 18 | // return true if num has odd set bit otherwise false 19 | int num4 = 8; 20 | __builtin_parity(num4); 21 | long num5 = 6; 22 | __builtin_parityl(num5); 23 | long long num6 = 3; 24 | __builtin_parityll(num6); 25 | 26 | // count leading zeroes in binary of an integer 27 | int num7 = 16; 28 | __builtin_clz(num7); 29 | long num8 = 11; 30 | __builtin_clzl(num8); 31 | long long num9 = 32; 32 | __builtin_clz(num9); 33 | 34 | // find minimum of x numbers 35 | int num10 = 2, num11 = 3, num12 = 1, num13 = 9; 36 | print min({num10, num11, num12, num13}); 37 | 38 | // find gcd of two numbers 39 | int num14 = 4, num15 = 6; 40 | print __gcd(num14, num15); 41 | } -------------------------------------------------------------------------------- /_Utility/08. List/list.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | // print elements of list container 5 | void printList(list myList) 6 | { 7 | list::iterator itr; 8 | for (itr = myList.begin(); itr != myList.end(); itr++) 9 | cout << *itr << " "; 10 | cout << "\n"; 11 | } 12 | 13 | // Driver code 14 | int main() 15 | { 16 | // create a singly linked list 17 | forward_list list_1; 18 | 19 | // create doubly linked list 20 | list list_2; 21 | 22 | /* 23 | =============== INITIALIZATION ============== 24 | general init 25 | */ 26 | list list_3{1, 2, 3}; 27 | list list_4 = {1, 2, 3}; 28 | 29 | // init from vector (same for other containers) 30 | vector v1 = {5, 6, 7}; 31 | list list_5{v1.begin(), v1.end()}; 32 | 33 | // =============== METHODS ============== // 34 | list intList{2, 3, 4}; 35 | intList.insert(intList.begin(), 1); // at a particular position 36 | intList.push_back(5); // at the end of list 37 | intList.push_front(0); // at the front of list 38 | intList.size(); // gives size 39 | intList.reverse(); // reverse list O(n) 40 | intList.sort(); // sort in O(nlogn) 41 | intList.remove(0); // remove element 42 | intList.pop_back(); // delete last element 43 | intList.pop_front(); // delete first elemtn 44 | printList(intList); // print list 45 | intList.clear(); // erase all elements 46 | } -------------------------------------------------------------------------------- /_Utility/09. stack/stack.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | // Driver code 5 | int main() 6 | { 7 | // internally, stack is implemented using deque container 8 | stack stk; 9 | 10 | // =========== PUSH ============= // 11 | stk.push(10); // push element 12 | stk.push(20); // push element 13 | stk.push(30); // push element 14 | stk.push(40); // push element 15 | stk.push(50); // push element 16 | stk.push(60); // push element 17 | 18 | // =========== POP ============= // 19 | stk.pop(); 20 | 21 | // =========== TOP ============= // 22 | int x = stk.top(); 23 | cout << "top element:" << x << "\n"; 24 | 25 | // =========== SIZE ============= // 26 | int sz = stk.size(); 27 | cout << "size " << sz << "\n"; 28 | 29 | // =========== EMPTY ============= // 30 | bool isEmpty = stk.empty(); 31 | cout << "is stack empty " << boolalpha << isEmpty << "\n"; 32 | 33 | // =========== PRINT =============// 34 | cout << "Stack elements: "; 35 | int stackSize = stk.size(); 36 | for (int i = 0; i < stackSize; i++) 37 | { 38 | cout << stk.top() << " "; 39 | stk.pop(); 40 | } 41 | } -------------------------------------------------------------------------------- /_Utility/_images/demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nikhilsourav/Data-Structures-and-Algorithms/28cfaeda58597a0f1e266f250e87875d44c22f3d/_Utility/_images/demo.png --------------------------------------------------------------------------------