Skip to content

Razorpay Data Structures and Algorithms Interview Questions & Answers

Curated interview practice questions with answers. These are practice scenarios, not a verified list of past interview questions.

About Razorpay hiring for Data Structures and Algorithms roles

Razorpay is an Indian fintech company providing payment gateway, payment links, payroll, business banking through RazorpayX and other tools for businesses. Its engineering and analytics teams work on payment success rates, risk, reconciliation and merchant products. It hires for software engineers, SDETs, data analysts and data scientists.

For Data Structures and Algorithms roles, this Razorpay practice set focuses most on Arrays, Strings and Hashing (6), Dynamic Programming (5), Heaps, Priority Queues and Greedy (4), Trees and Binary Search Trees (4). It has 5 easy, 20 medium, 5 hard questions, so you can start easy and work up to the harder ones.

Company type
Fintech
Headquarters
Bengaluru, India
Main India offices
Bengaluru, Mumbai

Razorpay Data Structures and Algorithms interview process

  1. Online assessment or assignment
  2. Machine coding or technical round
  3. Design or problem solving round
  4. Hiring manager round
  5. Culture fit round

Typical pattern based on public candidate experiences. Rounds vary by role, team and year.

Solved for RazorpayStart practicing
3 QUESTIONS FREESign up to unlock the full question bank and track your progress.Unlock every question and answer, then continue practising company-wise and package-wise.
3 questions free Unlock the rest in seconds
01

A learning platform has courses with prerequisites. How do you find a valid order, and what if none exists?

Save to ▾
Show answer
Model courses as vertices with an edge from each prerequisite to the course that needs it, then run topological sort with Kahn's algorithm. Courses with no pending prerequisites enter a queue first, and taking one reduces the in-degree of dependent courses. If the output has fewer courses than the total, there is a cycle, so no valid order exists, and I would report the courses involved so the content team can fix them.
02

Merge K sorted linked lists using a min-heap.

Save to ▾
Show answer
import heapq def merge_k_lists(lists): heap = [] for i, node in enumerate(lists): if node: heapq.heappush(heap, (node.val, i, node)) # i breaks ties dummy = tail = ListNode() while heap: val, i, node = heapq.heappop(heap) tail.next = node tail = node if node.next: heapq.heappush(heap, (node.next.val, i, node.next)) return dummy.next # O(N log K) for N total nodes
03

Explain best, average and worst case complexity using quicksort.

Save to ▾
Show answer
Best case is the minimum work over inputs of size n, worst case the maximum and average case the expected work over typical inputs. Quicksort averages O(n log n) because random pivots split arrays reasonably evenly. Its worst case is O(n squared) when the pivot is always the smallest or largest element, such as sorted input with a first-element pivot. Random pivots or median-of-three make the worst case very unlikely.
04

What is the difference between memoisation and tabulation?

Save to ▾
Show answer
Memoisation is top-down: write the natural recursion and cache results in a map or array, so only needed states are computed, but recursion depth can be a problem. Tabulation is bottom-up: fill a table iteratively from base cases in an order where dependencies are ready, avoiding recursion overhead and making space optimisation easier. Both usually have the same time complexity; choose whichever is clearer for the problem.
05

Compute the edit distance between two words.

Save to ▾
Show answer
def edit_distance(a, b): m, n = len(a), len(b) prev = list(range(n + 1)) # distances from empty prefix of a for i in range(1, m + 1): cur = [i] + [0] * n for j in range(1, n + 1): if a[i - 1] == b[j - 1]: cur[j] = prev[j - 1] else: cur[j] = 1 + min(prev[j], # delete cur[j - 1], # insert prev[j - 1]) # replace prev = cur return prev[n] # edit_distance('horse', 'ros') -> 3; O(m * n) time, O(n) space
06

How is the longest common subsequence computed with DP?

Save to ▾
Show answer
Let dp[i][j] be the LCS length of the first i characters of A and the first j characters of B. If A[i-1] equals B[j-1], dp[i][j] is dp[i-1][j-1] plus 1; otherwise it is the maximum of dp[i-1][j] and dp[i][j-1]. Fill the table row by row in O(m times n) time. Backtracking from dp[m][n] recovers the actual subsequence. LCS underlies diff tools and DNA sequence comparison.
07

