Skip to content

TCS 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 TCS hiring for Data Structures and Algorithms roles

Tata Consultancy Services is a Tata Group company and one of the largest IT services and consulting firms in the world. It delivers application development, testing, cloud, data and analytics services to clients in banking, retail, manufacturing and other industries. In India it hires freshers and experienced staff for software testing, data engineering, BI reporting and analytics roles across its delivery centres.

For Data Structures and Algorithms roles, this TCS practice set focuses most on Dynamic Programming (7), Arrays, Strings and Hashing (6), Graphs and Graph Algorithms (4), Sorting, Searching and Backtracking (3). It has 12 easy, 17 medium, 1 hard questions, so you can start easy and work up to the harder ones.

Company type
IT services
Headquarters
Mumbai, India
Main India offices
Mumbai, Chennai, Pune, Bengaluru, Hyderabad

TCS Data Structures and Algorithms interview process

  1. TCS NQT online assessment (aptitude + coding)
  2. Technical interview
  3. Managerial round
  4. HR round

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

Solved for TCSStart 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

Implement merge sort.

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
02

What are lower bound and upper bound, and what common bugs appear in binary search?

Save to ▾
Show answer
Lower bound returns the first index whose value is not less than the target, and upper bound the first index whose value is greater, so their difference counts occurrences. Common bugs are off-by-one errors in the loop condition, infinite loops when mid does not move, and integer overflow from (low plus high) divided by 2 in Java or C++; use low plus (high minus low) divided by 2. Python's bisect module provides both functions.
03

What is a greedy algorithm and when does it give the optimal answer?

Save to ▾
Show answer
A greedy algorithm builds a solution step by step, always taking the choice that looks best right now and never revisiting it. It is optimal only when the problem has the greedy choice property, meaning a locally best choice is part of some optimal solution, and optimal substructure. Examples where greedy works are activity selection, Huffman coding, Dijkstra and Kruskal. For many problems, such as 0/1 knapsack, it fails.
04

How do you recognise a DP problem and define its state?

Save to ▾
Show answer
Signals include asking for a minimum, maximum, count of ways or whether something is possible, with choices at each step that affect later options. Start from brute-force recursion and ask what parameters fully describe a subproblem, such as index, remaining capacity or last chosen item; those become the state. Then write the transition between states, the base cases and the order of computation, and check the state count times transition cost fits limits.
05

A warehouse robot moves only right or down on a grid with some blocked cells. How do you count the number of paths?

Save to ▾
Show answer
Use DP where dp[r][c] is the number of ways to reach cell r, c. A blocked cell has 0 ways; the start has 1; every other cell is dp[r-1][c] plus dp[r][c-1]. Fill row by row in O(rows times columns), and keep a single row array to use O(columns) space. Counts can become huge, so problems often ask for the result modulo 10 to the power 9 plus 7.
06

Check whether a string is a palindrome, ignoring case and non-alphanumeric characters.

Save to ▾
Show answer
// Java static boolean isPalindrome(String s) { int i = 0, j = s.length() - 1; while (i < j) { char a = s.charAt(i), b = s.charAt(j); if (!Character.isLetterOrDigit(a)) { i++; continue; } if (!Character.isLetterOrDigit(b)) { j--; continue; } if (Character.toLowerCase(a) != Character.toLowerCase(b)) return false; i++; j--; } return true; } // Two pointers, O(n) time, O(1) space.
07

Tell me about a time you worked with people from other teams to solve a complex problem.

Save to ▾
Show answer
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.
08

Find the lowest common ancestor of two nodes in a binary tree.

Save to ▾
Show answer
def lca(root, p, q): if root is None or root is p or root is q: return root left = lca(root.left, p, q) right = lca(root.right, p, q) if left and right: # p and q are on different sides return root return left or right # O(n) time, O(h) space; assumes both nodes exist in the tree
09

Implement 0/1 knapsack using a one-dimensional DP array.

Save to ▾
Show answer
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

What is the difference between full, complete and perfect binary trees?

Save to ▾
Show answer
In a full binary tree every node has zero or two children. In a complete binary tree every level except possibly the last is completely filled, and the last level is filled from the left, which is exactly the shape of a binary heap and allows array storage. A perfect binary tree has all internal nodes with two children and all leaves at the same level, containing 2 to the power h plus 1, minus 1 nodes.
11

You need to build a tool that shows the differences between two versions of a file line by line. What algorithm would you use?

