Practicing Dynamic Programming Through a one of the most popular Problem While practicing problems on LeetCode, I recently worked on the Climbing Stairs problem. At first glance, the problem is simple: You can climb either 1 step or 2 steps at a time. How many distinct ways can you reach the top of n stairs? I started with the most natural idea --> recursion. The recurrence relation is straightforward: f(n) = f(n-1) + f(n-2) Meaning, to reach step n, you must come either from step n-1 or step n-2. But while analyzing the recursion, I noticed something important: many subproblems were being solved repeatedly(it is known as overlapping subproblem). For example, f(3) or f(2) gets calculated multiple times inside the recursion tree. That observation led me to explore Dynamic Programming approaches. I ended up implementing the solution in four different ways: 1. Recursion (Brute Force) Time Complexity: O(2^n) Space Complexity: O(n) (recursion stack) 2. Memoization (Top-Down Dynamic Programming) Time Complexity: O(n) Space Complexity: O(n) 3. Tabulation (Bottom-Up Dynamic Programming) Time Complexity: O(n) Space Complexity: O(n) 4. Space Optimized Dynamic Programming Time Complexity: O(n) Space Complexity: O(1) Since each state only depends on the previous two values, the DP array can be reduced to just two variables. Interestingly, the pattern behind this problem follows the Fibonacci sequence. Problems like this are a great reminder that sometimes the goal is not just to solve the problem, but to understand how different approaches affect efficiency. Still learning, still exploring. If you have suggestions or improvements to this approach, I’d love to hear them. #DynamicProgramming #Algorithms #DSA #LeetCode #Cpp #ProblemSolving
Climbing Stairs Problem: Dynamic Programming Approaches
More Relevant Posts
-
HI CONNECTIONS I recently tackled LeetCode 120, a classic problem that perfectly demonstrates how to transform an exponential brute-force search into a linear-time Dynamic Programming solution. 🔍 The Challenge Given a triangle array, find the minimum path sum from top to bottom. For each step, you can move to the adjacent index of the row below. Example: From index i in the current row, you can move to index i or i + 1 in the next row. 🛠️ My Approach: Bottom-Up Dynamic Programming While a top-down approach (starting from the peak) is intuitive, a bottom-up approach is much cleaner because it avoids complex boundary checks at the edges of the triangle. Start at the Base: Begin with the last row of the triangle as your initial "minimum path" values. Move Upwards: For every node in the row above, the minimum path to the bottom is: Current Value + min(Left Child, Right Child) State Compression: Instead of a full 2D table, I used a 1D array (the size of the bottom row) to store and update the minimum sums in place. The Result: After reaching the top, the first element of the array contains the minimum path sum for the entire triangle. 📊 Efficiency Time Complexity: O(n^2) — Where n is the number of rows. we visit each element in the triangle exactly once. Space Complexity: O(n) — Using only a 1D array to store the bottom row's state. 💡 Key Takeaway The "Bottom-Up" mindset is a powerful tool in optimization. By starting at the destination and working back to the source, we can often simplify the logic and reduce the memory footprint of our algorithms. #LeetCode #DynamicProgramming #AlgorithmDesign #SoftwareEngineering #Optimization #ProblemSolving
To view or add a comment, sign in
-
-
Binary Tree Maximum Path Sum Just came across an exciting LeetCode problem that basically asks you to find the maximum path sum in a tree. The maximum sum of a sequence of nodes in a tree, where a node can only appear in the sequence at most once. At first, I thought of a simple DFS traversal for each node, where I find the maximum (the current node value, maximumPathsum(left_subtree), maximumPathSum(RightSubtree), the node value + left_vertical_max_path sum, the node value + right_vertical_max_path sum, the node value + left_vertical_max_path sum + right_vertical_max_path sum). But then I realized I'm going to be recomputing the cost more and more as I traverse down the tree. So I switched to a bottom-up recursion that allows me to find the maximum subtree of each node, starting at the base cases, and bubble up the maximum path sum that starts at the node so that the parent node can reuse that value rather than recomputing. Pretty Interesting Dynamic Programming 😁 #leetCodeIsFun #DynamicProgrammingIsCool
To view or add a comment, sign in
-
-
🚀 Day 142 — LeetCode 150 Days Challenge 🔥 Problem: Distinct Subsequences Today’s problem focused on Dynamic Programming + Recursion (Take / Not Take pattern) — a classic and very important concept for interviews. 🧠 Problem Summary Given two strings s and t, find the number of distinct subsequences of s which equals t. 👉 A subsequence is formed by deleting characters without changing the order. Example: s = "rabbbit" t = "rabbit" ✅ Output = 3 Because there are 3 different ways to delete one 'b' from s to form t. 💡 Intuition At every character of string s, we have two choices: 1️⃣ Take the character If s[i] == t[j], we match both characters and move forward. 2️⃣ Not Take the character Skip the current character of s (as we want all characters of t we only move index on s but not on t). This naturally forms a recursive decision tree. ⚡ Base Cases ✅ If we formed string t completely → return 1 ✅ If string s finishes before forming t → return 0 🧩 DP Optimization (Memoization) Since many states repeat, we store results in a DP table: dp[i][j] → number of ways to form t[j....] from s[i...] This reduces exponential recursion to: ⏱ Time Complexity: O(N × M) 📦 Space Complexity: O(N × M) 🎯 Key Learning ✔ Recognizing Take / Not Take DP pattern ✔ Converting recursion → memoization ✔ Counting problems using Dynamic Programming Dynamic Programming becomes easier once you start identifying patterns! ✅ Day 142 Complete Consistency > Motivation 💪 #LeetCode #150DaysChallenge #Day142 #DSA #DynamicProgramming #CodingJourney #ProblemSolving #SoftwareEngineer #LearningInPublic
To view or add a comment, sign in
-
-
🚀 Ever wondered how to optimize your code with dynamic programming? Let's break it down! 🤔 Dynamic programming is a technique used to solve complex problems by breaking them down into simpler subproblems. By storing the results of subproblems, we can avoid redundant computations and improve the efficiency of our code. This is crucial for developers as it can significantly enhance the performance of algorithms, making them faster and more scalable. 👉 Here's a simple step-by-step breakdown: 1️⃣ Identify the problem and determine if it can be divided into subproblems. 2️⃣ Define a recursive function to solve each subproblem efficiently. 3️⃣ Store the results of subproblems in a data structure like an array or hashmap. 4️⃣ Write the base case to stop the recursion. 5️⃣ Implement the recursive function using memoization or tabulation. 🚨 Pro tip: Start with a brute-force solution first to understand the problem before optimizing with dynamic programming techniques. ❌ Common mistake to avoid: Forgetting to handle edge cases or not initializing the base cases correctly can lead to incorrect results. 🤔 What's your favorite dynamic programming problem to solve? Share below! ⬇️ 🌐 View my full portfolio and more dev resources at tharindunipun.lk 🚀 #DynamicProgramming #Algorithm #CodingTips #DeveloperCommunity #CodeOptimization #TechTalk #LearnToCode #ProblemSolving #DevLife #DataStructures #SoftwareEngineering
To view or add a comment, sign in
-
-
Today I worked through a LeetCode problem involving Dynamic Programming. It’s true that we might not encounter this exact scenario in day-to-day work, but I find these exercises very useful for improving problem-solving skills and exploring different ways to approach a problem. Problem summary: You are given an m x n grid. Starting from the top-left corner, you can only move right or down. The goal is to find a path to the bottom-right corner such that the product of all visited cells is maximized (non-negative). If all possible results are negative, return -1. At first, I tried solving it using a tree + breadth-first traversal approach. It worked, but the time complexity was extremely high — not a scalable solution. After digging a bit more into Dynamic Programming, I took a step back and started sketching the problem on paper. By analyzing how each cell depends on its top and left neighbors, I realized I could store intermediate results in a separate matrix and build the solution bottom-up. One important lesson learned (the hard way 😄): 👉 I initially used int and spent quite some time debugging before realizing the issue was integer overflow. Switching to long fixed it. This was a great reminder of how powerful Dynamic Programming can be, especially when combined with careful thinking about edge cases like negative values and overflow. Always something new to learn 🚀 #programming #dotnet #algorithms #learning
To view or add a comment, sign in
-
-
🚀 Day 28/30 – 30 Days of Python Project Challenge Consistency builds skill. Skill builds confidence. 🚀 As part of my 30-day challenge, I’m focused on solving real-world problems while strengthening core development concepts. 🧠 Today’s Project: Video to Audio (MP3) Converter I built a Python-based media utility that allows users to quickly extract audio tracks from video files through a simple graphical interface. ✨ Why this project matters: This project bridges the gap between file management and media processing. It demonstrates how Python can automate tedious tasks—like converting formats—with just a few lines of code and a user-friendly file picker. ⚙️ Key Features: Native File Explorer: Uses Tkinter's filedialog to browse and select videos easily 📂 High-Quality Extraction: Preserves audio fidelity during the MP4 to MP3 transition 🎵 Resource Efficient: Automatically closes file streams to save memory 🔋 Instant Feedback: Console confirmation once the conversion is complete ✅ 💡 Concepts Applied: Media Processing with MoviePy OS Interactivity through Tkinter's GUI components Stream Management (opening/closing file handles) Error Handling for file selection and module dependencies Environment Configuration for Linux-based development 🔗 GitHub: https://lnkd.in/djsKiuE7 📌 Takeaway: Automation is at its best when it removes friction. Turning a multi-step manual conversion into a single-click script is what makes coding so rewarding. On to Day 29. 🔥 #Python #BuildInPublic #DeveloperJourney #30DaysOfCode #MoviePy #Tkinter #Automation #SoftwareDevelopment #Coding #Learning #OpenSource #Projects
To view or add a comment, sign in
-
The SOLID principles are five essential guidelines most powerful foundations for enhance software design. Let’s break it down 👇 🔹 S — Single Responsibility Principle (SRP) A class should have only one reason to change. Keep your code focused and modular. This principle states that "A class should have only one reason to change" which means every class should have a single responsibility and keep your code focused and modular or single purpose within the software system. 🔹 O — Open/Closed Principle (OCP) This principle states that software entities should be open for extension but closed for modification. which means you should be able to extend behavior without breaking existing code. 🔹 L — Liskov Substitution Principle (LSP) According to this principle, "derived or child classes must be able to replace their base or parent classes". This ensures that any subclass can be used in place of its parent class without 🔹 I — Interface Segregation Principle (ISP) Don’t force a class to implement interfaces it doesn’t use. Keep interfaces small and specific. 🔹 D — Dependency Inversion Principle (DIP) Depend on abstractions, Principle in object-oriented design that states that "High-level modules should not depend on low-level modules. Both should depend on abstractions". means "Big parts of your program should not directly depend on small, detailed parts. This improves flexibility and testability. #SOLIDPrinciples #CleanCode #SoftwareEngineering #Python #Django #BackendDevelopment #CodingBestPractices #SystemDesign #Developers #Programming
To view or add a comment, sign in
-
Just shipped a 25 category function test suite for Chuks programming language. One file. One golden output. Every way you can write a function in the language, exercised end-to-end. Here's what's covered: → All arrow forms: expression body, block body, zero-param, single-param → Named declarations, anonymous expressions, IIFEs → Default & optional parameters → Function type annotations and arrow type annotations in param/return positions → Higher-order functions: compose, factories, twice → Closures: counter pattern, multi-var capture, mutable shared state via getter/setter pairs → Nested functions: 2-level and 3-level deep → Recursion: fib, sumTo → Generic classes & methods: Box<T>, map<U>, Pair<A,B> → Async functions with await → Class methods: chaining, closures from methods, static → Functions in data structures: arrays and maps of functions → Callbacks: .map(), .filter(), .reduce() using all function styles → Currying: 3-level chain → Void functions, mixed parameter types, functions as arguments This isn't just a test suite, it's a living spec. If you want to understand what Chuks functions look like, this file is the answer. Follow ChuksLang on X for more: https://lnkd.in/egzWUUmR Visit chuks.org to try Chuks #ProgrammingLanguages #Compilers #softwareEngineering #Chukslang #programming
To view or add a comment, sign in
-
-
🚀 Day 10 of 100 Days LeetCode Challenge Problem: Find All Possible Stable Binary Arrays II Today’s problem is an extension of Day 9—but with optimized Dynamic Programming ⚡ 💡 Key Insight: Same constraints: Fixed number of 0s and 1s No more than limit consecutive identical elements 👉 Which means: We must carefully control streak length And efficiently count all valid combinations 🔍 Approach (Optimized DP): Use DP + Prefix Sum Optimization State includes: Count of 0s used Count of 1s used Ending with 0 or 1 💡 Optimization: Instead of recalculating ranges repeatedly, use prefix sums This reduces time complexity significantly 👉 Apply modulo (10⁹ + 7) for large answers 🔥 What I Learned Today: Same problem can have multiple levels of optimization Prefix sum is powerful in reducing DP transitions Moving from brute → DP → optimized DP is real growth 📈 📈 Challenge Progress: Day 10/100 ✅ Double digits achieved! LeetCode, Dynamic Programming, Prefix Sum, Optimization, Combinatorics, Binary Arrays, DSA Practice, Coding Challenge, Problem Solving #100DaysOfCode #LeetCode #DSA #CodingChallenge #DynamicProgramming #PrefixSum #Optimization #ProblemSolving #TechJourney #ProgrammerLife #SoftwareDeveloper #CodingLife #LearnToCode #Developers #Consistency #GrowthMindset #InterviewPrep
To view or add a comment, sign in
-
-
I would like to announce a new programming language, Real Futhark! It is entirely written in ancient norse runes. This is because programming is magic, software developers are wizards, and it's time we acted like it! Remember: It's only "Real Futhark" if it is hewn into rock by Vikings, otherwise it's just a sparkling polyglot, high-level, functional, data-parallel, serialization language. https://lnkd.in/dVe5WtdA #CheckTheDate
To view or add a comment, sign in
Explore related topics
Explore content categories
- Career
- Productivity
- Finance
- Soft Skills & Emotional Intelligence
- Project Management
- Education
- Technology
- Leadership
- Ecommerce
- User Experience
- Recruitment & HR
- Customer Experience
- Real Estate
- Marketing
- Sales
- Retail & Merchandising
- Science
- Supply Chain Management
- Future Of Work
- Consulting
- Writing
- Economics
- Artificial Intelligence
- Employee Experience
- Workplace Trends
- Fundraising
- Networking
- Corporate Social Responsibility
- Negotiation
- Communication
- Engineering
- Hospitality & Tourism
- Business Strategy
- Change Management
- Organizational Culture
- Design
- Innovation
- Event Planning
- Training & Development