Partner – Orkes – NPI EA (cat=Spring)
announcement - icon

Modern software architecture is often broken. Slow delivery leads to missed opportunities, innovation is stalled due to architectural complexities, and engineering resources are exceedingly expensive.

Orkes is the leading workflow orchestration platform built to enable teams to transform the way they develop, connect, and deploy applications, microservices, AI agents, and more.

With Orkes Conductor managed through Orkes Cloud, developers can focus on building mission critical applications without worrying about infrastructure maintenance to meet goals and, simply put, taking new products live faster and reducing total cost of ownership.

Try a 14-Day Free Trial of Orkes Conductor today.

Partner – Orkes – NPI EA (tag=Microservices)
announcement - icon

Modern software architecture is often broken. Slow delivery leads to missed opportunities, innovation is stalled due to architectural complexities, and engineering resources are exceedingly expensive.

Orkes is the leading workflow orchestration platform built to enable teams to transform the way they develop, connect, and deploy applications, microservices, AI agents, and more.

With Orkes Conductor managed through Orkes Cloud, developers can focus on building mission critical applications without worrying about infrastructure maintenance to meet goals and, simply put, taking new products live faster and reducing total cost of ownership.

Try a 14-Day Free Trial of Orkes Conductor today.

eBook – Guide Spring Cloud – NPI EA (cat=Spring Cloud)
announcement - icon

Let's get started with a Microservice Architecture with Spring Cloud:

>> Join Pro and download the eBook

eBook – Mockito – NPI EA (tag = Mockito)
announcement - icon

Mocking is an essential part of unit testing, and the Mockito library makes it easy to write clean and intuitive unit tests for your Java code.

Get started with mocking and improve your application tests using our Mockito guide:

Download the eBook

eBook – Java Concurrency – NPI EA (cat=Java Concurrency)
announcement - icon

Handling concurrency in an application can be a tricky process with many potential pitfalls. A solid grasp of the fundamentals will go a long way to help minimize these issues.

Get started with understanding multi-threaded applications with our Java Concurrency guide:

>> Download the eBook

eBook – Reactive – NPI EA (cat=Reactive)
announcement - icon

Spring 5 added support for reactive programming with the Spring WebFlux module, which has been improved upon ever since. Get started with the Reactor project basics and reactive programming in Spring Boot:

>> Join Pro and download the eBook

eBook – Java Streams – NPI EA (cat=Java Streams)
announcement - icon

Since its introduction in Java 8, the Stream API has become a staple of Java development. The basic operations like iterating, filtering, mapping sequences of elements are deceptively simple to use.

But these can also be overused and fall into some common pitfalls.

To get a better understanding on how Streams work and how to combine them with other language features, check out our guide to Java Streams:

>> Join Pro and download the eBook

eBook – Jackson – NPI EA (cat=Jackson)
announcement - icon

Do JSON right with Jackson

Download the E-book

eBook – HTTP Client – NPI EA (cat=Http Client-Side)
announcement - icon

Get the most out of the Apache HTTP Client

Download the E-book

eBook – Maven – NPI EA (cat = Maven)
announcement - icon

Get Started with Apache Maven:

Download the E-book

eBook – Persistence – NPI EA (cat=Persistence)
announcement - icon

Working on getting your persistence layer right with Spring?

Explore the eBook

eBook – RwS – NPI EA (cat=Spring MVC)
announcement - icon

Building a REST API with Spring?

Download the E-book

Course – LS – NPI EA (cat=Jackson)
announcement - icon

Get started with Spring and Spring Boot, through the Learn Spring course:

>> LEARN SPRING
Course – RWSB – NPI EA (cat=REST)
announcement - icon

Explore Spring Boot 3 and Spring 6 in-depth through building a full REST API with the framework:

>> The New “REST With Spring Boot”

Course – LSS – NPI EA (cat=Spring Security)
announcement - icon

Yes, Spring Security can be complex, from the more advanced functionality within the Core to the deep OAuth support in the framework.

I built the security material as two full courses - Core and OAuth, to get practical with these more complex scenarios. We explore when and how to use each feature and code through it on the backing project.

You can explore the course here:

>> Learn Spring Security

Course – LSD – NPI EA (tag=Spring Data JPA)
announcement - icon

Spring Data JPA is a great way to handle the complexity of JPA with the powerful simplicity of Spring Boot.

Get started with Spring Data JPA through the guided reference course:

>> CHECK OUT THE COURSE

Partner – LambdaTest – NPI EA (cat=Testing)
announcement - icon