Tell me about an interview or exam you failed and what you learned.

Save to ▾
Show answer
Situation: I was rejected after a coding round because I could not solve a tree problem in time. Task: understand the gap honestly. Action: I wrote down the question, realised I memorised solutions instead of patterns, and reorganised my practice by patterns such as postorder aggregation and BFS by level, explaining each solution aloud. Result: three months later I cleared a similar round comfortably, and I now review every mistake within a day.
08

Design a simple scheduler that gives each job a fixed time slice in turn.

Save to ▾
Show answer
Round-robin scheduling fits a queue. Put all jobs in a FIFO queue. Repeatedly dequeue a job, run it for one time slice, and if it is not finished, enqueue it at the back with its remaining time. Each step is O(1). For priorities, keep one queue per priority level or use a priority queue. A circular buffer works well if the number of jobs is bounded, avoiding allocations.
09

Find the minimum number of railway platforms needed given arrival and departure times.

Save to ▾
Show answer
// Java static int minPlatforms(int[] arr, int[] dep) { Arrays.sort(arr); Arrays.sort(dep); int i = 0, j = 0, cur = 0, best = 0; while (i < arr.length) { if (arr[i] <= dep[j]) { // a train arrives before the next departs cur++; i++; best = Math.max(best, cur); } else { cur--; j++; } } return best; } // O(n log n) for sorting, O(1) extra space.
10

Find the length of the longest substring without repeating characters.

Save to ▾
Show answer
def length_of_longest_substring(s): last = {} # char -> last index seen left = best = 0 for right, ch in enumerate(s): if ch in last and last[ch] >= left: left = last[ch] + 1 last[ch] = right best = max(best, right - left + 1) return best # 'abcabcbb' -> 3, 'bbbbb' -> 1, 'pwwkew' -> 3; O(n) time
11

Return an array where each element is the product of all other elements, without using division.

Save to ▾
Show answer
def product_except_self(nums): n = len(nums) out = [1] * n prefix = 1 for i in range(n): # product of everything to the left out[i] = prefix prefix *= nums[i] suffix = 1 for i in range(n - 1, -1, -1): # multiply by everything to the right out[i] *= suffix suffix *= nums[i] return out # [1,2,3,4] -> [24,12,8,6]; O(n) time, O(1) extra space besides output
12
Save to ▾
Show answer
def merge_sort(a): if len(a) <= 1: return a mid = len(a) // 2 left = merge_sort(a[:mid]) right = merge_sort(a[mid:]) out, i, j = [], 0, 0 while i < len(left) and j < len(right): if left[i] <= right[j]: # <= keeps the sort stable out.append(left[i]); i += 1 else: out.append(right[j]); j += 1 out.extend(left[i:]) out.extend(right[j:]) return out # O(n log n) time, O(n) extra space
13

A recursive DFS in Python crashes with RecursionError on a deep input. How do you fix it?

Save to ▾
Show answer
CPython limits recursion depth to about 1000 by default. Raising the limit with sys.setrecursionlimit works for moderate depth but can crash the interpreter on very deep inputs because the C stack is limited. The reliable fix is to rewrite the DFS iteratively with an explicit stack, pushing nodes and processing them in a loop. In Java the same issue appears as StackOverflowError and has the same solution.
14

What are inorder, preorder, postorder and level order traversals?

Save to ▾
Show answer
Inorder visits left subtree, node, then right subtree, and gives sorted order for a BST. Preorder visits node, left, then right, which is useful for copying or serialising a tree. Postorder visits left, right, then node, used for deleting trees or computing subtree results. Level order visits nodes level by level using a queue. All take O(n) time; recursive versions use O(h) stack space.
15

Find the minimum number of coins needed to make an amount.

Save to ▾
Show answer
def coin_change(coins, amount): INF = amount + 1 dp = [0] + [INF] * amount # dp[x] = min coins for amount x for x in range(1, amount + 1): for c in coins: if c <= x and dp[x - c] + 1 < dp[x]: dp[x] = dp[x - c] + 1 return dp[amount] if dp[amount] != INF else -1 # coin_change([1, 3, 4], 6) -> 2 (3 + 3) # O(amount * len(coins)) time, O(amount) space
16

