🚀 LeetCode 207 – Course Schedule | From Multiple Approaches → Cleaner Thinking While working on graph problems, I revisited Course Schedule and explored multiple implementations in Java — not just to solve it, but to understand why each approach works. 🔍 Core Idea Courses + prerequisites → Directed Graph Goal → Check if graph has a cycle 👉 If cycle exists → ❌ cannot finish all courses 👉 If no cycle → ✅ valid ordering exists (DAG) 💡 Approach 1: BFS (Kahn’s Algorithm) Build graph + compute in-degree Process nodes with in-degree = 0 Count processed nodes ✔ Intuitive (layer-by-layer removal) ✔ Great for topological sorting ❗ Slight overhead (separate passes) 💡 Approach 2: DFS (Visited + Recursion Stack) Track visited[] and recStack[] Detect back-edge → cycle ✔ Strong conceptual clarity ✔ Useful for many graph problems ❗ Extra space for 2 arrays 💡 Approach 3: Optimized BFS (Single Pass) ⭐ Build graph + in-degree together Use ArrayDeque for performance No extra passes ✔ Cleaner ✔ More efficient in practice ✔ Interview-friendly 💡 Approach 4: DFS with State Array (Latest Submission) 🔥 // 0 = unvisited, 1 = visiting, 2 = visited Replace visited[] + recStack[] with single state[] Detect cycle when visiting a node already in state = 1 ✔ Same time complexity → O(V + E) ✔ Reduced space usage ✔ Cleaner logic (less bookkeeping) 🔥 What Changed My Understanding Same problem. Same complexity. But different implementations gave me: Better control over graph traversal patterns Clear understanding of cycle detection Ability to optimize space without changing logic 📌 Takeaway Don’t stop at “Accepted” ✅ Push further: Try another approach Optimize space or structure Compare trade-offs That’s where real growth happens. #Java #DSA #Graphs #LeetCode #TopologicalSort #BackendDevelopment #LearningInPublic
Course Schedule LeetCode Solution with Multiple Approaches
More Relevant Posts
-
Day 7/30 – Encapsulation and Graph Safety States Day 7 of the challenge focused on strengthening OOP fundamentals and solving another important graph problem. Today’s learning was about writing secure, maintainable code through encapsulation and understanding reverse graph logic in DSA. MERN / OOP Concepts – Encapsulation Today I learned about Encapsulation, one of the core pillars of Object Oriented Programming. What is Encapsulation: • Binding data and methods together inside a single unit (class) • Restricting direct access to object data using access modifiers How it works: • Variables are usually marked as private • Public getter and setter methods are used to access or update values safely Why it matters: • Protects data from unwanted modification • Improves code security and maintainability • Gives better control over how data is handled Real world example: • A bank account balance should not be modified directly • It should only change through deposit or withdraw methods Key takeaway: • Encapsulation is about data hiding and controlled access DSA – Find Eventual Safe States Today I solved Find Eventual Safe States, a graph problem based on cycles and topological sorting. Approach: • Reverse all graph edges • Calculate outdegree of each node • Nodes with outdegree 0 are terminal nodes and considered safe • Add them to queue • Process using BFS and reduce outdegree of connected nodes • Nodes that become outdegree 0 are also safe Key insight: • Nodes leading to cycles are unsafe • Nodes eventually reaching terminal nodes are safe Why reverse graph helps: • Makes it easier to process dependencies backward Time Complexity: O(V + E) Space Complexity: O(V + E) Takeaways • Encapsulation helps build clean and secure object-oriented code • Controlled access to data prevents many bugs • Graph problems often become easier after reversing perspective • Topological thinking is useful beyond DAG problems Day 7 completed. One more day of consistency, one more step of growth. #30DaysChallenge #OOP #Encapsulation #Java #DSA #Graphs #TopologicalSort #Consistency #LearningInPublic
To view or add a comment, sign in
-
-
🚀 Day 88 — Prefix Sum Pattern (Pivot Index) Continuing the prefix sum journey — today I solved a problem that finds the equilibrium point where the sum of elements to the left equals the sum to the right. This is a great example of optimizing space using simple math. 📌 Problem Solved: LeetCode 724 – Find Pivot Index 🧠 Optimized Approach – Single Pass with Total Sum: java int total = 0, leftSum = 0; for (int num : nums) total += num; for (int i = 0; i < nums.length; i++) { // rightSum = total - leftSum - nums[i] if (leftSum == total - leftSum - nums[i]) return i; leftSum += nums[i]; } return -1; Why this works: total = sum of all elements. At index i, rightSum = total - leftSum - nums[i]. No need to store prefix/suffix arrays — just update leftSum as we go. Space complexity drops from O(n) to O(1). Key Insight from Revision: Earlier we discussed the Pivot Index optimization using the relationship: Total Sum = Left Sum + arr[i] + Right Sum → Right Sum = Total Sum - Left Sum - arr[i] This eliminates extra arrays. Edge Cases: Pivot at index 0 → left sum = 0. Pivot at last index → right sum = 0. No pivot → return -1. 💡 Takeaway: Not every prefix sum problem needs extra arrays. Recognizing when you can derive one side from the total sum and the other side saves space and simplifies code. No guilt about past breaks — just mastering optimizations within patterns. #DSA #PrefixSum #PivotIndex #LeetCode724 #CodingJourney #Revision #Java #ProblemSolving #Consistency #GrowthMindset #TechCommunity #LearningInPublic
To view or add a comment, sign in
-
Day 111: DSU, Graphs, and Hamming Distances 🧠⚡ Problem 1722: Minimize Hamming Distance After Swap Operations Today was a massive step up. I moved beyond simple pointers and dove into Disjoint Set Union (DSU) to solve a complex graph-based problem. The Strategy: • The Swap Logic: Since allowedSwaps can be chained, any indices in the same connected component can be rearranged freely. • Disjoint Set Union: I used DSU to group these indices. If index A can swap with B, and B with C, then {A, B, C} form a component where any value can move to any position. • Frequency Tracking: For each connected component, I used a nested HashMap to track the available numbers from the source. • Calculating the Distance: For each position, I checked if the target value existed in its component's pool. If not, the Hamming distance increased. The Java vs. C++ Choice: I actually tried implementing this in C++ first, but the time complexity turned out to be higher than expected for this specific logic. To ensure the most efficient O(N⋅α(N)) performance and clear the tight test cases, I stuck with Java for today’s solve. Day 111 in the books. Sometimes choosing the right tool for the specific problem is the most important engineering decision you can make. 🚀 #LeetCode #Java #DSU #Graphs #Algorithms #ProblemSolving #DailyCode
To view or add a comment, sign in
-
-
#CodeEveryday — My DSA Journey | Day 2 🧩 Problem Solved: Combination Sum II (LeetCode) 💭 What I Learned: Used backtracking to generate all unique combinations whose sum equals the target. Sorted the array initially to efficiently handle duplicates and enable pruning. At each step: ✔️ Skipped duplicate elements using i > n && nums[i] == nums[i-1] ✔️ Stopped recursion early when the current element exceeded the target ✔️ Moved to the next index (i+1) to avoid reusing elements Strengthened my understanding of handling duplicates in recursion and optimizing search space. ⏱ Time Complexity: O(2ⁿ)*k (k is avg length of each combination) 🧠 Space Complexity: O(n) ⚡ Key Takeaways: ✔️ Sorting helps in both pruning and duplicate handling ✔️ Skipping duplicates is crucial for unique combinations ✔️ Backtracking becomes efficient with early stopping conditions 💻 Language Used: Java ☕ 📘 Concepts: Backtracking · Recursion · Arrays · Duplicate Handling · Pruning #CodeEveryday #DSA #LeetCode #Java #Backtracking #ProblemSolving #Algorithms #CodingJourney #Consistency 🚀
To view or add a comment, sign in
-
-
🚀 DAY 105/150 — NAVIGATING FILE SYSTEM LOGS! 📂🧭 Day 105 of my 150 Days DSA Challenge in Java and today I solved a problem based on stack simulation and directory navigation 💻🧠 📌 Problem Solved: Crawler Log Folder 📌 LeetCode: #1598 📌 Difficulty: Easy 🔹 Problem Insight The task is to determine the minimum number of operations needed to go back to the main folder after performing a series of folder operations. 👉 Operations include: • "../" → move to parent folder • "./" → stay in current folder • "x/" → move into a child folder 🔹 Approach Used I used a Stack-based simulation (or counter optimization): ✅ Stack Approach: • Push folder names when moving into a directory • Pop when encountering "../" • Ignore "./" ✅ Optimized Approach (Counter): • Maintain a variable depth • "x/" → depth++ • "../" → depth-- (only if > 0) • "./" → ignore ✔️ Final depth = minimum steps to return ⏱ Complexity Time Complexity: O(n) Space Complexity: • Stack → O(n) • Optimized → O(1) 🧠 What I Learned • Simulation problems can often be optimized using simple counters • Stack helps visualize hierarchy (like folders) • Edge case: cannot go above root directory 💡 Key Takeaway This problem taught me: How to simulate file system operations How to optimize stack-based solutions Importance of handling boundary conditions 🌱 Learning Insight Now I’m getting better at: 👉 Identifying when to use stack vs simple variables 👉 Writing clean and efficient logic 🚀 ✅ Day 105 completed 🚀 45 days to go 🔗 Java Solution on GitHub: 👉 https://lnkd.in/eadhHjNW 💡 Simplify the process, and the solution becomes obvious. #DSAChallenge #Java #LeetCode #Stack #Simulation #DataStructures #150DaysOfCode #ProblemSolving #CodingJourney #InterviewPrep #LearningInPublic
To view or add a comment, sign in
-
-
📅 Day 46/100 – LeetCode DSA Challenge 🧩 Problem: Longest Continuous Increasing Subsequence (674) 💡 Problem Summary Find the length of the longest continuous strictly increasing subarray. The sequence must be continuous, not just increasing elements from anywhere. 💡 My Approach I solved this problem by comparing each element with its next element: Initialized: count = 1 → current increasing sequence max = 1 → maximum length Traversed the array till n-1 to safely check nums[i+1] If nums[i] < nums[i+1] → increment count Else → reset count = 1 Continuously updated max using Math.max() This approach ensures we only consider continuous increasing sequences. 🧾 Code: class Solution { public int findLengthOfLCIS(int[] nums) { if(nums.length == 0) return 0; int count = 1; int max = 1; for(int i = 0; i < nums.length - 1; i++) { if(nums[i] < nums[i+1]) { count++; max = Math.max(count, max); } else { count = 1; } } return max; } } 📚 What I Learned How to safely use i+1 by controlling loop boundary Importance of handling edge cases (nums.length == 0) Difference between continuous vs non-continuous sequences Greedy approach for tracking subarray length Writing optimized O(n) solutions 🚀 Small improvements every day lead to big results! #Day46 #100DaysOfCode #LeetCode #DSA #Java #CodingJourney #ProblemSolving
To view or add a comment, sign in
-
-
Problem :- Remove Duplicates from Sorted Array (LeetCode 26) Problem Statement :- Given an integer array nums sorted in non-decreasing order, remove the duplicates in-place such that each unique element appears only once. Return the number of unique elements. The relative order of elements should be kept the same. Approach :- Two Pointer Technique i - Use pointer k to track position of unique elements ii - Traverse array from index 1 iii - If nums[i] != nums[k-1], place it at nums[k] iv - Time Complexity : O(n) v - Space Complexity : O(1) class Solution { public int removeDuplicates(int[] nums) { int k = 1; for(int i = 1; i < nums.length; i++) { if(nums[i] != nums[k - 1]) { nums[k] = nums[i]; k++; } } return k; } } Key Takeaway :- Since the array is already sorted, duplicates are adjacent. Using two pointers allows us to efficiently overwrite duplicates in a single pass without extra space. If yes, how would you optimize this further? #Java #DSA #LeetCode #CodingJourney #LearnInPublic #SoftwareEngineering #TwoPointers
To view or add a comment, sign in
-
-
🚀 Day 86 — Prefix Sum Pattern (Introduction) Today I started learning the Prefix Sum pattern — a fundamental technique for array problems where decisions at a given index depend on the sum of previous elements. Unlike sliding window, prefix sum handles negative numbers gracefully. 📌 What is Prefix Sum? At index i, the prefix sum is the sum of all elements from the start up to i-1. It stores “historical information” to make efficient decisions. 🧠 Why Prefix Sum > Sliding Window for Negatives? Sliding window fails with negatives because removing a negative actually increases the sum — breaking the logic of expanding/shrinking. Prefix sum remains effective. 📊 Four Categories of Prefix Sum Problems: 1️⃣ Left‑Right Comparisons (e.g., Pivot Index) → Can often be solved with simple variables (no extra arrays). 2️⃣ Exact Sums (Subarray Sum = K) → Requires a HashMap to store and lookup previous prefix sums. 3️⃣ Shortest Window with Sum ≥ K (with negatives) → Needs a Deque (double‑ended queue). 4️⃣ Range Sum Queries → Advanced techniques like Merge Sort on prefix array. 🔧 General Template: Initialize data structure (variable, array, or HashMap). Loop through the array, updating prefix information. Check problem‑specific condition. ⚡ Optimization Insight (Pivot Index Example): Instead of storing both prefix and suffix arrays, use: Total Sum = Left Sum + arr[i] + Right Sum → Right Sum = Total Sum - Left Sum - arr[i] This finds the pivot using only O(1) space. 💡 Takeaway: Prefix sum is a pattern, not just an algorithm. Recognizing when to use it — especially with negative numbers — unlocks efficient solutions for subarray sum problems. No guilt about past breaks — just adding another powerful pattern to the toolkit. #DSA #PrefixSum #ArrayPatterns #CodingJourney #Revision #Java #ProblemSolving #Consistency #GrowthMindset #TechCommunity #LearningInPublic
To view or add a comment, sign in
-
𝐃𝐚𝐲 𝟓𝟕 – 𝐃𝐒𝐀 𝐉𝐨𝐮𝐫𝐧𝐞𝐲 | 𝐀𝐫𝐫𝐚𝐲𝐬 🚀 Today’s problem focused on finding the maximum gap between consecutive elements in sorted order — without actually sorting. 𝐏𝐫𝐨𝐛𝐥𝐞𝐦 𝐒𝐨𝐥𝐯𝐞𝐝 • Maximum Gap 𝐀𝐩𝐩𝐫𝐨𝐚𝐜𝐡 – 𝐁𝐮𝐜𝐤𝐞𝐭 𝐒𝐨𝐫𝐭 𝐈𝐝𝐞𝐚 • Found global minimum and maximum • Calculated minimum possible gap using: gap = ceil((max − min) / (n − 1)) • Created buckets to store min and max values • Placed elements into buckets based on their range • Final answer comes from the gap between buckets, not inside them 𝐊𝐞𝐲 𝐋𝐞𝐚𝐫𝐧𝐢𝐧𝐠𝐬 • Sorting is not always required to find ordered differences • Bucket strategy helps achieve linear time • Maximum gap always lies between buckets, not within • Mathematical insights (pigeonhole principle) guide optimization 𝐂𝐨𝐦𝐩𝐥𝐞𝐱𝐢𝐭𝐲 • Time: O(n) • Space: O(n) 𝐓𝐚𝐤𝐞𝐚𝐰𝐚𝐲 Sometimes the problem is not about sorting — but about understanding how elements are distributed. 57 days consistent 🚀 On to Day 58. #DSA #Arrays #BucketSort #LeetCode #Java #ProblemSolving #DailyCoding #LearningInPublic #SoftwareDeveloper
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
Great insights 💡 This made things easier to understand!”