Save to ▾
Show answer
The core is the longest common subsequence over lines: lines in the LCS are unchanged, and the rest are additions or deletions. Hash each line first so comparisons are fast. Classic LCS DP is O(m times n), which is too slow for large files, so real diff tools use Myers' algorithm, which runs in O((m plus n) times d), where d is the number of differences, fast when versions are similar.
12

How can you reduce the space used by a DP solution?

Save to ▾
Show answer
If each row of the table depends only on the previous row, keep two rows or even a single array, reducing O(n times m) space to O(m). Fibonacci-like problems need only the last two values, so O(1). For 0/1 knapsack in one array, iterate capacity from high to low so each item is used once; for unbounded knapsack iterate low to high. The trade-off is that reconstructing the actual solution becomes harder.
13

Implement fast exponentiation to compute x to the power n in O(log n).

Save to ▾
Show answer
def power(x, n): if n < 0: x, n = 1 / x, -n result = 1 while n > 0: if n & 1: # odd bit set: multiply current base in result *= x x *= x # square the base n >>= 1 # move to next bit return result # power(2, 10) == 1024; use % mod after each multiply for modular power
14

What is Kadane's algorithm?

Save to ▾
Show answer
Kadane's algorithm finds the maximum sum contiguous subarray in O(n) time and O(1) space. At each element it decides whether to extend the current subarray or start fresh: current = max(x, current + x), and best = max(best, current). The insight is that a negative running sum never helps a future subarray. For an all-negative array it correctly returns the largest single element when initialised with the first value.
15

Find the first and last position of a target in a sorted array.

Save to ▾
Show answer
from bisect import bisect_left, bisect_right def search_range(nums, target): lo = bisect_left(nums, target) # first index >= target if lo == len(nums) or nums[lo] != target: return [-1, -1] hi = bisect_right(nums, target) - 1 # last index <= target return [lo, hi] # [5,7,7,8,8,10], 8 -> [3, 4]; two binary searches: O(log n)
16

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.
17

Why is naive recursive Fibonacci exponential, and how do you fix it?

Save to ▾
Show answer
fib(n) calls fib(n-1) and fib(n-2), and each of those branches again, so the call tree has roughly 1.6 to the power n nodes and the same subproblems are recomputed many times. fib(40) makes over 300 million calls. Memoisation stores each result after the first computation, reducing it to O(n) time. A bottom-up loop keeping only the last two values gives O(n) time and O(1) space.
18

Explain the sliding window technique with fixed and variable windows.

Save to ▾
Show answer
A sliding window keeps a contiguous range and updates its result incrementally instead of recomputing. A fixed window of size k, such as the maximum sum of k consecutive elements, adds the new element and removes the old one each step in O(n). A variable window grows the right end and shrinks the left end while a condition is violated, as in the longest substring without repeating characters. Both turn O(n squared) into O(n).
19

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.
20

What is a binary search tree and what is its time complexity?

Save to ▾
Show answer
In a BST every node's left subtree contains smaller keys and the right subtree larger keys. Search, insert and delete follow one path from the root, so they take O(h) time, where h is the height. A balanced tree has h about log n, giving O(log n). Inserting sorted data into a plain BST creates a skewed tree that behaves like a linked list with O(n) operations, which is why balanced variants exist.
21

Tell me about a time you had to make a decision with incomplete information.

Save to ▾
Show answer
Situation: during a release, a performance test showed occasional slow responses but the logs were incomplete. Task: decide whether to ship on schedule. Action: I listed what we knew, estimated the impact using the available percentiles, proposed shipping behind a feature flag with extra monitoring, and prepared a rollback plan. Result: we shipped on time, the extra metrics revealed a slow cache warm-up that we fixed in the next patch with no user complaints.
22

What is the two pointer technique and when is it used?

Save to ▾
Show answer
Two pointers move through an array or string, often from both ends or at different speeds, to avoid nested loops. On a sorted array you can find a pair with a given sum in O(n) by moving left or right depending on the current sum. It is also used for reversing, removing duplicates in place, merging sorted arrays, palindrome checks and partitioning. It usually needs sorted data or a monotonic condition.
23

Find the shortest path length from the top-left to the bottom-right of a grid where 1 is a wall.

