Practice Java coding interview questions to improve problem-solving skills and programming logic.
In this section, we have discussed some popular Coding Interview Questions. Practising the problems provided in this section will enhance your coding skills. The tutorial is beneficial for both experienced and novice candidates.
It also covers complexity analysis and corner cases to help candidates understand how to approach them. Whether you are preparing for campus placements or looking to switch to a better role, having a solid grasp of Java programming concepts is essential. The guide includes carefully selected questions that are frequently asked in technical interviews.
Each problem is designed to assess your understanding of data structures, algorithms, and core Java fundamentals. The answers are presented in a beginner-friendly manner, making it easier to follow the logic step by step.
In a Fibonacci series, the value of any term is the sum of the values of the last two terms.
For example, if we want to compute the 3rd term of the series, then it is the sum of the 1st and the 2nd term. Note that the first two terms of the Fibonacci series are defined as 0 and 1. Thus, the 3rd term will be 0 + 1 = 1. The 4th term will be the sum of the 3rd and the 2nd terms, 1 + 1 = 2. The 5th term will be the sum of the 4th and the 3rd term, which is 2 + 1 = 3.
Thus the Fibonacci series looks like the following.
0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, … (considering 1 - indexing)
Therefore, in general, the nth term of the series can be written as
F(n) = F(n - 1) + F(n - 2)
Now, we can write the program for computing the nth term of the Fibonacci series as follows. Note that the user will provide the value of n.
Output:
The 6th Fibonacci number is: 5
Complexity Analysis: The program takes O(n) time to compute the value of the Nth term of the Fibonacci series. The space complexity of the program is O(1), as no extra space is being used.
Corner Cases: The corner of this problem is handling the negative values of N, which we have done in the if-condition. In a lot of cases, it is seen that candidates miss the handling of negative values of n.
Follow-up: One can also solve this problem with the help of dynamic programming. It will consume O(n) time and O(n) space. Readers are advised to try it themselves.
If we take the number 5647, we find that the number consists of 4 digits that are 5, 6, 4, and 7. When can find the total number of digits present in a number by continuously dividing the given number by 10 using a loop, until it becomes zero. In the loop, we keep incrementing a counter in each iteration.
Output:
The total digits in number 7485 are: 4
Complexity Analysis: The time complexity of the program is O(log10(n)), where n is the input number. The space complexity of the program is O(1) because the program is not using any extra space.
Corner Cases: Observe the loop mentioned in the above program. Its terminating condition is when n != 0. So, what will happen if the input number is 0? For the number 0, separate handling is required to give answer 1. Also, we have to take care of the numbers that are negative.
The question is a modified form of the previous question. So, tweaking the above code will do the job for us, and the same is evident by looking at the following code.
Output:
The total count of digit 2 occurring in the number 2228118 is: 3
Complexity Analysis: The time complexity of the program is O(log10(n)), where n is the input number. The space complexity of the program is O(1), because the program is not using any extra space.
Corner Cases: We have to take care of cases when N and D both are 0. Also, we have to deal with situations when the user inputs a negative number.
In a recursion, one needs to look for the relation between the larger problem and the smaller problem. In this problem, there is a relationship between the larger and the smaller problem. See the following mathematical relation.
an = a x an - 1
In the programming world, we can write the above as:
(a to the power n) = a x (a to the power n - 1)
For example, 3 to the power 4 = 81. It can be computed as 3 x (3 to the power 3) = 3 x 27 = 81.
For every recurrence relation, there is a base case. In our case, the base case is when the power is 0, and we know that any number to the power 0 is 1. Now we are in a position to write the following code.
Output:
The value of 2.2 ^ 2 is: 4.840000000000001
Complexity Analysis: The time complexity of the program is O(n), where n is the input number serving the power of number y. The space complexity of the program is O(1) because the program is not using any extra space.
Corner Cases: We have to take care of cases when power is negative.
It is a well-known fact that strings are immutable in Java. Therefore, it is required to create a new string. For toggling, we can use the ASCII value; 'a can be converted to 'A' by 'A' = 'a - 32.
Code For Toggling the Cases.
Toggling can be done using ASCII values:
Output:
After toggling, the string "TpoiNttecH" becomes: "tPOInTTECh"
Complexity Analysis: The time complexity of the program is O(num). The space complexity of the program is also O(num) because the program is using extra for creating a new string, and num is the total number of characters present in the input string.
Corner Cases: We have to take care of cases when the characters of the input string do not contain small capital letters. For example, consider the string "ut8Pmn". In this string, characters 'u', 't', 'P', 'm', 'n' gets toggled to 'U', 'T', 'p', 'M', and 'N'. However, character 8 can never be toggled as there is nothing called small 8 and capital 8. Therefore, this case requires special handling.
We can create an integer array of size 256, as there are 256 characters present in the input string. Now, we count the frequency of occurrence of every character present in the input string and update the integer array accordingly. Now iterate over the integer array to check which element has the value 1. The character corresponding to that element index is printed on the console. Note that the 0th index of the array maps to 'a', the 1st index maps to 'b', and so on.
Output:
The unique characters present in the string: 'pppdaf' are: a d f
Complexity Analysis: The time complexity of the program is O(num), where num is the total number of characters present in the input string. The space complexity of the program is constant, even though we are using an integer array. Note that the size of the input array is constant.
Corner Cases: We have to take care of cases when a null string is passed, or when a string is passed that has all the duplicate characters. We have to handle that case separately.
In order to check that strings are immutable in Java, we have to use the == operator. It is because the == compares the references or the addresses of the objects. If, after making a change in the string and comparing it with the unchanged one and we get a true value, then it means strings are not immutable; otherwise, they are immutable. True value means the changed string has the same address as compared to the previous one. The following program shows the immutability of strings.
Output:
Strings are immutable.
To reverse an array using recursion without extra space, we swap the elements at the start and end indices and recursively process the sub-array by moving inward. It continues until the start index meets or crosses the end index. Since no additional data structures are used and the array is modified in place, it efficiently achieves reversal using only the recursion stack.
Output:
Original Array is: 23, 45, 12, 44, 9, 1, 22, 6 The reversed array is: 6, 22, 1, 9, 44, 12, 45, 23
Complexity Analysis: The time complexity of the program is O(num), where num is the total number of elements present in the input array. The space complexity of the program is constant, which is O(1).
The program finds the first and last index of a given element in an array using linear time and no extra space. It assumes 1-based indexing and is useful for understanding efficient array traversal in interviews.
Output:
For the target element: 2, First Index = 1 Last Index = 8
Complexity Analysis
The time complexity of the program is O(num), where num is the total number of elements present in the input array. The space complexity of the program is constant, which is O(1).
Corner Case: We have to take care of the case where the target element is not present in the array. It is because the index of the element becomes irrelevant if the element is absent.