Accessibility testing is a crucial aspect to ensure that your application is usable for everyone and meets accessibility standards that are required in many countries.

By automating these tests, teams can quickly detect issues related to screen reader compatibility, keyboard navigation, color contrast, and other aspects that could pose a barrier to using the software effectively for people with disabilities.

Learn how to automate accessibility testing with Selenium and the LambdaTest cloud-based testing platform that lets developers and testers perform accessibility automation on over 3000+ real environments:

Automated Accessibility Testing With Selenium

1. Overview

As we know, a number is a palindrome if it remains the same when its digits are reversed.

In this tutorial, we’ll explore different ways to check if a number is a palindrome, including iterative methods, recursive methods, and a few optimized ways to achieve our goal.

2. Problem Statement

Given a positive integer N, we want to find whether it’s a palindrome.

Input: N = 12321
Output: Yes
Explanation: 12321 is a palindrome number because after reversing its digits, it becomes 12321, the same as the original number.

Input: N = 123
Output: No
Explanation: 123 isn’t a palindrome number because after reversing its digits, the number becomes 321 which is different from the original number.

Now, let’s move into the approaches that help us find if a number is a palindrome.

3. Using Iterative Approach

The most straightforward way to check if a number is a palindrome is by reversing the digits and comparing the reversed number with the original one:

public static boolean isPalindromeIterative(int number) {
    int originalNumber = number;
    int reversedNumber = 0;

    while (number > 0) {
        int digit = number % 10;
	reversedNumber = reversedNumber * 10 + digit;
	number /= 10;
    }
    return originalNumber == reversedNumber;
}

So, we start by keeping a copy of the original number. This is important because we’ll need to compare it later. Next, we reverse the number by extracting its digits one by one. We do this by taking the number’s last digit and adding it to a new number we’re building, which starts at 0. Pulling each digit off the original number, we shrink it by dividing it by 10.

Let’s see the test case for the iterative approach:

@Test
void givenNumber_whenUsingIterativeApproach_thenCheckPalindrome() {     
    assertTrue(PalindromeNumber.isPalindromeIterative(12321));
    assertFalse(PalindromeNumber.isPalindromeIterative(123));
}

Once we’ve processed all the digits, we have a reversed version of the original number. The final step is to compare this reversed number with the original one we saved earlier. If they match, it means the number is a palindrome.

Let’s understand this logic:

  • Step 1: Set originalNumber = 12321 and reversedNumber = 0.
  • Step 2: Reverse the number
    • First digit: Extract 1, update the reversed number to 1, and reduce the number to 1232.
    • Second digit: Extract 2, update the reversedNumber to 12, and reduce the number to 123.
    • Third digit: Extract 3, update the reversedNumber to 123, and reduce the number to 12.
    • Fourth digit: Extract 2, update reversedNumber to 1232, and reduce the number to 1.
    • Fifth digit: Extract 1, update the reversedNumber to 12321, and reduce the number to 0.
  • Step 3: Since, reversedNumber (12321) matches the originalNumber (12321), so the number is a palindrome.

The loop runs once for each digit in the number. If the number has n digits, the time complexity is O(n). Each operation inside the loop (modulus, division, and multiplication) takes constant time O(1). So, the overall time complexity is O(n). And, we have used a constant amount of extra space for variables like originalNumber, reversedNumber, and digit, so the space complexity is O(1).

4. Using String Conversion

Another approach is to convert the number to a string, reverse it, and compare it with the original string:

public static boolean isPalindromeString(int number) {
    String original = String.valueOf(number);
    String reversed = new StringBuilder(original).reverse().toString();
    return original.equals(reversed);
}

In this approach, we first convert the number into a string. Then, we use a handy tool called StringBuilder to reverse that string. Once we have the reversed version, we compare it to the original string. If they match, the number is a palindrome.

Let’s see the test case for the string approach:

@Test
void givenNumber_whenUsingStringApproach_thenCheckPalindrome() {
    assertTrue(PalindromeNumber.isPalindromeString(12321));
    assertFalse(PalindromeNumber.isPalindromeString(123));
}

Let’s have a dry run of this code:

  • Step 1: Convert the number to String: original = “12321”.
  • Step 2: Reverse the string using the built-in method: reversed = “12321”.
  • Final step: Compare using original.equals(reversed). Since it returns true, it indicates that the number is a palindrome.

