CRED Previous Year Coding Questions

CRED is a members-only fintech platform best known for its credit card bill payment app and CRED Coins rewards system. It hires SDE-1, SDE-2, and Backend Engineers through campus drives, off-campus applications, and internships, primarily for its Bangalore engineering teams. Unlike interviews that lean heavily on LeetCode grinding, CRED evaluates how you actually build things: clean code, extensible architecture, and real-world design thinking set candidates apart as much as raw DSA speed. The Machine Coding round is the single most CRED-specific round and the one that separates most candidates, while the System Design round leans specifically into fintech concerns like idempotency and data de-duplication rather than generic scale questions.


Hiring Process

Step 1: Resume Screening CRED shortlists based on relevant projects, prior internship experience, and (for some roles) a short take-home assignment shared within 24 hours of application.

Step 2: Online Assessment (for campus/bulk roles) Around 105 minutes on a proctored platform such as HackerRank, with 3 DSA-based coding questions. For some experienced tracks, this is replaced by 5 MCQs, 2 coding questions, and 2 database-related questions instead.

Step 3: DSA & Puzzles Round Roughly 1.5 hours, mostly Medium-difficulty problems with an emphasis on Arrays and Strings, plus logic puzzles. Some candidates report coding directly in a shared Google Doc instead of an IDE, so clearly explaining your approach out loud matters as much as the code itself.

Step 4: Machine Coding / LLD Round The most CRED-specific round. You are given a product requirement (Contact Management System is the most frequently reported) and 1.5–2 hours (sometimes a 24-hour take-home with a design document, where AI tool usage is explicitly allowed) to implement it with good OOP design, SOLID principles, and error handling, using in-memory data structures rather than a real database, verified with your own unit tests.

Step 5: System Design + Managerial Round Often conducted directly with the Head of Engineering. CRED's system design questions are pointedly fintech-flavoured: schema design, idempotency of payment operations, data de-duplication, failure/retry handling, and designing systems that operate safely at CRED's transaction scale.

Step 6: HR / Culture Fit Round A conversation about your background, why CRED, and compensation expectations.

Tips: Practice explaining your DSA approach out loud and on paper/doc, not just in an IDE, since some rounds are deliberately IDE-free. For the Machine Coding round, a clean, fully-working Contact Management System (add/update contact, search by name or number, case-insensitive partial match) built with no external libraries is the single highest-leverage thing you can prepare. For System Design, think specifically about idempotency keys and de-duplication whenever payments or transactions come up, that lens is what CRED interviewers are listening for.


Preparation Resources

Part 1 — OA Questions

1. Maximum Swap Medium

OA Array · Greedy LeetCode:{' '} #670

One of the most frequently reported CRED OA questions. Given a non-negative integer, you may swap two digits at most once. Return the maximum valued number you can get.

Input: num = 2736
Output: 7236

Input: num = 9973
Output: 9973

Approach: Convert the number to a digit array. For each position from left to right, find the largest digit occurring later in the array. If that digit is larger than the current one, swap the last occurrence of that largest digit into the current position and stop. Complexity: Time O(n) · Space O(n) Follow-up: What if you are allowed up to K swaps instead of just one?


2. Is Subsequence Easy

OA Two Pointers · String LeetCode:{' '} #392

Given two strings s and t, return true if s is a subsequence of t (characters of s appear in t in the same relative order, not necessarily contiguous).

Input: s = "abc", t = "ahbgdc"
Output: true

Input: s = "axc", t = "ahbgdc"
Output: false

Approach: Two pointers, one for each string. Advance the t-pointer always; advance the s-pointer only when characters match. s is a subsequence if the s-pointer reaches the end of s. Complexity: Time O(n) · Space O(1) Follow-up: What if there are millions of incoming s strings to check against the same t? (Precompute a next-occurrence table for binary search.)


3. Open the Lock Medium

OA BFS · Graph LeetCode:{' '} #752

A 4-wheel lock starts at '0000'. Given a list of deadend combinations and a target, return the minimum number of turns to reach the target, or -1 if impossible.

Input: deadends = ["0201","0101","0102","1212","2002"], target = "0202"
Output: 6

Approach: BFS over the state space of all 4-digit combinations. From each state, generate the 8 neighbouring states (each wheel turned up or down by 1), skipping deadends and already-visited states. Return the BFS depth at which the target is first reached. Complexity: Time O(10^4) states explored · Space O(10^4) Follow-up: Solve it with bidirectional BFS from both the start and the target to reduce the search space.


4. Longest Substring Without Repeating Characters Medium

OA Sliding Window · String LeetCode:{' '} #3

Given a string s, find the length of the longest substring without repeating characters.

Input: s = "abcabcbb"
Output: 3
Explanation: "abc" has length 3.

Approach: Sliding window with a HashMap tracking the last seen index of each character. Expand the right pointer; whenever a repeated character is seen within the current window, jump the left pointer just past its previous occurrence. Complexity: Time O(n) · Space O(min(n, charset)) Follow-up: Return the actual longest substring, not just its length.


5. Group Anagrams Medium

OA HashMap · String LeetCode:{' '} #49