Save to ▾
Show answer
from collections import deque def shortest_path(grid): R, C = len(grid), len(grid[0]) if grid[0][0] or grid[R-1][C-1]: return -1 q = deque([(0, 0, 1)]) seen = {(0, 0)} while q: r, c, d = q.popleft() if (r, c) == (R - 1, C - 1): return d for dr, dc in ((1, 0), (-1, 0), (0, 1), (0, -1)): nr, nc = r + dr, c + dc if 0 <= nr < R and 0 <= nc < C and not grid[nr][nc] and (nr, nc) not in seen: seen.add((nr, nc)) q.append((nr, nc, d + 1)) return -1 # BFS: O(R * C)
24

Solve climbing stairs: how many ways are there to climb n steps taking 1 or 2 steps at a time?

Save to ▾
Show answer
def climb_stairs(n): if n <= 2: return n prev2, prev1 = 1, 2 # ways(1), ways(2) for _ in range(3, n + 1): prev2, prev1 = prev1, prev1 + prev2 return prev1 # ways(n) = ways(n-1) + ways(n-2): a Fibonacci pattern # climb_stairs(5) -> 8; O(n) time, O(1) space
25

How does Floyd's cycle detection algorithm work and why is it correct?

Save to ▾
Show answer
Floyd uses a slow pointer moving one step and a fast pointer moving two steps. If there is no cycle, fast reaches the end. If there is a cycle, fast gains one step per iteration on slow inside the loop, so they must meet. To find the cycle start, reset one pointer to the head and move both one step at a time; they meet at the start because the distances from head and from the meeting point are equal modulo the cycle length.
26

How would you check whether two strings are anagrams, and what changes if input can contain any Unicode characters?

Save to ▾
Show answer
For lowercase English letters, compare character counts using an array of 26 integers in O(n) time and O(1) space; sorting both strings also works in O(n log n). With arbitrary Unicode, use a hash map of counts instead of a fixed array. I would also clarify whether case and spaces matter and whether to normalise accented characters, since visually identical text can have different code point sequences.
27

Where do you see yourself in five years?

Save to ▾
Show answer
Situation: I am starting my career with a strong interest in solving algorithmic and system problems. Task: grow into an engineer others rely on. Action: in the first years I want to master the codebase, deliver features reliably and deepen my skills in data structures, system design and the domain. Result: in five years I see myself as a senior engineer owning important components, mentoring juniors and contributing to design decisions in this team.
28

What is the difference between a static array and a dynamic array?

Save to ▾
Show answer
A static array has a fixed size set at creation, such as int[] in Java, and offers O(1) index access with contiguous memory. A dynamic array such as Java ArrayList or Python list grows automatically by allocating a larger block and copying elements, giving amortised O(1) append. Both have O(n) insertion or deletion in the middle because elements must shift. Dynamic arrays trade a little memory for flexibility.
29

How does Huffman coding work?

Save to ▾
Show answer
Huffman coding builds an optimal prefix-free binary code for compression. Put each character with its frequency into a min-heap. Repeatedly remove the two least frequent nodes, merge them into a new node whose frequency is their sum, and push it back. The final tree gives codes: left edges are 0 and right edges are 1, so frequent characters get shorter codes. It runs in O(n log n) and is used in ZIP and JPEG.
30

List common complexity classes from fastest to slowest with examples.

Save to ▾
Show answer
O(1): array index access or a hash lookup on average. O(log n): binary search. O(n): linear scan. O(n log n): merge sort and heap sort. O(n squared): nested loops over pairs, as in bubble sort. O(2 to the power n): generating all subsets. O(n factorial): generating all permutations. For n around one lakh, anything up to O(n log n) is comfortable, while O(n squared) usually times out.

Tips to crack the TCS Data Structures and Algorithms interview

  • Practise TCS NQT style numerical, verbal and reasoning sections along with two basic coding problems under strict time limits.
  • Be ready to explain your final-year project, SQL basics and core concepts like OOP, DBMS and software testing life cycle.
  • Read about TCS service lines such as BFSI and its iON and Ignio platforms to answer why you want to join.
  • 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; TCS interviewers usually ask follow-ups on your first answer.

Frequently asked questions

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

Candidates usually go through 4 stages: TCS NQT online assessment (aptitude + coding); Technical interview; Managerial 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 TCS Data Structures and Algorithms interview?

This practice set leans on Dynamic Programming (7), Arrays, Strings and Hashing (6), Graphs and Graph Algorithms (4), Sorting, Searching and Backtracking (3). Revise those first, then practise explaining one or two of your own projects end to end, because most TCS interviewers ask you to walk through real work.

Are these the exact questions asked at TCS?

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

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

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

Data Structures and Algorithms questions for similar companies