In this problem we consider only strings consisting of lower-case English letters (a−z).
A string is a palindrome if it reads exactly the same from left to right as it does from right to left. For example, these strings are palindromes:
- aza
- abba
- abacaba
These strings are not palindromes:
- zaza
- abcd
- abacada
Given a string S of length N, a slice of S is a substring of S specified by a pair of integers (p, q), such that 0 ≤ p < q < N. A slice (p, q) of string S is palindromic if the string consisting of letters S[p], S[p+1], ..., S[q] is a palindrome. For example, in a string S = abbacada:
- slice (0, 3) is palindromic because abba is a palindrome,
- slice (6, 7) is not palindromic because da is not a palindrome,
- slice (2, 5) is not palindromic because baca is not a palindrome,
- slice (1, 2) is palindromic because bb is a palindrome.
Write a function
int solution(string &S);
that, given a string S of length N letters, returns the number of palindromic slices of S. The function should return −1 if this number is greater than 1,000,000,000.
For example, for string S = baababa the function should return 6, because exactly six of its slices are palindromic; namely: (0, 3), (1, 2), (2, 4), (2, 6), (3, 5), (4, 6).
Write an efficient algorithm for the following assumptions:
- N is an integer within the range [0..200,000];
- string S is made only of lowercase letters (a−z).
// you can use includes, for example:
// #include <algorithm>
#include <vector>
// you can write to stdout for debugging purposes, e.g.
// cout << "this is a debug message" << endl;
int solution(string &S) {
// write your code in C++11
int count = 0;
if(S.size() > 0)
{
std::string tempString = "#";
for(int i = 0 ; i < S.size(); i++)
{
tempString.append(std::string(1,S[i]));
tempString.append("#");
}
vector<int> palinCount(tempString.size());
int C = 0, R = 0;
for(int i = 1 ; i < tempString.size() - 1 ; i++)
{
int i_mirror = C - (i - C);
palinCount[i] = (R > i) ? std::min(R-i, palinCount[i_mirror]) : 0;
// Attempt to expand palindrome centered at i
while((i + 1 + palinCount[i] < tempString.size() - 1 && i - 1 - palinCount[i] > 0) && (tempString[i + 1 + palinCount[i]] == tempString[i - 1 - palinCount[i]]))
palinCount[i]++;
count += palinCount[i]/2;
if(count > 100000000)
count = -1;
// If palindrome centered at i expand past R,
// adjust center based on expanded palindrome.
if (i + palinCount[i] > R) {
C = i;
R = i + palinCount[i];
}
}
}
return count;
}
// you can also use imports, for example:
// import java.util.*;
// you can use System.out.println for debugging purposes, e.g.
// System.out.println("this is a debug message");
class Solution {
public int solution(String S) {
//This is where result will be stored
int palindromicSlicesCount = 0;
//Sanity check
if (!String.IsNullOrEmpty(S))
{
//In order to be able to handle palindromes of odd and even lengths in the same way, we insert special character (#) between letters as well as delimiters.
//i.g. 'baababa' becomes '^#b#a#a#b#a#b#a#$'
S = "^#" + String.Join("#", Array.ConvertAll(S.ToCharArray(), c => c.ToString())) + "#$";
int N = S.Length;
//This is where the length of the longest palindrome centered at given index will be stored
int[] P = new int[N];
//This is where the index of current palindrome center will be stored
int C = 0;
//This is where the index of right edge of the palindrome most to the right will be stored
int R = 0;
//For every character index in the string
for (int i = 1; i < N - 1; i++)
{
//We need to find the mirrored index i’ around the palindrome’s center C
int iprime = C - (i - C);
//If the palindrome most to the right reaches further then current index
if (R > i)
//The initial palindrome length is calculated as minimum of 'distance between current index and the index of right edge of the palindrome most to the right' and 'the lenght of the longest palindrome centered at i’'
P[i] = Math.Min(R-i, P[iprime]);
else
P[i] = 0;
//Now we try to expand palindrome beyond the initial length
while (S[i + 1 + P[i]] == S[i - 1 - P[i]])
P[i]++;
//We can get the count of plaindormes around current index by dividing the lenght of the longest one by 2 (fixed point division)
palindromicSlicesCount += P[i]/2;
//If the number of palindromic slices is above 100,000,000 we should return -1
if (palindromicSlicesCount > 100000000)
{
palindromicSlicesCount = -1;
break;
}
//If the palindrome expands beyond R
if (i + P[i] > R)
{
//We need to adjust C and R
C = i;
R = i + P[i];
}
}
}
//Return the result
return palindromicSlicesCount;
}
}
Solution.java:17: error: illegal start of expression S = "^#" + String.Join("#", Array.ConvertAll(S.ToCharArray(), c => c.ToString())) + "#$"; ^ 1 error
using System;
// you can also use other imports, for example:
// using System.Collections.Generic;
// you can use Console.WriteLine for debugging purposes, e.g.
// Console.WriteLine("this is a debug message");
class Solution {
public int solution(string S) {
//This is where result will be stored
int palindromicSlicesCount = 0;
//Sanity check
if (!String.IsNullOrEmpty(S))
{
//In order to be able to handle palindromes of odd and even lengths in the same way, we insert special character (#) between letters as well as delimiters.
//i.g. 'baababa' becomes '^#b#a#a#b#a#b#a#$'
S = "^#" + String.Join("#", Array.ConvertAll(S.ToCharArray(), c => c.ToString())) + "#$";
int N = S.Length;
//This is where the length of the longest palindrome centered at given index will be stored
int[] P = new int[N];
//This is where the index of current palindrome center will be stored
int C = 0;
//This is where the index of right edge of the palindrome most to the right will be stored
int R = 0;
//For every character index in the string
for (int i = 1; i < N - 1; i++)
{
//We need to find the mirrored index i’ around the palindrome’s center C
int iprime = C - (i - C);
//If the palindrome most to the right reaches further then current index
if (R > i)
//The initial palindrome length is calculated as minimum of 'distance between current index and the index of right edge of the palindrome most to the right' and 'the lenght of the longest palindrome centered at i’'
P[i] = Math.Min(R-i, P[iprime]);
else
P[i] = 0;
//Now we try to expand palindrome beyond the initial length
while (S[i + 1 + P[i]] == S[i - 1 - P[i]])
P[i]++;
//We can get the count of plaindormes around current index by dividing the lenght of the longest one by 2 (fixed point division)
palindromicSlicesCount += P[i]/2;
//If the number of palindromic slices is above 100,000,000 we should return -1
if (palindromicSlicesCount > 100000000)
{
palindromicSlicesCount = -1;
break;
}
//If the palindrome expands beyond R
if (i + P[i] > R)
{
//We need to adjust C and R
C = i;
R = i + P[i];
}
}
}
//Return the result
return palindromicSlicesCount;
}
}
// you can use includes, for example:
// #include <algorithm>
#include <vector>
// you can write to stdout for debugging purposes, e.g.
// cout << "this is a debug message" << endl;
int solution(string &S) {
// write your code in C++11
int count = 0;
if(S.size() > 0)
{
std::string tempString = "#";
for(int i = 0 ; i < S.size(); i++)
{
tempString.append(std::string(1,S[i]));
tempString.append("#");
}
vector<int> palinCount(tempString.size());
int C = 0, R = 0;
for(int i = 1 ; i < tempString.size() - 1 ; i++)
{
int i_mirror = C - (i - C);
palinCount[i] = (R > i) ? std::min(R-i, palinCount[i_mirror]) : 0;
// Attempt to expand palindrome centered at i
while((i + 1 + palinCount[i] < tempString.size() - 1 && i - 1 - palinCount[i] > 0) && (tempString[i + 1 + palinCount[i]] == tempString[i - 1 - palinCount[i]]))
palinCount[i]++;
count += palinCount[i]/2;
if(count > 100000000)
{
count = -1;
break;
}
// If palindrome centered at i expand past R,
// adjust center based on expanded palindrome.
if (i + palinCount[i] > R) {
C = i;
R = i + palinCount[i];
}
}
}
return count;
}
// you can use includes, for example:
// #include <algorithm>
#include <vector>
// you can write to stdout for debugging purposes, e.g.
// cout << "this is a debug message" << endl;
int solution(string &S) {
// write your code in C++11
int count = 0;
if(S.size() > 0)
{
std::string tempString = "#";
for(int i = 0 ; i < S.size(); i++)
{
tempString.append(std::string(1,S[i]));
tempString.append("#");
}
vector<int> palinCount(tempString.size());
int C = 0, R = 0;
for(int i = 1 ; i < tempString.size() - 1 ; i++)
{
int i_mirror = C - (i - C);
palinCount[i] = (R > i) ? std::min(R-i, palinCount[i_mirror]) : 0;
// Attempt to expand palindrome centered at i
while((i + 1 + palinCount[i] < tempString.size() - 1 && i - 1 - palinCount[i] > 0) && (tempString[i + 1 + palinCount[i]] == tempString[i - 1 - palinCount[i]]))
palinCount[i]++;
if(tempString[i] == '#')
{
count += palinCount[i + 1]/2;
}
else
{
count += palinCount[i]/2;
}
if(count > 100000000)
{
count = -1;
break;
}
// If palindrome centered at i expand past R,
// adjust center based on expanded palindrome.
if (i + palinCount[i] > R) {
C = i;
R = i + palinCount[i];
}
}
}
return count;
}
// you can use includes, for example:
// #include <algorithm>
#include <vector>
// you can write to stdout for debugging purposes, e.g.
// cout << "this is a debug message" << endl;
int solution(string &S) {
// write your code in C++11
int count = 0;
if(S.size() > 0)
{
std::string tempString = "#";
for(int i = 0 ; i < S.size(); i++)
{
tempString.append(std::string(1,S[i]));
tempString.append("#");
}
vector<int> palinCount(tempString.size());
int C = 0, R = 0;
for(int i = 1 ; i < tempString.size() - 1 ; i++)
{
int i_mirror = C - (i - C);
palinCount[i] = (R > i) ? std::min(R-i, palinCount[i_mirror]) : 0;
// Attempt to expand palindrome centered at i
while((i + 1 + palinCount[i] < tempString.size() - 1 && i - 1 - palinCount[i] > 0) && (tempString[i + 1 + palinCount[i]] == tempString[i - 1 - palinCount[i]]))
palinCount[i]++;
if(tempString[i] == '#')
{
count += (palinCount[i] + 1)/2;
}
else
{
count += palinCount[i]/2;
}
if(count > 100000000)
{
count = -1;
break;
}
// If palindrome centered at i expand past R,
// adjust center based on expanded palindrome.
if (i + palinCount[i] > R) {
C = i;
R = i + palinCount[i];
}
}
}
return count;
}
// you can use includes, for example:
// #include <algorithm>
#include <vector>
// you can write to stdout for debugging purposes, e.g.
// cout << "this is a debug message" << endl;
int solution(string &S) {
// write your code in C++11
int count = 0;
if(S.size() > 0)
{
std::string tempString = "#";
for(int i = 0 ; i < S.size(); i++)
{
tempString.append(std::string(1,S[i]));
tempString.append("#");
}
vector<int> palinCount(tempString.size());
int C = 0, R = 0;
for(int i = 1 ; i < tempString.size() - 1 ; i++)
{
int i_mirror = C - (i - C);
palinCount[i] = (R > i) ? std::min(R-i, palinCount[i_mirror]) : 0;
// Attempt to expand palindrome centered at i
while((i + 1 + palinCount[i] < tempString.size() - 1 && i - 1 - palinCount[i] > 0) && (tempString[i + 1 + palinCount[i]] == tempString[i - 1 - palinCount[i]]))
palinCount[i]++;
if(tempString[i] == '#')
{
count += (palinCount[i] + 1)/2;
}
else
{
count += palinCount[i]/2;
}
if(count > 100000000)
{
count = -1;
break;
}
// If palindrome centered at i expand past R,
// adjust center based on expanded palindrome.
if (i + palinCount[i] > R) {
C = i;
R = i + palinCount[i];
}
}
}
return count;
}
// you can use includes, for example:
// #include <algorithm>
#include <vector>
// you can write to stdout for debugging purposes, e.g.
// cout << "this is a debug message" << endl;
int solution(string &S) {
// write your code in C++11
int count = 0;
if(S.size() > 0)
{
std::string tempString = "#";
for(int i = 0 ; i < S.size(); i++)
{
tempString.append(std::string(1,S[i]));
tempString.append("#");
}
vector<int> palinCount(tempString.size());
int C = 0, R = 0;
for(int i = 1 ; i < tempString.size() - 1 ; i++)
{
int i_mirror = C - (i - C);
palinCount[i] = (R > i) ? std::min(R-i, palinCount[i_mirror]) : 0;
// Attempt to expand palindrome centered at i
while((i + 1 + palinCount[i] < tempString.size() - 1 && i - 1 - palinCount[i] > 0) && (tempString[i + 1 + palinCount[i]] == tempString[i - 1 - palinCount[i]]))
palinCount[i]++;
if(tempString[i] == '#')
{
count += (palinCount[i] + 1)/2;
}
else
{
count += palinCount[i]/2;
}
if(count > 100000000)
{
count = -1;
break;
}
// If palindrome centered at i expand past R,
// adjust center based on expanded palindrome.
if (i + palinCount[i] > R) {
C = i;
R = i + palinCount[i];
}
}
}
return count;
}
The solution obtained perfect score.