给定一个数字,找到比该数字大的下一个最小回文。例如,如果输入数字为“ 2 3 5 4 5”,则输出应为“ 2 3 6 3 2”。如果输入数字为“ 9 9 9”,则输出应为“ 1 0 0 1”。
假定输入为数组。数组中的每个条目代表输入数字中的一个数字。令数组为“ num []”,数组大小为“ n”
可能有三种不同类型的输入需要分别处理。
1)输入的数字是回文,并且全为9。例如“ 9 9 9”。输出应为“ 1 0 0 1”
2)输入的号码不是回文。例如“ 1 2 3 4”。输出应为“ 1 3 3 1”
3)输入的数字是回文,并且不全为9。例如“ 1 2 2 1”。输出应为“ 1 3 3 1”。
输入类型1的解决方案很简单。输出包含n +1个数字,其中转角数字为1,而转角数字之间的所有数字均为0。
现在让我们首先讨论输入类型2和3。如何将给定数字转换为更大的回文?为了理解该解决方案,让我们首先定义以下两个术语:
左侧:给定数字的左半部分。 “ 1 2 3 4 5 6”的左侧是“ 1 2 3”,“ 1 2 3 4 5”的左侧是“ 1 2”
右侧:给定数字的右半部分。 “ 1 2 3 4 5 6”的右侧是“ 4 5 6”,“ 1 2 3 4 5”的右侧是“ 4 5”
要转换为回文,我们可以取其左侧的镜子,也可以取其右侧的镜子。但是,如果我们拿右边的镜子,那么形成的回文就不能保证是下一个更大的回文。因此,我们必须拿起左侧的镜子并将其复制到右侧。但是有些情况下必须以不同的方式处理。请参阅以下步骤。
我们将从两个索引i和j开始。我指向两个中间元素(或者在n为奇数的情况下指向中间元素周围的两个元素)。我们一步一步地将i和j彼此分开。
步骤1.首先,忽略与右侧对应部分相同的左侧部分。例如,如果数字为“ 8 3 4 2 2 4 6 9 9”,我们将忽略中间的四个元素。我现在指向元素3,j现在指向元素6。
步骤2.在步骤1之后,出现以下情况:
情况1:指标i和j越过边界。
当输入数字是回文式时,会发生这种情况。在这种情况下,我们只需将1加到中间数字(或n等于偶数的数字)向左侧的MSB数字传播进位,并同时将左侧的镜像复制到右侧。
例如,如果给定的数字是“ 1 2 9 2 1”,我们将9递增到10并传播进位。因此数字变为“ 1 3 0 3 1”
情况2:左侧和右侧之间留有不相同的数字。因此,我们只是将左侧镜像到右侧,并尝试最小化形成的数量以保证下一个最小的回文。
在这种情况下,可以有两个子情况。
2.1)复制左侧到右侧就足够了,我们不需要增加任何数字,结果只是左侧的镜像。以下是此子案例的一些示例。
下一个回文“ 7 8 3 3 2 2”是“ 7 8 3 3 8 7”
下一个回文“ 1 2 5 3 2 2”是“ 1 2 5 5 2 1”
“ 1 4 5 8 7 6 7 8 3 2 2”的下一个回文是“ 1 4 5 8 7 6 7 8 5 4 1”
我们如何检查这种情况?我们需要检查的只是步骤1中被忽略部分之后的数字。该数字在上面的示例中突出显示。如果该数字大于右侧数字中的相应数字,则将左侧复制到右侧就足够了,我们无需执行其他任何操作。
2.2)仅将左侧复制到右侧是不够的。当左侧的上述定义的数字较小时,会发生这种情况。以下是这种情况的一些示例。
“ 7 1 3 3 2 2”的下一个回文是“ 7 1 4 4 1 7”
“ 1 2 3 4 6 2 8”的下一个回文是“ 1 2 3 5 3 2 1”
“ 9 4 1 8 7 9 7 8 3 2 2”的下一个回文是“ 9 4 1 8 8 0 8 8 1 4 9”
我们像情况1一样处理这种子情况。我们只向中间数字(或n表示偶数的数字)加1,将进位向左侧的MSB数字传播,同时将左侧的镜像复制到右侧。
C++
#include
using namespace std;
// Utility that prints out an array on a line
void printArray(int arr[], int n)
{
int i;
for(i = 0; i < n; i++)
printf("%d ", arr[i]);
printf("\n");
}
// A utility function to check if num has all 9s
int AreAll9s(int* num, int n )
{
int i;
for(i = 0; i < n; ++i)
if (num[i] != 9)
return 0;
return 1;
}
// Returns next palindrome of a given number num[].
// This function is for input type 2 and 3
void generateNextPalindromeUtil (int num[], int n )
{
// Find the index of mid digit
int mid = n / 2;
// A bool variable to check if copy of left
// side to right is sufficient or not
bool leftsmaller = false;
// End of left side is always 'mid -1'
int i = mid - 1;
// Beginning of right side depends
// if n is odd or even
int j = (n % 2) ? mid + 1 : mid;
// Initially, ignore the middle same digits
while (i >= 0 && num[i] == num[j])
i--, j++;
// Find if the middle digit(s) need to be
// incremented or not (or copying left
// side is not sufficient)
if (i < 0 || num[i] < num[j])
leftsmaller = true;
// Copy the mirror of left to tight
while (i >= 0)
{
num[j] = num[i];
j++;
i--;
}
// Handle the case where middle digit(s) must
// be incremented. This part of code is for
// CASE 1 and CASE 2.2
if (leftsmaller == true)
{
int carry = 1;
i = mid - 1;
// If there are odd digits, then increment
// the middle digit and store the carry
if (n % 2 == 1)
{
num[mid] += carry;
carry = num[mid] / 10;
num[mid] %= 10;
j = mid + 1;
}
else
j = mid;
// Add 1 to the rightmost digit of the
// left side, propagate the carry towards
// MSB digit and simultaneously copying
// mirror of the left side to the right side.
while (i >= 0)
{
num[i] += carry;
carry = num[i] / 10;
num[i] %= 10;
// Copy mirror to right
num[j++] = num[i--];
}
}
}
// The function that prints next palindrome
// of a given number num[] with n digits.
void generateNextPalindrome(int num[], int n)
{
int i;
printf("Next palindrome is:");
// Input type 1: All the digits are 9, simply o/p 1
// followed by n-1 0's followed by 1.
if (AreAll9s(num, n))
{
printf("1 ");
for(i = 1; i < n; i++)
printf("0 ");
printf("1");
}
// Input type 2 and 3
else
{
generateNextPalindromeUtil(num, n);
// print the result
printArray (num, n);
}
}
// Driver code
int main()
{
int num[] = { 9, 4, 1, 8, 7, 9, 7, 8, 3, 2, 2 };
int n = sizeof(num) / sizeof(num[0]);
generateNextPalindrome(num, n);
return 0;
}
// This code is contributed by rohan07
C
#include
// A utility function to print an array
void printArray (int arr[], int n);
// A utility function to check if num has all 9s
int AreAll9s (int num[], int n );
// Returns next palindrome of a given number num[].
// This function is for input type 2 and 3
void generateNextPalindromeUtil (int num[], int n )
{
// find the index of mid digit
int mid = n/2;
// A bool variable to check if copy of left side to right is sufficient or not
bool leftsmaller = false;
// end of left side is always 'mid -1'
int i = mid - 1;
// Beginning of right side depends if n is odd or even
int j = (n % 2)? mid + 1 : mid;
// Initially, ignore the middle same digits
while (i >= 0 && num[i] == num[j])
i--,j++;
// Find if the middle digit(s) need to be incremented or not (or copying left
// side is not sufficient)
if ( i < 0 || num[i] < num[j])
leftsmaller = true;
// Copy the mirror of left to tight
while (i >= 0)
{
num[j] = num[i];
j++;
i--;
}
// Handle the case where middle digit(s) must be incremented.
// This part of code is for CASE 1 and CASE 2.2
if (leftsmaller == true)
{
int carry = 1;
i = mid - 1;
// If there are odd digits, then increment
// the middle digit and store the carry
if (n%2 == 1)
{
num[mid] += carry;
carry = num[mid] / 10;
num[mid] %= 10;
j = mid + 1;
}
else
j = mid;
// Add 1 to the rightmost digit of the left side, propagate the carry
// towards MSB digit and simultaneously copying mirror of the left side
// to the right side.
while (i >= 0)
{
num[i] += carry;
carry = num[i] / 10;
num[i] %= 10;
num[j++] = num[i--]; // copy mirror to right
}
}
}
// The function that prints next palindrome of a given number num[]
// with n digits.
void generateNextPalindrome( int num[], int n )
{
int i;
printf("Next palindrome is:");
// Input type 1: All the digits are 9, simply o/p 1
// followed by n-1 0's followed by 1.
if( AreAll9s( num, n ) )
{
printf( "1 ");
for( i = 1; i < n; i++ )
printf( "0 " );
printf( "1" );
}
// Input type 2 and 3
else
{
generateNextPalindromeUtil ( num, n );
// print the result
printArray (num, n);
}
}
// A utility function to check if num has all 9s
int AreAll9s( int* num, int n )
{
int i;
for( i = 0; i < n; ++i )
if( num[i] != 9 )
return 0;
return 1;
}
/* Utility that prints out an array on a line */
void printArray(int arr[], int n)
{
int i;
for (i=0; i < n; i++)
printf("%d ", arr[i]);
printf("\n");
}
// Driver Program to test above function
int main()
{
int num[] = {9, 4, 1, 8, 7, 9, 7, 8, 3, 2, 2};
int n = sizeof (num)/ sizeof(num[0]);
generateNextPalindrome( num, n );
return 0;
}
Java
// Java program to find next smallest
// palindrome
public class nextplaindrome
{
// Returns next palindrome of a given
// number num[]. This function is for
// input type 2 and 3
static void generateNextPalindromeUtil(int num[], int n)
{
int mid = n / 2;
// end of left side is always 'mid -1'
int i = mid - 1;
// Beginning of right side depends
// if n is odd or even
int j = (n % 2 == 0) ? mid : mid + 1;
// A bool variable to check if copy of left
// side to right
// is sufficient or not
boolean leftsmaller = false;
// Initially, ignore the middle same digits
while (i >= 0 && num[i] == num[j])
{
i--;
j++;
}
// Find if the middle digit(s) need to
// be incremented or not (or copying left
// side is not sufficient)
if (i < 0 || num[i] < num[j])
{
leftsmaller = true;
}
// Copy the mirror of left to tight
while (i >= 0)
{
num[j++] = num[i--];
}
// Handle the case where middle digit(s)
// must be incremented. This part of code
// is for CASE 1 and CASE 2.2
if (leftsmaller)
{
int carry = 1;
// If there are odd digits, then increment
// the middle digit and store the carry
if (n % 2 == 1) {
num[mid] += 1;
carry = num[mid] / 10;
num[mid] %= 10;
}
i = mid - 1;
j = (n % 2 == 0 ? mid : mid + 1);
// Add 1 to the rightmost digit of the left
// side, propagate the carry towards MSB digit
// and simultaneously copying mirror of the
// left side to the right side.
//when carry is zero no need to loop through till i>=0
while (i >= 0 && carry>0)
{
num[i] = num[i] + carry;
carry = num[i] / 10;
num[i] %= 10;
num[j] = num[i];// copy mirror to right
i--;
j++;
}
}
}
// The function that prints next palindrome
// of a given number num[] with n digits.
static void generateNextPalindrome(int num[], int n)
{
System.out.println("Next Palindrome is:");
// Input type 1: All the digits are 9,
// simply o/p 1 followed by n-1 0's
// followed by 1.
if (isAll9(num, n)) {
System.out.print("1");
for (int i = 0; i < n - 1; i++)
System.out.print("0");
System.out.println("1");
}
// Input type 2 and 3
else {
generateNextPalindromeUtil(num, n);
printarray(num);
}
}
// A utility function to check if num has all 9s
static boolean isAll9(int num[], int n) {
for (int i = 0; i < n; i++)
if (num[i] != 9)
return false;
return true;
}
/* Utility that prints out an array on a line */
static void printarray(int num[]) {
for (int i = 0; i < num.length; i++)
System.out.print(num[i]);
System.out.println();
}
public static void main(String[] args)
{
int num[] = { 9, 4, 1, 8, 7, 9, 7, 8, 3, 2, 2 };
generateNextPalindrome(num, num.length);
}
}
Python3
# Returns next palindrome of a given number num[].
# This function is for input type 2 and 3
def generateNextPalindromeUtil (num, n) :
# find the index of mid digit
mid = int(n/2 )
# A bool variable to check if copy of left
# side to right is sufficient or not
leftsmaller = False
# end of left side is always 'mid -1'
i = mid - 1
# Beginning of right side depends
# if n is odd or even
j = mid + 1 if (n % 2) else mid
# Initially, ignore the middle same digits
while (i >= 0 and num[i] == num[j]) :
i-=1
j+=1
# Find if the middle digit(s) need to be
# incremented or not (or copying left
# side is not sufficient)
if ( i < 0 or num[i] < num[j]):
leftsmaller = True
# Copy the mirror of left to tight
while (i >= 0) :
num[j] = num[i]
j+=1
i-=1
# Handle the case where middle
# digit(s) must be incremented.
# This part of code is for CASE 1 and CASE 2.2
if (leftsmaller == True) :
carry = 1
i = mid - 1
# If there are odd digits, then increment
# the middle digit and store the carry
if (n%2 == 1) :
num[mid] += carry
carry = int(num[mid] / 10 )
num[mid] %= 10
j = mid + 1
else:
j = mid
# Add 1 to the rightmost digit of the
# left side, propagate the carry
# towards MSB digit and simultaneously
# copying mirror of the left side
# to the right side.
while (i >= 0) :
num[i] += carry
carry = int(num[i] / 10)
num[i] %= 10
num[j] = num[i] # copy mirror to right
j+=1
i-=1
# The function that prints next
# palindrome of a given number num[]
# with n digits.
def generateNextPalindrome(num, n ) :
print("\nNext palindrome is:")
# Input type 1: All the digits are 9, simply o/p 1
# followed by n-1 0's followed by 1.
if( AreAll9s( num, n ) == True) :
print( "1")
for i in range(1, n):
print( "0" )
print( "1")
# Input type 2 and 3
else:
generateNextPalindromeUtil ( num, n )
# print the result
printArray (num, n)
# A utility function to check if num has all 9s
def AreAll9s(num, n ):
for i in range(1, n):
if( num[i] != 9 ) :
return 0
return 1
# Utility that prints out an array on a line
def printArray(arr, n):
for i in range(0, n):
print(int(arr[i]),end=" ")
print()
# Driver Program to test above function
if __name__ == "__main__":
num = [9, 4, 1, 8, 7, 9, 7, 8, 3, 2, 2]
n = len(num)
generateNextPalindrome( num, n )
# This code is contributed by Smitha Dinesh Semwal
C#
// C# program to find next smallest palindrome
using System;
public class GFG {
// Returns next palindrome of a given
// number num[]. This function is for
// input type 2 and 3
static void generateNextPalindromeUtil(int []num, int n)
{
int mid = n / 2;
// end of left side is always 'mid -1'
int i = mid - 1;
// Beginning of right side depends
// if n is odd or even
int j = (n % 2 == 0) ? mid : mid + 1;
// A bool variable to check if copy of left
// side to right
// is sufficient or not
bool leftsmaller = false;
// Initially, ignore the middle same digits
while (i >= 0 && num[i] == num[j])
{
i--;
j++;
}
// Find if the middle digit(s) need to
// be incremented or not (or copying left
// side is not sufficient)
if (i < 0 || num[i] < num[j])
{
leftsmaller = true;
}
// Copy the mirror of left to tight
while (i >= 0)
{
num[j++] = num[i--];
}
// Handle the case where middle digit(s)
// must be incremented. This part of code
// is for CASE 1 and CASE 2.2
if (leftsmaller)
{
int carry = 1;
// If there are odd digits, then increment
// the middle digit and store the carry
if (n % 2 == 1) {
num[mid] += 1;
carry = num[mid] / 10;
num[mid] %= 10;
}
i = mid - 1;
j = (n % 2 == 0 ? mid : mid + 1);
// Add 1 to the rightmost digit of the left
// side, propagate the carry towards MSB digit
// and simultaneously copying mirror of the
// left side to the right side.
while (i >= 0)
{
num[i] = num[i] + carry;
carry = num[i] / 10;
num[i] %= 10;
num[j] = num[i];// copy mirror to right
i--;
j++;
}
}
}
// The function that prints next palindrome
// of a given number num[] with n digits.
static void generateNextPalindrome(int []num, int n)
{
Console.WriteLine("Next Palindrome is:");
// Input type 1: All the digits are 9,
// simply o/p 1 followed by n-1 0's
// followed by 1.
if (isAll9(num, n)) {
Console.Write("1");
for (int i = 0; i < n - 1; i++)
Console.Write("0");
Console.Write("1");
}
// Input type 2 and 3
else {
generateNextPalindromeUtil(num, n);
printarray(num);
}
}
// A utility function to check if num has all 9s
static bool isAll9(int[] num, int n) {
for (int i = 0; i < n; i++)
if (num[i] != 9)
return false;
return true;
}
/* Utility that prints out an array on a line */
static void printarray(int []num) {
for (int i = 0; i < num.Length; i++)
Console.Write(num[i]+ " ");
Console.Write(" ");
}
// Driver code
public static void Main()
{
int []num = { 9, 4, 1, 8, 7, 9, 7, 8, 3, 2, 2 };
generateNextPalindrome(num, num.Length);
}
}
// This code is contributed by Smitha.
PHP
= 0 &&
$num[$i] == $num[$j])
{
$i--;
$j++;
}
// Find if the middle digit(s)
// need to be incremented or
// not (or copying left side
// is not sufficient)
if ($i < 0 || $num[$i] < $num[$j])
{
$leftsmaller = true;
}
// Copy the mirror
// of left to tight
while ($i >= 0)
{
$num[$j++] = $num[$i--];
}
// Handle the case where
// middle digit(s) must be
// incremented. This part
// of code is for CASE 1
// and CASE 2.2
if ($leftsmaller)
{
$carry = 1;
// If there are odd digits,
// then increment the middle
// digit and store the carry
if ($n % 2 == 1)
{
$num[$mid] += 1;
$carry = (int)($num[$mid] / 10);
$num[$mid] %= 10;
}
$i = $mid - 1;
$j = ($n % 2 == 0 ?
$mid : $mid + 1);
// Add 1 to the rightmost digit
// of the left side, propagate
// the carry towards MSB digit
// and simultaneously copying
// mirror of the left side to
// the right side.
while ($i >= 0)
{
$num[$i] = $num[$i] + $carry;
$carry = (int)($num[$i] / 10);
$num[$i] %= 10;
// copy mirror to right
$num[$j] = $num[$i];
$i--;
$j++;
}
}
return $num;
}
// The function that prints
// next palindrome of a given
// number num[] with n digits.
function generateNextPalindrome($num, $n)
{
echo "Next Palindrome is:\n";
// Input type 1: All the
// digits are 9, simply
// o/p 1 followed by n-1
// 0's followed by 1.
if (isAll9($num, $n))
{
echo "1";
for ($i = 0; $i < $n - 1; $i++)
echo "0";
echo "1";
}
// Input type 2 and 3
else
{
$num = generateNextPalindromeUtil($num, $n);
printarray($num);
}
}
// A utility function to
// check if num has all 9s
function isAll9($num, $n)
{
for ($i = 0; $i < $n; $i++)
if ($num[$i] != 9)
return false;
return true;
}
/* Utility that prints out
an array on a line */
function printarray($num)
{
for ($i = 0;
$i < count($num); $i++)
echo $num[$i];
echo "\n";
}
// Driver code
$num = array(9, 4, 1, 8, 7,
9, 7, 8, 3, 2, 2);
generateNextPalindrome($num,
count($num));
// This code is contributed by mits.
?>
Javascript
输出:
Next palindrome is:
9 4 1 8 8 0 8 8 1 4 9