Algorithmic Problem Solving in Java — The LeetCode Playbook
LeetCode-এর জন্য Java — প্যাটার্ন ভিত্তিক চিন্তা
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.
2. Java's Competitive Toolbox
| Need | Use | Why |
|---|---|---|
| Fast input | BufferedReader | 10× faster than Scanner for big inputs. |
| Dynamic array | ArrayList | O(1) amortised add, random access. |
| Map / Set | HashMap / HashSet | O(1) average lookup. |
| Min/Max heap | PriorityQueue | O(log n) insert/poll. |
| Double-ended queue | ArrayDeque | Faster than LinkedList for stack/queue. |
| Sorted map/set | TreeMap / TreeSet | Ordered, O(log n) ops, floor/ceiling. |
HashMap, PriorityQueue, ArrayDeque। এগুলোর API মুখস্থ রাখুন।
3. The Pattern Map
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.
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.
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.
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
| Term | Meaning | বাংলায় |
|---|---|---|
| Big-O | Asymptotic upper bound on work. | Asymptotic upper bound। |
| Amortized | Average cost over many operations. | অনেক call-এর গড় খরচ। |
| Invariant | A condition preserved by each loop step. | প্রতি loop step-এ অক্ষুণ্ণ শর্ত। |
| Memoization | Top-down DP: cache recursive calls. | Top-down DP — cache। |
| Tabulation | Bottom-up DP: fill a table iteratively. | Bottom-up DP — table ভরা। |
| Backtracking | DFS that undoes choices on failure. | DFS যা ভুল হলে step undo করে। |
8. Pattern-Based Practice Problems
Each problem targets one pattern. Try first, then reveal.
-
Two Pointers: given a sorted
int[], remove duplicates in-place and return the new length.Two Pointers: sorted array থেকে duplicates সরিয়ে নতুন length ফেরান।✨ Show Answer
Main.javaclass 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] + " "); } } -
Sliding Window: longest substring with at most 2 distinct characters.Sliding Window: সবচেয়ে দীর্ঘ substring যাতে ২টির বেশি distinct character নেই।
✨ Show Answer
Main.javaimport 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 } } -
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.javaimport 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)); } } -
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.javaimport 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 } } -
DP: climb N stairs, one or two steps at a time — number of ways.DP: N সিঁড়ি, এক বা দুই ধাপে — মোট কতভাবে উঠা যায়?
✨ Show Answer
Main.javaclass 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.
java.util এইসব কাজের জন্য world-class data structure বিনামূল্যে দেয়।