TCS Ninja Coding Questions

Published: 11 Feb 2025 | Reading Time: 7 min read

Overview

Tata Consultancy Services (TCS) is among the most sought-after companies for freshers and experienced professionals alike, and TCS Ninja is the hiring process that piques the interest of both. The process consists of coding challenges with precise expectations to evaluate a candidate's level of skill. These TCS Ninja coding questions aim to assess problem-solving skills, technical proficiencies, and logical thinking in general.

Understanding the types of coding questions that TCS Ninja usually asks, as well as how to approach these questions and some best practices on how to cruise through the tests, can be crucial while preparing for this competitive interview. This article looks into the various aspects of coding questions for TCS Ninja interviews, right from those targeted to freshers and experienced candidates to answer multiple-choice questions (MCQs).

Table of Contents

Everything You Need to Know About TCS

TCS Ninja

TCS Ninja is an entry-level hiring program by Tata Consultancy Services (TCS) for fresh graduates. It tests candidates' aptitude, programming, and communication skills to select them for software roles. The exam includes quantitative aptitude, logical reasoning, verbal ability, and coding. Candidates who perform well may be shortlisted for interviews assessing technical knowledge and problem-solving skills. Preparing for TCS Ninja requires a good understanding of C, Java, or Python and strong analytical skills. It is a great opportunity for students looking to start their careers in the IT industry with one of India's top companies.

How to Register for TCS Ninja Recruitment

To register for TCS Ninja Recruitment, follow these steps:

Step 1: Visit the TCS NextStep Portal

Step 2: Create an Account

Step 3: Complete the Application Form

Step 4: Apply for TCS Ninja

Step 5: Download the Application Form

Step 6: Check for Updates

Following these steps, you can successfully register for the TCS Ninja recruitment drive and begin preparing.

TCS Digital

TCS Digital, an initiative by Tata Consultancy Services (TCS), focuses on supporting businesses in their digital transformation journey while also recruiting skilled digital talent. It provides various services, including digital labs, innovative software solutions, and enhanced customer experience offerings.

How to Register for TCS Digital Recruitment

To register for TCS Digital Recruitment, follow these steps:

Step 1: Visit the TCS NextStep Portal

Go to the official TCS NextStep website: https://nextstep.tcs.com

Step 2: Create an Account

Step 3: Complete Your Profile

Step 4: Apply for TCS Digital Recruitment

Step 5: Take the Online Test

Step 6: Attend Interviews

Which One is Better to Join: TCS Ninja or TCS Digital

The choice between TCS Ninja and TCS Digital depends on your skills, experience, and career goals. Here's a comparison to help you decide:

1. Salary Package

2. Difficulty Level & Selection Process

3. Job Role & Responsibilities

4. Career Growth & Opportunities

5. Required Skills

Which One Should You Choose?

TCS Ninja Coding Round Overview

The TCS Ninja Coding Round is a crucial part of the selection process, assessing problem-solving and programming skills. Here's what you need to know:

Category Details
Number of Questions & Difficulty Level Typically 3 or 4 coding questions. Difficulty level: Hard. Covers topics like arrays, strings, recursion, sorting, and basic data structures.
Time Duration 90 minutes, depending on the exam pattern for that year.
Allowed Programming Languages Candidates can code in any of the following languages: C, C++, Java, Python, Perl
Question Types Basic Algorithmic Problems (e.g., Fibonacci series, prime numbers, factorial). String Manipulation (e.g., reversing a string, checking palindromes). Array-Based Problems (e.g., finding missing numbers, sum of elements). Mathematical & Logical Puzzles (e.g., pattern-based problems).

TCS Ninja Syllabus

The TCS Ninja recruitment process is divided into two parts: Cognitive Skills and Programming Skills. Below is the detailed syllabus:

Part A – Cognitive Skills

Numerical Ability

Verbal Ability

Reasoning Ability

Part B – Programming

Programming Logic

Data Structures & Algorithms

Hands-on Coding

Candidates can write code in any of the following programming languages:

TCS Ninja Coding Questions for Freshers

Being a fresher, the competitive TCS Ninja interview process may seem daunting. However, a well-planned approach to TCS Ninja coding questions can work wonders for your success. The interview for freshers typically tests fundamental programming skills and logical reasoning.

The most common coding questions for TCS Ninja interviews for freshers tend to focus on the following:

Overview of Freshers' Challenges

Fresh graduates entering the TCS Ninja program often face a mix of straightforward and moderately challenging coding problems. These problems typically test basic programming concepts, logical reasoning, and algorithmic thinking.

Sample Questions and Explanations

1. Reverse a String