Given an array of strings, group the anagrams together (strings made of the same characters in a different order).

Input: strs = ["eat","tea","tan","ate","nat","bat"]
Output: [["bat"],["nat","tan"],["ate","eat","tea"]]

Approach: For each string, compute a canonical key (sorted characters, or a 26-length character-count signature). Group strings sharing the same key in a HashMap. Complexity: Time O(n * k log k) (k = max string length) · Space O(n * k) Follow-up: Use character counts instead of sorting for an O(n * k) solution.


6. Subarray Sum Equals K Medium

OA Prefix Sum · HashMap LeetCode:{' '} #560

Given an integer array and an integer k, return the total number of contiguous subarrays whose sum equals k.

Input: nums = [1,1,1], k = 2
Output: 2

Approach: Maintain a running prefix sum and a HashMap of prefix-sum frequencies seen so far. At each index, check how many times (currentSum - k) has occurred before, that count is added to the answer, then record the current sum. Complexity: Time O(n) · Space O(n) Follow-up: What if you needed the actual subarrays, not just the count?


Part 2 — Phone Screen Questions

7. Sliding Window Maximum Hard

Phone Screen Deque · Sliding Window LeetCode:{' '} #239

Given an array and a sliding window of size k moving from left to right, return the maximum value in each window position.

Input: nums = [1,3,-1,-3,5,3,6,7], k = 3
Output: [3,3,5,5,6,7]

Approach: Maintain a monotonically decreasing deque of indices. Pop indices from the back whose values are smaller than the current element (they can never be the max again). Pop from the front if the index falls outside the current window. The front of the deque is always the window maximum. Complexity: Time O(n) · Space O(k) Follow-up: Solve the same problem for the sliding window minimum.


8. Top K Frequent Words Medium

Phone Screen Heap · HashMap LeetCode:{' '} #692

Given an array of strings and an integer k, return the k most frequent strings, sorted by frequency (highest first), and by lexicographical order for ties.

Input: words = ["i","love","leetcode","i","love","coding"], k = 2
Output: ["i","love"]

Approach: Count frequencies with a HashMap. Use a min-heap of size k with a comparator that orders by frequency ascending, then lexicographically descending (so popping the smallest evicts correctly). Reverse the final result. Complexity: Time O(n log k) · Space O(n) Follow-up: What if ties should preserve original input order instead of lexicographical order?


9. Design HashMap Easy

Phone Screen Design · Hashing LeetCode:{' '} #706

Design a HashMap without using any built-in hash table libraries, supporting put(key, value), get(key), and remove(key).

put(1, 1); put(2, 2); get(1) → 1; get(3) → -1; put(2, 1); get(2) → 1; remove(2); get(2) → -1

Approach: Use an array of buckets (fixed size, e.g. 10007) where each bucket is a linked list of (key, value) pairs. Hash the key modulo bucket count to find the bucket, then linearly scan the bucket's list for the key on get/put/remove. Complexity: Time O(1) average per operation · Space O(n) Follow-up: How would you handle resizing when the load factor gets too high?


10. Climbing Stairs Easy

Phone Screen Dynamic Programming · Fibonacci LeetCode:{' '} #70

A common basic screening question at CRED, testing recursive thinking before moving to harder problems. You are climbing a staircase of n steps, and can climb 1 or 2 steps at a time. Return the number of distinct ways to reach the top.

Input: n = 3
Output: 3
Explanation: (1,1,1), (1,2), (2,1)

Approach: This is the Fibonacci sequence: ways(n) = ways(n-1) + ways(n-2). Compute iteratively with two variables to avoid the exponential blowup of naive recursion. Complexity: Time O(n) · Space O(1) Follow-up: What if you could also climb 3 steps at a time?


11. Shortest Path Between Two Files in a File System Medium

Phone Screen Tree/Graph · BFS

A CRED-specific framing reported in interviews. Given a file system represented as a tree (directories containing files/subdirectories), find the shortest path (fewest hops) between two given files or folders.

Input: tree rooted at "/", path1 = "/a/b/file1", path2 = "/a/c/file2"
Output: 4
Explanation: file1 -> b -> a -> c -> file2 (go up to the common ancestor "a", then down).

Approach: Model the file system as an undirected tree/graph (each node connected to its parent and children). Run BFS from one file to the other, since the tree is unweighted this gives the shortest path directly. Alternatively, find the LCA of the two nodes and the answer is depth(node1) + depth(node2) - 2*depth(LCA). Complexity: Time O(n) · Space O(n) Follow-up: What if the file system also has symlinks, turning the tree into a general graph with possible cycles?


12. Longest Consecutive Sequence Medium

Phone Screen HashSet · Array LeetCode:{' '} #128

Given an unsorted array of integers, return the length of the longest sequence of consecutive integers, in O(n) time.

Input: nums = [100,4,200,1,3,2]
Output: 4
Explanation: [1,2,3,4] is the longest consecutive sequence.

Approach: Put all numbers in a HashSet. For each number that is the start of a sequence (i.e., number - 1 is not in the set), count forward (number+1, number+2, ...) while values exist in the set, tracking the longest run found. Complexity: Time O(n) · Space O(n) Follow-up: Return the actual longest sequence, not just its length.


