Algorithmic Problem Solving in Java — The LeetCode Playbook

LeetCode-এর জন্য Java — প্যাটার্ন ভিত্তিক চিন্তা

Read: ~50 min Advanced 5 pattern problems Live code runner

1. Patterns Beat Memorisation

There are thousands of problems on LeetCode but only a handful of patterns. Master six or seven — two pointers, sliding window, BFS/DFS, heap (priority queue), binary search, dynamic programming — and you will recognise most interview problems on sight. Java's Collections and java.util give you excellent tools for every one of them.

LeetCode-এ হাজারো problem থাকলেও pattern আসলে অল্প কয়েকটি। ৬–৭টি pattern (two pointers, sliding window, BFS/DFS, priority queue, binary search, dynamic programming) ভালোভাবে শিখলে বেশির ভাগ interview problem চিনতে পারবেন। Java-র Collections API এই সবের জন্য উপযুক্ত টুল দেয়।

2. Java's Competitive Toolbox

NeedUseWhy
Fast inputBufferedReader10× faster than Scanner for big inputs.
Dynamic arrayArrayListO(1) amortised add, random access.
Map / SetHashMap / HashSetO(1) average lookup.
Min/Max heapPriorityQueueO(log n) insert/poll.
Double-ended queueArrayDequeFaster than LinkedList for stack/queue.
Sorted map/setTreeMap / TreeSetOrdered, O(log n) ops, floor/ceiling.
Interview-এ সবচেয়ে বেশি লাগে — HashMap, PriorityQueue, ArrayDeque। এগুলোর API মুখস্থ রাখুন।

3. The Pattern Map

Which Pattern? · A Quick Decision Map Sorted array? → Two Pointers or Binary Search Subarray / window? → Sliding Window fixed or variable Graph / grid? → BFS / DFS Queue / Stack / recursion Top K / streaming? → PriorityQueue min- or max-heap Optimal substructure? → Dynamic Programming memoize or tabulate Pairs / triples in array? → Sort + Two Pointers or HashMap complement Figure 49.1 — সমস্যার প্রকৃতি বুঝে pattern বেছে নিন।

4. Two Pointers & Sliding Window

Two pointers walk an array from both ends (or same end, different speeds) to reduce O(n²) pair problems to O(n). The sliding window is a special two-pointer shape — both pointers move forward, maintaining an invariant.

Two pointers — দুই পাশ থেকে বা একই দিকে ভিন্ন গতিতে চলে O(n²) সমস্যাকে O(n) বানায়। Sliding window দুই pointer-ই সামনে এগোয়, একটি invariant ধরে।
Main.java
class Main {
    // Two Pointers: given sorted array, find pair summing to target.
    static int[] twoSumSorted(int[] a, int target) {
        int l = 0, r = a.length - 1;
        while (l < r) {
            int s = a[l] + a[r];
            if (s == target) return new int[]{l, r};
            if (s < target) l++; else r--;
        }
        return new int[0];
    }

    // Sliding Window: longest subarray with sum <= S (non-negative ints).
    static int longestWindow(int[] a, int S) {
        int left = 0, sum = 0, best = 0;
        for (int right = 0; right < a.length; right++) {
            sum += a[right];
            while (sum > S) sum -= a[left++];
            best = Math.max(best, right - left + 1);
        }
        return best;
    }

    public static void main(String[] args) {
        int[] arr = { 1, 3, 4, 5, 7, 11 };
        int[] pair = twoSumSorted(arr, 9);
        System.out.println("pair idx: " + pair[0] + "," + pair[1]);
        System.out.println("longest window (sum<=10): " + longestWindow(arr, 10));
    }
}

5. BFS & Priority Queue — Graphs and Top-K

BFS walks a graph level by level using a queue; it finds shortest paths in unweighted graphs. A PriorityQueue is a heap — perfect for top-K problems, Dijkstra, and event scheduling.

BFS queue দিয়ে graph-এ level-by-level যায় — unweighted graph-এ shortest path পায়। PriorityQueue (heap) top-K, Dijkstra, event scheduling-এ আদর্শ।
Main.java
import java.util.*;