By observing the image, it is evident that for columns that are even, the traversal is top to down, and when the columns are odd, the traversal is bottom to top. The program prints the elements of a matrix in Wave Order, where we traverse each column top to bottom for even-indexed columns and bottom to top for odd-indexed columns. It works for matrices of any size and helps understand 2D array manipulation in Java.
Output:
The wave order traversal of the input matrix is: 1 4 7 8 5 2 3 6 9
Complexity Analysis: The time complexity of the program is O(r x c), where r is the row size and c is the column size. The space complexity of the program is constant, which is O(1).
In this program, we define a class called Developer with some basic properties (like name, language, experience) and methods (like coding and displaying info). We then instantiate the class in the main method to show how object-oriented programming works in Java through class creation and method usage.
Output:
Shiva writes code. Shiva drinks tea and then converts the quadratic complexity codes to linear.
Explanation: Some things you should keep in mind: The properties must usually be set private, and we should have getter and setter methods to access and modify them. This is good OOPS practice. Also, always create a default constructor, as when we create a parameterized constructor, Java removes its own default constructor, and object creation without passing the parameters to the constructor would not be possible.
The program counts the number of vowels and consonants in a given string. The input string may contain numeric characters, but only lowercase letters are considered for counting. It helps practice character checking and string traversal in Java.
Output:
Count of vowels in the String: 'abcd44eiut' is: 4 Count of consonants in the String: 'abcd44eiut' is: 4 Count of other characters in the String: 'abcd44eiut' is: 2
Corner Cases:
One might miss the case that what will happen if the string contains some numbers or special characters like '0', '5', '#', '@', etc. These characters are neither vowels nor consonants. For characters like these, separate handling is required. Generally, candidates find the vowels count and then subtract it from the size of the string to find consonants, which will give the wrong result if the string contains some characters that are not alphabetical.
Complexity Analysis:
The time complexity of the program is O(n), where n is the total number of characters present in the input string. The space complexity of the program is O(1) as the program uses an array of size 5, which will not change if we change the input string.
The following program demonstrates inheritance with the help of the extends keyword. The following program shows a SmartPhone class that extends the Mobile class and has features like playing and stopping the music player, making a call, taking photos, etc.
Output:
Count of vowels in the String : '@51#$%290(){}' is: 0
Phone number is: 94863472
Calling the dialled number.
Music is getting Played.
Music player Paused.
Music player Stopped.
A photo is clicked.
The divide-by-zero exception, also known as ArithmeticException, occurs when we try to perform division by zero in Java. It will not be allowed in arithmetic operations and will result in a runtime error. The illustration of the same is mentioned in the following Java program, which also shows how to handle the exception using a try-catch block gracefully.
Output:
Attempting to divide 3 by zero. Exception caught: java.lang.ArithmeticException: / by zero Program is completed.
The program demonstrates a single thread in Java. In single-threading, the program executes one task at a time sequentially. Java uses the Thread class to define thread behavior. The example shows how to create a thread by extending the Thread class and running it using the start() method. It's useful to understand the basics of multithreading, starting with a single-threaded execution.
Output:
Thread[The Main Thread,7,main] The Main Thread 7
The approach is to traverse the whole string and remove all those characters that are not alphanumeric. Also, remove the white space. Convert all the alphabetical letters to either small or capital letters. After that, with the help of a loop, check whether the updated string is a palindrome or not.
Output:
The string 'a&* B BA bB a' is a palindrome.
Corner case: It is important to note that we have to convert all the alphabets to either small or capital letters. Also, we need to take care of the case when the user inputs a string that consists of only white spaces. In our case, a string containing only white spaces should be a palindrome.
Complexity Analysis: The time complexity of the program is O(n), where n is the total number of characters present in the string. The space complexity of the program is constant, i.e., O(1).
Rules for the binary addition are mentioned below.
It is evident by looking at the fourth rule that whenever the result exceeds 1, the answer of the addition becomes zero, and the carry is 1. It shows that whenever the result exceeds 1, the answer of the addition becomes 0 and the carry becomes 1. Using these four rules, we will do the addition starting from the rightmost index and will move towards the first or the leftmost index. The illustration of it is mentioned in the following program.
Output:
The addition of binary strings is: 11101
Corner case
It is important to note that the user can enter strings of any length. It is not mentioned in the question that input strings will be of the same length. Therefore, the length of the first string can be either less or more or equal to the length of the second string. Also, one should note that the final answer may or may not contain an extra bit. For example, 100 + 1 = 101 but, 111 + 111 = 1000. 1000 contains one more bit as compared to the input strings.
Complexity Analysis
The time complexity of the program is O(max(m, n)), where m is the total number of characters present in the first input string, and n is the total number of characters present in the second input string. The space complexity of the program is constant, i.e., O(1).
Two strings are considered anagrams if they have the same characters occurring the same number of times. However, the order in which they appear may or may not be different.
For example, "tpointtech" and "ttaaniojvp" are considered as anagrams. Each character present in "tpointtech" is also there in "ttaaniojvp". Also, the characters that are not present in "tpointtech" are not in "ttaaniojvp".
We will be using a HashMap to store the number of times the characters occur in the first string. Note that the character will be the key, and the number of times it occurs is its value. After that, we will traverse the second string and start reducing the frequency of occurrence of characters stored in the HashMap. If the frequency is already zero or the character is absent in the HashMap, we can say that the strings are not anagrams; otherwise, they are anagrams.
Output:
Strings 'tpointtech' & 'ttaaniojvp' are not anagrams.
Corner Cases: It is necessary to check whether the strings are of the same length or not. If not, we can say that the given strings are not anagrams.
Complexity Analysis: The time complexity of the program is O(m + n), where m and n are the sizes of the two strings. The space complexity of the program is O(1).
It is given in the problem that the array is sorted. So, the best approach is to apply the binary search. The following code is an illustration of it.
Output:
For the input array: 2 6 9 13 24 35 78 90 99 The index of the target element 7 is: 2 For the input array: -3 5 24 40 51 80 89 97 The index of the target element 51 is: 4
Complexity Analysis:
The time complexity of the program is O(log2(nums)), where nums is the total number of elements present in the input array. The space complexity of the program is O(1), as the program does not use any extra space.