13. Find Median from Data Stream Hard

Phone Screen Heap · Design LeetCode:{' '} #295

Design a data structure that supports adding numbers from a stream and finding the median of all numbers added so far, at any point.

addNum(1); addNum(2); findMedian() → 1.5; addNum(3); findMedian() → 2

Approach: Maintain two heaps: a max-heap for the lower half of numbers and a min-heap for the upper half, keeping their sizes balanced (differ by at most 1). The median is either the top of the larger heap, or the average of both tops when sizes are equal. Complexity: Time O(log n) per insertion, O(1) for median · Space O(n) Follow-up: What if 99% of the numbers fall in a known small range (e.g., 0-100)? (Bucket counting instead of heaps.)


Part 3 — Onsite Questions

14. Word Search Medium

Onsite Backtracking · Matrix LeetCode:{' '} #79

Given an m x n grid of characters and a word, return true if the word can be constructed from letters of sequentially adjacent cells (horizontally or vertically), using each cell at most once.

Input: board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "ABCCED"
Output: true

Approach: Backtracking DFS from every cell matching the first letter. Mark cells visited (or temporarily mutate them) while exploring all 4 directions, un-marking on backtrack. Complexity: Time O(rows * cols * 4^L) (L = word length) · Space O(L) Follow-up: Search for multiple words simultaneously using a Trie to avoid redundant traversal (Word Search II).


15. Number of Provinces Medium

Onsite Union-Find · Graph LeetCode:{' '} #547

Given an n x n adjacency matrix where isConnected[i][j] = 1 if city i and city j are directly connected, return the number of provinces (connected components).

Input: isConnected = [[1,1,0],[1,1,0],[0,0,1]]
Output: 2

Approach: Union-Find: for every pair (i, j) marked connected, union their sets. The number of distinct root parents at the end is the number of provinces. DFS/BFS from unvisited nodes works equally well. Complexity: Time O(n^2 * α(n)) · Space O(n) Follow-up: What if connections arrive as a stream of updates instead of a fixed matrix (online connectivity queries)?


16. Binary Search Tree Iterator Medium

Onsite Tree · Stack · Design LeetCode:{' '} #173

Design an iterator over a BST that supports next() (returns the next smallest number) and hasNext(), both in amortised O(1) time.

BSTIterator it = new BSTIterator(root);
it.next() → 3; it.next() → 7; it.hasNext() → true

Approach: Use an explicit stack, initialised by pushing all left-children from the root down. next() pops the top, then pushes all left-children of its right child. This simulates inorder traversal lazily. Complexity: Time O(1) amortised per call · Space O(h) Follow-up: Support an additional hasPrevious()/previous() pair as well.


17. Decode Ways Medium

Onsite Dynamic Programming · String LeetCode:{' '} #91

A message containing letters A-Z is encoded as numbers 1-26. Given an encoded string of digits, return the number of ways to decode it.

Input: s = "226"
Output: 3
Explanation: "BZ" (2 26), "VF" (22 6), "BBF" (2 2 6)

Approach: dp[i] = ways to decode s[0..i). dp[i] += dp[i-1] if s[i-1] is a valid single-digit code (1-9). dp[i] += dp[i-2] if s[i-2..i) is a valid two-digit code (10-26). Complexity: Time O(n) · Space O(1) with rolling variables Follow-up: What if "*" can represent any digit 1-9 (Decode Ways II)?


18. Combination Sum Medium

Onsite Backtracking LeetCode:{' '} #39

Given an array of distinct positive integers and a target, return all unique combinations where the chosen numbers sum to target. The same number may be reused unlimited times.

Input: candidates = [2,3,6,7], target = 7
Output: [[2,2,3],[7]]

Approach: Backtracking: at each step, try including the current candidate (allowing reuse by not advancing the index) or moving to the next candidate. Prune when the running sum exceeds target. Complexity: Time O(2^target) worst case · Space O(target) Follow-up: Solve Combination Sum II where each number can be used at most once and the input may contain duplicates.


19. Spiral Matrix Medium

Onsite Array · Simulation LeetCode:{' '} #54

Given an m x n matrix, return all elements of the matrix in spiral order.

Input: matrix = [[1,2,3],[4,5,6],[7,8,9]]
Output: [1,2,3,6,9,8,7,4,5]

Approach: Maintain 4 boundaries (top, bottom, left, right). Traverse right along the top row, down the right column, left along the bottom row, up the left column, shrinking each boundary after its pass, until boundaries cross. Complexity: Time O(rows * cols) · Space O(1) excluding output Follow-up: Generate a spiral matrix filled with 1 to n^2 instead of reading one (Spiral Matrix II).


20. Reverse Linked List II Medium

Onsite Linked List LeetCode:{' '} #92

Given the head of a linked list and two integers left and right, reverse the nodes of the list from position left to right, and return the modified list.

Input: head = [1,2,3,4,5], left = 2, right = 4
Output: [1,4,3,2,5]

