Construct the Largest Palindromic String which lies between two other Strings
Last Updated :
16 Nov, 2023
Given two strings A and B of length N which contains only lowercase characters, find the lexicographically largest string C of length N which contains only lowercase characters such that the following conditions are satisfied.
- C should be lexicographically greater than the string A.
- C should be lexicographically smaller than the string B.
- C should be palindrome.
Examples:
Input: N = 3, A = "aba", B = "ade"
Output: ada
Explanation: "ada" is lexicographically greater than the string A and lexicographically smaller than the string B and it is a palindrome.
Input: N = 1, A = "z", B = "z"
Output: -1
Approach: The idea behind the following approach is:
This problem can be solved with the some observations. Our goal is to make palindrome and it should be lexicographically larger than A but smaller than B. We will perform operations on string B. Divide B to half string and add first half to C, add a middle character (when N is odd) and again add first half to C but in reverse order. Now, to make it smaller than B and greater than A, we will change characters in C accordingly.
Below are the steps involved in the implementation of the code:
- Check A should be smaller than B otherwise return -1.
- Create a empty string ans representing C.
- Split B into two halves and add first half to ans, add a middle character (when N is odd) and again first half of B in backward direction.
- Now, to make it greater than A and smaller than B.
- Iterate in it and try changing character (on both sides) one by one through i and j variables.
- If character present at ans[i] and ans[j] is 'a' skip it.
- If not reduce it by one both the ans[i] and ans[j] and make the characters between i and j index of ans as 'z'. As our goal is to make lexicographically largest.
- If ans > A and ans < B, return ans.
- Otherwise "-1".
Below is the implementation of the code:
C++
// C++ Implementation of the code:
#include <bits/stdc++.h>
using namespace std;
// Function to find String C
string constructString(int N, string A, string B)
{
// If A is greater than or equal to B
if (A >= B) {
return "-1";
}
int mid = N / 2;
string ans = "";
// Form ans upto half of mid of B
for (int i = 0; i < mid; i++)
ans += B[i];
string copy = ans;
reverse(copy.begin(), copy.end());
if (N & 1) {
ans += B[mid];
}
// Making ans string palindrome
ans += copy;
int i = mid, j = mid;
// If length of A is even
if (N % 2 == 0) {
i--;
}
while (i >= 0 && j < A.length()) {
if (ans[i] == 'a') {
i--;
j++;
}
else {
// Check whether ans is smaller
// than B and greater than A
if (ans < B && ans > A) {
return ans;
}
ans[i] = ans[i] - 1;
ans[j] = ans[i];
int l = i + 1;
int r = j - 1;
// Converting other characters to z
// to form biggest lexicographically
// string
while (l <= r) {
ans[l++] = 'z';
ans[r--] = 'z';
}
// If ans is less than A
// lexicographically
if (ans > A)
return ans;
return "-1";
}
}
return "-1";
}
// Driver code
int main()
{
string A = "aaaaa";
string B = "axaae";
int N = A.length();
// Function call
string res = constructString(N, A, B);
cout << res << endl;
return 0;
}
Java
// Java Implementation of the code:
import java.util.*;
public class Main {
// Function to find String C
public static String constructString(int N, String A, String B) {
// If A is greater than or equal to B
if (A.compareTo(B) >= 0) {
return "-1";
}
int mid = N / 2;
StringBuilder ans = new StringBuilder();
// Form ans up to half of mid of B
for (int i = 0; i < mid; i++) {
ans.append(B.charAt(i));
}
StringBuilder copy = new StringBuilder(ans);
copy.reverse();
if (N % 2 == 1) {
ans.append(B.charAt(mid));
}
// Making ans string palindrome
ans.append(copy);
int i = mid, j = mid;
// If length of A is even
if (N % 2 == 0) {
i--;
}
while (i >= 0 && j < A.length()) {
if (ans.charAt(i) == 'a') {
i--;
j++;
} else {
// Check whether ans is smaller
// than B and greater than A
if (ans.toString().compareTo(B) < 0 &&
ans.toString().compareTo(A) > 0) {
return ans.toString();
}
ans.setCharAt(i, (char)(ans.charAt(i) - 1));
ans.setCharAt(j, ans.charAt(i));
int l = i + 1;
int r = j - 1;
// Converting other characters to z
// to form the biggest lexicographically
// string
while (l <= r) {
ans.setCharAt(l, 'z');
ans.setCharAt(r, 'z');
l++;
r--;
}
// If ans is less than A
// lexicographically
if (ans.toString().compareTo(A) > 0) {
return ans.toString();
}
return "-1";
}
}
return "-1";
}
// Driver code
public static void main(String[] args) {
String A = "aaaaa";
String B = "axaae";
int N = A.length();
// Function call
String res = constructString(N, A, B);
System.out.println(res);
}
}
// this code is contributed by uttamdp_10
Python3
def constructString(N, A, B):
# If A is greater than or equal to B
if A >= B:
return "-1"
mid = N // 2
ans = []
# Form ans up to half of mid of B
for i in range(mid):
ans.append(B[i])
copy = ans[::-1]
if N % 2 == 1:
ans.append(B[mid])
# Making ans string palindrome
ans.extend(copy)
i, j = mid, mid
# If the length of A is even
if N % 2 == 0:
i -= 1
while i >= 0 and j < len(A):
if ans[i] == 'a':
i -= 1
j += 1
else:
# Check whether ans is smaller
# than B and greater than A
if ''.join(ans) < B and ''.join(ans) > A:
return ''.join(ans)
ans[i] = chr(ord(ans[i]) - 1)
ans[j] = ans[i]
l, r = i + 1, j - 1
# Converting other characters to 'z'
# to form the biggest lexicographically
# string
while l <= r:
ans[l] = 'z'
ans[r] = 'z'
l += 1
r -= 1
# If ans is less than A
# lexicographically
if ''.join(ans) > A:
return ''.join(ans)
return "-1"
return "-1"
# Driver code
A = "aaaaa"
B = "axaae"
N = len(A)
# Function call
res = constructString(N, A, B)
print(res)
# by phasing17
C#
using System;
class GFG
{
// Function to find String C
public static string ConstructString(int N, string A, string B)
{
// If A is greater than or equal to B
if (A.CompareTo(B) >= 0)
return "-1";
int mid = N / 2;
string ans = "";
// Form ans upto half of mid of B
for (int x = 0; x < mid; x++)
ans += B[x];
string copy = new string(ans.ToCharArray());
char[] charArray = copy.ToCharArray();
Array.Reverse(charArray);
copy = new string(charArray);
if (N % 2 == 1)
ans += B[mid];
// Making ans string palindrome
ans += copy;
int i = mid, j = mid;
// If length of A is even
if (N % 2 == 0)
i--;
while (i >= 0 && j < A.Length)
{
if (ans[i] == 'a')
{
i--;
j++;
}
else
{
// Check whether ans is smaller than B and greater than A
if (string.Compare(ans, B) < 0 && string.Compare(ans, A) > 0)
{
return ans;
}
ans = ans.Remove(i, 1).Insert(i, Convert.ToString((char)(ans[i] - 1)));
ans = ans.Remove(j, 1).Insert(j, Convert.ToString(ans[i]));
int l = i + 1;
int r = j - 1;
// Converting other characters to z to form biggest lexicographically string
while (l <= r)
{
ans = ans.Remove(l, 1).Insert(l, "z");
ans = ans.Remove(r, 1).Insert(r, "z");
l++;
r--;
}
// If ans is less than A lexicographically
if (string.Compare(ans, A) > 0)
return ans;
return "-1";
}
}
return "-1";
}
// Driver code
public static void Main(string[] args)
{
string A = "aaaaa";
string B = "axaae";
int N = A.Length;
// Function call
string res = ConstructString(N, A, B);
Console.WriteLine(res);
}
}
JavaScript
function constructString(N, A, B) {
//If A is greater than or equal to B
if (A >= B) {
return "-1";
}
var mid = Math.floor(N / 2);
var ans = [];
//Form ans up to half of mid of B
for (var i = 0; i < mid; i++) {
ans.push(B[i]);
}
var copy = ans.slice().reverse();
if (N % 2 === 1) {
ans.push(B[mid]);
}
//Making ans string palindrome
ans = ans.concat(copy);
var i = mid;
var j = mid;
//If the length of A is even
if (N % 2 === 0) {
i -= 1;
}
while (i >= 0 && j < A.length) {
if (ans[i] === 'a') {
i -= 1;
j += 1;
} else {
//Check whether ans is smaller
//than B and greater than A
if (ans.join('') < B && ans.join('') > A) {
return ans.join('');
}
ans[i] = String.fromCharCode(ans[i].charCodeAt(0) - 1);
ans[j] = ans[i];
var l = i + 1;
var r = j - 1;
//Converting other characters to 'z'
//to form the biggest lexicographically
//string
while (l <= r) {
ans[l] = 'z';
ans[r] = 'z';
l += 1;
r -= 1;
}
//If ans is less than A
//lexicographically
if (ans.join('') > A) {
return ans.join('');
}
return "-1";
}
}
return "-1";
}
//Driver code
var A = "aaaaa";
var B = "axaae";
var N = A.length;
//Function call
var res = constructString(N, A, B);
console.log(res);
Time Complexity: O(N), where N is the length of strings A and B
Auxiliary Space: O(N)
Similar Reads
Given two strings check which string makes a palindrome first Given two strings 'A' and 'B' of equal length. Two players play a game where they both pick a character from their respective strings (First picks from A and second from B) and put into a third string (which is initially empty). The player that can make the third string palindrome, is winner. If fir
6 min read
Split string into three palindromic substrings with earliest possible cuts Given string str, the task is to check if it is possible to split the given string S into three palindromic substrings or not. If multiple answers are possible, then print the one where the cuts are made the least indices. If no such possible partition exists, then print "-1". Examples: Input: str =
15+ min read
Form the largest palindromic number using atmost two swaps Given a non-negative palindromic number num containing n number of digits. The problem is to apply at most two swap operations on the number num so that the resultant is the largest possible palindromic number. Examples: Input : 4697557964 Output : 9647557469 In, 4697557964 the highlighted digits we
10 min read
All distinct palindromic sub-strings of a given string Given a string str of lowercase ASCII characters. The task is to find all the distinct continuous palindromic sub-strings which are present in the string str. Examples: Input: str = "abaaa"Output: [ "a", "aa", "aaa", "aba", "b" ]Explanation: All 5 distinct continuous palindromic sub-strings are list
15+ min read
Longest Substring that can be made a palindrome by swapping of characters Given a numeric string S, the task is to find the longest non-empty substring that can be made palindrome. Examples: Input: S = "3242415"Output: 5Explanation: "24241" is the longest such substring which can be converted to the palindromic string "24142". Input: S = "213123"Output: 6Explanation: "213
12 min read
Print the longest palindromic prefix of a given string Given a string str, the task is to find the longest palindromic prefix of the given string. Examples: Input: str = "abaac" Output: aba Explanation: The longest prefix of the given string which is palindromic is "aba". Input: str = "abacabaxyz" Output: abacaba Explanation: The prefixes of the given s
12 min read