Salesforce 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 Salesforce hiring for Data Structures and Algorithms roles
Salesforce is a cloud software company best known for its CRM platform, along with products such as Tableau, Slack, MuleSoft and Data Cloud. Its India centres in Hyderabad and Bengaluru handle large parts of product engineering and support. It hires for software engineers, quality engineers, data engineers and analysts working on CRM, analytics and AI features.
For Data Structures and Algorithms roles, this Salesforce practice set focuses most on Heaps, Priority Queues and Greedy (7), Trees and Binary Search Trees (5), Dynamic Programming (5), Linked Lists, Stacks and Queues (4). It has 1 easy, 19 medium, 10 hard questions, so you can start easy and work up to the harder ones.
Company type
Product
Headquarters
San Francisco, California, USA
Main India offices
Hyderabad, Bengaluru, Mumbai, Gurugram
Salesforce Data Structures and Algorithms interview process
Online coding assessment
Technical round 1 (DSA)
Technical round 2 (design or domain)
Hiring manager round
HR round
Typical pattern based on public candidate experiences. Rounds vary by role, team and year.
Solved for SalesforceStart 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
You are building undo and redo for a text editor. Which data structures would you use?
I would use two stacks. Every user action is pushed onto the undo stack as a command object that knows how to reverse itself. Undo pops from the undo stack, reverts the action and pushes it onto the redo stack. Redo pops from the redo stack and re-applies it. Any new action clears the redo stack. For memory limits, cap the undo stack size, for example using a deque that drops the oldest entries.
02
An application needs sorted data with frequent inserts, deletes and range queries such as all orders between two timestamps. Which structure fits?
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.
03
Write a function to validate a binary search tree.
def is_valid_bst(root, low=float('-inf'), high=float('inf')):
if not root:
return True
if not (low < root.val < high):
return False
return (is_valid_bst(root.left, low, root.val) and
is_valid_bst(root.right, root.val, high))
# Passing bounds checks the whole-subtree property, not just children.
# O(n) time, O(h) space.
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
05
A recursive tree traversal crashes on a skewed tree with one million nodes. How do you fix it?
A skewed tree has height about n, so recursion needs a million stack frames and overflows. Rewrite the traversal iteratively with an explicit stack stored on the heap, or use Morris traversal, which threads temporary links through the tree to achieve O(1) extra space. If the tree is built by our code, also consider why it is skewed and switch to a self-balancing tree so height stays O(log n).
06
Design a rate limiter that allows at most 100 requests per user in any rolling 60-second window.
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.
07
A sorted array has been rotated at an unknown point. How can you still search it in O(log n)?
At every step of binary search, at least one half around mid is sorted. Compare nums[low] with nums[mid]: if the left half is sorted and the target lies within its range, search left, otherwise search right. If the right half is sorted, apply the same check on the right. This keeps O(log n). With duplicates allowed, equal values can hide which half is sorted, and the worst case becomes O(n).
08
Generate all subsets of a list of distinct numbers.
def subsets(nums):
result = []
current = []
def backtrack(i):
if i == len(nums):
result.append(current[:])
return
current.append(nums[i]) # include nums[i]
backtrack(i + 1)
current.pop() # exclude nums[i]
backtrack(i + 1)
backtrack(0)
return result
# 2^n subsets, each up to n long: O(n * 2^n) time
09
Implement 0/1 knapsack using a one-dimensional DP array.
def knapsack(weights, values, capacity):
dp = [0] * (capacity + 1) # dp[w] = best value with capacity w
for wt, val in zip(weights, values):
for w in range(capacity, wt - 1, -1): # go downwards: each item once
dp[w] = max(dp[w], dp[w - wt] + val)
return dp[capacity]
# knapsack([1, 3, 4], [15, 20, 30], 4) -> 35
# O(n * W) time, O(W) space
10
You must merge two sorted arrays where the first array has enough empty space at the end for the second. How would you do it in place?
Merging from the front would overwrite unread elements, so merge from the back. Use three pointers: the last real element of the first array, the last element of the second, and the last slot of the first array. Repeatedly place the larger of the two candidates at the write position and move pointers left. When the second array is exhausted, the rest is already in place. This takes O(m plus n) time and O(1) space.
11
Return an array where each element is the product of all other elements, without using division.
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
How do you handle pressure during a timed online coding test?
Situation: in a 90-minute test I faced three problems, one of them a tough DP. Task: maximise my score. Action: I read all problems first, solved the easiest one quickly to secure marks, wrote a brute-force version of the DP problem for partial credit, then improved it to memoised DP once I spotted the state. I kept an eye on time at fixed checkpoints. Result: I cleared all test cases on two problems and most of the third.
13
A Sudoku solver using plain backtracking is too slow on hard puzzles. How would you speed it up?
Add stronger pruning and better choice ordering. Keep bitmasks of used digits for each row, column and box, so validity checks are O(1). Always fill the empty cell with the fewest candidates first, the minimum remaining values heuristic, which shrinks the search tree dramatically. Apply constraint propagation, filling cells with a single candidate before guessing. For the hardest cases, exact cover with Dancing Links is very fast.
14
How do you prove that a greedy algorithm is correct?
The common method is an exchange argument: take any optimal solution, show that replacing its first choice with the greedy choice does not make it worse, then apply the same reasoning to the remaining subproblem by induction. Another method is showing greedy stays ahead, meaning after each step its partial solution is at least as good as any other. In interviews, stating the argument briefly and testing small counterexamples builds confidence.
Bitmask DP represents a subset of up to about 20 items as the bits of an integer, so the state can be the set of items already used plus perhaps the last item. The travelling salesman problem uses dp[mask][last], the minimum cost to visit the cities in mask ending at last, giving O(2 to the power n times n squared) instead of n factorial. It is used for assignment, scheduling and covering problems with small n.
16
Find the next greater element for every element of an array.
def next_greater(nums):
res = [-1] * len(nums)
stack = [] # indices with decreasing values
for i, x in enumerate(nums):
while stack and nums[stack[-1]] < x:
res[stack.pop()] = x
stack.append(i)
return res
# [4, 5, 2, 25] -> [5, 25, 25, -1]
# Each index is pushed and popped once: O(n)
17
Given meeting start and end times for a day, how do you find the minimum number of rooms needed?
Sort meetings by start time and keep a min-heap of end times for rooms in use. For each meeting, if the earliest ending room is free by its start time, pop it; then push this meeting's end time. The heap size at the end, or its maximum, is the answer. This is O(n log n). An alternative sorts start and end times separately and sweeps with two pointers, counting overlaps.
18
Find the minimum number of railway platforms needed given arrival and departure times.
// 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.
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
20
Implement a data structure that returns the median of all numbers added so far.
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
22
An interviewer asks you to reduce your solution's extra space from O(n) to O(1). How do you approach it?
I check what the extra structure stores and whether the input itself can hold that information. Common techniques: use two pointers instead of a hash set on sorted data, keep only the last few DP values instead of a full table, modify the input in place, such as marking visited indices by negating values, or use bit manipulation like XOR to find a missing number. I state any trade-offs, such as mutating input.
23
A teammate's BST validation only checks that each node is greater than its left child and smaller than its right child. Why is that wrong?
The BST property applies to entire subtrees, not just direct children. A node deep in the left subtree could be larger than the root and still pass the local check. The correct approach passes a valid range down the recursion: the left child must lie between the lower bound and the node value, the right child between the node value and the upper bound. Alternatively, check that an inorder traversal is strictly increasing.
Instead of searching an array, you binary search over possible answers when there is a monotonic feasibility check: if capacity X works, any larger capacity also works. Examples include minimum ship capacity to deliver within D days, minimum eating speed, or the largest minimum distance between placed items. Each check is often O(n) greedy, so total time is O(n log of the answer range), which is very efficient.
25
How does heap sort work and how does it compare with quicksort and merge sort?
Heap sort builds a max-heap in O(n), then repeatedly swaps the root with the last element, shrinks the heap and sifts down, giving O(n log n) in all cases with O(1) extra space. It is not stable and has poor cache locality, so in practice it is slower than quicksort. Merge sort is stable but needs O(n) space. Introsort switches from quicksort to heap sort to guarantee O(n log n).
26
Solve house robber: maximise money robbed from houses in a row without robbing two adjacent houses.
def rob(nums):
take, skip = 0, 0 # best if the previous house is taken or skipped
for x in nums:
take, skip = skip + x, max(take, skip)
return max(take, skip)
# rob([2, 7, 9, 3, 1]) -> 12 (2 + 9 + 1)
# dp[i] = max(dp[i-1], dp[i-2] + nums[i]); O(n) time, O(1) space
27
Two linked lists merge at some node and share the rest. How do you find the merge point efficiently?
A hash set of the first list's nodes works in O(m plus n) time but uses O(m) space. The O(1) space trick uses two pointers: walk each list, and when a pointer reaches the end, redirect it to the head of the other list. Both pointers travel m plus n steps, so they meet at the intersection, or both become null if there is none. Comparing node references, not values, is essential.
28
A game leaderboard with millions of players needs fast score updates and queries like what rank is this player. How would you design it?
Sorting on every query is too slow. I would bucket scores and use a Fenwick tree or segment tree over score values, storing how many players have each score; a player's rank is the count of players with higher scores, found in O(log S). Updates move a player between buckets in O(log S). An order-statistic balanced tree also works, and in production Redis sorted sets, built on skip lists, provide this directly.
29
Tell me about a time you worked with people from other teams to solve a complex problem.
Situation: delivery route suggestions in our app were slow and the data team blamed the backend while we blamed the data. Task: find the real issue. Action: I set up a joint session, we traced one slow request end to end and found the graph was rebuilt from raw tables on every call. I proposed caching the adjacency lists, and the data team added change notifications. Result: response time dropped from 3 seconds to 200 milliseconds.
30
Why does greedy work for fractional knapsack but fail for 0/1 knapsack?
In fractional knapsack you may take part of an item, so taking items in decreasing value per weight and filling the remainder with a fraction is optimal. In 0/1 knapsack items are all or nothing; the best ratio item may leave wasted capacity that a combination of other items would fill better. Example: capacity 50 with items of weight 10, 20 and 30 shows greedy by ratio losing. 0/1 knapsack needs DP in O(n times W).
Tips to crack the Salesforce Data Structures and Algorithms interview
Learn Salesforce core ideas like multi-tenancy, objects and Apex basics, and know what Tableau and Data Cloud do.
Practise test automation concepts using Selenium or similar tools if applying for quality engineering roles.
Read about Salesforce's values of Trust, Customer Success, Innovation, Equality and Sustainability for behavioural questions.
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; Salesforce interviewers usually ask follow-ups on your first answer.
Frequently asked questions
How many rounds are there in the Salesforce Data Structures and Algorithms interview?
Candidates usually go through 5 stages: Online coding assessment; Technical round 1 (DSA); Technical round 2 (design or domain); Hiring manager round; HR 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 Salesforce Data Structures and Algorithms interview?
This practice set leans on Heaps, Priority Queues and Greedy (7), Trees and Binary Search Trees (5), Dynamic Programming (5), Linked Lists, Stacks and Queues (4). Revise those first, then practise explaining one or two of your own projects end to end, because most Salesforce interviewers ask you to walk through real work.
Are these the exact questions asked at Salesforce?
No. These are curated practice questions that match the skills and difficulty usually tested in product interviews like Salesforce's. They are not a leaked or verified list of past questions.
Where does Salesforce hire Data Structures and Algorithms professionals in India?
Salesforce has large teams in Hyderabad, Bengaluru, Mumbai, Gurugram. Openings and locations change often, so check the Salesforce careers page and filter by city and experience.
Data Structures and Algorithms questions for similar companies