Google Interview Question for Software Engineer / Developers






Comment hidden because of low score. Click to expand.
3
of 3 vote

I think DP could be doable here. Let T[i,j] stores minimum number of palindromic substring that form substring S[i...j].

Initially, T[i,i] = 1. To compute T[i,j] for i+1 <= j <= n, first check if S[i...j] is palindrome. If it's, T[i,j] = 1. Else, T[i,j] = Min (T[i,k] + T[k+1,j]) for i <= k < j. This leads O(n^3) solution. There probably exists some O(n^2) solution, I guess.

- buried.shopno May 06, 2011 | Flag Reply
Comment hidden because of low score. Click to expand.
1
of 1 vote

This problem can be solved in O(n^2).

Basic DP:
Assume A[i] is the least cut number of string[1:i]. Then A[i + 1] should be min(A[i]+1, A[i-1]+check(i, i+1), A[i-2] + check(i-1,i+1), ....). Here check(i,j) do the check whether string[i:j] is palindromic, if it's false, (A[i - 1] + check(i, j)) should be unlimited large. It should cost O(n). So the time complexity of basic DP should be O(n^3).

However we can calculate check(i, j) in advance. Every time we choose an element (or two) as the center of palindrome, and spread towards left and right to get all the palindromes. So this preprocess cost O(n^2).

At last the DP can be solve in O(n^2) as check(i, j) can be calculated in O(1) after preprocess.

Here is the C++ code:

#include <iostream>
using namespace std;

int A[1000];
bool check[1000][1000];

int mincut(int *array, int n)
{
    for (int i = 1; i <= n; ++i)
    {
        int offset = 0;
        while (i - offset > 0 && i + offset <= n && array[i - offset] == array[i + offset])
        {
            check[i - offset][i + offset] = true;
            ++offset;
        }
        offset = 0;
        while (i - offset > 0 && i + 1 + offset <= n && array[i - offset] == array[i + 1 + offset])
        {
            check[i - offset][i + 1 + offset] = true;
            ++offset;
        }
    }
    A[0] = 0;
    for (int i = 1; i <= n; ++i)
    {
        A[i] = A[i - 1] + 1;
        for (int j = i - 1; j > 0; j -= 2)
        {
            if (check[j][i])
            {
                if (A[i] > A[j - 1] + 1)
                {
                    A[i] = A[j - 1] + 1;
                }
            }
        }
        for (int j = i - 2; j > 0; j -= 2)
        {
            if (check[j][i])
            {
                if (A[i] > A[j - 1] + 1)
                {
                    A[i] = A[j - 1] + 1;
                }
            }
        }
    }
    return A[n];
}

int main()
{
    int n;
    int array[1000];
    cin >> n;
    for (int i = 1; i <= n; ++i)
    {
        cin >> array[i];
    }
    int result = mincut(array, n);
    cout << result << endl;
    return 0;
}

- wenlei.zhouwl May 23, 2012 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

that's an incorrect solution .

- ANONYMOUS November 13, 2012 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

If we can preprocess check, why not to preprocess whole result and have it in O(1) :-)... On the other hand, idea to find the edge palindrome is good idea, because you don't need to count with all possibilities, just cut off the first palindrome on the right, because this cut will surely need to be done and it doesn't matter when.

- mbriskar May 31, 2015 | Flag
Comment hidden because of low score. Click to expand.
1
of 1 vote

It can be solved by simple DP

static int minCutsforPalindrome(String str){
if(str == null)
return -1;
if(str.length()<2)
return str.length();

int[] min = new int[str.length()+1];
min[0] = 0;
min[1] = 1;
for(int i =2;i<=str.length();i++){
min[i] = min[i-1] + 1;
int p = hasPalindrome(str,i-1);
if(p!=-1){
min[i] = Math.min(min[i], 1+min[p]);
}
}
return min[str.length()]-1;
}

private static int hasPalindrome(String str, int index) {
for(int i=0;i<index;i++){
if(isPalindrome(str.substring(i,index+1)))
return i;
}
return -1;
}

private static boolean isPalindrome(String str) {
if(str.length()<=1)
return true;
int i =0;
int j = str.length() - 1;
while(i<j){
if(str.charAt(i) == str.charAt(j)){
i++;
j--;
}else{
return false;
}
}
return true;
}

- loveCoding December 31, 2011 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

Good solution!!!
But I think you need to adjust your parameters to str.substring() call. It should probably be str.substring(i,index-i)

- IntwPrep October 09, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

if for given string of size n you check if string(1...N-1) is palindrome, and check if 0..n-1 and 1...n cases. returning maximum substring length in any case.
As I see each char is checked 3 times max, so running time is O(n). Where's my mistake?