Classic string reversal is a traditional problem that will help you in string manipulation and understand some of the basic algorithms. In Python, the slicing function makes it easy and efficient to perform such a reversal by using a step value of -1. This will allow the slice to traverse in reverse, starting from the end of the string.

For example, consider the string "hello". Using slicing in Python, we can reverse it with the following code:

Python Implementation

def reverse_string(s):
    # Slicing technique to reverse a string in Python
    return s[::-1]

# Example
input_string = "hello"
reversed_string = reverse_string(input_string)
print("Reversed String:", reversed_string)

Output:

Reversed String: olleh

=== Code Execution Successful ===

Here, s[::-1] slices the string, starting from the end and stepping backwards, producing a reversed version of the string. This approach is concise and performs well in Python.

C++ Implementation

In C++, reversing a string typically involves manually swapping characters from both ends of the string towards the centre. This iterative approach ensures that the string is reversed in place without using additional space for a new string.

#include <iostream>
#include <string>
using namespace std;

string reverse_string(string s) {
    int n = s.length();
    for (int i = 0; i < n / 2; ++i) {
        swap(s[i], s[n - i - 1]);
    }
    return s;
}

int main() {
    string input = "hello";
    string reversed = reverse_string(input);
    cout << "Reversed String: " << reversed << endl;
    return 0;
}

Output:

Reversed String: olleh

=== Code Execution Successful ===

The loop iterates up to half the length of the string, swapping characters from both ends, effectively reversing the string.

Concepts Covered: String manipulation, loops, slicing techniques

2. Find the Maximum in an Array

The maximum-finding problem has an effortless appeal. It requires the same approach of iterating through the array while maintaining a reference to the largest element that has already been seen. It is quite easy to implement with a for loop that compares each element with the current maximum in Python.

Assuming we have an array consisting of [1, 5, 3, 9, 2], we start with the assumption that the first element is the maximum. The most recent maximum will be updated each time the current maximum encounters a number larger than itself.

Python Implementation

def find_maximum(arr):
    max_element = arr[0]
    for num in arr:
        if num > max_element:
            max_element = num
    return max_element

arr = [1, 5, 3, 9, 2]
print("Maximum Element:", find_maximum(arr))

Output:

Maximum Element: 9
=== Code Execution Successful ===

The function first takes the very first element of the array and treats it as the max_element. It then traverses through the elements in the array, assigning to max_element the value of the larger number it encounters. The algorithm runs in O(n), where n is the number of elements present in the array.

C++ Implementation

#include <iostream>
#include <vector>
using namespace std;

int find_maximum(vector<int>& arr) {
    int max_element = arr[0];
    for (int i = 1; i < arr.size(); ++i) {
        if (arr[i] > max_element) {
            max_element = arr[i];
        }
    }
    return max_element;
}

int main() {
    vector<int> arr = {1, 5, 3, 9, 2};
    cout << "Maximum Element: " << find_maximum(arr) << endl;
    return 0;
}

Output:

Maximum Element: 9

=== Code Execution Successful ===

Concepts Covered: Array traversal, loops, conditionals

3. Check for Balanced Parentheses

The famous problem of parentheses balancing in a string is an implementation of the stack data structure. The approach is to push opening parentheses into the stack as they occur but popping them each time a closing parenthesis comes. If a closing parenthesis doesn't correspond to the closing of the most recent opening parenthesis, the string is not well-formed.

For instance, let us consider "(())". We will proceed through the string while, on getting the character (, we commit it to the stack. When we get a character closing parenthesis ), we check the opening parenthesis on top of the stack. Conclusively, on completion of reading the string, if the stack is now empty, it means that there are balanced parentheses.

Python Implementation

def is_balanced(s):
    stack = []
    for char in s:
        if char == '(':
            stack.append('(')
        elif char == ')':
            if not stack or stack[-1] != '(':
                return False
            stack.pop()
    return len(stack) == 0

input_string = "(())"
print("Balanced Parentheses:", is_balanced(input_string))

Output:

Balanced Parentheses: True

=== Code Execution Successful ===

This solution is implemented using a stack to make sure that every opening parenthesis has a related closing parenthesis. The stack is empty at the end which means that the parentheses are balanced.

C++ Implementation

#include <iostream>
#include <stack>
#include <string>
using namespace std;

bool is_balanced(string s) {
    stack<char> stack;
    for (char c : s) {
        if (c == '(') {
            stack.push('(');
        } else if (c == ')') {
            if (stack.empty() || stack.top() != '(') {
                return false;
            }
            stack.pop();
        }
    }
    return stack.empty();
}

