├── .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