Facebook Interview Question
Software Engineer / DevelopersCountry: Israel
Interview Type: Phone Interview
Recursive solution in python:
def stripit(string):
while (len(string) > 0 and not string[0].isalpha()):
string = string[1:]
while (len(string) > 0 and not string[-1].isalpha()):
string = string[:-1]
return string
def palindrome(string):
string = stripit(string)
if (len(string) <= 1):
return True
if (string[0].lower() == string[-1].lower() and palindrome(string[1:-1])):
return True
return False
assert palindrome("A man, a plan, a canal -- Panama!")
public class isPalindrome {
static boolean ispal(String str){
int n = str.length()-1;
int i = 0;
while(i<n){
while(!Character.isLetter(str.charAt(i))){
i++;
}
while(!Character.isLetter(str.charAt(n))){
n--;
}
if(str.charAt(i) != str.charAt(n)){
return false;
}
i++;
n--;
}
return true;
}
public static void main(String[]args){
String str = "A man, a plan, a canal -- Panama!";
str= str.toLowerCase();
System.out.println(ispal(str));
}
}
public class isPalindrome {
static boolean ispal(String str){
int n = str.length()-1;
int i = 0;
while(i<n){
while(!Character.isLetter(str.charAt(i))){
i++;
}
while(!Character.isLetter(str.charAt(n))){
n--;
}
if(str.charAt(i) != str.charAt(n)){
return false;
}
i++;
n--;
}
return true;
}
public static void main(String[]args){
String str = "A man, a plan, a canal -- Panama!";
str= str.toLowerCase();
System.out.println(ispal(str));
}
}
I think this is pretty easy in C, or C++
bool isPallindrome(char * text)
{
size = 0;
char * temp = text;
// Just get the size of the string since it is char*
while (temp != '\0'){
temp++;
size++;
}
front = 0;
rear = size-1;
while (front < rear){
if (text[front] == ' '){ // you do not want to count the space, right?
front++; // of course I can consider tap and newline
continue;
}
if (text[rear] == ' '){ // you do not want to count the space, right?
rear--;
continue;
}
if (text[front++] != text[rear--])
return False;
}
return True;
}
public static boolean isParlindrome(String str) {
str = str.toLowerCase();
int left = updateIndex(str, 0, 1);
int right = updateIndex(str, str.length() - 1, -1);
while (left < right) {
if (str.charAt(left) != str.charAt(right))
return false;
left = updateIndex(str, left + 1, 1);
right = updateIndex(str, right - 1, -1);
}
return true;
}
private static int updateIndex(String str, int index, int direction) {
while (!isAlphabet(str.charAt(index)))
index = index + direction;
return index;
}
private static boolean isAlphabet(char c) {
return (c >= 'a' && c <= 'z');
}
}
private static bool IsPalindrome(string input)
{
int right = input.Length - 1;
for(int left = 0; left < input.Length / 2; left++)
{
while(!Char.IsLetter(input[left]))
{
left++;
}
while(!Char.IsLetter(input[right]))
{
right--;
}
if(Char.ToLower(input[left]) != Char.ToLower(input[right--]))
{
return false;
}
}
return true;
}
public static boolean pal(String c){
c = c.replaceAll("[^a-zA-Z0-9]", "").toLowerCase();
int left=0, right=c.length()-1;
while (left<right){
if (c.charAt(left) != c.charAt(right)) return false;
else {left++;right--;}
}
return true;
}
public static void main(String[] args) {
String str = "A man, a plan, a canal: Panama";
System.out.println(pal(str));
}
private boolean isPalindrome(String s){
if(s == null || (s != null && s.length()==0 )) return false;
if(s.length() == 1) return true;
s = s.toLowerCase();
int half = (int)s.length()/2;
int rightEnd = s.length()-1;
int leftEnd = 0;
char right = s.charAt(rightEnd);
char left = s.charAt(leftEnd);
boolean shouldCompare = true;
boolean moveRight = false;
boolean moveLeft = false;
for(int i = 0; i<half;){
left = s.charAt(leftEnd);
right = s.charAt(rightEnd);
shouldCompare = true;
if(!isAlpha(right)){
moveRight = true;
shouldCompare = false;
}
if(!isAlpha(left)){
moveLeft = true;
shouldCompare = false;
}
if(!shouldCompare){
if(moveRight && rightEnd-1 >=half){
rightEnd--;
}
if(moveLeft && leftEnd+1 <= half){
leftEnd++;
}
}else{
if(right != left) return false;
i++;
}
}
return true;
}
private boolean isAlpha(char c) {
return isLower(c) || isUpper(c);
}
private boolean isLower(char c){
return c >= 97 && c <= 122;
}
private boolean isUpper(char c){
return c >= 65 && c <= 90;
}
static bool IsPalindrome(string S)
{
int forward = 0;
int backward = S.Length - 1;
while(forward < backward)
{
char fs = SanitizeChar(S[forward]);
char bs = SanitizeChar(S[backward]);
if(fs == bs)
{
forward++;
backward--;
}
else if(bs == (char) 0)
{
backward--;
}
else if(fs == (char) 0)
{
forward++;
}
else
{
return false;
}
}
}
char SanitizeChar(char C)
{
if(C >= 'a' && C <= 'z')
return C;
if(C >= 'A' && C <= 'Z')
{
C = C - 'A' + 'a';
return C;
}
else
return (char)0;
}
#include<iostream>
using namespace std;
bool ignore(char c) {
int aA = (int)'A';
int aZ = (int)'Z';
int aa = (int)'a';
int az = (int)'z';
int ac = (int)c;
if((ac >= aA && ac <= aZ) || (ac >= aa && ac <=az))
return false;
else
return true;
}
char toLowerCase(char c) {
int aA = (int)'A';
int aZ = (int)'Z';
int aC = (int)c;
if(aC >= aA && aC <= aZ)
return (char)(aC - aA + (int)'a');
else
return c;
}
bool equals(char c1, char c2) {
return toLowerCase(c1) == toLowerCase(c2);
}
int main() {
string s = "A man, a plan, a canal -- Pnama!";
int i = 0;
int j = s.size() -1;
bool isPalindrome = true;
while( i != j ) {
if(ignore(s[i])) i++;
else if(ignore(s[j])) j--;
else if(equals(s[i], s[j])) {
i++;
j--;
} else {
isPalindrome = false;
break;
}
}
cout<<isPalindrome<<endl;
}
Most of these examples don't cover edge cases where the string contains little or no alphabetical characters:
bool isPalindrome(const char *start, const char *end) {
while (start != end && !isalpha(*start)) {
start++;
}
while (start != end && !isalpha(*end)) {
end--;
}
if (tolower(*start) != tolower(*end)) {
return false;
} else {
if (isalpha(*start) && (start == end || end == start + 1)) {
return true;
} else {
return isPalindrome(start + 1, end - 1);
}
}
}
Test cases:
"A man, a plan, a canal -- Panama!" == 1
"cheeze whiz" = 0
" a " = 1
" " = 0
#include <iostream>
bool IsPalindrome(char str[])
{
long len = strlen(str);
char* start;
char* end;
start = str;
end = &str[len-1];
for(int i = 0; i < len/2; i++)
{
if(((int)*start>=65 && (int)*start <= 90) || ((int)*start >= 97 && (int)*start <= 122))
{
if(((int)*end>=65 && (int)*end <= 90) || ((int)*end >= 97 && (int)*end <= 122))
{
if(*start == *end || *start+32 == *end || *start-32 == *end || *start == *end+32 || *start == *end-32)
{
start++;
end--;
}
else
{
return false;
}
}
else
{
end--;
}
}
else
{
start++;
}
}
return true;
}
int main(int argc, const char * argv[]) {
// insert code here...
char str[] = "A Man, A Plan, A Canal – Panama!";
if(IsPalindrome(str))
puts("Yes It is");
else
puts("No It is not");
return 0;
}
//Other Test Strings
//A dog, a panic in a pagoda!
//A car, a man, a maraca!
In Java:
private static boolean isPalindrome(String text) {
char[] array = text.toCharArray();
for (char ch : array) {
if (!((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z'))) {
text = text.replaceAll(String.valueOf(ch), "");
}
}
if (text.equalsIgnoreCase(new StringBuffer(text).reverse().toString())) {
return true;
} else {
return false;
}
}
Here is the C++ solution with O(N) running time.
#include<iostream>
#include <string>
using namespace std;
bool isChar(char c)
{
return (c>='a' && c<='z')||(c>='A' && c<='Z');
}
bool isSame(char s, char d)
{
int low_s = s -'a';
int up_s= s-'A';
int low_d = d-'a';
int up_d = d-'A';
return (low_s == low_d)|| (low_s == up_d) || (up_s == up_d)||(up_s == low_d);
}
bool isPalindrom(string input)
{
int s = 0;
int e = input.length()-1;
while (s < e)
{
if (!isChar(input[s]))
s++;
else if (!isChar(input[e]))
e--;
else if(!isSame(input[s++], input[e--]))
return false;
}
return true;
}
int main()
{
string input = "A man, a plan, a canal -- Panama!";
cout << "is input palindrom : " << isPalindrom(input)<<endl;
}
C++ solution
#include<iostream>
#include <string>
using namespace std;
bool isChar(char c)
{
return (c>='a' && c<='z')||(c>='A' && c<='Z');
}
bool isSame(char s, char d)
{
int low_s = s -'a';
int up_s= s-'A';
int low_d = d-'a';
int up_d = d-'A';
return (low_s == low_d)|| (low_s == up_d) || (up_s == up_d)||(up_s == low_d);
}
bool isPalindrom(string input)
{
int s = 0;
int e = input.length()-1;
while (s < e)
{
if (!isChar(input[s]))
s++;
else if (!isChar(input[e]))
e--;
else if(!isSame(input[s++], input[e--]))
return false;
}
return true;
}
Here is C++ version of solution
#include<iostream>
#include <string>
#include <math.h>
using namespace std;
bool isChar(char c)
{
return (c>='a' && c<='z')||(c>='A' && c<='Z');
}
bool isSame(char s, char d)
{
return (s == d)|| (abs(s-d)=='a'-'A');
}
bool isPalindrom(string input)
{
int s = 0;
int e = input.length()-1;
while (s < e)
{
if (!isChar(input[s]))
s++;
else if (!isChar(input[e]))
e--;
else if(!isSame(input[s++], input[e--]))
return false;
}
return true;
}
Here is C++ solution
#include<iostream>
#include <string>
#include <math.h>
using namespace std;
bool isChar(char c)
{
return (c>='a' && c<='z')||(c>='A' && c<='Z');
}
bool isSame(char s, char d)
{
return (s == d)|| (abs(s-d)=='a'-'A');
}
bool isPalindrom(string input)
{
int s = 0;
int e = input.length()-1;
while (s < e)
{
if (!isChar(input[s]))
s++;
else if (!isChar(input[e]))
e--;
else if(!isSame(input[s++], input[e--]))
return false;
}
return true;
}
boolean isPalindrome(String s) {
int i = 0;
int j = s.length() - 1;
int half = s.length() / 2;
while(i < half && j > half) {
if (Character.toLowerCase(s.charAt(i)) < 'a' || Character.toLowerCase(s.charAt(i)) > 'z') {
i++;
} else if (Character.toLowerCase(s.charAt(j)) < 'a' || Character.toLowerCase(s.charAt(j)) > 'z') {
j--;
} else {
if (Character.toLowerCase(s.charAt(i)) != Character.toLowerCase(s.charAt(j))) return false;
i++;
j--;
}
}
return true;
}
- Anonymous November 14, 2014