LinkedIn Previous Year Coding Questions
LinkedIn hires Software Engineers through campus drives, internships, and off-campus applications, primarily for its Bangalore engineering teams working on the feed, connections graph, search, and messaging systems. The process typically runs a recruiter screen, a technical phone screen, and a 5-round onsite loop that notably includes a "coding with AI" round alongside the standard DSA, system design, hiring manager, and project deep-dive rounds. LinkedIn's DSA questions lean heavily toward graphs and trees, unsurprising given the product is fundamentally a graph of people, and its system design questions consistently circle back to the News Feed and Connections Graph.
Hiring Process
Step 1: Recruiter Screen A 15-minute call discussing your background, notable projects, and interest in LinkedIn.
Step 2: Online Assessment (for campus/bulk roles) Around 1 hour with 3 coding questions at easy-to-medium difficulty, covering priority queues, dynamic programming, and general problem-solving. Some tracks (notably SRE) instead run a 2-hour, 40-question test (37 MCQs + 3 coding), with MCQs weighted toward networking, Linux/UNIX, DBMS, OS, and OOP.
Step 3: Technical Phone Screen A video call (often over CoderPad or Collabedit) that opens with a discussion of your past projects, followed by one medium-difficulty coding question.
Step 4: Onsite Loop (5 rounds, 45–60 minutes each)
- Standard Coding Round: 2 problems (1 Medium, 1 Hard) in about 40 minutes.
- "Coding with AI" Round: You solve a problem using an AI coding assistant, evaluated on how well you direct and review AI-generated code, not on typing speed.
- System Design (HLD) Round: Almost always touches the News Feed or the Connections Graph in some form.
- Project Deep-Dive: A detailed technical walkthrough of a project on your resume.
- Hiring Manager Round: Behavioural and team-fit focused.
Tips: Graphs and trees dominate LinkedIn's DSA rounds far more than at most companies, practice BFS/DFS on graphs until it's automatic, since "shortest path between two connections" style framing shows up often. For the "coding with AI" round, practice actually talking through and critiquing AI-suggested code rather than just accepting it, that is explicitly what is being evaluated. For System Design, know the fan-out-on-write vs fan-out-on-read tradeoff for feed generation cold, it comes up in nearly every LinkedIn HLD round.
Preparation Resources
Part 1 — OA Questions
1. Number Complement Easy
Reported in LinkedIn's OA as a 'bitwise complement' question. Given a positive integer, return its complement (flip every bit in its binary representation, ignoring leading zeros).
Input: num = 5
Output: 2
Explanation: 5 is "101" in binary, complement is "010" = 2.
Approach: Find the smallest bitmask of all 1s that is >= num (e.g. by finding the bit-length of num), then XOR num with that mask to flip every relevant bit.
Complexity: Time O(log n) · Space O(1)
Follow-up: Do it without converting to a string at any point, using pure bit operations.
2. Search in a Binary Search Tree Easy
Given the root of a BST and a value, find the node in the BST whose value equals the given value and return the subtree rooted at that node, or null if not found.
Input: root = [4,2,7,1,3], val = 2
Output: [2,1,3]
Approach: Iterative or recursive traversal exploiting the BST property: if val < node.val go left, if val > node.val go right, otherwise found.
Complexity: Time O(h) · Space O(1) iterative, O(h) recursive
Follow-up: What changes if the tree is not guaranteed to be a valid BST?
3. Count of Distinct Substrings Medium
A classic GfG-style question reported in LinkedIn's OA. Given a string, count the number of distinct (non-empty) substrings it contains.
Input: s = "aab"
Output: 5
Explanation: Distinct substrings are "a", "aa", "aab", "ab", "b".
Approach: Insert every substring into a Trie character by character; each newly created Trie node represents one new distinct substring. Count total nodes created (excluding the root). A suffix array with an LCP array gives an alternative O(n log n) approach.
Complexity: Time O(n^2) with a Trie · Space O(n^2) worst case
Follow-up: Solve it in O(n log n) using a suffix array and LCP array instead.
4. Max Consecutive Ones III with Wraparound Medium
A reported extension of LeetCode's Max Consecutive Ones III. Given a circular binary array and an integer k, return the length of the longest subarray (allowing wraparound from the end to the start) containing only 1s after flipping at most k zeros.
Input: nums = [1,0,1,1,0,0,1], k = 1
Output: 5
Explanation: Wrapping around and flipping one zero can connect trailing and leading 1s.
Approach: Run the standard sliding-window "at most k zero-flips" solution on the array doubled (nums + nums), capping the window length at the original array length to avoid counting the same element twice.
Complexity: Time O(n) · Space O(n) for the doubled array
Follow-up: Solve the non-circular version first (LeetCode 1004) to build the core sliding window technique.
5. Count Good Nodes in Binary Tree Medium
Reported as 'total visible nodes' where a node is visible/good if no node on the path from the root to it has a value greater than it. Given a binary tree, return the number of good nodes.
Input: root = [3,1,4,3,null,1,5]
Output: 4
Approach: DFS carrying the maximum value seen so far along the current root-to-node path. A node is "good" if its value >= that running maximum; update the running maximum before recursing into children.
Complexity: Time O(n) · Space O(h)
Follow-up: Return the actual list of good nodes, not just the count.
6. Maximize Ticket Revenue (Greedy Scheduling) Medium
Reported as a 'railway ticket window' problem. Given the number of tickets available at each of several counters and a total number of tickets you must sell, where selling the kth ticket from a counter with c tickets remaining earns c rupees, return the maximum total revenue achievable.
Input: counters = [8,5,9,3], ticketsToSell = 6
Output: 40
Approach: Max-heap of counter ticket counts. Repeatedly pop the largest count, add it to revenue, decrement it, and push it back (if still positive). Repeat ticketsToSell times.
Complexity: Time O(t log c) (t = tickets to sell, c = number of counters) · Space O(c)
Follow-up: This is structurally identical to LeetCode 1962 'Reduce a Number to Zero' style greedy-heap problems, generalise it to minimise total revenue instead.
Part 2 — Phone Screen Questions
7. Minimum Window Substring Hard
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.
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 satisfied, shrink from the left while still valid, tracking the smallest valid window.
Complexity: Time O(n + m) · Space O(m)
Follow-up: LinkedIn interviewers reportedly extend this with a wraparound variant, where s is circular. Discuss how you would adapt the sliding window for that.
8. All O`one Data Structure Hard
Design a data structure that supports incrementing/decrementing the count of a key, and returning any key with the maximum count and any key with the minimum count, all in O(1) time.
inc("hello"); inc("hello"); inc("leet"); getMaxKey() → "hello"; getMinKey() → "leet"
Approach: A doubly linked list of "buckets", each bucket holding a distinct count value and the set of keys with that count, kept sorted by count. A HashMap maps key → its current bucket for O(1) lookup. inc/dec move a key to the adjacent bucket (creating one if it does not exist, removing the old bucket if it becomes empty).
Complexity: Time O(1) per operation · Space O(n)
Follow-up: Why does a simple HashMap + sorted structure (like a TreeMap) not achieve O(1), and how does the bucket list get around that?
9. Max Stack Hard
Design a stack that supports push, pop, top, peekMax, and popMax (remove the maximum element seen), reported as a question with discussion expected on 2-3 optimal approaches.
push(5); push(1); push(5); top() → 5; popMax() → 5; top() → 1; peekMax() → 5; pop() → 1; top() → 5
Approach: Two stacks (main + max-tracking) give O(1) push/pop/top/peekMax but O(n) popMax. For O(log n) popMax, use a doubly linked list combined with a TreeMap (sorted map of value → list of node references), removing the target node directly from the list rather than popping and re-pushing.
Complexity: Time O(1) push/pop/top/peekMax, O(log n) popMax (optimal) or O(n) (simple) · Space O(n)
Follow-up: Walk through why the simple two-stack approach makes popMax O(n), and exactly how the linked-list + TreeMap approach avoids that.
10. Find Leaves of Binary Tree Medium
Given the root of a binary tree, collect the tree's nodes as if repeatedly removing all current leaf nodes, level by level from the bottom, until the tree is empty.
Input: root = [1,2,3,4,5]
Output: [[4,5,3],[2],[1]]
Approach: DFS computing the height of each node (leaves have height 0). Group node values into result[height], since a node's "removal round" equals its height in the tree.
Complexity: Time O(n) · Space O(h)
Follow-up: Solve it iteratively without recursion, by repeatedly detecting and stripping actual leaf nodes.
11. Word Ladder Hard
Given a beginWord, endWord, and a word list, return the length of the shortest transformation sequence changing one letter at a time, with every intermediate word in the word list.
Input: beginWord = "hit", endWord = "cog", wordList = ["hot","dot","dog","lot","log","cog"]
Output: 5
Approach: BFS from beginWord, trying every single-character substitution at each position and checking membership in the word set, tracking visited words to avoid cycles.
Complexity: Time O(n * 26 * L) · Space O(n)
Follow-up: LinkedIn interviewers reportedly ask multiple follow-ups here, discuss returning all shortest sequences (Word Ladder II) and bidirectional BFS for better average performance.
12. K Closest Points to Origin Medium
Given an array of points on the X-Y plane and an integer k, return the k closest points to the origin.
Input: points = [[1,3],[-2,2]], k = 1
Output: [[-2,2]]
Approach: Max-heap of size k keyed by squared distance (avoiding sqrt). Push points, popping the farthest whenever the heap exceeds size k. Quickselect gives average O(n).
Complexity: Time O(n log k) (heap) or O(n) average (quickselect) · Space O(k)
Follow-up: What if k changes dynamically and the point set is also being updated (a live, queryable structure)?
13. Distinct Palindromic Substrings Hard
An extension of counting palindromic substrings, reported in LinkedIn interviews. Given a string, return the number of distinct (unique) palindromic substrings it contains.
Input: s = "abaaa"
Output: 5
Explanation: Distinct palindromes: "a", "b", "aa", "aba", "aaa".
Approach: Expand around every centre (2n-1 centres) to enumerate all palindromic substrings, inserting each into a HashSet to automatically deduplicate. For very long strings, Eertree (palindromic tree) gives an O(n) construction that directly counts distinct palindromic substrings.
Complexity: Time O(n^2) (expand-around-centre + hashing) or O(n) with an Eertree · Space O(n^2) worst case for the substrings stored
Follow-up: Explain how an Eertree (palindromic tree) achieves this in linear time.
Part 3 — Onsite Questions
14. Number of Islands Medium
Given a 2D binary grid of land and water, return the number of islands (connected groups of land).
Input: grid = [["1","1","0","0"],["1","1","0","0"],["0","0","1","0"],["0","0","0","1"]]
Output: 3
Approach: DFS/BFS from every unvisited land cell, marking the whole connected component visited, incrementing the island count once per new component.
Complexity: Time O(rows * cols) · Space O(rows * cols)
Follow-up: Solve it using Union-Find instead.
15. Course Schedule Medium
Given numCourses and prerequisite pairs, determine if it is possible to finish all courses (no cycle in the prerequisite graph).
Input: numCourses = 2, prerequisites = [[1,0],[0,1]]
Output: false
Approach: Kahn's algorithm (BFS): build in-degree counts, repeatedly remove nodes with in-degree 0. If all nodes are processed, no cycle exists.
Complexity: Time O(V + E) · Space O(V + E)
Follow-up: Return a valid course order instead of just true/false.
16. Clone Graph Medium
Given a reference to a node in a connected undirected graph, return a deep copy of the graph.
Input: adjList = [[2,4],[1,3],[2,4],[1,3]]
Output: deep copy of the same structure
Approach: DFS/BFS with a HashMap of original node → cloned node to avoid infinite loops and reuse already-cloned nodes.
Complexity: Time O(V + E) · Space O(V)
Follow-up: Clone a graph representing LinkedIn connections, where edges also carry a "connection date" weight.
17. Word Break Medium
Given a string s and a dictionary wordDict, return true if s can be segmented into a space-separated sequence of dictionary words.
Input: s = "leetcode", wordDict = ["leet","code"]
Output: true
Approach: dp[i] = true if s[0..i) is segmentable. For each i, check every j < i where dp[j] is true and s[j..i) is in the dictionary.
Complexity: Time O(n^2) · Space O(n)
Follow-up: Return all possible segmentations (Word Break II).
18. LRU Cache Medium
Design a Least Recently Used cache supporting get(key) and put(key, value), both in O(1) time.
capacity = 2; put(1,1); put(2,2); get(1) → 1; put(3,3) evicts key 2
Approach: HashMap (key → node) combined with a doubly linked list ordered by recency. get() moves the node to the front; put() evicts the tail when over capacity.
Complexity: Time O(1) per operation · Space O(capacity)
Follow-up: Design an LFU cache instead.
19. Merge Intervals Medium
Given an array of intervals, merge all overlapping intervals.
Input: intervals = [[1,3],[2,6],[8,10],[15,18]]
Output: [[1,6],[8,10],[15,18]]
Approach: Sort by start time. Merge the current interval into the last merged one if they overlap, otherwise append a new interval.
Complexity: Time O(n log n) · Space O(n)
Follow-up: Insert a new interval into an already-sorted, non-overlapping list efficiently.
20. Binary Tree Maximum Path Sum Hard
Given the root of a binary tree, return the maximum path sum of any non-empty path (a path need not pass through the root).
Input: root = [-10,9,20,null,null,15,7]
Output: 42
Explanation: Path 15 -> 20 -> 7.
Approach: DFS returning the best downward path sum from each node (clamped at 0 to ignore negative branches), while tracking a global maximum of (node.val + leftContribution + rightContribution) at every node visited.
Complexity: Time O(n) · Space O(h)
Follow-up: Return the actual path (sequence of node values), not just the sum.
21. Serialize and Deserialize Binary Tree Hard
Design an algorithm to serialize a binary tree to a string and deserialize it back into the original tree.
Input: root = [1,2,3,null,null,4,5]
Serialized: "1,2,#,#,3,4,#,#,5,#,#"
Approach: Preorder DFS serialization with a sentinel for null children. Deserialize by reading tokens in the same preorder sequence, recursively rebuilding subtrees.
Complexity: Time O(n) · Space O(n)
Follow-up: Do the same for an N-ary tree.
22. Longest Increasing Subsequence Medium
Given an integer array, return the length of the longest strictly increasing subsequence.
Input: nums = [10,9,2,5,3,7,101,18]
Output: 4
Approach: Maintain a "tails" array of smallest possible tail values per subsequence length. Binary search each number's position in tails and replace or append.
Complexity: Time O(n log n) · Space O(n)
Follow-up: Reconstruct the actual subsequence.
23. Coin Change Medium
Given coin denominations and a target amount, return the fewest coins needed to make that amount, or -1 if impossible.
Input: coins = [1,2,5], amount = 11
Output: 3
Approach: dp[i] = min coins for amount i. dp[0]=0. For each amount, try every coin and take dp[amount-coin]+1 if it improves the best.
Complexity: Time O(amount * coins) · Space O(amount)
Follow-up: Return the number of combinations instead (Coin Change II).
24. Top K Frequent Elements Medium
Given an integer array and k, return the k most frequent elements.
Input: nums = [1,1,1,2,2,3], k = 2
Output: [1,2]
Approach: Count frequencies with a HashMap, use a min-heap of size k or bucket sort by frequency.
Complexity: Time O(n log k) or O(n) with bucket sort · Space O(n)
Follow-up: What if the input is a continuous stream?
25. Product of Array Except Self Medium
Given an array, return an array where each element is the product of all elements except itself, without division.
Input: nums = [1,2,3,4]
Output: [24,12,8,6]
Approach: Prefix-product pass followed by a suffix-product pass, combined into the output array.
Complexity: Time O(n) · Space O(1) extra excluding output
Follow-up: Handle zeros without special-casing.
26. Trapping Rain Water Hard
Given an elevation map, compute how much water it can trap after raining.
Input: height = [0,1,0,2,1,0,1,3,2,1,2,1]
Output: 6
Approach: Two pointers tracking max height seen from each side, moving the pointer with the smaller max height inward.
Complexity: Time O(n) · Space O(1)
Follow-up: Solve the 2D version using a priority queue.
27. 3Sum Medium
Given an integer array, return all unique triplets that sum to zero.
Input: nums = [-1,0,1,2,-1,-4]
Output: [[-1,-1,2],[-1,0,1]]
Approach: Sort the array, then use two pointers for each fixed first element, skipping duplicates.
Complexity: Time O(n^2) · Space O(1) excluding output
Follow-up: Solve 4Sum with an extra outer loop.
28. Subsets Medium
Given an array of unique integers, return all possible subsets.
Input: nums = [1,2,3]
Output: [[],[1],[2],[1,2],[3],[1,3],[2,3],[1,2,3]]
Approach: Backtracking: at each index branch into include/exclude, adding the current subset at every call.
Complexity: Time O(2^n) · Space O(2^n)
Follow-up: Handle duplicate values without duplicate subsets.
29. Permutations Medium
Given an array of distinct integers, return all possible permutations.
Input: nums = [1,2,3]
Output: [[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]
Approach: Backtracking with a used array, trying every unused number at each recursive level.
Complexity: Time O(n * n!) · Space O(n!)
Follow-up: Handle duplicate values (Permutations II).
30. Rotate Image Medium
Given an n x n matrix, rotate it 90 degrees clockwise in place.
Input: matrix = [[1,2,3],[4,5,6],[7,8,9]]
Output: [[7,4,1],[8,5,2],[9,6,3]]
Approach: Transpose the matrix, then reverse each row.
Complexity: Time O(n^2) · Space O(1)
Follow-up: Rotate counter-clockwise, and by an arbitrary multiple of 90 degrees.
31. Valid Parentheses Easy
Given a string of brackets, determine if it is valid (every open bracket closed by the matching type in order).
Input: s = "()[]{}"
Output: true
Approach: Stack: push opening brackets, match and pop on closing brackets, verify empty at the end.
Complexity: Time O(n) · Space O(n)
Follow-up: Return the minimum insertions needed to make an invalid string valid.
32. Kth Largest Element in an Array Medium
Given an integer array and k, return the kth largest element.
Input: nums = [3,2,1,5,6,4], k = 2
Output: 5
Approach: Min-heap of size k, or quickselect for average O(n).
Complexity: Time O(n log k) or O(n) average · Space O(k)
Follow-up: What if the array is a live stream?
33. Design Twitter Medium
A near-exact fit for a LinkedIn-style mini feed. Design a simplified social feed supporting posting, following/unfollowing, and retrieving the 10 most recent posts in a user's feed from people they follow (including themselves), most recent first.
postTweet(1, 5); getNewsFeed(1) → [5]; follow(1, 2); postTweet(2, 6); getNewsFeed(1) → [6,5]; unfollow(1, 2); getNewsFeed(1) → [5]
Approach: Store each user's own posts as a list with a global increasing timestamp. followMap: userId → set of followed userIds. getNewsFeed merges the current user's and all followees' post lists using a heap (k-way merge), taking the top 10 by timestamp.
Complexity: Time O(k log f) for feed generation (f = followees) · Space O(n)
Follow-up: Scale this to millions of users by discussing fan-out-on-write vs fan-out-on-read.
34. Group Anagrams Medium
Given an array of strings, group the anagrams together.
Input: strs = ["eat","tea","tan","ate","nat","bat"]
Output: [["bat"],["nat","tan"],["ate","eat","tea"]]
Approach: Compute a canonical key per string (sorted characters or a character-count signature) and group by key in a HashMap.
Complexity: Time O(n * k log k) · Space O(n * k)
Follow-up: Use character counts instead of sorting for O(n * k).
35. Longest Substring Without Repeating Characters Medium
Given a string, find the length of the longest substring without repeating characters.
Input: s = "abcabcbb"
Output: 3
Approach: Sliding window with a HashMap of last-seen index per character, jumping the left pointer past repeats.
Complexity: Time O(n) · Space O(min(n, charset))
Follow-up: Return the actual substring.
36. Two Sum Easy
Given an array and a target, return indices of the two numbers that add up to target.
Input: nums = [2,7,11,15], target = 9
Output: [0,1]
Approach: HashMap of value → index, checking for the complement before inserting each number.
Complexity: Time O(n) · Space O(n)
Follow-up: Solve it with O(1) space if the array is sorted.
37. Add Two Numbers Medium
Given two non-empty linked lists representing non-negative integers in reverse digit order, return their sum as a linked list.
Input: l1 = [2,4,3], l2 = [5,6,4]
Output: [7,0,8]
Approach: Traverse both lists simultaneously, adding digits plus carry, creating new nodes for each resulting digit.
Complexity: Time O(max(m, n)) · Space O(max(m, n))
Follow-up: Solve it with digits stored in forward order (Add Two Numbers II).
38. Design a Messaging Rate Limiter (InMail) Medium
Design a component that limits how many InMail/connection-request messages a free-tier user can send per rolling 30-day window, rejecting requests beyond the limit.
RateLimiter.canSendMessage(userId) → boolean
RateLimiter.recordMessageSent(userId)
Approach: Sliding Window Counter: maintain a per-user counter with a reset timestamp, or a Redis sorted set of send-timestamps (ZADD + ZREMRANGEBYSCORE) for exact rolling-window accuracy across multiple app servers. canSendMessage() checks current count against the tier limit before allowing recordMessageSent() to proceed atomically. Key Design Principles: Distributed-safe counting via Redis for multi-server correctness, tier-based limits via a Strategy/config lookup rather than hardcoded values Follow-up: How would you handle a user upgrading their tier mid-window, does their new limit apply retroactively to the current window?
39. Design a "People You May Know" Suggestion Engine Hard
Design the component that generates connection suggestions for a user, primarily based on mutual connections (friends-of-friends), ranked by mutual connection count.
SuggestionEngine.getSuggestions(userId, limit) → List<UserId>
Approach: Model users and connections as a graph. For a given user, run a 2-hop BFS (friends-of-friends) to collect candidate users, excluding existing connections and the user themselves. Count mutual connections per candidate (number of paths of length 2), and return the top-limit candidates ranked by that count.
Key Design Principles: Graph-based 2-hop traversal, separation of candidate generation from ranking so ranking signals can be extended later (shared company, shared school, etc.)
Follow-up: At LinkedIn scale, a live 2-hop BFS per request is too slow. Discuss precomputing and caching suggestions offline via a batch job instead.
40. Design a Connection Request & Mutual Connections System Medium
Design a system that handles sending, accepting, and rejecting connection requests, and can efficiently compute the mutual connection count between any two users.
System.sendRequest(fromUserId, toUserId)
System.acceptRequest(requestId) / rejectRequest(requestId)
System.getMutualConnections(userA, userB) → List<UserId>
Approach: ConnectionRequest (id, fromUserId, toUserId, status: PENDING/ACCEPTED/REJECTED). On accept, create bidirectional Connection edges for both users in an adjacency-list style store. getMutualConnections() intersects userA's and userB's connection sets (a HashSet intersection). Key Design Principles: Explicit request/connection state separation (a pending request is not yet an edge), O(min(deg(A), deg(B))) mutual-connection computation via set intersection Follow-up: How do you prevent duplicate pending requests between the same two users sent in both directions simultaneously (a race condition)?
41. Design a Profile View Tracker Medium
Design a system that records who viewed a user's profile and lets that user see a list of recent viewers (subject to privacy settings), without double-counting rapid repeated views from the same viewer.
ProfileViewTracker.recordView(viewerId, profileOwnerId)
ProfileViewTracker.getRecentViewers(profileOwnerId, limit) → List<ViewEvent>
Approach: ViewEvent (viewerId, profileOwnerId, timestamp). recordView() checks the most recent existing event for that (viewer, owner) pair and skips recording if within a de-duplication window (e.g. 24 hours), otherwise inserts a new event. getRecentViewers() queries events for that owner sorted by timestamp descending, filtering out viewers who have "private mode" enabled. Key Design Principles: De-duplication window to avoid recording rapid repeat views as noise, privacy filtering applied at read-time rather than baked into storage Follow-up: How would you support "anonymous view" mode, where the owner sees that someone viewed their profile but not who?
42. Design a Notification System Medium
Design a service that sends notifications (connection request, profile view, post like) to users through their preferred channels (push, email, in-app), where each notification type has different default channel behaviour.
NotificationService.notify(userId, eventType, payload)
// User has per-eventType channel preferences
Approach: A NotificationChannel interface (PushChannel, EmailChannel, InAppChannel implementations) selected via Strategy pattern based on the user's preference for that eventType. notify() looks up preferences, builds the appropriate message per channel, and dispatches asynchronously through a queue so a slow channel provider never blocks the triggering action. Key Design Principles: Strategy pattern for channel selection, async dispatch via a queue for resilience, per-event-type preference lookup rather than a single global preference Follow-up: How do you batch multiple similar notifications (e.g. "5 people viewed your profile") instead of sending 5 separate ones?
43. Design LinkedIn's News Feed Hard
LinkedIn's single most frequently reported HLD question. Design the backend that generates a personalised feed of posts from a user's connections, ranked by relevance and freshness, for hundreds of millions of users.
Functional: getFeed(userId, pageSize, cursor), createPost(userId, content)
Non-functional: <200ms feed load latency, handle users with 10M+ followers (influencers) without degrading normal users' write latency
Approach: Hybrid fan-out: for regular users (under ~10K connections), fan-out-on-write pushes new posts directly into each connection's precomputed feed (stored in Redis/a feed store) at post time. For high-follower accounts, fan-out-on-read merges their posts into the requester's feed at read time instead, avoiding a massive write amplification. A ranking service (separate from the raw feed) re-scores the candidate posts by relevance, freshness, and engagement signals before returning the final page. Key Design Principles: Hybrid fan-out-on-write/fan-out-on-read split by follower count, cursor-based pagination, ranking as a separate concern from feed assembly Follow-up: How do you handle a user editing or deleting a post after it has already been fanned out to millions of precomputed feeds?
44. Design the Connections Graph (Degrees of Separation Search) Hard
Design the backend that stores LinkedIn's connection graph (billions of nodes and edges) and answers 'degree of connection' queries (1st, 2nd, 3rd+) between any two users in real time.
Functional: getDegreeOfConnection(userA, userB), getConnections(userId)
Non-functional: billions of nodes/edges, sub-second degree lookups, connection graph changes constantly
Approach: Store the graph in a graph-native or graph-optimised store (adjacency lists sharded by userId, or a dedicated graph database). For degree lookups, bidirectional BFS from both userA and userB simultaneously, meeting in the middle, capped at 3 hops (LinkedIn only distinguishes 1st/2nd/3rd+, so BFS can stop early). Cache hot users' (celebrities') immediate connection lists aggressively since they are queried disproportionately often. Key Design Principles: Bidirectional BFS capped at a small hop limit (since exact distance beyond 3 is not needed), sharding by userId for horizontal scale, aggressive caching for high-degree nodes Follow-up: Why does capping BFS at 3 hops matter so much for performance at LinkedIn's actual graph density, walk through the node-explosion math.
45. Design LinkedIn People & Job Search Hard
Design a search system that lets users search for people (by name, company, skills) and jobs (by title, location, skills), with results personalised by the searching user's own profile and network.
Functional: searchPeople(query, filters), searchJobs(query, filters)
Non-functional: <150ms search latency, results ranked by relevance + network proximity, near-real-time updates when a profile changes
Approach: Elasticsearch (or similar) indexes profile/job documents for full-text and filtered search, kept in sync via a change-data-capture pipeline (Kafka consumer reading DB writes) rather than dual writes. Personalisation is applied as a re-ranking step after the base search results are fetched, boosting results with closer network proximity (using the Connections Graph service) or shared attributes (same company/school). Key Design Principles: CDC-based index sync (not dual writes) to avoid search/DB drift, personalisation as a separate re-ranking layer decoupled from base retrieval Follow-up: How do you keep search results from feeling stale when a user updates their profile (e.g. a new job title) but the search index has not caught up yet?
46. Number of Provinces Medium
Given an n x n adjacency matrix, return the number of provinces (connected components), directly analogous to counting disconnected clusters in a connections graph.
Input: isConnected = [[1,1,0],[1,1,0],[0,0,1]]
Output: 2
Approach: Union-Find: union every connected pair, count distinct root parents at the end.
Complexity: Time O(n^2 * α(n)) · Space O(n)
Follow-up: Solve it for a streaming sequence of connection updates instead of a fixed matrix.
47. Course Schedule II Medium
Given numCourses and prerequisite pairs, return a valid course order, or an empty array if impossible.
Input: numCourses = 4, prerequisites = [[1,0],[2,0],[3,1],[3,2]]
Output: [0,1,2,3]
Approach: Kahn's algorithm: process nodes with in-degree 0, decrementing neighbours, building the order as you go.
Complexity: Time O(V + E) · Space O(V + E)
Follow-up: Return all valid topological orderings.
48. Kth Smallest Element in a BST Medium
Given the root of a BST and k, return the kth smallest value in the tree.
Input: root = [3,1,4,null,2], k = 1
Output: 1
Approach: Inorder traversal visits BST nodes in ascending order; stop once the kth node is visited.
Complexity: Time O(h + k) · Space O(h)
Follow-up: Handle frequent insert/delete with repeated kth-smallest queries.
49. Longest Common Subsequence Medium
Given two strings, return the length of their longest common subsequence.
Input: text1 = "abcde", text2 = "ace"
Output: 3
Approach: 2D DP where dp[i][j] = LCS of text1[0..i) and text2[0..j), matching characters extend diagonally, otherwise take the max of excluding one character from either string.
Complexity: Time O(m * n) · Space O(m * n), reducible to O(min(m,n))
Follow-up: Reconstruct the actual subsequence string.
50. Maximum Product Subarray Medium
Given an integer array, find a contiguous subarray with the largest product.
Input: nums = [2,3,-2,4]
Output: 6
Approach: Track both max and min product ending at the current index (a negative number can flip a very negative product into the new max), updating both at every step.
Complexity: Time O(n) · Space O(1)
Follow-up: Return the actual subarray, not just the product.
Preparation Tips
LinkedIn's DSA rounds lean unusually heavily on graphs and trees given the product itself is a graph of people, practice BFS/DFS and topological sort until they're automatic, and expect at least one tree or graph problem in nearly every round. The "coding with AI" round is genuinely unique to LinkedIn, prepare by practicing how to direct, review, and correct AI-generated code out loud rather than just accepting suggestions. For System Design, the News Feed (fan-out-on-write vs fan-out-on-read) and the Connections Graph (bidirectional BFS, degree-of-separation search) are asked so often that knowing both cold is the single highest-leverage system design prep you can do.
Join Telegram group to get the latest LinkedIn OA questions and connect with candidates currently in the LinkedIn interview process.