int main() {
    string input = "(())";
    cout << "Balanced Parentheses: " << (is_balanced(input) ? "Yes" : "No") << endl;
    return 0;
}

Output:

Balanced Parentheses: Yes

=== Code Execution Successful ===

This solution checks for balanced parentheses in O(n) time complexity, where n is the length of the string.

Concepts Covered: Stack data structure, string traversal

4. Check if a Number is Prime

To check if the number is prime means to check if it is divisible by any number other than 1 and itself. A prime number can be nicely divisible by 1 or itself. The algorithm used to check for primality is iterating in the range of 2 to the square root of the number. This is because any factor larger than the square root would have already been found as a smaller factor.

For example, to check if 17 is prime, we iterate from 2 to the square root of 17 (approximately 4.12). Since no numbers divide 17 evenly, it is prime. On the other hand, 18 is divisible by 2 and 3, so it is not prime.

Python Implementation

import math

def is_prime(num):
    if num <= 1:
        return False
    for i in range(2, int(math.sqrt(num)) + 1):
        if num % i == 0:
            return False
    return True

print("Is 17 prime?", is_prime(17))
print("Is 18 prime?", is_prime(18))

Output:

Is 17 prime? True
Is 18 prime? False

=== Code Execution Successful ===

In the code, we employ a loop starting from 2 to the square root of the number to check for divisibility. If it finds a divisor amidst those iterations, it returns a False; if, upon completion, there are no factors, it returns a True.

C++ Implementation

#include <iostream>
#include <cmath>
using namespace std;

bool is_prime(int num) {
    if (num <= 1) return false;
    for (int i = 2; i <= sqrt(num); ++i) {
        if (num % i == 0) {
            return false;
        }
    }
    return true;
}

int main() {
    cout << "Is 17 prime? " << (is_prime(17) ? "Yes" : "No") << endl;
    cout << "Is 18 prime? " << (is_prime(18) ? "Yes" : "No") << endl;
    return 0;
}

Output:

Is 17 prime? Yes
Is 18 prime? No

=== Code Execution Successful ===

Since we are only checking for divisibility against numbers up to the square root of n, the time complexity is O(√n) which is much better than O(n) and gives time for checking divisibility for any number.

Concepts Covered: Loops, conditionals, mathematical optimization

5. Nth Fibonacci Number using Command Line Arguments

Python Implementation

# Function to calculate the Nth Fibonacci number
def fibonacci(n):
    if n <= 0:
        return "Input should be a positive integer."
    elif n == 1:
        return 0
    elif n == 2:
        return 1
    else:
        a, b = 0, 1
        for _ in range(2, n):
            a, b = b, a + b
        return b

# Main function to take user input and compute Fibonacci number
if __name__ == "__main__":
    try:
        # Get the Nth Fibonacci number from user input
        n = int(input("Enter the value of N: "))
        if n <= 0:
            print("Please enter a positive integer.")
        else:
            # Call fibonacci function and display the result
            result = fibonacci(n)
            print(f"The {n}th Fibonacci number is: {result}")
    except ValueError:
        print("Please enter a valid integer for N.")

Output:

Enter the value of N: 10
The 10th Fibonacci number is: 34

=== Code Execution Successful ===

This Python code calculates the Nth Fibonacci number by prompting the user to enter an integer value for n. It uses an iterative approach to compute the Fibonacci sequence up to the specified index. If the input is valid, it outputs the Nth Fibonacci number; otherwise, it displays an error message. For example, when the user inputs 10, the output will be "The 10th Fibonacci number is: 34."

Concepts Covered: Recursion, iteration, command line arguments, input validation

Tips for Freshers

TCS Ninja Coding Questions: Advanced

Understanding Experienced-Level Expectations

For experienced candidates, the expectations are higher. The focus shifts to much more complex and sophisticated problems that require a deeper understanding of programming concepts, data structures, and algorithms. For candidates with experience, TCS coding questions may include:

Sample Advanced Questions and Explanations

1. Longest Increasing Subsequence (LIS)

Problem Statement: Find the length of the longest increasing subsequence given an integer array. The subsequence does not have to be contiguous itself, but its elements should account for an increasing order.

In this way, we will use Dynamic Programming to solve the problem. The idea is to create a DP table where each entry dp[i] denotes the longest increasing subsequence that ends at index i. We will check, for each element of the array, whether it is extending any of those sequences that end before it by comparing it to the previous elements.

Python Implementation
def longest_increasing_subsequence(arr):
    if not arr:
        return 0

    # Initialize the dp array where each element is 1
    dp = [1] * len(arr)

    for i in range(1, len(arr)):
        for j in range(i):
            if arr[i] > arr[j]:
                dp[i] = max(dp[i], dp[j] + 1)

    # The length of the longest increasing subsequence is the maximum value in dp
    return max(dp)