Approach: Use a dummy node before head. Advance to the node just before position left. Then repeatedly move the next node to the front of the sublist being reversed (the "insertion" reversal technique) exactly (right - left) times. Complexity: Time O(n) · Space O(1) Follow-up: Reverse the list in groups of k instead of a single [left, right] range (Reverse Nodes in k-Group).


21. Copy List with Random Pointer Medium

Onsite Linked List · HashMap LeetCode:{' '} #138

A linked list where each node has an additional random pointer that can point to any node in the list or null. Return a deep copy of the list.

Input: head = [[7,null],[13,0],[11,4],[10,2],[1,0]]
Output: deep copy with matching next and random pointers

Approach: First pass: create a HashMap of original node → cloned node (with only value set). Second pass: for each original node, set the clone's next and random pointers using the map to look up the corresponding cloned nodes. Complexity: Time O(n) · Space O(n) Follow-up: Solve it in O(1) extra space by interleaving cloned nodes directly into the original list.


22. Validate Binary Search Tree Medium

Onsite Tree · DFS LeetCode:{' '} #98

Given the root of a binary tree, determine if it is a valid binary search tree (every node's value strictly between a valid lower and upper bound from its ancestors).

Input: root = [5,1,4,null,null,3,6]
Output: false
Explanation: root value 5 is greater than right child's left child value 3.

Approach: Recursive DFS carrying a (min, max) valid range for each node. At each node, check its value falls strictly within the range, then recurse left with (min, node.val) and right with (node.val, max). Complexity: Time O(n) · Space O(h) Follow-up: Do it via inorder traversal instead, checking that values are strictly increasing.


23. Diameter of Binary Tree Easy

Onsite Tree · DFS LeetCode:{' '} #543

Given the root of a binary tree, return the length (number of edges) of the longest path between any two nodes in the tree, which may or may not pass through the root.

Input: root = [1,2,3,4,5]
Output: 3
Explanation: path [4,2,1,3] or [5,2,1,3].

Approach: DFS computing height at each node, while tracking a global maximum of (left height + right height) at every node visited, since the diameter through any node equals the sum of its left and right subtree heights. Complexity: Time O(n) · Space O(h) Follow-up: Return the actual longest path (sequence of node values), not just its length.


24. Path Sum III Medium

Onsite Tree · Prefix Sum LeetCode:{' '} #437

Given the root of a binary tree and an integer targetSum, return the number of paths where the sum of values along the path equals targetSum. The path does not need to start or end at the root or a leaf, but must go downward.

Input: root = [10,5,-3,3,2,null,11,3,-2,null,1], targetSum = 8
Output: 3

Approach: DFS while maintaining a running prefix sum from the root to the current node, and a HashMap of prefix-sum frequencies seen along the current path. At each node, check how many times (currentSum - targetSum) has occurred, add to the count, then recurse into children and remove the current prefix sum on backtrack. Complexity: Time O(n) · Space O(h) Follow-up: What if paths could go in any direction (not just downward)?


25. Rotting Oranges Medium

Onsite BFS · Matrix LeetCode:{' '} #994

Given a grid with 0 (empty), 1 (fresh orange), and 2 (rotten orange), every minute a rotten orange rots its 4-directionally adjacent fresh oranges. Return the minimum minutes until no fresh orange remains, or -1 if impossible.

Input: grid = [[2,1,1],[1,1,0],[0,1,1]]
Output: 4

Approach: Multi-source BFS starting from all initially rotten oranges simultaneously. Process level by level (minute by minute), rotting adjacent fresh oranges and tracking elapsed minutes. If fresh oranges remain after BFS exhausts, return -1. Complexity: Time O(rows * cols) · Space O(rows * cols) Follow-up: What if rotting happens in all 8 directions instead of just 4?


26. Accounts Merge Medium

Onsite Union-Find · HashMap LeetCode:{' '} #721

Given a list of accounts, each with a name and a list of emails, merge accounts belonging to the same person (accounts sharing at least one common email belong to the same person) and return the merged accounts with sorted emails. Directly relevant to CRED's Contact Management theme, deduplicating contacts by shared identifiers.

Input: accounts = [["John","johnsmith@mail.com","john_newyork@mail.com"],["John","johnsmith@mail.com","john00@mail.com"],["Mary","mary@mail.com"]]
Output: [["John","john00@mail.com","john_newyork@mail.com","johnsmith@mail.com"],["Mary","mary@mail.com"]]

Approach: Union-Find where each email is a node. For each account, union all its emails together. Then group emails by their root parent, attach the corresponding name, and sort each group's emails. Complexity: Time O(n log n) · Space O(n) Follow-up: What if merging should also happen transitively through phone numbers, not just emails?


27. Time Based Key-Value Store Medium

Onsite HashMap · Binary Search LeetCode:{' '} #981

Design a time-based key-value store that supports set(key, value, timestamp) and get(key, timestamp) that returns the value set at the largest timestamp <= the given timestamp.

set("foo", "bar", 1); get("foo", 1) → "bar"; get("foo", 3) → "bar"; set("foo", "bar2", 4); get("foo", 4) → "bar2"; get("foo", 5) → "bar2"

Approach: HashMap of key → list of (timestamp, value) pairs, appended in increasing timestamp order (since set() calls are guaranteed increasing per key). On get(), binary search the list for the largest timestamp <= the query. Complexity: Time O(log n) per get, O(1) per set · Space O(n) Follow-up: Support delete(key, timestamp) as well.


28. Insert Delete GetRandom O(1) Medium

Onsite HashMap · Array · Design LeetCode:{' '} &#35;380

Design a data structure supporting insert, remove, and getRandom (each element has equal probability of being returned), all in average O(1) time.

insert(1); insert(2); remove(1); insert(2) → false (already present); getRandom() → 2

Approach: Combine an array (for O(1) random access) with a HashMap of value → index in the array. To remove an element in O(1), swap it with the last array element before popping, updating the HashMap accordingly. Complexity: Time O(1) average per operation · Space O(n) Follow-up: Support duplicate values as well (Insert Delete GetRandom O(1) - Duplicates allowed).


29. Longest Repeating Character Replacement Medium

Onsite Sliding Window LeetCode:{' '} &#35;424

Given a string and an integer k, you may replace up to k characters with any other character. Return the length of the longest substring containing the same letter after such replacements.

Input: s = "AABABBA", k = 1
Output: 4
Explanation: Replace one 'A' to get "AABBBBA" → "BBBB".

Approach: Sliding window tracking character frequency counts inside the window. The window is valid while (windowSize - maxFrequencyCharCount) <= k. Shrink from the left when invalid, and track the maximum valid window size seen. Complexity: Time O(n) · Space O(1) (26 letters) Follow-up: What if the replacement budget k differs per character?


30. Minimum Window Substring Hard

Onsite Sliding Window · HashMap LeetCode:{' '} &#35;76

Given two strings s and t, return the minimum window substring of s such that every character in t (including duplicates) is included in the window. Return "" if no such window exists.

Input: s = "ADOBECODEBANC", t = "ABC"
Output: "BANC"

Approach: Sliding window with a frequency map of characters needed from t. Expand the right pointer, decrementing needed counts. Once all characters are satisfied, shrink from the left as much as possible while still valid, tracking the smallest valid window seen. Complexity: Time O(n + m) · Space O(m) Follow-up: What if t can contain characters not present anywhere in s?


31. K Closest Points to Origin Medium

Onsite Heap · Array LeetCode:{' '} &#35;973

Given an array of points on the X-Y plane and an integer k, return the k closest points to the origin (0, 0).

Input: points = [[1,3],[-2,2]], k = 1
Output: [[-2,2]]

Approach: Use a max-heap of size k keyed by squared Euclidean distance (avoiding the sqrt). Push points, popping the farthest whenever the heap exceeds size k. Quickselect gives average O(n) if optimal complexity is required. Complexity: Time O(n log k) (heap) or O(n) average (quickselect) · Space O(k) Follow-up: What if points arrive as a continuous stream and you need the k closest at any point in time?


32. Daily Temperatures Medium

Onsite Monotonic Stack LeetCode:{' '} &#35;739

Given an array of daily temperatures, return an array where answer[i] is the number of days you have to wait after day i to get a warmer temperature, or 0 if there is no future day for which this is possible.

Input: temperatures = [73,74,75,71,69,72,76,73]
Output: [1,1,4,2,1,1,0,0]

Approach: Monotonic decreasing stack of indices (by temperature). For each day, pop all indices from the stack whose temperature is lower than the current day, setting their answer to (currentIndex - poppedIndex), then push the current index. Complexity: Time O(n) · Space O(n) Follow-up: Solve the general "next greater element" problem this generalises from.


33. Evaluate Reverse Polish Notation Medium

Onsite Stack LeetCode:{' '} &#35;150

Evaluate the value of an arithmetic expression given in Reverse Polish Notation (postfix notation).

Input: tokens = ["2","1","+","3","*"]
Output: 9
Explanation: ((2 + 1) * 3) = 9

Approach: Use a stack. For each token: if it is a number, push it. If it is an operator, pop the top two operands, apply the operator, and push the result back. Complexity: Time O(n) · Space O(n) Follow-up: Extend it to support an expression with variables and a symbol table.


34. Container With Most Water Medium

Onsite Two Pointers · Array LeetCode:{' '} &#35;11

Given an array of heights representing vertical lines, find two lines that together with the x-axis form a container holding the most water, and return that maximum area.

Input: height = [1,8,6,2,5,4,8,3,7]
Output: 49

Approach: Two pointers starting at both ends. Compute the area at each step (min height * width). Move the pointer with the smaller height inward, since moving the taller one can never increase the area. Complexity: Time O(n) · Space O(1) Follow-up: Solve Trapping Rain Water, a related but distinct problem, using a similar two-pointer technique.


35. 3Sum Medium

Onsite Two Pointers · Sorting LeetCode:{' '} &#35;15

Given an integer array, return all unique triplets [a, b, c] such that a + b + c = 0.

Input: nums = [-1,0,1,2,-1,-4]
Output: [[-1,-1,2],[-1,0,1]]

Approach: Sort the array. For each index i, use two pointers on the remaining subarray to find pairs summing to -nums[i], skipping duplicate values at every level to avoid duplicate triplets. Complexity: Time O(n^2) · Space O(1) excluding output Follow-up: Solve 4Sum using the same two-pointer technique with an extra outer loop.


36. Add Two Numbers Medium

Onsite Linked List · Math LeetCode:{' '} &#35;2

Given two non-empty linked lists representing two non-negative integers in reverse digit order, add the two numbers and return the sum as a linked list, also in reverse order.

Input: l1 = [2,4,3], l2 = [5,6,4]
Output: [7,0,8]
Explanation: 342 + 465 = 807

Approach: Traverse both lists simultaneously, adding corresponding digits plus any carry from the previous step, creating a new node for each resulting digit. Continue past the shorter list's end while a carry or remaining digits exist. Complexity: Time O(max(m, n)) · Space O(max(m, n)) Follow-up: Solve it when digits are stored in forward order instead (Add Two Numbers II).


37. Flatten Binary Tree to Linked List Medium

Onsite Tree · DFS LeetCode:{' '} &#35;114

Given the root of a binary tree, flatten it into a "linked list" in place, following preorder traversal order, using only the right child pointers.

Input: root = [1,2,5,3,4,null,6]
Output: [1,null,2,null,3,null,4,null,5,null,6]

Approach: Reverse-preorder DFS (right, then left, then node) while maintaining a "previously processed" pointer. At each node, set its right child to the previous node and left child to null, then update previous to the current node. Complexity: Time O(n) · Space O(h) Follow-up: Do it using O(1) extra space with the Morris traversal technique.


38. Design a Contact Management System Hard

Onsite · LLD OOP · Design · Search

CRED's single most frequently reported machine coding question. Design an in-memory contact management system (no database) supporting adding/updating contacts, and searching by partial or complete first name, last name, or phone number, case-insensitively, returning the total match count alongside results.

System.addContact(firstName, lastName, phoneNumber) → contactId
System.updateContact(contactId, firstName, lastName, phoneNumber)
System.search(query) → { count: int, results: List<Contact> }

Approach: Classes: Contact (id, firstName, lastName, phoneNumber). ContactRepository stores contacts in a Map<id, Contact> as the source of truth. For search, maintain auxiliary indexes: a Trie (or simple prefix-scan over a sorted list) for name prefixes, and a HashMap for exact/partial phone lookups. search() normalises the query to lowercase and checks partial matches against firstName, lastName, and phoneNumber. updateContact() must update all auxiliary indexes, not just the primary map. Key Design Principles: In-memory only (no external DB per the constraint), SOLID: separate SearchIndex from ContactRepository so search strategy can change independently, testable via unit tests without any I/O Follow-up: How would you extend search to rank results by relevance (exact match > prefix match > substring match) instead of returning them unordered?


39. Design a Parking Lot System Medium

Onsite · LLD OOP · Design

Design a multi-level parking lot system that supports different vehicle types (motorcycle, car, bus) with different spot size requirements, ticket issuance on entry, and fee calculation on exit.

ParkingLot.parkVehicle(vehicle) → Ticket
ParkingLot.unparkVehicle(ticket) → fee
ParkingLot.getAvailableSpots(vehicleType) → int

Approach: Classes: Vehicle (abstract, with Motorcycle/Car/Bus subclasses), ParkingSpot (size, isOccupied), Level (list of spots), ParkingLot (list of levels), Ticket (vehicle, spot, entryTime). parkVehicle() finds the smallest available spot that fits the vehicle (a bus may need multiple adjacent spots). Fee calculation uses a Strategy interface so pricing rules (hourly, flat, per-vehicle-type) can vary independently. Key Design Principles: Strategy pattern for pricing, Factory for vehicle-to-spot-size matching, Level/Spot separation for multi-floor scalability Follow-up: How would you handle a bus that requires 3 consecutive large spots, ensuring they are actually adjacent?


40. Design an Idempotent Payment Processing System Hard

Onsite · LLD OOP · Design · Fintech

A fintech-specific LLD question fitting CRED's explicit emphasis on idempotency. Design a payment processing component where the same payment request, if retried due to a network timeout, must never result in the user being charged twice.

PaymentService.processPayment(idempotencyKey, userId, amount) → PaymentResult

Approach: Every incoming request carries a client-generated idempotencyKey. Before processing, check a PaymentAttempt store (keyed by idempotencyKey) for an existing record. If found and COMPLETED, return the cached result without reprocessing. If found and IN_PROGRESS, reject as a concurrent duplicate. If not found, atomically insert an IN_PROGRESS record (using a DB unique constraint on idempotencyKey to handle races), process the payment, then update the record to COMPLETED or FAILED with the result. Key Design Principles: Idempotency key as a first-class concept, atomic check-and-insert to handle concurrent retries, distinguishing IN_PROGRESS (reject) from COMPLETED (return cached result) Follow-up: What is the correct behaviour if the same idempotencyKey is reused with a different amount, silently succeed, or reject as a client error?


41. Design a CRED Coins Rewards System Medium

Onsite · LLD OOP · Design

Design the reward engine that credits CRED Coins to a user's wallet on successful bill payment, supports redeeming coins for rewards, and prevents a coin balance from ever going negative.

RewardEngine.creditCoins(userId, paymentId, amount) // rule-based: e.g. 1 coin per rupee paid
RewardEngine.redeemCoins(userId, rewardId, coinCost) → success/failure
RewardEngine.getBalance(userId) → int

Approach: Wallet (userId, balance) with an append-only CoinTransaction ledger (userId, paymentId/rewardId, delta, timestamp) as the source of truth, balance is a derived/cached value updated transactionally alongside each ledger entry. creditCoins() is keyed by paymentId to stay idempotent (reuse the same idempotency principle as payment processing). redeemCoins() must atomically check sufficient balance and deduct within a single transaction to prevent race conditions from creating a negative balance. Key Design Principles: Append-only ledger for auditability, idempotent crediting keyed by paymentId, atomic check-and-deduct for redemption Follow-up: How do you handle a payment that is credited with coins but later reversed/refunded?


42. Design a Bill Due-Date Reminder & Notification System Medium

Onsite · LLD OOP · Design · Scheduling

Design a system that tracks each user's credit card bill due dates and sends reminder notifications at configurable intervals before the due date (e.g. 5 days, 1 day, on the day).

ReminderService.scheduleReminders(userId, cardId, dueDate)
ReminderService.cancelReminders(userId, cardId) // e.g. bill already paid
// Triggers NotificationService.send(userId, message) at each configured offset

Approach: Classes: Bill (userId, cardId, dueDate, status), ReminderRule (offsetDays list, e.g. [-5,-1,0]). On scheduleReminders(), compute concrete reminder timestamps and insert jobs into a scheduled-job store (e.g. a time-bucketed queue or a DB table polled by a cron worker). A worker polls due jobs and calls NotificationService (Strategy pattern, reusing the multi-channel design from a general notification service). cancelReminders() marks pending jobs for that bill as cancelled so the worker skips them. Key Design Principles: Decoupling reminder scheduling from actual sending via a job queue, cancellable jobs for the "bill already paid" case, Strategy pattern for notification channels Follow-up: How would you handle a due date change (e.g. the bank updates it) after reminders are already scheduled?


43. Design CRED's Credit Card Bill Payment System Hard

Onsite · HLD System Design · Fintech

Design the backend that lets a user pay a credit card bill through CRED, which integrates with the bank/payment gateway, must never double-charge on retries, and must reconcile CRED's records with the bank's records even if a request times out mid-flight.

Functional: initiatePayment(userId, cardId, amount) → paymentId, getPaymentStatus(paymentId)
Non-functional: exactly-once charging, reconciliation within minutes even if the gateway callback is lost, audit trail for every rupee moved

Approach: Payment initiation creates a PENDING record with a unique idempotency key before calling the payment gateway. The gateway call itself is wrapped with retries using the same idempotency key (gateways like Razorpay/Cashfree support this natively). A separate reconciliation job periodically polls the gateway for the final status of any PENDING payment older than a threshold (in case the callback webhook was lost), updating CRED's record to match the gateway's source of truth. All state transitions are Kafka events for downstream consumers (Rewards, Notifications). Key Design Principles: Idempotency keys shared with the payment gateway itself, reconciliation job as a safety net for lost webhooks, event-driven fan-out to Rewards/Notifications Follow-up: The bank confirms the charge succeeded, but CRED's callback handler crashes before recording it. Walk through exactly how reconciliation recovers this.


44. Design a De-duplication Service for Duplicate Payment Detection Hard

Onsite · HLD System Design · Fintech

Directly reported as a CRED system design theme. Design a service that detects and blocks duplicate payment attempts, for example a user double-tapping 'Pay' or a client retrying a request that actually already succeeded on the backend, before money moves twice.

Functional: checkAndReservePayment(userId, cardId, amount, clientRequestId) → allowed/duplicate
Non-functional: sub-100ms decision latency, must work correctly under concurrent requests from the same user

Approach: Two layers of de-duplication. Layer 1 (client-provided): the idempotency key pattern from the payment LLD question, an atomic check-and-insert on clientRequestId. Layer 2 (fuzzy, for clients that don't send a proper key): a short-TTL Redis lock keyed by (userId, cardId, amount), rejecting a second request for the same tuple within a small window (e.g. 5 seconds), since a legitimate user is unlikely to intentionally pay the identical amount twice within seconds. Both layers write to an audit log for manual review of borderline cases. Key Design Principles: Layered de-duplication (exact idempotency key + fuzzy time-windowed lock), Redis for low-latency distributed locking, audit trail for cases the system is unsure about Follow-up: How do you tune the fuzzy-match time window to avoid falsely blocking two genuinely separate payments of the same amount made close together?


45. Design a Financial Health / Credit Score Aggregation System Hard

Onsite · HLD System Design · Fintech

Design the backend behind CRED's credit score / financial health feature, which pulls a user's credit report from external bureaus (CIBIL, Experian, etc.), caches it, and refreshes it periodically without hitting bureau rate limits or costing money on every app open.

Functional: getCreditScore(userId) → score + report, refreshCreditScore(userId)
Non-functional: bureau calls cost money and are rate-limited, score data can be up to 30 days stale, refresh should happen proactively, not just on-demand

Approach: Store the latest fetched score/report per user in a database with a fetchedAt timestamp. getCreditScore() serves the cached value if fetchedAt is within the freshness window (e.g. 30 days), avoiding a bureau call entirely. A background scheduler proactively refreshes scores approaching staleness, spread out over time (not all at once) to respect bureau rate limits, using a priority queue keyed by fetchedAt. Manual refreshCreditScore() calls are rate-limited per user (e.g. once per day) to control cost. Key Design Principles: Cache-first reads to minimise paid external API calls, proactive background refresh spread over time to respect rate limits, per-user rate limiting on manual refresh Follow-up: How would you handle a bureau being temporarily down, serve stale data, or fail the request? Discuss the tradeoff.


46. Rotate List Medium

Onsite Linked List LeetCode:{' '} &#35;61

Given the head of a linked list, rotate the list to the right by k places.

Input: head = [1,2,3,4,5], k = 2
Output: [4,5,1,2,3]

Approach: Find the list length and connect the tail to the head to form a cycle. Compute the new tail position as (length - k % length - 1) from the head, break the cycle there, and return the node after the break as the new head. Complexity: Time O(n) · Space O(1) Follow-up: What if k could be a very large number relative to a streamed, unknown-length list?


47. Number of Islands II Hard

Onsite Union-Find · Online Queries LeetCode:{' '} &#35;305

Given an m x n grid initially all water, process a sequence of land-addition operations one at a time, returning the number of islands after each addition.

Input: m = 3, n = 3, positions = [[0,0],[0,1],[1,2],[2,1]]
Output: [1,1,2,3]

Approach: Union-Find over the grid. On each addition, mark the cell as land, then union it with any of its 4 already-land neighbours, decrementing the island count for each successful union (starting from incrementing by 1 for the new land cell). Complexity: Time O(k * α(mn)) (k = number of queries) · Space O(mn) Follow-up: Support land removal as well as addition, which Union-Find cannot handle efficiently, discuss why.


48. Course Schedule II Medium

Onsite Graph · Topological Sort LeetCode:{' '} &#35;210

Given numCourses and a list of prerequisite pairs, return a valid order in which to take all courses, or an empty array if it is impossible (a cycle exists).

Input: numCourses = 4, prerequisites = [[1,0],[2,0],[3,1],[3,2]]
Output: [0,1,2,3] (or [0,2,1,3])

Approach: Kahn's algorithm: build an adjacency list and in-degree count. Repeatedly process nodes with in-degree 0 (add to the result, decrement neighbours' in-degree). If the result doesn't include all courses at the end, a cycle exists. Complexity: Time O(V + E) · Space O(V + E) Follow-up: Return all valid topological orderings, not just one.


49. Longest Increasing Path in a Matrix Hard

Onsite DFS · Memoization LeetCode:{' '} &#35;329

Given an m x n integer matrix, return the length of the longest increasing path, moving in any of the 4 directions to a strictly greater value.

Input: matrix = [[9,9,4],[6,6,8],[2,1,1]]
Output: 4
Explanation: The path [1,2,6,9] has length 4.

Approach: DFS with memoization: memo[i][j] = longest increasing path starting at (i, j). Recursively explore the 4 neighbours with a strictly greater value, memoizing results to avoid recomputation, since the answer at each cell depends only on its neighbours. Complexity: Time O(rows * cols) · Space O(rows * cols) Follow-up: What if equal values were also allowed to continue the path (non-strict increasing)?


50. Trapping Rain Water II Hard

Onsite Heap · Matrix · BFS LeetCode:{' '} &#35;407

Given an m x n matrix of heights representing a 2D elevation map, return the total volume of water it can trap after raining.

Input: heightMap = [[1,4,3,1,3,2],[3,2,1,3,2,4],[2,3,3,2,3,1]]
Output: 4

Approach: Min-heap seeded with all border cells (water cannot be trapped there). Repeatedly pop the lowest boundary cell, and for each unvisited neighbour, trapped water = max(0, currentBoundaryHeight - neighbourHeight), then push the neighbour with height = max(currentBoundaryHeight, neighbourHeight) as the new boundary. Complexity: Time O(rows * cols * log(rows * cols)) · Space O(rows * cols) Follow-up: Explain why a simple two-pointer approach (which works for the 1D version) does not generalise to 2D.


Preparation Tips

CRED's DSA rounds lean heavily on Arrays and Strings with a good mix of sliding window and HashMap-based problems, and some interviewers deliberately move you off an IDE into a shared doc to test how clearly you can explain your logic. The Machine Coding round is where most candidates are actually filtered, practice a clean, fully in-memory Contact Management System with case-insensitive partial search before your interview, since it is the most consistently reported question. For System Design, always reach for idempotency and de-duplication whenever the discussion touches payments or transactions, that lens is specifically what CRED's fintech-focused interviewers are evaluating.

Join Telegram group to get the latest CRED OA questions and connect with candidates currently in the CRED interview process.

Useful Resources