do a recursion like this: (can be easily modified to remember maximum in any case and select best division in O(n).

int getMinimimNumberOfSubstring(string s) {
 if (s.length == 1) { return 1; };
 max_mid_sub = getMinimimNumberOfSubstring(s.substring(1, s.length-1)); //get middle
 
 int maxSub = 1;
 if (max_mid_sub.length == s.length -2) { //its maximum
    //middle is a max, check if our 0 and n-1 creating palindrome
    if (s.substring(0,1).equals(s.substring(s.length-2,s.length-1))) {
        return max_min_sub.length + 2; 
    else {
        maxSub = max(max_min_sub.length, 1); //string and borders
 }

 //check 0...n-2 and 1...n-1 cases
 return max(maxSub,
            getMinimimNumberOfSubstring(s.substring(1)),
            getMinimimNumberOfSubstring(s.substring(0, s.length-1));
}

- Anonymous May 08, 2011 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

<pre lang="" line="1" title="CodeMonkey79135" class="run-this">//To break a long string to minimum substring which are palindromes

package com.stringtopalindome;

import java.util.*;

public class StringToPalindrome {

private static List<String> out = new ArrayList<String>();

public static void main(String[] args)
{
String input ="mnopabcdcbanhohnp";

generatePalindrome(input);

for(String output:out)
{
System.out.println(output);
}

}

//To generate palindrome inside input to out
private static void generatePalindrome(String input) {

char[] inputToArray = input.toCharArray();
int startIndex=0;
int indexFromEnd = inputToArray.length-1;
while(startIndex<inputToArray.length)
{
int presentIndex=-1;
boolean indexToUsed = true;
while((presentIndex=isPresent(inputToArray,startIndex,indexFromEnd))>0)
{
if(isPalindrome(inputToArray,startIndex,presentIndex))
{
out.add(input.substring(startIndex,presentIndex+1));
indexToUsed=false;
startIndex = presentIndex;
break;
}
else
{
indexFromEnd=presentIndex-1;
}
}

if(indexToUsed)
{
out.add(String.valueOf(inputToArray[startIndex]));

}

++startIndex;
indexFromEnd=inputToArray.length-1;

}
}

//To check whether string from given range is palindrome or not
private static boolean isPalindrome(char[] inputToArray, int startIndex,
int presentIndex) {

while(startIndex<presentIndex)
{
if(inputToArray[startIndex]==inputToArray[presentIndex])
{
++startIndex;
--presentIndex;
}
else
return false;
}
return true;
}

//return the first occurrence of the startIndex character from indexFromEnd
private static int isPresent(char[] inputToArray, int startIndex,
int indexFromEnd) {

for(int i=indexFromEnd;i>startIndex;i--)
{
if(inputToArray[i]==inputToArray[startIndex])
return i;
}

return -1;
}




}
</pre><pre title="CodeMonkey79135" input="yes">
</pre>

- Anonymous May 14, 2011 | Flag Reply
Comment hidden because of low score. Click to expand.
1
of 1 vote

Who pay a shit to your code without any explanation? Give your explanation, only then code (though many people DISCOURAGE looking into other's code to get the idea verbatim)!

- anonymous May 21, 2011 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

this code take O(n^2)..

- Nishank May 14, 2011 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

You are returning a -1 in a method that is designed to return boolean??? Also, you're while loop doesn't make any sense --> what is this : while(startIndexstartIndex;i--)

- Anonymous May 19, 2011 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

You should be able to do this using divide-and-conquer approach. The solution to this problem is similar to the solution to the divide-and-conquer approach to the maximum sum subset problem (find a consecutive subset of an array that gives the maximum sum).

The algorithm goes like this:
- find the longest possible palindromes from the left half
- find the longest possible palindromes from the right half
- look at the two results and see if there is an overlapping palindrome between the two halves...if there is, combine the two palindromes into one

if there is only one element, add it to data structure you're using to store splits (because one element is a palindrome)

the divide portion alone will take O(log n) and the combine step at the very end can at worst go through n elements, giving O( n log n )

- vinnybad May 19, 2011 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

Your method isn't sound at all! I saw this question in Jeff Erickson's (UIUC prof) problem section (google it). It was a DP, not divide-and-conquer.

If you wish to challenge, why not code it. I'd give you a counter example.

- anonymous May 21, 2011 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

My thought is to store the substrings in two rounds:
1. from left to right, store all substrings like (leftindex, rightindex) = hash(substring)
2. from right to left, store all substrings like (rightindex, leftindex) = hash(substring)
3. And then compare these two n^2 arrays in length order.
for 1-3 steps you can consider the cost as O(n^2), but in fact it doesn's include the cost of hash().

- justcoder May 26, 2011 | Flag Reply
Comment hidden because of low score. Click to expand.
-1
of 1 vote

It doesn't work, because it follows basically GREEDY approach. This problem is designed for DP (someone pointed already) - a solution given by buried.shopno on May 6's post. My approach is similar to this, which gives correct result. Try to understand the logic, and code it rather reinventing the wheel on wrong track.

- lol May 28, 2011 | Flag
Comment hidden because of low score. Click to expand.
1
of 1 vote

stop judging. he's trying too.

- Anonymous July 16, 2011 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

f[i] = minimum number of palindrome can be made from str[0,...,i]
f[i] = 1 + min(f[k]), where 0 <= k < i and str[k+1,...,i] is a palindrome.
let len=strlen(str), then the answer is f[len-1].

- lambda2fei August 22, 2012 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

here the greedy approach doesn't work, that is, in each decision, we can not just choose the longest palindrome ended at i. example: abcbab

- lambda2fei August 22, 2012 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

and i don't know whether there is an O(n) or O(nlogn) algorithm. my algorithm can be done in O(n^2).

- lambda2fei August 22, 2012 | Flag


Add a Comment
Name:

Writing Code? Surround your code with {{{ and }}} to preserve whitespace.

Books

is a comprehensive book on getting a job at a top tech company, while focuses on dev interviews and does this for PMs.

Learn More

Videos

CareerCup's interview videos give you a real-life look at technical interviews. In these unscripted videos, watch how other candidates handle tough questions and how the interviewer thinks about their performance.

Learn More

Resume Review

Most engineers make critical mistakes on their resumes -- we can fix your resume with our custom resume review service. And, we use fellow engineers as our resume reviewers, so you can be sure that we "get" what you're saying.

Learn More

Mock Interviews

Our Mock Interviews will be conducted "in character" just like a real interview, and can focus on whatever topics you want. All our interviewers have worked for Microsoft, Google or Amazon, you know you'll get a true-to-life experience.

Learn More