The main objective is to generate the wave graph. It can be achieved by generating the peaks in the input array or looking at valley generation in the input array. So, we will try to make peaks in the array. We want the first element as the peak element, so the first element remains untouched, and we begin from the second index, leave it as it is and start from the index = 2.

Here, since we want to generate a peak, we need to have the next and previous elements greater than the second element. In the similar fashion, we will have the fourth element smaller than the third and the fifth element.
Thus, we need to take a jump of 2 indices every time until we reach the end of the given array.

Output:
The input array is: 19 18 16 13 14 17 12 After the wave sort 19 16 18 13 17 12 14 The input array is: -45 45 -50 -60 0 34 9 12 After the wave sort 45 -50 -45 -60 34 0 12 9
Complexity Analysis: The time complexity of the program is O(nums), where nums is the total number of elements present in the input array. The space complexity of the program is O(1), as the program is not using any extra space.
Corner Case: In the code, the previous and the next element are getting swapped; thus, it is required to take care of the index out-of-bounds condition.
In the following program, A class called LowBalanceExcptn is created for the bank. Therefore, when a person creates a bank account, the minimum balance the person should maintain is Rs. 7000. Therefore, when the bank balance becomes less than Rs. 7000, an exception is raised. The illustration of the same is mentioned below.
Output:
The account can't be created. Account has the low balance: The bank balance can never be less than Rs.7000/- The account has been created and the bank balance has set to: 7000 The bank account is created and the balance is set to: 10000 account - 1 balance = 0 account - 2 balance = 7000 account - 3 balance = 10000
In Java, it is not possible to implement multiple inheritance. Therefore, we need to take the help of interfaces to make a multiple inheritance scenario. In the following example, a Main class is created that implements multiple interfaces, and by doing this, multiple inheritance is achieved.
Output:
Default Interface1 Default Interface2 Now Executing methods showOfInterface1() showOfInterface2() Default Interface1 Default Interface2
Defining a class inside another class is known as the nesting of classes. Usually, in Java, the inner class is a static class. Nesting means defining one class inside another class, and such inner classes can be static or non-static. Static nested classes can be accessed without creating an instance of the outer class. The concept is useful for grouping classes logically and helps in encapsulation. Observe the following program to see how nesting is implemented in Java.
Output:
The parameterized constructor of the Outer class is invoked. The parameterized constructor of the second inner class is invoked. Z = 40 101 The parameterized constructor of the third inner class is invoked. Z = 409
A diamond problem is a problem of multiple inheritances where one class extends two or more classes. In other words, when a child class has more than one parent class, then an error occurs. The diamond problem using a Java program is discussed below.
Output:
Inside the display method of the interface C1. Inside the display method of the interface C2.
Explanation: The problem with the above code is when we override the display() method in class GC1 which method is overridden, the compiler does not know whether the class C1 display() method is overridden or of the class C2 display() method is overridden.
The method isAlive() gives information about a thread, whether it is terminated or alive. These terminated and alive are the thread states in Java. Also, the operation join() joins a thread with another, which means that a thread will have to wait for the completion of the thread to which it is joined, even if the thread has accomplished its own work. Together both will terminate.
Output:
Thread id: 14 Thread name: first Thread Thread priority: 10 Thread State: RUNNABLE Thread alive: false 1 2 3 4 5 6
We can achieve thread synchronization with the help of the synchronization keyword. When multiple threads access shared resources concurrently, there is a risk of data inconsistency or race conditions. To prevent this, Java provides synchronization, which ensures that only one thread can access a block of code or method at a time. We achieve this using the synchronized keyword. The following example shows how to protect shared resources using thread synchronization.
Output:
11 22 33 44 55 66 77 88 99 110 12 24 36 48 60 72 84 96 108 120
Whenever there is a scenario where two or more than two threads are locked forever, then that scenario is a deadlock scenario. Deadlocks usually occur in a multi-threaded environment. The following program gives demonstration of a deadlock scenario:
Output:
th1 is taking control on the lock java.lang.Object@256f00b6 th1 acquired the lock on java.lang.Object@256f00b6 th2 is taking control on the lock java.lang.Object@5cdddb56 th2 acquired the lock on java.lang.Object@5cdddb56 th3 is taking control on the lock java.lang.Object@248f4cc7 th3 acquired the lock on java.lang.Object@248f4cc7
Explanation: All of the three threads are able to take a lock on the first object. But, they are also using the resources that is shared and are started in a way that the threads keep on indefinitely waiting in order to acquire the lock on the second object.
A sudoku puzzle is a popular Japanese puzzle that is based on the logical positioning of numbers from 1 to 9. The task is to fill the 9 x 9 grid with numbers from 1 to 9 such that all columns, rows and sub-grids (there will be 9 sub-grids of 3 x 3) contain each number from 1 to 9 with zero repeats. The program for solving the sudoku is mentioned below.
Output:
5 3 4 6 7 8 9 1 2 6 7 2 1 9 5 3 4 8 1 9 8 3 4 2 5 6 7 8 5 9 7 6 1 4 2 3 4 2 6 8 5 3 7 9 1 7 1 3 9 2 4 8 5 6 9 6 1 5 3 7 2 8 4 2 8 7 4 1 9 6 3 5 3 4 5 2 8 6 1 7 9
Time complexity: In the worst case, it is required to put every number in the empty cell and check whether it is a valid one or not. Thus, there are 9 choices for every cell, making the time complexity O(9^(n x n)).
Auxiliary Space: O(n x n).
The goal is to implement a thread-safe Singleton class in Java that ensures only one instance of the class is created, even in a multi-threaded environment. It is a common design pattern used when only a single instance of a class should exist globally, such as when managing a shared resource like a database connection.
Approach:
To achieve thread safety and ensure a single instance:
Output:
Singleton instance created. Hello from Singleton! Hello from Singleton!
Complexity Analysis: Time complexity is O(1) for accessing getInstance() after initialization, with minimal synchronization overhead on the first call. Space complexity is O(1) since only a single instance is stored.
In Java, both HashMap and ConcurrentHashMap are data structures used to store key-value pairs. However, they differ in their behavior, especially in multi-threaded environments. Understanding these differences is critical for choosing the appropriate map based on the use case.
Key Differences Between HashMap and ConcurrentHashMap
| Feature | HashMap | ConcurrentHashMap |
|---|---|---|
| Thread-Safety | Not thread-safe. Needs external synchronization. | Thread-safe. Handles synchronization internally. |
| Performance | Faster in single-threaded environments. | Better suited for multi-threaded environments with minimal blocking. |
| Concurrency Level | Not suitable for concurrent operations without synchronization. | Allows multiple threads to read and write simultaneously, using segment-based locking. |
| Null Keys and Values | Allows one null key and multiple null values. | Does not allow null keys or null values. |
| Locking Mechanism | Requires the entire HashMap to be synchronized manually for thread safety. | Uses fine-grained locks (lock per segment) to minimize contention. |
| Usage | Best for single-threaded scenarios or non-concurrent collections. | Best for concurrent scenarios where read/write operations are frequent. |
| Introduced In | Java 1.2 | Java 1.5 (as part of the java.util.concurrent package). |
Implementation of HashMap
Output:
HashMap contents: city → New York name → Alice
Implementation for ConcurrentHashMap
Output:
ConcurrentHashMap Contents: city -> San Francisco name -> Bobz language -> Java
Given two arrays in Java, your task is to find their intersection. The intersection of two arrays refers to the set of elements that are common to both arrays. The result should contain only the distinct common elements, unless otherwise specified (for example, including duplicates).
Example
The intersection is:
Output:
Intersection of the two arrays: 2 3 5
Complexity Analysis
Time Complexity: The time complexity of this approach is O(n + m), where n is the size of the first array and m is the size of the second.
Space Complexity: The space complexity is O(n + k), where n is the number of elements stored in the first set, and k is the number of common elements stored in the result set.
Given a string s, the goal is to find the longest palindromic substring within it. A palindrome is a sequence of characters that reads the same forward and backwards and like "racecar" or "abba". Your task is to identify the longest such substring.
Approach: Expand Around Centre
The idea is to expand around each character in the string as a potential centre of a palindrome. For every character (and between every two characters for even-length palindromes), we try to expand outward as long as the characters at both ends match.
Why This Approach?
Output:
Longest Palindromic Substring: aba
Complexity Analysis
Time Complexity: O(n²)
For each character in the string, we expand in both directions, which in the worst case can take linear time.
Space Complexity: O(1)
No extra space is used except variables for tracking indices.
In Java, the exceptions help us handle errors gracefully during the execution of a program. While Java provides many built-in exceptions like NullPointerException, IOException, and ArrayIndexOutOfBoundsException, there are situations where we want to define our own exception that makes the code more meaningful and specific to the application logic. These are called custom exceptions.
Creating a Custom Exception
To create a custom exception in Java:
Output:
Caught Exception: Age must be 18 or above to register.
Handling text data is a common operation, and the language provides three main classes to work with strings: String, StringBuilder, and StringBuffer. While they all deal with sequences of characters, they differ significantly in how they handle memory, performance, and thread safety.
Output:
Result: Hello
Explanation: String is immutable, so even though concat() is called, the original string text is not changed unless explicitly reassigned.
Code Example: StringBuilder
Output:
Result: Hello World
Explanation:
StringBuilder is mutable and more efficient than String when frequent modifications are needed. It is ideal for single-threaded scenarios.
Code Example: StringBuffer
Output:
Result: Hello World
Explanation:
StringBuffer is also mutable, but unlike StringBuilder, it is synchronized. It makes it safe for use in multi-threaded environments, though slightly slower.
Difference Between String, StringBuilder, and StringBuffer
| Feature | String | StringBuilder | StringBuffer | |
|---|---|---|---|---|
| Mutability | Immutable | Mutable | Mutable | |
| Thread Safety | Not thread-safe | Not thread-safe | Thread-safe | |
| Performance | Slow for frequent changes | Fast | Slower than StringBuilder | |
| Synchronized | No | No | Yes | |
| Use Case | Constant data, safe from change | Efficient manipulation in single-threaded code | Safe string operations in multithreaded code | |
| Introduced In | Java 1.0 | Java 1.5 | Java 1.0 |
Reversing a linked list is a classic data structure problem that tests your understanding of pointers and node manipulation. It's a common question in interviews and serves as a foundation for many other complex operations on linked lists. In Java, we can reverse a linked list using iterative or recursive approaches.
To reverse a singly linked list in-place using the iterative approach:
Output:
Original List: 1 2 3 4 5 Reversed List: 5 4 3 2 1
Complexity Analysis
Time Complexity: O(n) where n is the number of nodes. We visit each node exactly once.
Space Complexity: O(1) constant space. We reverse the list in-place without using any additional data structures.
The Producer-Consumer problem is a classic example of a multi-threading challenge. It involves two types of threads:
The challenge is ensuring proper synchronization so the consumer does not try to consume data that has not yet been produced, and the producer does not add items when the buffer is full.
Output:
Produced: 0 Consumed: 0 Produced: 1 Produced: 2 Consumed: 1 Produced: 3 Consumed: 2 Produced: 4 Consumed: 3 Consumed: 4
Complexity Analysis
Time Complexity: Operations like put() and take() are O(1) since they are atomic operations.
Space Complexity: Depends on the queue's size (O(n) for a queue of capacity n).
Given a string, find the first character that appears only once in the entire string. If all characters are repeated, return a message indicating that.
Logic Flow:
Output:
First non-repeating character: c
Complexity Analysis
Time Complexity: We scan the string twice: once to build the map, once to find the non-repeating character. So, the time complexity is O(n).
Space Complexity: Since the character set is limited (typically 26 lowercase or 256 ASCII characters), space remains constant. So, the time complexity is O(1).
Caching is crucial for improving performance. The Least Recently Used (LRU) cache is a common strategy that removes the least recently accessed items when the cache exceeds its capacity.
The main challenge is to design a system that can:
Output:
10 -1 -1 30 40
Complexity Analysis
Time Complexity: The time complexity of get() and put() is O(1) because of the HashMap and constant-time list operations.
Space Complexity: The space complexity is O(capacity) for storing nodes in the HashMap and linked list.
Here is a resizable, thread-safe array that comes with Java thanks to the java.util.concurrent package. Every time a change is made, a new copy of the underlying array is created to guarantee thread safety. However, for lists that are updated regularly, this may use a lot of memory.
Thread safety is provided by concurrent collections, such as CopyOnWriteArrayList, which do not require explicit synchronization. Every time an element is added or modified; a new duplicate of the underlying array is created to ensure a safe iteration.
Output:
The elements present in the array is: 10 20 30 40 50
Given two sorted arrays, the task is to merge them into a single sorted array. The resulting array should also be in ascending order. Since both input arrays are already sorted, we can efficiently merge them using the two-pointer technique.
Steps
Step 4: If any elements are left in either array, add them directly to the result array.
Output:
Merged Sorted Array: [1, 2, 3, 4, 5, 6, 7, 8]
Complexity Analysis
Time Complexity: O(n + m). We visit each element exactly once.
Space Complexity: O(n + m) for storing the result array.
You are given the head of a singly linked list. Your task is to determine whether the list contains a cycle. A cycle occurs when a node's next pointer points back to a previous node in the list, creating a loop. If there's a cycle, the traversal could go on infinitely.
The most popular and efficient way to detect a cycle in a linked list is by using Floyd's Cycle Detection Algorithm there also known as the Tortoise and Hare algorithm.
How does it work?
Output:
Cycle Detected? True
Complexity Analysis
Time Complexity: Each pointer traverses the list at most once. Hence, the time complexity is O(n).
Space Complexity: No extra space is used - just two pointers. Hence, the time complexity is O(1).
Given the root node of a binary tree, your task is to determine the maximum depth (or height) of the tree. The depth is defined as the number of nodes along the longest path from the root node down to the farthest leaf node.
Approach
To find the maximum depth of a binary tree, we can use a recursive depth-first search (DFS) approach:
Output:
Maximum Depth of Binary Tree: 3
Complexity Analysis
Time Complexity: Every node is visited once. Hence, the time complexity is O(n).
Space Complexity: Due to recursive stack space, where h is the height of the tree (in worst case, could be n for a skewed tree). Hence, the time complexity is O(h).
Implement a stack (Last-In-First-Out) behavior using two queues (First-In-First-Out). In a stack, the last element inserted should be the first one to be removed. However, queues operate differently - elements are added at the rear and removed from the front. The challenge is to simulate stack operations (push, pop, and peek) using the constraints of queues.
We can implement a stack using two queues (q1 and q2) in one of two main ways:
Here, we will use the costly push() approach, where we maintain the invariant that the most recently added element is always at the front of q1.
How does it work?
The approach ensures the stack's LIFO behavior.
Output:
Top Element: 30 Popped: 30 Top Element: 20 Is Empty? False
Complexity Analysis
Time Complexity: The push() operation has a time complexity of O(n) because it involves transferring all elements from the first queue to the second each time a new element is pushed. The pop() and top() operations run in O(1) time since they directly access or remove the front element of the primary queue.
Space Complexity: The space complexity is O(n) because the implementation uses two queues to store all stack elements, resulting in space usage proportional to the number of elements stored.
In the following Java program, first, we have converted the list into a stream. After that, we have grouped the strings based on their length by using the Collectors.groupingBy(String::length) method, where String::length is a method reference that refers to the length() method of the String class. At last, the result is stored in a Map<Integer, List<String>>, where, key is the string length and the value is a list of all strings with that length.
Output:
{1=[a], 2=[bb, dd], 3=[ccc]}Given an unsorted array of integers, your task is to find the kth smallest element. For example, if the array is {7, 10, 4, 3, 20, 15} and k = 3, then the 3rd smallest element is 7. To find the kth smallest element in an efficient manner, one commonly used technique is:
Using a Min-Heap (PriorityQueue)
Output:
The 3rd smallest element is: 7
Complexity Analysis
Time Complexity: The time complexity of this approach is O(n + k log n). Inserting all n elements into the PriorityQueue (min-heap) takes O(n), and then polling the smallest element k times takes O(k log n), as each poll() operation requires log n time for reheapifying.
Space Complexity: The space complexity is O(n) because the entire array of n elements is stored in the min-heap. No additional space is used beyond this data structure, making it space-efficient in that regard.
A priority queue is a special type of queue in which each element is associated with a priority, and elements are served based on their priority (higher or lower, depending on the configuration). A min-heap is a binary tree structure where each parent node is less than or equal to its children. It allows quick access to the minimum (or highest-priority) element at the root.
Output:
[3, 5, 20, 10] Peek: 3 Poll: 3 [5, 10, 20]
Complexity Analysis
Time Complexity: The offer() and poll() operations in a custom priority queue using a binary heap each require O(log n) time because they involve maintaining the heap property through up-heap or down-heap adjustments.
Space Complexity: The space complexity is O(n) because we use an ArrayList to store all n elements in the heap structure, without any additional memory overhead beyond the list itself.
Two strings are said to be permutations of each other if they contain the same characters in the same frequency, but possibly in a different order. For example, "listen" and "silent" are permutations, while "hello" and "world" are not. Given two strings, write a Java program to check whether one string is a permutation of the other. The comparison should be case-sensitive and should consider all characters, including whitespace and special symbols.
Output:
The strings are permutations of each other.
Complexity Analysis
Time Complexity: The time complexity of this solution is O(n), where n is the length of the input strings. We go through both strings once, and hash map operations (put, get, containsKey) are all constant time on average.
Space Complexity: The space complexity is O(1) if we assume the character set is fixed and limited (like ASCII). The HashMap will have at most 128 entries. For Unicode, it would be O(n) in the worst case, depending on the character diversity.
Quicksort algorithm is based on the divide and conquer approach, where an array is divided into subarrays by selecting a pivot element. While dividing the array, the pivot element should be positioned in such a way that elements less than the pivot are kept on the left side and elements greater than the pivot are on the right side.
Output:
Unsorted Array [8, 7, 2, 1, 0, 9, 6] Sorted Array in Ascending Order [0, 1, 2, 6, 7, 8, 9]
First, creates a stream from the list. After that, it filters the stream to include only even numbers. At last, print each even number.
Output:
2 4 6
1. What is the time complexity of the binary search algorithm?
Answer: B
Explanation: Binary search has a time complexity of O(log n) as it halves the search space in each iteration.
2. When is it appropriate to use a HashMap instead of a TreeMap in Java?
Answer: D
Explanation: HashMap provides constant-time access to elements, making it suitable when fast lookups are required.
3. What is the main advantage of using an interface over an abstract class in Java?
Answer: D
Explanation: Interfaces allow classes to implement multiple behaviors, promoting loose coupling and enabling flexibility in implementation.
4. Which design pattern is used to create objects without exposing the instantiation logic to the client?
Answer: B
Explanation: The Factory Method pattern defines an interface for creating objects but allows subclasses to alter the type of objects that will be created.
5. In Java, what is the purpose of the volatile keyword?
Answer: C
Explanation: The volatile keyword in Java indicates that a variable's value will be modified by different threads asynchronously.
We request you to subscribe our newsletter for upcoming updates.