Top 5 DSA Patterns I Used to Crack LeetCode Challenges

After solving 1000+ problems on LeetCode and CodeForces and reaching a max rating of 1810 on Leetcode, I noticed that most problems fall into repeatable patterns. Here are the 5 that helped me the most.


🔥 Why Patterns Matter

When I started DSA, I used to solve problems randomly. But things changed when I began spotting repeatable problem patterns. Once you master a pattern, you can apply it to dozens of problems — it’s like unlocking a cheat code in LeetCode.


🔁 1. Sliding Window

This pattern is a game-changer for problems involving subarrays, strings, or windows of size k.

When to Use: You need to find max/min/average in a window, or the longest/shortest substring with some condition.

// LeetCode 3: Longest Substring Without Repeating Characters
int lengthOfLongestSubstring(string s) {
    unordered_set<char> seen;
    int left = 0, right = 0, maxLen = 0;
    while (right < s.length()) {
        if (seen.find(s[right]) == seen.end()) {
            seen.insert(s[right++]);
            maxLen = max(maxLen, right - left);
        } else {
            seen.erase(s[left++]);
        }
    }
    return maxLen;
}

📊 2. Prefix Sum / Difference Array

Prefix sum is my go-to for range sum queries or subarray comparisons.

Example Problems:

  • Range Sum Query (LeetCode 303)
  • Subarray Sum Equals K (LeetCode 560)
// LeetCode 560: Subarray Sum Equals K
int subarraySum(vector<int>& nums, int k) {
    unordered_map<int, int> prefix;
    prefix[0] = 1;
    int sum = 0, count = 0;
    for (int num : nums) {
        sum += num;
        if (prefix.count(sum - k)) count += prefix[sum - k];
        prefix[sum]++;
    }
    return count;
}

🔄 3. Two Pointers

Two pointers are great for sorted arrays or problems involving distances, duplicates, or merging.

Where I Used It: Merge intervals, remove duplicates, 3Sum, container with most water.

// LeetCode 167: Two Sum II - Input Array Is Sorted
int twoSum(vector<int>& nums, int target) {
    int left = 0, right = nums.size() - 1;
    while (left < right) {
        int sum = nums[left] + nums[right];
        if (sum == target) return {left + 1, right + 1};
        else if (sum < target) left++;
        else right--;
    }
    return {};
}

🧠 4. Binary Search (Classic + Variations)

This isn’t just for searching in arrays. I used binary search for finding answers in range-based problems or minimizing/maximizing functions.

Example Applications:

  • Search in Rotated Sorted Array
  • Koko Eating Bananas (Search on answer)
  • Median of Two Sorted Arrays

🌳 5. DFS + Backtracking

Used heavily in recursion-based problems: permutations, subsets, N-Queens, Sudoku Solver, etc.

// LeetCode 46: Permutations
void backtrack(vector<int>& nums, vector<bool>& used, vector<int>& path, vector<vector<int>>& res) {
    if (path.size() == nums.size()) {
        res.push_back(path);
        return;
    }
    for (int i = 0; i < nums.size(); ++i) {
        if (used[i]) continue;
        used[i] = true;
        path.push_back(nums[i]);
        backtrack(nums, used, path, res);
        path.pop_back();
        used[i] = false;
    }
}

vector<vector<int>> permute(vector<int>& nums) {
    vector<vector<int>> res;
    vector<int> path;
    vector<bool> used(nums.size(), false);
    backtrack(nums, used, path, res);
    return res;
}

📚 Final Thoughts

Once I recognized patterns in LeetCode problems, I stopped feeling stuck. I wasn’t guessing — I was mapping problems to strategies I already understood.

My tip: Don’t just solve problems. Group them by patterns, master those patterns, and apply them like tools in a toolkit.


💻 My LeetCode: leetcode.com/u/rhythm_21
👨‍💻 GitHub: github.com/rhythm217
📲 Connect: LinkedIn

Comments

Post a Comment

Popular Posts