The loop in this approach iterates once for each digit in the number, leading to a time complexity of O(n), where n is the number of digits. Each operation within the loop, such as modulus, division, and multiplication, is performed in constant time, O(1). As for space complexity, only a constant amount of extra space is required for variables like originalNumber, reversedNumber, and digit, resulting in a space complexity of O(1).

5. Using Recursive Approach

We can also check for a palindrome using recursion, though it’s more complex and not as commonly used:

public static boolean isPalindromeRecursive(int number) {
    return isPalindromeHelper(number, 0) == number;
}

private static int isPalindromeHelper(int number, int reversedNumber) {
    if (number == 0) {
        return reversedNumber;
    }
    reversedNumber = reversedNumber * 10 + number % 10;
    return isPalindromeHelper(number / 10, reversedNumber);
}

In the recursive approach, we keep a copy of the original number. This is important because we’ll need to compare it later. Next, we reverse the number by extracting its digits one by one. We do this by taking the number’s last digit and adding it to a new number we’re building, which starts at zero. Pulling each digit off the original number, we shrink it by dividing it by 10.

Below is the test case for the recursive approach:

@Test
void givenNumber_whenUsingRecursiveApproach_thenCheckPalindrome() {
    assertTrue(PalindromeNumber.isPalindromeRecursive(12321));
    assertFalse(PalindromeNumber.isPalindromeRecursive(123));
}

Once we’ve processed all the digits, we have a reversed version of the original number. The final step is to compare this reversed number with the original one we saved earlier. If they match, it means the number is a palindrome.

Let’s dry-run this code to check if 12321 is a palindrome.

  • Step 1: Call isPalindromeHelper(12321, 0).
  • Step 2: Build reversed number recursively
    • First call: Reverse the last digit 1, update reversedNumber to 1, and call isPalindromeHelper(1232, 1).
    • Second call: Reverse 2, update reversedNumber to 12, and call isPalindromeHelper(123, 12)
    • Third call: Reverse 3, update reversedNumber to 123, and call isPalindromeHelper(12, 123).
    • Fourth call: Reverse 2, update reversedNumber to 1232, and call isPalindromeHelper(1, 1232).
    • Fifth call: Reverse 1, update reversedNumber to 12321, and call isPalindromeHelper(0, 12321).
  • Base case: Return reversedNumber (12321) and compare it with the originalNumber (12321). Since they match, it confirms that the number is a palindrome.

The recursive function is called once for each digit in the number, so the time complexity is O(n). Each recursive call involves a constant-time operation O(1). The recursion depth is equal to the number of digits in the number, so the space complexity is O(n) due to the call stack.

6. Half-Reversal Approach

This approach is more space-efficient than the full reversal method because it only reverses half of the number. The idea is to reverse the digits of the second half of the number and compare it with the first half.

Let’s understand this approach step by step along with its implementation and an example:

public static boolean isPalindromeHalfReversal(int number) {
    if (number < 0 || (number % 10 == 0 && number != 0)) {
        return false;
    }
    int reversedNumber = 0;
    while (number > reversedNumber) {
        reversedNumber = reversedNumber * 10 + number % 10;
        number /= 10;
    }
    return number == reversedNumber || number == reversedNumber / 10;
}

Here is the test case for the half-reversal approach:

@Test
void givenNumber_whenUsingHalfReversalApproach_thenCheckPalindrome() {
    assertTrue(PalindromeNumber.isPalindromeHalfReversal(12321));
    assertFalse(PalindromeNumber.isPalindromeHalfReversal(123));
}

Let’s dry-run this code to check if 12321 is a palindrome:

  • Initially, number = 12321 and reversedNumber = 0.
  • First iteration: number = 1232, reversedNumber = 1.
  • Second iteration: number = 123, reversedNumber = 12.
  • Third iteration: number = 12, reversedNumber = 123.
  • The loop stops because the number (12) is no longer greater than reversedNumber (123).
  • Since number == reversedNumber / 10, the function returns true.

Since we only process half of the digits, the time complexity is O(n), where n is the number of digits and we only use a few integer variables, so the space complexity is O(1).

7. Digit-by-Digit Comparison

This approach avoids reversing the number altogether by comparing digits from the start and end of the number moving toward the center.

Let’s understand this approach step by step along with its implementation and an example:

public static boolean isPalindromeDigitByDigit(int number) {
    if (number < 0) {
        return false;
    }
    int divisor = 1;
    while (number / divisor >= 10) {
        divisor *= 10;
    }
    while (number != 0) {
        int leading = number / divisor;
        int trailing = number % 10;
        if (leading != trailing) {
            return false;
        }
        number = (number % divisor) / 10;
        divisor /= 100;
    }
    return true;
}