class Main {
    // BFS on an adjacency-list graph — return shortest distance from src to dst.
    static int bfs(Map<Integer, List<Integer>> g, int src, int dst) {
        Deque<int[]> q = new ArrayDeque<>();
        Set<Integer> seen = new HashSet<>();
        q.add(new int[]{src, 0}); seen.add(src);
        while (!q.isEmpty()) {
            int[] cur = q.poll();
            if (cur[0] == dst) return cur[1];
            for (int nb : g.getOrDefault(cur[0], List.of())) {
                if (seen.add(nb)) q.add(new int[]{nb, cur[1] + 1});
            }
        }
        return -1;
    }

    // Top-K: given numbers, return the 3 largest using a MIN-heap of size 3.
    static List<Integer> topK(int[] nums, int k) {
        PriorityQueue<Integer> heap = new PriorityQueue<>();
        for (int n : nums) {
            heap.offer(n);
            if (heap.size() > k) heap.poll();
        }
        return new ArrayList<>(heap);
    }

    public static void main(String[] args) {
        Map<Integer, List<Integer>> g = new HashMap<>();
        g.put(1, List.of(2, 3));
        g.put(2, List.of(4));
        g.put(3, List.of(4, 5));
        g.put(4, List.of(5));
        System.out.println("shortest 1->5: " + bfs(g, 1, 5));

        System.out.println("top 3: " + topK(new int[]{3, 1, 5, 12, 2, 11, 7}, 3));
    }
}

6. Dynamic Programming — Remember What You've Computed

DP is recursion plus a cache. Write the naive recursion first, then memoize identical subproblems. Fibonacci is the canonical starting example — O(2n) without DP, O(n) with.

DP মানে recursion + cache। আগে naive recursion লিখুন, তারপর একই subproblem memoize করুন। Fibonacci classic — DP ছাড়া O(2ⁿ), DP-সহ O(n)।
Main.java
class Main {
    // Bottom-up DP — House Robber in O(n) time, O(1) space.
    static int rob(int[] nums) {
        int prev = 0, curr = 0;
        for (int n : nums) {
            int take = prev + n;
            int skip = curr;
            prev = curr;
            curr = Math.max(take, skip);
        }
        return curr;
    }

    public static void main(String[] args) {
        int[] houses = { 2, 7, 9, 3, 1 };
        System.out.println("max loot = " + rob(houses));   // 2 + 9 + 1 = 12
    }
}

7. Vocabulary

TermMeaningবাংলায়
Big-OAsymptotic upper bound on work.Asymptotic upper bound।
AmortizedAverage cost over many operations.অনেক call-এর গড় খরচ।
InvariantA condition preserved by each loop step.প্রতি loop step-এ অক্ষুণ্ণ শর্ত।
MemoizationTop-down DP: cache recursive calls.Top-down DP — cache।
TabulationBottom-up DP: fill a table iteratively.Bottom-up DP — table ভরা।
BacktrackingDFS that undoes choices on failure.DFS যা ভুল হলে step undo করে।

8. Pattern-Based Practice Problems