# Example
arr = [10, 22, 9, 33, 21, 50, 41, 60, 80]
print("Length of Longest Increasing Subsequence:", longest_increasing_subsequence(arr))

Output:

Length of Longest Increasing Subsequence: 6

=== Code Execution Successful ===

The longest increasing subsequence for the input array [10, 22, 9, 33, 21, 50, 41, 60, 80] would be: [10, 22, 33, 50, 60, 80] and length would be 6.

C++ Implementation
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int longest_increasing_subsequence(vector<int>& arr) {
    if (arr.empty()) return 0;

    vector<int> dp(arr.size(), 1);

    for (int i = 1; i < arr.size(); ++i) {
        for (int j = 0; j < i; ++j) {
            if (arr[i] > arr[j]) {
                dp[i] = max(dp[i], dp[j] + 1);
            }
        }
    }

    return *max_element(dp.begin(), dp.end());
}

int main() {
    vector<int> arr = {10, 22, 9, 33, 21, 50, 41, 60, 80};
    cout << "Length of Longest Increasing Subsequence: " << longest_increasing_subsequence(arr) << endl;
    return 0;
}

Output:

Length of Longest Increasing Subsequence: 6

=== Code Execution Successful ===

The C++ implementation is pretty similar to the Python version. The dp array will store the length of the longest increasing subsequence that ends at every index. The nested loops compare each element with the previous elements and thus update the dp array accordingly. The result will be the maximum element in the dp array obtained, which will be the LIS length.

Concepts Covered: Dynamic Programming, array manipulation, optimization

2. Implement a Least Recently Used (LRU) Cache

Implement an LRU Cache that supports the following operations:

Approach: To build an LRU cache efficiently, you can either use an OrderedDict in Python or use a combination of a doubly linked list and a hashmap. The former keeps track of the order in which data was inserted, and the latter allows for efficient removal of the least recently used item. The hashmap allows for the fast searching of keys for the get and put operations.

Python Implementation (using OrderedDict)
from collections import OrderedDict

class LRUCache:
    def __init__(self, capacity: int):
        self.cache = OrderedDict()
        self.capacity = capacity

    def get(self, key: int) -> int:
        if key in self.cache:
            self.cache.move_to_end(key)
            return self.cache[key]
        return -1

    def put(self, key: int, value: int) -> None:
        if key in self.cache:
            self.cache.move_to_end(key)
        elif len(self.cache) == self.capacity:
            self.cache.popitem(last=False)  # Remove least recently used item
        self.cache[key] = value

# Example Usage
lru = LRUCache(2)
lru.put(1, 1)
lru.put(2, 2)
print(lru.get(1))  # Returns 1
lru.put(3, 3)      # Evicts key 2
print(lru.get(2))  # Returns -1 (not found)
lru.put(4, 4)      # Evicts key 1
print(lru.get(1))  # Returns -1 (not found)
print(lru.get(3))  # Returns 3
print(lru.get(4))  # Returns 4

The LRU Cache is created with an initial capacity. An OrderedDict is used extensively to store key-value pairs, keeping the order of their insertion. Whenever we access a key using get, if the key exists, it gets moved to the last position in the OrderedDict so that it maintains that it is the most recently used element. Whenever a new key-value pair is added, and the capacity is breached, the least recently used item is removed from the OrderedDict by using the method popitem(last=False).

After inserting keys (1,1), (2,2), and (3,3), the cache looks like this: {1:1, 2:2, 3:3}. After put(4,4), key 1 is evicted because it is the least recently used.

Output:

1
-1
-1
3
4

=== Code Execution Successful ===
C++ Implementation (using doubly linked list and hashmap)
#include <iostream>
#include <unordered_map>
using namespace std;

// Doubly Linked List Node
struct Node {
    int key, value;
    Node* prev;
    Node* next;
};

class LRUCache {
private:
    int capacity;
    unordered_map<int, Node*> cache;
    Node* head;
    Node* tail;

    void remove(Node* node) {
        node->prev->next = node->next;
        node->next->prev = node->prev;
    }

    void insert(Node* node) {
        node->next = head->next;
        node->prev = head;
        head->next->prev = node;
        head->next = node;
    }

public:
    LRUCache(int capacity) {
        this->capacity = capacity;
        head = new Node();
        tail = new Node();
        head->next = tail;
        tail->prev = head;
    }

    int get(int key) {
        if (cache.find(key) == cache.end()) {
            return -1;
        }
        Node* node = cache[key];
        remove(node);
        insert(node);
        return node->value;
    }