Here’s the test case for this approach:

@Test
void givenNumber_whenUsingDigitByDigitApproach_thenCheckPalindrome() {
    assertTrue(PalindromeNumber.isPalindromeDigitByDigit(12321));
    assertFalse(PalindromeNumber.isPalindromeDigitByDigit(123));
}

Let’s run this code for 12321:

  • For 12321, initially, divisor = 10000, which is 10^(number of digits – 1).
  • Compare the first digit (1) with the last digit (1).
  • Remove both digits, adjust the divisor, and continue comparing.
  • If all digit pairs match, return true.

Since we compare digits from both ends moving towards the center, the time complexity is O(n), where n is the number of digits and we only use a few integer variables, so space complexity remains O(1).

8. Conclusion

In this article, we came across several approaches to check whether a number is palindrome. Choosing the right approach depends on our specific needs. If we’re looking for simplicity and can afford a bit more memory usage, the string conversion method might be our go-to. The half-reversal or digit-by-digit comparison methods offer excellent performance with minimal space overhead for a more efficient solution, especially with large numbers.

Each method has its charm, and understanding these different strategies can help us choose the most appropriate one for our situation, whether we prioritize readability, memory usage, or computational efficiency.

The code backing this article is available on GitHub. Once you're logged in as a Baeldung Pro Member, start learning and coding on the project.
Baeldung Pro – NPI EA (cat = Baeldung)
announcement - icon

Baeldung Pro comes with both absolutely No-Ads as well as finally with Dark Mode, for a clean learning experience:

>> Explore a clean Baeldung

Once the early-adopter seats are all used, the price will go up and stay at $33/year.

Partner – Orkes – NPI EA (cat = Spring)
announcement - icon

Modern software architecture is often broken. Slow delivery leads to missed opportunities, innovation is stalled due to architectural complexities, and engineering resources are exceedingly expensive.

Orkes is the leading workflow orchestration platform built to enable teams to transform the way they develop, connect, and deploy applications, microservices, AI agents, and more.

With Orkes Conductor managed through Orkes Cloud, developers can focus on building mission critical applications without worrying about infrastructure maintenance to meet goals and, simply put, taking new products live faster and reducing total cost of ownership.

Try a 14-Day Free Trial of Orkes Conductor today.

Partner – Orkes – NPI EA (tag = Microservices)
announcement - icon

Modern software architecture is often broken. Slow delivery leads to missed opportunities, innovation is stalled due to architectural complexities, and engineering resources are exceedingly expensive.

Orkes is the leading workflow orchestration platform built to enable teams to transform the way they develop, connect, and deploy applications, microservices, AI agents, and more.

With Orkes Conductor managed through Orkes Cloud, developers can focus on building mission critical applications without worrying about infrastructure maintenance to meet goals and, simply put, taking new products live faster and reducing total cost of ownership.

Try a 14-Day Free Trial of Orkes Conductor today.

eBook – HTTP Client – NPI EA (cat=HTTP Client-Side)
announcement - icon

The Apache HTTP Client is a very robust library, suitable for both simple and advanced use cases when testing HTTP endpoints. Check out our guide covering basic request and response handling, as well as security, cookies, timeouts, and more:

>> Download the eBook

eBook – Java Concurrency – NPI EA (cat=Java Concurrency)
announcement - icon

Handling concurrency in an application can be a tricky process with many potential pitfalls. A solid grasp of the fundamentals will go a long way to help minimize these issues.

Get started with understanding multi-threaded applications with our Java Concurrency guide:

>> Download the eBook

eBook – Java Streams – NPI EA (cat=Java Streams)
announcement - icon

Since its introduction in Java 8, the Stream API has become a staple of Java development. The basic operations like iterating, filtering, mapping sequences of elements are deceptively simple to use.

But these can also be overused and fall into some common pitfalls.

To get a better understanding on how Streams work and how to combine them with other language features, check out our guide to Java Streams:

>> Join Pro and download the eBook

eBook – Persistence – NPI EA (cat=Persistence)
announcement - icon

Working on getting your persistence layer right with Spring?

Explore the eBook

Course – LS – NPI EA (cat=REST)

announcement - icon

Get started with Spring Boot and with core Spring, through the Learn Spring course:

>> CHECK OUT THE COURSE

eBook Jackson – NPI EA – 3 (cat = Jackson)