Given a palindromic number num having n number of digits. The problem is to find the smallest palindromic number greater than num using the same set of digits as in num. If no such number can be formed then return "-1".
Examples:
Input: n = "35453"
Output: 53435
Explanation: Next higher palindromic number is 53435.Input: n = "33"
Output: -1
Explanation: Next higher palindromic number does not exist.
Table of Content
[Brute Force Approach] Checking Every Larger Number – O(10ⁿ × n) Time and O(1) Space
The idea is to generate every number greater than the given palindrome and check whether it satisfies two conditions:
- It must itself be a palindrome
- It must contain the same frequency of digits as the original number
For every candidate number, palindrome verification is performed using two pointers, and digit frequencies are compared using frequency arrays. The first valid number found is returned as the next palindrome. If no such number exists,
-1is returned.
#include <bits/stdc++.h>
using namespace std;
// Function to check if two numbers have
// same digit frequency
bool sameFreq(string a, string b) {
vector<int> freqA(10, 0), freqB(10, 0);
for (char c : a) freqA[c - '0']++;
for (char c : b) freqB[c - '0']++;
return freqA == freqB;
}
// Function to check if a number is palindrome
bool isPalindrome(string num) {
int i = 0, j = num.length() - 1;
while (i < j) {
if (num[i]!= num[j]) return false;
i++;
j--;
}
return true;
}
// Two-Pointer Increment Approach
string nextPalin(string &n) {
long long num = stoll(n);
long long maxLimit = pow(10, n.length()) - 1;
// Try numbers greater than n
for (long long x = num + 1; x <= maxLimit; x++) {
string curr = to_string(x);
// Check if x has same length (to maintain digit count)
if (curr.length() > n.length()) break;
// Check palindrome property
if (!isPalindrome(curr)) continue;
// Check same digit frequency
if (sameFreq(n, curr)) {
return curr;
}
}
return "-1";
}
// Driver code
int main() {
string n = "1221";
string result = nextPalin(n);
cout << "Input: " << n << endl;
cout << "Output: " << result << endl;
return 0;
}
import java.util.Arrays;
// Function to check if two numbers have
// same digit frequency
public static boolean sameFreq(String a, String b) {
int[] freqA = new int[10];
int[] freqB = new int[10];
for (char c : a.toCharArray()) freqA[c - '0']++;
for (char c : b.toCharArray()) freqB[c - '0']++;
return Arrays.equals(freqA, freqB);
}
// Function to check if a number is palindrome
public static boolean isPalindrome(String num) {
int i = 0, j = num.length() - 1;
while (i < j) {
if (num.charAt(i)!= num.charAt(j)) return false;
i++;
j--;
}
return true;
}
// Two-Pointer Increment Approach
public static String nextPalin(String n) {
long num = Long.parseLong(n);
long maxLimit = (long) Math.pow(10, n.length()) - 1;
// Try numbers greater than n
for (long x = num + 1; x <= maxLimit; x++) {
String curr = Long.toString(x);
// Check if x has same length (to maintain digit count)
if (curr.length() > n.length()) break;
// Check palindrome property
if (!isPalindrome(curr)) continue;
// Check same digit frequency
if (sameFreq(n, curr)) {
return curr;
}
}
return "-1";
}
// Driver code
public static void main(String[] args) {
String n = "1221";
String result = nextPalin(n);
System.out.println("Input: " + n);
System.out.println("Output: " + result);
}
from array import array
# Function to check if two numbers have
# same digit frequency
def sameFreq(a, b):
freqA = [0] * 10
freqB = [0] * 10
for c in a: freqA[int(c)] += 1
for c in b: freqB[int(c)] += 1
return freqA == freqB
# Function to check if a number is palindrome
def isPalindrome(num):
i, j = 0, len(num) - 1
while i < j:
if num[i]!= num[j]: return False
i += 1
j -= 1
return True
# Two-Pointer Increment Approach
def nextPalin(n):
num = int(n)
maxLimit = pow(10, len(n)) - 1
# Try numbers greater than n
for x in range(num + 1, maxLimit + 1):
curr = str(x)
# Check if x has same length (to maintain digit count)
if len(curr) > len(n):
break
# Check palindrome property
if not isPalindrome(curr):
continue
# Check same digit frequency
if sameFreq(n, curr):
return curr
return "-1"
# Driver code
if __name__ == '__main__':
n = "1221"
result = nextPalin(n)
print('Input:', n)
print('Output:', result)
using System;
class Program
{
// Function to check if two numbers have
// same digit frequency
public static bool sameFreq(string a, string b)
{
int[] freqA = new int[10];
int[] freqB = new int[10];
foreach (char c in a) freqA[c - '0']++;
foreach (char c in b) freqB[c - '0']++;
for (int i = 0; i < 10; i++)
{
if (freqA[i]!= freqB[i]) return false;
}
return true;
}
// Function to check if a number is palindrome
public static bool isPalindrome(string num)
{
int i = 0, j = num.Length - 1;
while (i < j)
{
if (num[i]!= num[j]) return false;
i++;
j--;
}
return true;
}
// Two-Pointer Increment Approach
public static string nextPalin(string n)
{
long num = long.Parse(n);
long maxLimit = (long)Math.Pow(10, n.Length) - 1;
// Try numbers greater than n
for (long x = num + 1; x <= maxLimit; x++)
{
string curr = x.ToString();
// Check if x has same length (to maintain digit count)
if (curr.Length > n.Length) break;
// Check palindrome property
if (!isPalindrome(curr)) continue;
// Check same digit frequency
if (sameFreq(n, curr))
{
return curr;
}
}
return "-1";
}
// Driver code
public static void Main(string[] args)
{
string n = "1221";
string result = nextPalin(n);
Console.WriteLine("Input: " + n);
Console.WriteLine("Output: " + result);
}
}
// Function to check if two numbers have
// same digit frequency
function sameFreq(a, b) {
let freqA = Array(10).fill(0);
let freqB = Array(10).fill(0);
for (let c of a) freqA[c.charCodeAt(0) - '0'.charCodeAt(0)]++;
for (let c of b) freqB[c.charCodeAt(0) - '0'.charCodeAt(0)]++;
return freqA.toString() === freqB.toString();
}
// Function to check if a number is palindrome
function isPalindrome(num) {
let i = 0, j = num.length - 1;
while (i < j) {
if (num[i]!== num[j]) return false;
i++;
j--;
}
return true;
}
// Two-Pointer Increment Approach
function nextPalin(n) {
let num = parseInt(n);
let maxLimit = Math.pow(10, n.length) - 1;
// Try numbers greater than n
for (let x = num + 1; x <= maxLimit; x++) {
let curr = x.toString();
// Check if x has same length (to maintain digit count)
if (curr.length > n.length) break;
// Check palindrome property
if (!isPalindrome(curr)) continue;
// Check same digit frequency
if (sameFreq(n, curr)) {
return curr;
}
}
return "-1";
}
// Driver code
let n = "1221";
let result = nextPalin(n);
console.log('Input:', n);
console.log('Output:', result);
Output
Input: 1221 Output: 2112
[Efficient Approach] Using Next Permutation Logic on First Half – O(n) Time and O(1) Space
The idea is based on the observation that a palindrome is completely determined by its first half. To obtain the next greater palindromic number using the same digits, we generate the next lexicographically greater arrangement of the first half of the palindrome and mirror the changes in the second half. If the first half is already in descending order, then no larger palindrome can be formed using the same digits.
- Find the middle index of the palindrome
- Traverse the first half from right to left: Find the first decreasing digit
- If no such digit exists, return
-1 - Find the smallest greater digit on the right side
- Swap both corresponding palindrome positions
- Reverse the remaining portions of both halves and return the resulting palindrome
#include <bits/stdc++.h>
using namespace std;
// function to reverse the digits in the
// range i to j in 'num'
void reverse(char num[], int i, int j)
{
while (i < j) {
swap(num[i], num[j]);
i++;
j--;
}
}
// function to find next higher palindromic
// number using the same set of digits
string nextPalin(string &n)
{
int len = n.length();
char num[len + 1];
strcpy(num, n.c_str());
// if length of number is less than '3'
// then no higher palindromic number
// can be formed
if (len <= 3) {
return "-1";
}
// find the index of last digit
// in the 1st half of 'num'
int mid = len / 2 - 1;
int i, j;
// Start from the (mid-1)th digit and
// find the first digit that is
// smaller than the digit next to it.
for (i = mid - 1; i >= 0; i--)
if (num[i] < num[i + 1])
break;
// If no such digit is found, then all
// digits are in descending order which
// means there cannot be a greater
// palindromic number with same set of
// digits
if (i < 0) {
return "-1";
}
// Find the smallest digit on right
// side of ith digit which is greater
// than num[i] up to index 'mid'
int smallest = i + 1;
for (j = i + 2; j <= mid; j++)
if (num[j] > num[i] &&
num[j] <= num[smallest])
smallest = j;
// swap num[i] with num[smallest]
swap(num[i], num[smallest]);
// as the number is a palindrome, the same
// swap of digits should be performed in
// the 2nd half of 'num'
swap(num[len - i - 1], num[len - smallest - 1]);
// reverse digits in the range (i+1) to mid
reverse(num, i + 1, mid);
// if n is even, then reverse digits in the
// range mid+1 to n-i-2
if (len % 2 == 0)
reverse(num, mid + 1, len - i - 2);
// else if n is odd, then reverse digits
// in the range mid+2 to n-i-2
else
reverse(num, mid + 2, len - i - 2);
// required next higher palindromic number
return string(num);
}
// Driver program to test above
int main()
{
string n = "4697557964";
string result = nextPalin(n);
cout << "Input: " << n << endl;
cout << "Output: " << result << endl;
return 0;
}
// Java program to find next higher palindromic number
// using the same set of digits
import java.util.*;
class GfG {
// function to reverse the digits in the
// range i to j in 'num' array
static void reverse(char[] num, int i, int j)
{
while (i < j) {
char temp = num[i];
num[i] = num[j];
num[j] = temp;
i++;
j--;
}
}
// function to find next higher palindromic
// number using the same set of digits
static String nextPalin(String n)
{
int len = n.length();
char[] num = n.toCharArray();
// if length of number is less than '3'
// then no higher palindromic number
// can be formed
if (len <= 3) {
return "-1";
}
// find the index of last digit
// in the 1st half of 'num'
int mid = len / 2 - 1;
int i, j;
// Start from the (mid-1)th digit and
// find the first digit that is
// smaller than the digit next to it.
for (i = mid - 1; i >= 0; i--)
if (num[i] < num[i + 1])
break;
// If no such digit is found, then all
// digits are in descending order which
// means there cannot be a greater
// palindromic number with same set of
// digits
if (i < 0) {
return "-1";
}
// Find the smallest digit on right
// side of ith digit which is greater
// than num[i] up to index 'mid'
int smallest = i + 1;
for (j = i + 2; j <= mid; j++)
if (num[j] > num[i] && num[j] <= num[smallest])
smallest = j;
// swap num[i] with num[smallest]
char temp = num[i];
num[i] = num[smallest];
num[smallest] = temp;
// as the number is a palindrome, the same
// swap of digits should be performed in
// the 2nd half of 'num'
temp = num[len - i - 1];
num[len - i - 1] = num[len - smallest - 1];
num[len - smallest - 1] = temp;
// reverse digits in the range (i+1) to mid
reverse(num, i + 1, mid);
// if n is even, then reverse digits in the
// range mid+1 to n-i-2
if (len % 2 == 0)
reverse(num, mid + 1, len - i - 2);
// else if n is odd, then reverse digits
// in the range mid+2 to n-i-2
else
reverse(num, mid + 2, len - i - 2);
// required next higher palindromic number
return new String(num);
}
// Driver program to test above
public static void main(String[] args)
{
String n = "4697557964";
String result = nextPalin(n);
System.out.println("Input: " + n);
System.out.println("Output: " + result);
}
}
# Python program to find next higher palindromic number
# using the same set of digits
# function to reverse the digits in the
# range i to j in 'num' list
def reverse(num, i, j):
while i < j:
num[i], num[j] = num[j], num[i]
i += 1
j -= 1
# function to find next higher palindromic
# number using the same set of digits
def nextPalin(n):
length = len(n)
num = list(n)
# if length of number is less than '3'
# then no higher palindromic number
# can be formed
if length <= 3:
return "-1"
# find the index of last digit
# in the 1st half of 'num'
mid = length // 2 - 1
i = mid - 1
# Start from the (mid-1)th digit and
# find the first digit that is
# smaller than the digit next to it.
while i >= 0:
if num[i] < num[i + 1]:
break
i -= 1
# If no such digit is found, then all
# digits are in descending order which
# means there cannot be a greater
# palindromic number with same set of
# digits
if i < 0:
return "-1"
# Find the smallest digit on right
# side of ith digit which is greater
# than num[i] up to index 'mid'
smallest = i + 1
for j in range(i + 2, mid + 1):
if num[j] > num[i] and num[j] <= num[smallest]:
smallest = j
# swap num[i] with num[smallest]
num[i], num[smallest] = num[smallest], num[i]
# as the number is a palindrome, the same
# swap of digits should be performed in
# the 2nd half of 'num'
num[length - i - 1], num[length - smallest - 1] = \
num[length - smallest - 1], num[length - i - 1]
# reverse digits in the range (i+1) to mid
reverse(num, i + 1, mid)
# if n is even, then reverse digits in the
# range mid+1 to n-i-2
if length % 2 == 0:
reverse(num, mid + 1, length - i - 2)
# else if n is odd, then reverse digits
# in the range mid+2 to n-i-2
else:
reverse(num, mid + 2, length - i - 2)
# required next higher palindromic number
return ''.join(num)
# Driver program to test above
if __name__ == "__main__":
n = "4697557964"
result = nextPalin(n)
print("Input: {}".format(n))
print("Output: {}".format(result))
// C# program to find next higher palindromic number
// using the same set of digits
using System;
class GfG {
// function to reverse the digits in the
// range i to j in 'num' array
static void reverse(char[] num, int i, int j) {
while (i < j) {
char temp = num[i];
num[i] = num[j];
num[j] = temp;
i++;
j--;
}
}
// function to find next higher palindromic
// number using the same set of digits
static string nextPalin(string n) {
int len = n.Length;
char[] num = n.ToCharArray();
// if length of number is less than '3'
// then no higher palindromic number
// can be formed
if (len <= 3) {
return "-1";
}
// find the index of last digit
// in the 1st half of 'num'
int mid = len / 2 - 1;
int i, j;
// Start from the (mid-1)th digit and
// find the first digit that is
// smaller than the digit next to it.
for (i = mid - 1; i >= 0; i--)
if (num[i] < num[i + 1])
break;
// If no such digit is found, then all
// digits are in descending order which
// means there cannot be a greater
// palindromic number with same set of
// digits
if (i < 0) {
return "-1";
}
// Find the smallest digit on right
// side of ith digit which is greater
// than num[i] up to index 'mid'
int smallest = i + 1;
for (j = i + 2; j <= mid; j++)
if (num[j] > num[i] &&
num[j] <= num[smallest])
smallest = j;
// swap num[i] with num[smallest]
char temp = num[i];
num[i] = num[smallest];
num[smallest] = temp;
// as the number is a palindrome, the same
// swap of digits should be performed in
// the 2nd half of 'num'
temp = num[len - i - 1];
num[len - i - 1] = num[len - smallest - 1];
num[len - smallest - 1] = temp;
// reverse digits in the range (i+1) to mid
reverse(num, i + 1, mid);
// if n is even, then reverse digits in the
// range mid+1 to n-i-2
if (len % 2 == 0)
reverse(num, mid + 1, len - i - 2);
// else if n is odd, then reverse digits
// in the range mid+2 to n-i-2
else
reverse(num, mid + 2, len - i - 2);
// required next higher palindromic number
return new string(num);
}
// Driver program to test above
static void Main(string[] args) {
string n = "4697557964";
string result = nextPalin(n);
Console.WriteLine($"Input: {n}");
Console.WriteLine($"Output: {result}");
}
}
// JavaScript program to find next higher palindromic number
// using the same set of digits
// function to reverse the digits in the
// range i to j in 'num' array
function reverse(num, i, j) {
while (i < j) {
[num[i], num[j]] = [num[j], num[i]];
i++;
j--;
}
}
// function to find next higher palindromic
// number using the same set of digits
function nextPalin(n) {
let len = n.length;
let num = n.split('');
// if length of number is less than '3'
// then no higher palindromic number
// can be formed
if (len <= 3) {
return "-1";
}
// find the index of last digit
// in the 1st half of 'num'
let mid = Math.floor(len / 2) - 1;
let i, j;
// Start from the (mid-1)th digit and
// find the first digit that is
// smaller than the digit next to it.
for (i = mid - 1; i >= 0; i--)
if (num[i] < num[i + 1])
break;
// If no such digit is found, then all
// digits are in descending order which
// means there cannot be a greater
// palindromic number with same set of
// digits
if (i < 0) {
return "-1";
}
// Find the smallest digit on right
// side of ith digit which is greater
// than num[i] up to index 'mid'
let smallest = i + 1;
for (j = i + 2; j <= mid; j++)
if (num[j] > num[i] &&
num[j] <= num[smallest])
smallest = j;
// swap num[i] with num[smallest]
[num[i], num[smallest]] = [num[smallest], num[i]];
// as the number is a palindrome, the same
// swap of digits should be performed in
// the 2nd half of 'num'
[num[len - i - 1], num[len - smallest - 1]] =
[num[len - smallest - 1], num[len - i - 1]];
// reverse digits in the range (i+1) to mid
reverse(num, i + 1, mid);
// if n is even, then reverse digits in the
// range mid+1 to n-i-2
if (len % 2 === 0)
reverse(num, mid + 1, len - i - 2);
// else if n is odd, then reverse digits
// in the range mid+2 to n-i-2
else
reverse(num, mid + 2, len - i - 2);
// required next higher palindromic number
return num.join('');
}
// Driver program to test above
const n = "4697557964";
const result = nextPalin(n);
console.log(`Input: ${n}`);
console.log(`Output: ${result}`);
Output
Input: 4697557964 Output: 4756996574