    void put(int key, int value) {
        if (cache.find(key) != cache.end()) {
            Node* node = cache[key];
            node->value = value;
            remove(node);
            insert(node);
        } else {
            Node* node = new Node();
            node->key = key;
            node->value = value;
            cache[key] = node;
            insert(node);

            if (cache.size() > capacity) {
                Node* lru = tail->prev;
                remove(lru);
                cache.erase(lru->key);
                delete lru;
            }
        }
    }
};

// Example
int main() {
    LRUCache cache(3);
    cache.put(1, 1);
    cache.put(2, 2);
    cache.put(3, 3);
    cout << cache.get(2) << endl; // 2
    cache.put(4, 4);
    cout << cache.get(1) << endl; // -1
    cout << cache.get(3) << endl; // 3
    cout << cache.get(4) << endl; // 4
    return 0;
}

Output:

2
-1
3
4

=== Code Execution Successful ===

This solution operates in O(1) time for both get and put operations, making it highly efficient.

Concepts Covered: Data structures (doubly linked list, hashmap), cache implementation, O(1) operations

3. Find the Lowest Common Ancestor (LCA) in a Binary Tree

The Lowest Common Ancestor (LCA) of two nodes in a binary tree is the deepest node that is an ancestor of both nodes. This problem is widely used to test your understanding of recursion, tree traversal, and working with hierarchical data structures. The simplest approach is to use recursion to traverse the tree and check for the presence of the two nodes. If the root of a subtree is equal to one of the target nodes, then that root itself is the LCA. If the two nodes are found in different subtrees, the root of the current tree is the LCA.

Python Implementation
class TreeNode:
    def __init__(self, value):
        self.value = value
        self.left = None
        self.right = None

def findLCA(root, n1, n2):
    # Base case: If the root is None or the root is one of the nodes
    if root is None or root.value == n1 or root.value == n2:
        return root

    # Recur for the left and right subtrees
    left = findLCA(root.left, n1, n2)
    right = findLCA(root.right, n1, n2)

    # If both left and right subtrees return non-None values, root is LCA
    if left and right:
        return root

    # Otherwise, return the non-None value
    return left if left else right

# Example usage
root = TreeNode(3)
root.left = TreeNode(5)
root.right = TreeNode(1)
root.left.left = TreeNode(6)
root.left.right = TreeNode(2)
root.right.left = TreeNode(0)
root.right.right = TreeNode(8)
root.left.right.left = TreeNode(7)
root.left.right.right = TreeNode(4)

n1, n2 = 5, 1
lca = findLCA(root, n1, n2)
if lca:
    print(f"LCA of {n1} and {n2} is {lca.value}")
else:
    print("LCA not found")

Output:

LCA of 5 and 1 is 3

=== Code Execution Successful ===

Concepts Covered: Binary trees, recursion, tree traversal, hierarchical data structures

Tips for Experienced Candidates

Preparing For the TCS Ninja Recruitment Process

Master Core Programming Concepts

Solve Real-Time Problems

Focus on Time and Space Complexity

Practice with Mock Tests

Prepare for the MCQ Round

General Tips

Conclusion

Cracking the TCS Ninja coding questions requires a combination of knowledge, practice, and time management skills. By focusing on foundational programming concepts, solving a wide range of problems, and preparing for both coding challenges and MCQs, you can significantly improve your chances of success. Whether you are a fresher or an experienced candidate, mastering the skills required for the TCS Ninja coding interview will set you on the path to securing a position with one of the most prestigious companies in the world.

Learn more about coding by enrolling into the Intensive 3.0 Program at https://www.ccbp.in/intensive

Frequently Asked Questions

1. What programming languages are best for TCS Ninja coding questions?

Python, Java, and C++ are highly recommended due to their versatility and efficiency.

2. Are TCS Ninja coding questions challenging?

The difficulty ranges from basic to moderate for freshers and moderate to advanced for experienced candidates.

3. Are Python coding questions frequently asked in TCS Ninja?

Yes, TCS Ninja coding questions in Python are commonly asked due to the language's simplicity and effectiveness for problem-solving.

4. Is there a negative marking in TCS Ninja MCQs?

This depends on the specific year's recruitment guidelines. Always confirm the rules before attempting.

5. What is the time duration for the TCS Ninja coding test?

Typically, the coding assessment lasts 60-90 minutes, depending on the format.


About NxtWave

NxtWave provides comprehensive IT training programs to help students and professionals prepare for technical interviews and build successful careers in technology.

Contact Information:

Course Offerings:

Additional Resources: