
This course includes our updated coding exercises so you can practice your skills as you learn.
See a demo
Master recursion, backtracking, and dynamic programming in Java, exploring stack vs heap memory, tail recursion, and problems like factorial, Fibonacci, towers of Hanoi, and N-queens.
Explore how memory works behind the scenes by comparing stack and heap memory, their roles in local variables, method calls, recursion, allocation, and garbage collection.
Visualize how stack memory stores function calls and local variables in stacked frames, while heap memory stores objects; the reference sits on the stack, and garbage collection frees unreferenced objects.
Explore recursion as solving a problem by smaller subproblems using the same function, with a base case to avoid infinite loops. Identify tail and head recursion and their memory differences.
Explore how iteration and recursion solve the same problem, using summing the first n integers as an example, and see why recursion often reads more elegantly.
Explore how recursion pushes function calls onto the stack toward base case, forming frames, and how tail recursion with an accumulator avoids stack overflow and can be optimized into iteration.
Compare head recursion and tail recursion with Java examples, showing a base case, backtracking, and how tail recursion can resemble iteration, while noting that Java does not optimize tail recursion.
Study the factorial problem for non-negative integers with head recursion in Java, using a base case at zero and n minus one recursion to compute n, and guard stack overflow.
Visualize stack memory during a recursive factorial in Java, showing how head recursion pushes frames, backtracks at the base case, and reveals the final result.
Compare head recursion and tail recursion in the factorial problem, showing how calculations occur during backtracking versus during recursive calls, using an accumulator and base case n=0.
Compute Fibonacci numbers using head recursion, applying base cases 0 and 1 and the recurrence f(n)=f(n-1)+f(n-2), while noting the repeated calls and performance implications.
Visualize how fibonacci recursion uses stack memory, base cases, and stack frames. See how fib(n) calls fib(n-1) and fib(n-2) and backtracks to return results.
Explore the towers of Hanoi: a three-peg recursion puzzle moving n-1 disks to an auxiliary peg, then the largest to the destination, under top-only moves and exponential time.
Implement the towers of Hanoi with recursion by moving n-1 disks from source to middle, moving the largest to destination, then moving n-1 disks from middle to destination.
Visualize towers of Hanoi by tracing recursive calls and stack frames, moving disks from source to destination via rods A, B, and C under the base case.
Learn how the Euclidean algorithm computes the greatest common divisor using modulo and recursion, with a base case when the remainder is zero and examples like 45 and 10.
Implement the gcd in Java with a recursive Euclidean algorithm, using base case b equals zero and a mod b to reduce to the gcd, illustrated by 48 and 18.
Understand the key differences between recursion and iteration, including independent stack frames and why recursion cannot change variables. See how backtracking and dynamic programming fit these approaches.
Determine whether a given integer is a power of two using a logarithmic time approach that divides by two and checks the remainder. Explore iterative and recursive implementations.
Reverse an array in place with tail recursion by swapping left and right indices until the base case, showing 1234 become 4321.
Learn to implement a palindrome check with a recursive isPalindrome method using left and right indices. The approach uses a base case left >= right and recursive calls move inward.
Learn the staircase problem: count ways to climb n stairs with 1 or 2 steps using recursion, base cases for 0 and 1, and ways(n)=ways(n-1)+ways(n-2).
Reverse a given integer by repeatedly taking the last digit with modulo ten, removing it with integer division, and building the reversed number via a while-loop iterative process.
Explore linear search, finding an item in an unsorted list by checking each item, noting N comparisons and worst-case linear running time versus binary search or hash functions.
Implement linear search in Java by iterating an integer array with a for loop, returning the index of a found item or -1 if not found, with linear time complexity.
Explore binary search, a logarithmic search method for sorted data, compare middle items to discard half the dataset each iteration, achieving fast logarithmic running time.
Implement binary search in Java using recursion, managing left and right indices and a middle index to narrow a sorted array. Return the found index or -1 when not found.
Examine selection algorithms to find the k-th order statistics, compare sorting with linear-time methods like quickselect and median of medians, and explore online selection and the secretary problem.
Explore the quickselect algorithm, its partition and selection phases, and how a random pivot finds kth order statistics in place, with best linear, worst quadratic, and average linear time.
Visualize quickselect’s partition and selection phases to find the second smallest item (k=2, k-1=1) in an array, using random pivots and left-right partitioning.
Implement quickselect in Java by partitioning a one dimensional array with a random pivot, swapping elements, and recursively selecting the k-th smallest or largest item.
Learn how pivot selection affects quickselect performance, causing quadratic time when the largest or smallest item is chosen, and how median of medians guarantees linear worst-case time.
Apply the median of medians to select the pivot for quickselect, achieving balanced partitions and guaranteed linear time.
Introselect combines quick select and median of medians, starting with quick select and falling back to median of medians when progress slows, ensuring robust pivot selection and efficiency.
Master online selection strategies for the secretary problem, using the odds algorithm to maximize a 1/e (about 37%) chance of selecting the best secretary from a data stream.
Explore binary numbers and powers of two, learn binary to decimal conversion with examples like 11011 equals 27, and examine bit capacity in 2-bit, 32-bit, and 64-bit representations.
Explore bitwise operators on binary values, including and, or, and exclusive or, with examples like 27 and 15, and see how Java applies them bit by bit.
Learn how binary shift operators work, with left shifts doubling values and right shifts halving them, demonstrated on bit patterns and their crucial role in cryptography and hash functions.
Compute the bit length of an integer by counting right shifts until number becomes zero. For example, 120 yields 1111000, seven bits, illustrating binary conversion and the right shift operator.
Learn how to check if an integer is even or odd in Java using xor with one and the modulo approach, with constant time performance.
Explore the Russian peasant multiplication algorithm, doubling the first number while halving the second, summing when the second is odd, and using integer division and bit shifts.
Explore backtracking, a form of recursion, to solve constraint satisfaction problems (n-queens, Sudoku, coloring) by pruning invalid partial candidates through a depth-first search on a game tree.
Explore the N-queens problem on an n by n chessboard, using backtracking to avoid brute-force states and place queens on a 4x4 board without threats.
Explore the search tree representation of the n-queens problem, showing how backtracking prunes branches to discard bad states and speed up solutions compared to brute force.
Implement the N-queens problem in Java using a backtracking approach, representing the chessboard as a two-dimensional array and placing queens by column, validating positions, and backtracking when needed.
Implement the N-queens problem with backtracking in Java, placing one queen per column and validating rows and diagonals to avoid conflicts, then backtracking to explore solutions.
Explains the N-queens backtracking algorithm with stack memory visualization, detailing the recursive solve function, column-based placement, validity checks, backtracking, and a four-queen solution.
Explore the Hamiltonian cycle problem in graphs, learn adjacency matrix representation, and apply backtracking to find Hamiltonian paths and cycles while understanding n! permutations and NP-completeness.
Visualize the Hamiltonian cycle problem on a six-vertex graph and visit each vertex once. Backtracking prunes a dead end and builds a search tree toward a valid cycle.
Apply a backtracking approach to the hamiltonian cycle problem by building a hamiltonian path with an adjacency matrix and validating the last-to-first edge to form a cycle.
Implement Hamiltonian cycle using backtracking on an adjacency matrix graph, verify connectivity and avoid revisiting vertices to ensure every vertex is visited once, yielding a Hamiltonian path and cycle.
Color a graph by assigning colors to vertices so adjacent ones differ, revealing the chromatic number and how backtracking prunes infeasible states in applications like bipartite graphs and map coloring.
Explore the graph coloring problem on a six-vertex graph, using backtracking and pruning to color vertices with up to four colors, ensuring no adjacent vertices share a color.
Develop a Java graph coloring solution with backtracking, using a vertex count, colors array, and an adjacency matrix, plus a show solution routine.
Use backtracking to solve graph coloring by validating each node against its adjacent vertices with an adjacency matrix, testing three and four color choices.
Explore the knight's tour: visit every cell on an n by n board exactly once, with a closed tour equaling a Hamiltonian cycle, tackling eight-move exponential running time with backtracking.
Implement the knight's tour in Java using backtracking, with a chessboard, move arrays, and a solve method that fills cells with step numbers starting from the top-left corner.
Explore knight's tour solving in Java using recursion and backtracking, validating moves to stay on the board and avoid revisiting cells by checking unvisited positions on a chessboard.
Explore the maze problem’s theoretical background, using recursion and backtracking with depth-first search to navigate an n by n grid with obstacles, starting top-left to bottom-right.
Explain implementing a maze solver with 2d arrays for maze and its solution. Start at top-left, move right then down toward bottom-right, marking path with 1s and backtracking when needed.
Execute maze problem implementation II by validating moves in a 2d maze, enforcing bounds and obstacles, and finding a path from the top-left to the bottom-right using backtracking.
Demonstrate recursion and backtracking in a 4x4 maze, tracing stack memory frames as the algorithm moves from the top-left to the bottom-right by right and down.
Explore the sudoku problem on a nine by nine grid, enforcing digits 1–9 in every row, column, and box, and apply backtracking to prune invalid states in this np-complete search.
Implement a sudoku solver in Java from scratch using a 9x9 board, 3x3 boxes, and a backtracking algorithm with a two-dimensional sudoku table.
Implement a recursive backtracking solver for Sudoku, starting from the top-left cell and progressing row by row, backtracking on invalid choices until a solution is found.
Implement a sudoku solver by validating columns, rows, and 3x3 boxes, using backtracking to place numbers 1–9 so each digit appears exactly once per row, column, and box.
Explain why brute force is slow, how backtracking lowers it toward exponential time, and why NP-complete problems need metaheuristics like simulated annealing and genetic algorithms for practical approximations.
Explore Fibonacci numbers, compare recursive and dynamic programming approaches, and introduce memoization to avoid repeated subproblems. Store subproblem results in a hash table for linear time with extra memory.
Explore efficient Fibonacci number computation using dynamic programming in Java, transitioning from recursive baseline to memoization and tabulation, and compare top-down and bottom-up approaches.
Explore the knapsack problem, a dynamic programming challenge, and learn zero-one and divisible variants, weights and values, and how memoization builds a two-dimensional dynamic programming table to maximize value.
Explore a concrete knapsack problem example using a two-dimensional dynamic programming table to compute the maximum profit for a five-kilogram capacity and identify the items to include.
Implement the knapsack problem using dynamic programming in Java, defining weights, values, and a 2d table, deciding to take or skip items to maximize value, and displaying the result.
Explore the knapsack problem solved by recursion, with include and exclude choices, a recursion tree visualization, exponential running time, and the comparison to dynamic programming.
Explore the rod cutting problem, a dynamic programming approach similar to knapsack, to maximize profit from rod length n using a price list.
Explore the rod cutting problem with a dynamic programming table, solving subproblems from one to five meters to reach a final profit of 12 using one and two meter pieces.
Implement the rod cutting problem implementation in Java using dynamic programming with a two-dimensional dp table and a one-dimensional prices array to maximize profit. Show method reveals the chosen cuts.
explore the subset sum problem, an np-complete knapsack special case, by deciding if a subset of integers sums to a target using include/exclude and a two-dimensional dynamic programming table.
Demonstrate the subset sum problem with 5, 2, 1, 3 to reach 9, using dynamic programming to fill a two-dimensional table and backtrack the solution.
Learn to implement the subset sum problem in Java using dynamic programming with a two-dimensional boolean array, including initialization and solving steps to determine a feasible solution.
Explore Kadane's algorithm for the maximum subarray problem, moving from brute-force to a linear-time dynamic programming solution. Apply it to computer vision and bioinformatics.
Explore the longest common sop sequence problem: find the longest subsequence common to two strings, not necessarily consecutive, using dynamic programming and memoization.
Implement the longest common subsequence in Java using dynamic programming on a two-dimensional DP table, then backtrack to reconstruct the LCS string.
Examine the longest common subsequence via recursion, using base cases, matching characters, and excluding in non-matching cases. The lecture contrasts this approach with dynamic programming and a recursion tree.
Explore the bin packing problem, a knapsack-like, np-complete optimization, and compare naive brute-force, first fit, and first fit decreasing methods for efficient bin usage.
Execute the bin packing solution by applying the first fit decreasing algorithm in Java, sorting items by volumes, creating bins with a capacity, and placing items into bins.
This course is about the fundamental concepts of algorithmic problems focusing on recursion, backtracking, dynamic programming and divide and conquer approaches. As far as I am concerned, these techniques are very important nowadays, algorithms can be used (and have several applications) in several fields from software engineering to investment banking or R&D.
Section 1 - RECURSION
what are recursion and recursive methods
stack memory and heap memory overview
what is stack overflow?
Fibonacci numbers
factorial function
tower of Hanoi problem
Section 2 - SEARCH ALGORITHMS
linear search approach
binary search algorithm
Section 3 - SELECTION ALGORITHMS
what are selection algorithms?
how to find the k-th order statistics in O(N) linear running time?
quickselect algorithm
median of medians algorithm
the secretary problem
Section 4 - BIT MANIPULATION PROBLEMS
binary numbers
logical operators and shift operators
checking even and odd numbers
bit length problem
Russian peasant multiplication
Section 5 - BACKTRACKING
what is backtracking?
n-queens problem
Hamiltonian cycle problem
coloring problem
knight's tour problem
Sudoku game
Section 6 - DYNAMIC PROGRAMMING
what is dynamic programming?
knapsack problem
rod cutting problem
subset sum problem
Kadan's algorithm (maximum subarray)
longest common subsequence (LCS) problem
Section 7 - OPTIMAL PACKING
what is optimal packing?
bin packing problem
Section 8 - DIVIDE AND CONQUER APPROACHES
what is the divide and conquer approach?
dynamic programming and divide and conquer method
how to achieve sorting in O(NlogN) with merge sort?
the closest pair of points problem
Section 9 - COMMON INTERVIEW QUESTIONS
top interview questions (Google, Facebook and Amazon)
anagram problem
palindrome problem
trapping rain water problem
egg dropping problem
dutch national flag problem
In each section we will talk about the theoretical background for all of these algorithms then we are going to implement these problems together from scratch in Java.
Finally, YOU CAN LEARN ABOUT THE MOST COMMON INTERVIEW QUESTIONS (Google, Microsoft, Amazon etc.)
Thanks for joining the course, let's get started!