Implement Kadane's algorithm for the maximum subarray sum.

Save to ▾
Show answer
def max_subarray(nums): best = current = nums[0] for x in nums[1:]: current = max(x, current + x) # extend or start fresh best = max(best, current) return best # max_subarray([-2, 1, -3, 4, -1, 2, 1, -5, 4]) -> 6 (subarray 4, -1, 2, 1)
17

A hash map lookup in your service suddenly becomes very slow under certain traffic. What could cause it?

Save to ▾
Show answer
If many keys produce the same hash, they pile into a few buckets and operations degrade toward O(n). This can come from a poor custom hashCode, such as returning a constant or using only one field, or from attackers sending crafted keys. Fixes include a better hash function combining all fields, randomised hashing, which Python uses for strings, and tree-based buckets as in Java 8 HashMap, which caps the worst case at O(log n).
18

How does quicksort work and why does pivot choice matter?

Save to ▾
Show answer
Quicksort picks a pivot, partitions the array so smaller elements go left and larger go right, then recursively sorts both sides. It sorts in place with O(log n) stack space on average and is very cache friendly, averaging O(n log n). A bad pivot, such as always the first element on sorted input, gives unbalanced partitions and O(n squared). Random pivots, median-of-three and three-way partitioning for duplicates avoid this.
19

Rotate an array to the right by k steps in place.

Save to ▾
Show answer
def rotate(nums, k): n = len(nums) k %= n def reverse(l, r): while l < r: nums[l], nums[r] = nums[r], nums[l] l += 1 r -= 1 reverse(0, n - 1) # reverse all reverse(0, k - 1) # reverse first k reverse(k, n - 1) # reverse the rest # [1,2,3,4,5,6,7], k=3 -> [5,6,7,1,2,3,4]; O(n) time, O(1) space
20
Save to ▾
Show answer
Backtracking builds a solution step by step and abandons a partial solution as soon as it cannot lead to a valid answer, then undoes the last choice and tries the next. It is a DFS over the space of choices. It solves permutations, combinations, subsets, N-Queens, Sudoku and word search. The worst case is often exponential, so good pruning, such as checking constraints early, is what makes it practical.
21

What is the diameter of a binary tree and how do you compute it efficiently?

Save to ▾
Show answer
The diameter is the number of edges on the longest path between any two nodes, which may not pass through the root. Compute it in one postorder traversal: for each node, get the heights of the left and right subtrees, update a global best with left plus right, and return 1 plus the larger height to the parent. This visits each node once, giving O(n) time instead of O(n squared) from recomputing heights.
22

What are the complexities of heap operations, and why does building a heap take O(n)?

Save to ▾
Show answer
Peek at the root is O(1). Insert adds at the end and sifts up, and extract removes the root, moves the last element to the top and sifts down, both O(log n). Building a heap from n elements by sifting down from the last internal node to the root takes O(n), not O(n log n), because most nodes are near the bottom and move only a few levels; the sum of heights is linear.
23

What is the load factor of a hash table and why does it matter?

Save to ▾
Show answer
Load factor is the number of stored entries divided by the number of buckets. As it rises, collisions increase and operations slow down. Java HashMap resizes when the load factor passes 0.75, doubling buckets and rehashing every entry, which costs O(n) occasionally but keeps operations O(1) amortised. If you know the final size, set the initial capacity to avoid repeated resizing in performance-sensitive code.
24

An application needs sorted data with frequent inserts, deletes and range queries such as all orders between two timestamps. Which structure fits?

Save to ▾
Show answer
A balanced BST, such as Java TreeMap or a sorted container in Python, gives O(log n) insert and delete and O(log n plus k) range queries using floor, ceiling or subMap operations. A sorted array has fast range queries but O(n) inserts, and a hash map cannot do ranges at all. If the data lives in a database, a B-tree index on the timestamp column solves the same problem.
25

Design a rate limiter that allows at most 100 requests per user in any rolling 60-second window.

