
Explore algorithm design techniques in Java, including complexity analysis, recursion, divide and conquer, backtracking, greedy methods, and dynamic programming, with live problem solving.
Introduce algorithms as step-by-step, language-agnostic instructions to solve problems with examples like recipes. Explain data handling, multiple solutions, and focus on correctness and efficiency in time and space.
Begin exploring complexity analysis by examining two key concerns: algorithm correctness and time taken across input sizes, focusing on Big O notation for worst-case performance.
Analyze how input size drives algorithm time and space, and use big O notation to compare worst-case performance and memory usage through asymptotic analysis.
Explore growth rates from constant to factorial, including logarithmic and linear complexities. Apply big-O analysis to compare algorithms and simplify mixed terms to identify the dominant factors.
Analyze algorithm complexity by focusing on CPU usage while ignoring compiler optimizations. Explore big O notation and categorize complexities from O(1) to factorial through pseudo code.
Explore recurrence relations, their importance, and methods to solve them, including masters theorem, in this section of algorithms in java.
Explore recurrence relations as a tool for analyzing algorithms, with examples like factorial and Fibonacci, and learn how initial conditions and base cases shape recursive solutions and time complexity.
Use substitution to solve recurrence relations and determine time complexity, deriving the factorial case as O(n) and illustrating fibonacci lower bound.
Master the recurrence t(n)=a t(n/b)+f(n) using the master theorem to quickly derive time complexity. Apply the h_n and u_n tables to determine u_n, with an example t(n)=16 t(n/2)+n^2 yielding O(n^4).
Review recurrence relations, understand their importance and applications, and learn how to solve these relations. Apply the masters theorem to solve recurrence relations as we move to the next section.
Explore recursion as the foundation of algorithm design, including memory behavior, types, recurrence relations, problem identification, and tail call optimization through live coding and practice.
Learn how recursion solves problems by breaking them into similar subproblems, using the same method with a base condition to prevent infinite calls, as shown by factorial and call stack.
Identify whether a problem can be solved recursively by spotting identical subproblems and a base case, and practice breaking tasks on numbers, arrays, strings, and binary trees.
Learn to approach recursive problems by making educated assumptions, then apply four steps—define the function, pick a smaller subproblem, combine its result with the original, and identify the base condition.
This lecture explains how to find all subsequences of a string, including the empty string, by recursively solving the remaining substring and prefixing the first letter to each result.
Implement a private static get subsequence method in Java to recursively generate all subsequences of a word using charAt and substring, then test with abc.
Analyze the subsequence problem by recursively processing remaining letters and doubling subsequences with each added character, yielding exponential time O(2^n). Space complexity is linear O(n) due to recursion depth.
Learn to solve the Tower of Hanoi by recursion: move n-1 discs to the auxiliary rod, move the nth disc to the to_rod, then move n-1 discs to the to_rod.
implement tower of hanoi in java with recursive calls for n disks, moving disks between from-rod, aux-rod, and to-rod, and printing each move.
Analyze the Tower of Hanoi algorithm to reveal exponential time complexity of O(2^n) and its recurrence relation. Explore space complexity from stack depth equal to n for n disks.
Learn to compute the product sum of a special array using a recursive approach that multiplies the sum of its elements by depth, handling arrays within arrays.
Implement a recursive solution to compute the product sum of a special array, multiplying by depth and summing elements, and validate the result.
Demonstrate linear time by visiting every element once in the outer array and sub array. Assess space as the stack depth, which equals the array depth of three.
determine if one binary tree is a subtree of another using recursion, in order and pre order traversals, and array-based matching with linear time complexity.
Explores binary subtree checks in Java through live code, implementing in-order and pre-order traversals, storing results in lists, converting to strings, and comparing to determine subtree relationships.
Analyze the time complexity of checking if a tree is a subtree using in-order and pre-order traversals, requiring O(N+M) time and O(N+M) auxiliary space.
Weigh recursion against iteration; the iterative version is generally faster due to function call overhead, yet recursion remains intuitive and concise, with tail call optimization discussed later.
Explore types of recursion in Java, including direct, indirect, multi, head and tail recursion, and growth patterns from linear to tree and binary, exponential, and nested recursive functions.
Tail recursion uses an accumulator to carry the result and removes stack frames. Modern compilers, such as Scala and Kotlin, convert tail recursive calls into iteration at compile time.
Summarizes recursion concepts, memory behavior, and when to trust the recursion; explains types and relations, problem identification, approach, and practice with classic recursive problems, plus tail call optimization.
Explore backtracking, an extended recursion technique for solving problems that require undoing decisions, with live coding and pseudo code examples, focusing on game and strategy programming.
Explore backtracking as a recursive method that makes a series of choices, abandons failed paths, and resumes with different decisions to reach a solution, and learn to identify backtracking problems.
Identify backtracking involves making decisions from given choices under constraints, as shown with sudoku digits 1 to 9; when a choice fails, backtrack and try alternatives.
Discover a backtracking blueprint: identify choices, apply constraints, and use recursion to build a path in a matrix maze with zeros from top-left to bottom-right, with base cases and backtracking.
Solve the rat in a maze problem with backtracking by moving right or down, validating inside-maze cells with ones and avoiding zeros, and undoing moves until reaching the bottom-right exit.
Implement backtracking to solve a 4x4 rat-in-maze in Java, using isSafe and a solution matrix to build a path from (0,0) to the goal, with recursion and backtracking.
Analyze rat in maze with two recursive calls per step, yielding exponential time: 2^(n^2) for an n×n grid (2^(n*m) generally), and O(n^2) space for the output.
Solve the n-queen problem on an n by n board using backtracking, placing n queens column by column in a non-attacking way and undoing moves when a placement conflicts.
Solve the n-queens problem in java by placing n queens on a five cross five matrix using backtracking, with isSafe checks, recursion, and printing the resulting matrix.
Analyze the n queens problem using backtracking to place queens by column, examining n rows per column. Derive factorial time complexity and linear space usage due to recursion.
Solve the knight's tour problem on an n by n board using backtracking. Explore eight knight moves, ensuring unvisited, in-bounds cells, and backtrack to cover every cell exactly once.
Implement a knight's tour in java using backtracking and recursion, exploring eight moves and validating each step, printing the final 64-cell board.
Analyze knight tour complexity: worst-case runtime is 8 raised to the power n square for an n square board, and the stack may hold up to n square recursive calls.
Solve Boggle word search using backtracking on a character matrix by exploring eight adjacent cells without revisiting, validating formed words against a dictionary.
The lecture demonstrates boggle word search: starting from every letter, exploring eight adjacent cells with a visited matrix, using backtracking to find dictionary words and print them.
Analyze the word search (Boggle) complexity on an m by n board, where each step has up to eight choices, with worst time 8^(m n) and space O(m n).
Backtracking is introduced as an extended form of recursion that lets you change decisions at runtime and backtrack steps, a technique useful for game programming.
Learn the divide and conquer algorithm design technique, identify and approach problems using this method, and practice by solving handpicked classical problems with code-along guidance.
Divide and conquer splits problems into subproblems, conquers them, and combines results for a global solution, illustrated by binary search reducing time to O(log n) and mapreduce in big data.
Identify divide and conquer by splitting a problem into two or more identical subproblems solved recursively and merged for a global result. Recognize the recurrence T(n)=a T(n/b) + merge work.
Learn how merge sort uses divide and conquer to sort an array by splitting at the mid, recursively sorting subarrays, and merging them with i, j, and k pointers.
Watch a live Java merge sort code walk-through that builds an array, computes bounds, recursively sorts subarrays, merges them, and prints the final sorted result.
Analyze the complexity of merge sort by examining its divide and conquer steps and merge operations, revealing a time complexity of O(n log n) and space complexity of O(n).
Explore quicksort’s divide-and-conquer approach using a pivot and two-pointer partitioning to place elements in their correct index, then recursively sort subarrays in place.
Implement quick sort in Java by partitioning an array with a first-element pivot and left-right pointers. Partition and swap elements, recursively sort subarrays, and print the sorted array.
Analyze the worst-case time of quicksort as O(n^2) when the pivot is the largest element, and note the linear space due to recursion with up to n stack frames.
Apply the median of medians technique to find the median of an array by dividing into five-element subarrays, computing medians, and using the median as a pivot for O(n) time.
Discover median of medians in live java code, implementing partition and five-element chunks. Learn about the medians array, recursive pivot selection, and base case handling.
Explore divide and conquer concepts, identify and approach problems, and solve many examples to strengthen understanding, connecting ideas and previewing the next technique.
Explore the greedy algorithm, which picks the local best over the global solution, learn how to identify problems solvable by greedy, and practice applying greedy techniques to sample problems.
Explore the greedy technique, which makes locally optimal choices in one shot to seek a globally optimal solution, and understand its strengths, limitations, and the coin change challenges it faces.
Identify whether a problem can be solved with greedy by recognizing independence of subproblem sets, using the next-best choice to build a global solution.
Explore solving the fractional knapsack using a greedy approach to maximize profit under weight limit by selecting items by value per weight and taking fractions when needed, unlike zero-one knapsack.
Implements the fractional knapsack problem in Java using a greedy approach by sorting items by value-to-weight ratio and adding full items or fractions to maximize profit.
Analyze the time complexity of the fractional knapsack by sorting items by their value-to-weight ratio, achieving n log n time with built-in sorts, and note constant space usage.
Apply a greedy approach to interval scheduling maximization by sorting intervals by finish time and selecting non-overlapping tasks to maximize the total count.
demonstrates interval scheduling in java with a greedy approach, sorting intervals by finish time and selecting non overlapping intervals to form an optimal schedule.
Sort the intervals by end times and scan for non-overlapping intervals, giving O(n log n) time and O(n) space (including the output array; otherwise constant space).
Learn how Huffman coding uses a greedy, frequency-based approach to data compression, replacing fixed-length ASCII bits with variable-length codes for efficient binary transmission and an optimal solution.
Encode text with Huffman coding in Java by building a frequency map, constructing the Huffman tree, generating binary codes, and producing the final encoded string during live coding.
Analyze Huffman coding complexity, showing running time as n log k for n leaf nodes with a priority queue, and space as k for the generated tree.
Explain the Dijkstra algorithm on a weighted graph, where from a source node we iteratively update a distance table or matrix and a visited set, selecting the nearest unvisited vertex.
Explore live code for Dijkstra using an adjacency matrix, with distance and visited tracking, initialization from the source, and vertex-by-vertex distance updates to compute shortest paths.
Analyze time complexity of Dijkstra's algorithm by iterating through each vertex to find shortest paths, revealing a worst-case n^2 operations and linear space of n for distance and visited arrays.
Explore the greedy algorithm as a problem-solving technique, learn how to identify when it fits, and apply it to handpicked problems in this live Java algorithms session.
Discover dynamic programming, its top-down and bottom-up approaches, and how remembering intermediate results speeds up computations; explore problem identification, comparison with other methods, and tackling classical problems for interview success.
Discover how dynamic programming optimizes recursion by storing subproblem results to avoid overlap, using the fibonacci example to show memory-based solutions.
Identify whether a problem is suitable for dynamic programming by checking subdivision into smaller subproblems, overlapping subproblems, and the need for an optimal solution.
Explore how dynamic programming differs from recursion, divide and conquer, and greedy, focusing on overlapping subproblems, optimality, and practical coin change examples for algorithm design.
Master dynamic programming by choosing between top-down memoization and bottom-up iteration, caching subproblem results to avoid recomputation and building solutions from base cases up to n.
solve the staircase problem with dynamic programming, counting ways to reach the top using varying step sizes. implement top-down memoization and bottom-up approaches for efficient recursion-based solutions.
Analyze staircase complexity by comparing recursive, top-down, and bottom-up methods; show 3 raised to the power n time for recursion, and linear space with an n-sized array.
Explore the 0/1 knapsack problem, compare greedy and dynamic programming solutions, and implement top-down memoization and bottom-up DP to maximize profit with given weights and values.
Analyze the 0/1 knapsack complexities for recursive, top-down, and bottom-up solutions, highlighting exponential time, linear stack space, and O(nw) time/space with an n×w matrix.
Explore the coin change problem with infinite denominations, learn recursive and dynamic programming solutions, including top-down memoization and bottom-up approaches to compute the minimum coins for a target amount.
Analyze the coin change problem complexity across recursive, top-down, and bottom-up dynamic programming approaches, detailing time and space with m coins and target a.
Learn to solve the longest decreasing subsequence with dynamic programming, from brute-force to top-down memoization and bottom-up DP, including an O(n^2) and an O(n log n) approach.
Analyze the longest decreasing subsequence complexities across recursion, top-down, and bottom-up approaches, noting exponential time for recursion and O(n^2) time with O(n) space.
Explains the Levenshtein distance problem and how to compute edit distance between two strings using dynamic programming. Demonstrates top-down memoization and bottom-up dp with insert, delete, and replace operations.
Analyze Levenshtein distance complexity across recursive, top-down, and bottom-up approaches, revealing exponential time for naive recursion and m*n space, with memoization and optimization using three adjacent cells.
learn how to solve the rod cutting problem using dynamic programming, exploring recursive, top-down memoization, and bottom-up approaches to maximize revenue from rod lengths with given prices.
Analyze the rod cutting problem and compare recursion, top-down, and bottom-up approaches, noting exponential time for recursion and O(n^2) time with O(n) space for the others.
Explore matrix chain multiplication and how to minimize operations using dynamic programming, comparing top-down memoization and bottom-up approaches to optimal parenthesization.
Analyze matrix chain multiplication complexity across recursion and memoization approaches. Observe exponential time and O(n) space in recursion, then O(n^3) time and O(n^2) space in top-down and bottom-up methods.
Explore dynamic programming, identify problem structures, and apply top-down and bottom-up approaches, then compare with other techniques and solve example problems to prepare for your next coding assignment.
Explore Kadane's algorithm to solve the maximum contiguous subarray sum problem in linear time, using dynamic programming to build the maximum ending at each index and select the overall maximum.
Kadane's algorithm is implemented in Java to compute the maximum subarray sum in linear time, using a local max and a global max updated as the loop traverses the array.
Analyze Kadane's algorithm complexity, showing time complexity is linear, O(n), as a single for loop scans the array once, with constant space.
Bellman-Ford finds single-source shortest paths in graphs with negative weights by relaxing edges for n-1 iterations using dynamic programming; unlike Dijkstra, it handles negative weights but cannot handle negative cycles.
This live Java code demonstrates Bellman-Ford on a graph with six vertices and nine edges. It builds an edge class, initializes distances, relaxes edges, and detects negative cycles.
Explain the Bellman-Ford algorithm's time complexity as O(VE). Show space usage is O(V) with a distance array of size V.
Explore topological sort with Kahn's algorithm to produce a linear order of a directed acyclic graph by iteratively removing zero in-degree vertices and updating in-degrees, enabling dependency-aware scheduling.
Implements topological sort with Kahn's algorithm in Java, building a graph with adjacency lists, computing in-degrees, using a queue to produce a linear order, and detecting a negative cycle.
Analyze the complexity of Kahn's algorithm and its space needs. Show that Kahn's algorithm runs in O(v+e) time by traversing adjacency lists and filling in-degrees, with O(v) auxiliary space.
Learn to solve max flow problems using Ford-Fulkerson with residual graphs and augmenting paths, leveraging bottleneck capacities to maximize flow from source to sink.
Implement the Edmonds-Karp variant of Ford-Fulkerson using BFS to find augmenting paths, maintain a residual graph, compute the max flow, and update capacities.
Algorithm Design Techniques: Live problem-solving in Java
Algorithms are everywhere. One great algorithm applied sensibly can result in a System like GOOGLE!
Completer scientists have worked from 100s of years and derived some of the techniques that can be applied to write and design algorithms.
So Why to reinvent the wheel ??
Let’s go through some of the most famous algorithm design techniques in this course.
Once you will come to know these design techniques It will become very easy for you to approach a problem by identifying which technique to apply to solve that correctly and efficiently.
0. Complexity analysis
1. Recursion is the base of any algorithm design
2. Backtracking
3. Divide and Conquer
4. Greedy algorithms
5. Dynamic programming
And WE WILL WRITE THE CODE LINE BY LINE IN JAVA !!
By the end of this course -
1. You will understand how to design algorithms
2. A lot of coding practice and design live problems in Java
3. Algorithm Complexity analysis
AND
If you are preparing for your coding Interview or doing competitive programming This course will be a big help for you.
THRILLED? I welcome you to the course and I am sure this will be fun!!
If it does not - It comes with a 30 Days money-back guarantee so don’t think twice to give it a shot.
Happy Learning
Basics>Strong;