Each problem targets one pattern. Try first, then reveal.

  1. Two Pointers: given a sorted int[], remove duplicates in-place and return the new length.
    Two Pointers: sorted array থেকে duplicates সরিয়ে নতুন length ফেরান।
    ✨ Show Answer
    Main.java
    class Main {
        static int dedupe(int[] a) {
            if (a.length == 0) return 0;
            int slow = 0;
            for (int fast = 1; fast < a.length; fast++) {
                if (a[fast] != a[slow]) a[++slow] = a[fast];
            }
            return slow + 1;
        }
        public static void main(String[] args) {
            int[] a = {1,1,2,2,3,4,4,5};
            int n = dedupe(a);
            for (int i = 0; i < n; i++) System.out.print(a[i] + " ");
        }
    }
  2. Sliding Window: longest substring with at most 2 distinct characters.
    Sliding Window: সবচেয়ে দীর্ঘ substring যাতে ২টির বেশি distinct character নেই।
    ✨ Show Answer
    Main.java
    import java.util.*;
    
    class Main {
        static int longest2Distinct(String s) {
            Map<Character, Integer> cnt = new HashMap<>();
            int l = 0, best = 0;
            for (int r = 0; r < s.length(); r++) {
                cnt.merge(s.charAt(r), 1, Integer::sum);
                while (cnt.size() > 2) {
                    char c = s.charAt(l++);
                    if (cnt.merge(c, -1, Integer::sum) == 0) cnt.remove(c);
                }
                best = Math.max(best, r - l + 1);
            }
            return best;
        }
        public static void main(String[] args) {
            System.out.println(longest2Distinct("eceba"));  // 3
            System.out.println(longest2Distinct("ccaabbb")); // 5
        }
    }
  3. BFS: count islands in a 2D grid of 0/1. An island is a connected region of 1s (4-directional).
    BFS: 0/1 grid-এ কতগুলো island আছে গণনা করুন (4-direction)।
    ✨ Show Answer
    Main.java
    import java.util.*;
    
    class Main {
        static int numIslands(int[][] g) {
            int rows = g.length, cols = g[0].length, count = 0;
            int[][] dirs = {{1,0},{-1,0},{0,1},{0,-1}};
            for (int i = 0; i < rows; i++)
                for (int j = 0; j < cols; j++)
                    if (g[i][j] == 1) {
                        count++;
                        Deque<int[]> q = new ArrayDeque<>();
                        q.add(new int[]{i, j}); g[i][j] = 0;
                        while (!q.isEmpty()) {
                            int[] c = q.poll();
                            for (int[] d : dirs) {
                                int ni = c[0] + d[0], nj = c[1] + d[1];
                                if (ni >= 0 && nj >= 0 && ni < rows && nj < cols && g[ni][nj] == 1) {
                                    g[ni][nj] = 0;
                                    q.add(new int[]{ni, nj});
                                }
                            }
                        }
                    }
            return count;
        }
        public static void main(String[] args) {
            int[][] g = {{1,1,0,0},{0,1,0,1},{0,0,0,1}};
            System.out.println("islands = " + numIslands(g));
        }
    }
  4. Heap: k-th largest element in an unsorted array using a min-heap of size k.
    Heap: unsorted array-এ k-তম বৃহত্তম element — size-k min-heap দিয়ে।
    ✨ Show Answer
    Main.java
    import java.util.PriorityQueue;
    
    class Main {
        static int kthLargest(int[] nums, int k) {
            PriorityQueue<Integer> min = new PriorityQueue<>();
            for (int n : nums) {
                min.offer(n);
                if (min.size() > k) min.poll();
            }
            return min.peek();
        }
        public static void main(String[] args) {
            System.out.println(kthLargest(new int[]{3,2,1,5,6,4}, 2)); // 5
        }
    }
  5. DP: climb N stairs, one or two steps at a time — number of ways.
    DP: N সিঁড়ি, এক বা দুই ধাপে — মোট কতভাবে উঠা যায়?
    ✨ Show Answer
    Main.java
    class Main {
        static int climbStairs(int n) {
            if (n <= 2) return n;
            int a = 1, b = 2;
            for (int i = 3; i <= n; i++) { int c = a + b; a = b; b = c; }
            return b;
        }
        public static void main(String[] args) {
            for (int n = 1; n <= 10; n++) System.out.println(n + " -> " + climbStairs(n));
        }
    }

Summary — Module 49

LeetCode is not about memorising problems; it is about recognising patterns. Master two pointers, sliding window, BFS/DFS, heap, and DP, and most interview questions collapse into familiar shapes. Java's java.util — ArrayDeque, HashMap, PriorityQueue, TreeMap — gives you world-class data structures for free.

LeetCode মুখস্থ করার বিষয় নয়, pattern চেনার বিষয়। Two pointers, sliding window, BFS/DFS, heap, DP — এই কয়েকটি শিখলেই বেশিরভাগ interview question পরিচিত লাগবে। Java-র java.util এইসব কাজের জন্য world-class data structure বিনামূল্যে দেয়।

Next Module → Capstone — একটি সম্পূর্ণ production-grade Java project।