Save to ▾
Show answer
For each user keep a deque of request timestamps. On a request, pop timestamps older than now minus 60 seconds from the front, then allow the request only if fewer than 100 remain, pushing the new timestamp at the back. This sliding window log is exact but uses memory per request. At scale I would use a sliding window counter or token bucket stored in Redis with atomic operations to save memory and work across servers.
26

How does Dijkstra's algorithm work and why does it fail with negative edge weights?

Save to ▾
Show answer
Dijkstra keeps a min-heap of tentative distances. It repeatedly pops the closest unvisited vertex, marks its distance final and relaxes its outgoing edges, giving O((V plus E) log V). It relies on the fact that once a vertex is popped, no shorter path can appear later. A negative edge breaks that assumption because a longer path could later become cheaper. For negative weights use Bellman-Ford.
27

A cashier system uses the greedy rule of always giving the largest coin first. When can this fail?

Save to ▾
Show answer
Greedy coin change is optimal for canonical systems such as Indian rupee denominations, but fails for arbitrary coin sets. With coins 1, 3 and 4 and amount 6, greedy gives 4 plus 1 plus 1, three coins, while 3 plus 3 uses only two. For arbitrary denominations, use dynamic programming where dp of x is the minimum coins for amount x, computed in O(amount times number of coins).
28

A report generation function loops over all users and, for each user, scans all orders. It was fine at launch but is now very slow. How do you explain and fix it?

Save to ▾
Show answer
The loop is O(users times orders), so when both grow ten times, the work grows a hundred times. I would explain this with numbers and a quick profile. The fix is to group orders by user ID once using a hash map, making the total O(users plus orders), or to push the grouping into a database query with an index. I would add a performance test with production-scale data.
29

Packages with given weights must be shipped in order within D days. How do you find the minimum ship capacity?

Save to ▾
Show answer
The capacity lies between the heaviest package and the total weight, and if a capacity works, any larger one also works, so binary search the answer. For a candidate capacity, greedily load packages day by day, starting a new day when the next package does not fit, and count days. If the days are within D, try smaller; otherwise try larger. Time is O(n log of total weight).
30

Compute the length of the longest common subsequence of two strings.

Save to ▾
Show answer
// Java static int lcs(String a, String b) { int m = a.length(), n = b.length(); int[][] dp = new int[m + 1][n + 1]; for (int i = 1; i <= m; i++) { for (int j = 1; j <= n; j++) { if (a.charAt(i - 1) == b.charAt(j - 1)) dp[i][j] = dp[i - 1][j - 1] + 1; else dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]); } } return dp[m][n]; } // lcs(abcde, ace) = 3; O(m * n) time and space

Tips to crack the Razorpay Data Structures and Algorithms interview

  • Learn how a payment gateway works end to end, including authorisation, settlement, refunds and chargebacks.
  • Practise API testing with tools like Postman and understand webhooks if you are applying for QA roles.
  • Read Razorpay's engineering blog to understand its scale challenges and use them in design discussions.
  • Keep a one-minute story ready for every project on your CV: problem, your part, tools, result.
  • Practise the hard questions on this page aloud; Razorpay interviewers usually ask follow-ups on your first answer.

Frequently asked questions

How many rounds are there in the Razorpay Data Structures and Algorithms interview?

Candidates usually go through 5 stages: Online assessment or assignment; Machine coding or technical round; Design or problem solving round; Hiring manager round; Culture fit round. The exact rounds change with the role, team, location and your experience, so confirm the process with the recruiter.

Which topics should I prepare for the Razorpay Data Structures and Algorithms interview?

This practice set leans on Arrays, Strings and Hashing (6), Dynamic Programming (5), Heaps, Priority Queues and Greedy (4), Trees and Binary Search Trees (4). Revise those first, then practise explaining one or two of your own projects end to end, because most Razorpay interviewers ask you to walk through real work.

Are these the exact questions asked at Razorpay?

No. These are curated practice questions that match the skills and difficulty usually tested in fintech interviews like Razorpay's. They are not a leaked or verified list of past questions.

Where does Razorpay hire Data Structures and Algorithms professionals in India?

Razorpay has large teams in Bengaluru, Mumbai. Openings and locations change often, so check the Razorpay careers page and filter by city and experience.

Data Structures and Algorithms questions for similar companies