Google Interview Question for Software Engineers


Country: Switzerland
Interview Type: Phone Interview




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

This sounds like a type of bucketsort.
Create a hashtable mapping characters in O to a number counting its occurences in t
append characters that don't exist in o to the beginning of the output string.
Finally go through and add the number of a character corresponding to o

public String reorder(String t, String o) {
	
	HashMap<String, Integer> H = new HashMap();

	for (int i = 0; i < o.length; i++) {

		h.put(o.charAt(i), 0);//put o chars in hashmnap
	}

	StringBuffer output = new StringBuffer();

	for (int i = 0; i < t.length; i++) {

		if (h.keyExists(t.charAt(i))) {

			h.put(t.charAt(i), h.get(t.charAt(i)) + 1);//increment the value here
		}

		else {

			output.append(t.charAt(i));
		}
	}


	int copyNum = 0;

	for (int i = 0; i < o.length; i++) {

		copyNum = h.get(o.charAt(i));//get number of times this character occured

		for (int j = 0; j < copyNum; j++) {

			output.append(o.charAt(i));
		}
	}

	returnt output.toString()

}

- Skor March 21, 2015 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

Nice catch, seems like a better solution. Good thing though that my solution was good enough to pass to the on-site

- tested.candidate March 21, 2015 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Congratulations! :)

- SK March 21, 2015 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Nice. Applying principles of counting sort (creating a histogram of counts) really simplifies things and gets a nice O(n) runtime.

My initial design was to convert string T to a char array and apply principles of selection sort where you start partitioning the array into [sorted | unsorted] (for each char in O, grab chars in T and swap them into the beginning of the unsorted portion of the array). This works but is O(mn) and also has the extra work of creating a new string at the end to hold the unspecified chars at the beginning.

- JW March 24, 2015 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Nice solution! Since these are chars (i.e. 0 to 255 integers) you could probably just use an integer vector of length 256 instead of a hash_map.

- mp April 10, 2015 | Flag
Comment hidden because of low score. Click to expand.
1
of 1 vote

The solution to this question is a decorate-sort-undecorate algorithm. The characters of the string T are supposed to be decorated with values which are indices of those characters in the string O or value -1 if they are absent in string O. Since the order of the characters decorated with -1 is not important we are free to use any sorting algorithm (i.e. not necessarily a stable one).

def reorder(t, o):
    # Build a decorating hash table
    lut = {}
    for i in range(len(o)):
        lut[o[i]] = i
    # Reorder
    return ''.join(sorted(t, key=lambda character: lut[character] if lut.has_key(character) else -1))

print reorder('hello world', 'wrled')

- tested.candidate March 21, 2015 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

public class Solution {

	public static void main(String[] args) {

		String t = "water";
		String o = "zealot";
		System.out.println(orderStringByRef(t, o));
	}

	public static String orderStringByRef(String t, String o) {

		StringBuilder sb = new StringBuilder();
		char c;
		int indexOfChar = -1;
		List<CharSeq> list = new ArrayList<>();

		for (int i = 0; i < t.length(); i++) {
			c = t.charAt(i);
			indexOfChar = o.indexOf(c);
			if (indexOfChar >= 0) {
				CharSeq cs = new CharSeq();
				cs.c = c;
				cs.i = indexOfChar;
				list.add(cs);
			} else {
				sb.append(c);
			}
		}

		list.sort(new CharSeqComparator());

		for (CharSeq cs : list) {
			sb.append(cs.c);
		}

		return sb.toString();
	}

}

class CharSeq {
	char c;
	int i;
}

class CharSeqComparator implements Comparator<CharSeq> {

	@Override
	public int compare(CharSeq a, CharSeq b) {
		if (a.i < b.i) {
			return -1;
		} else if (a.i == b.i) {
			return 0;
		} else if (a.i > b.i) {
			return 1;
		}
		return -1;
	}
}

- guilhebl March 22, 2015 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

I think best solution is using quicksort. I am reordering string in place in my solution

public class StringReorder {
    public static void main(String[] args) {

        char[] string = {'f', 'f', 'c', 'b', 'a', 'c'};
        String order = "abcf";
        reorderString(string, order);
        System.out.println("Reordered " + new String(string));
    }

    public static void reorderString(char[] string, String order) {
        quickSort(string, 0, string.length - 1, order);
    }

    public static void quickSort(char[] string, int startIdx, int endIdx, String order) {
        if(endIdx <= startIdx) return;
        System.out.println("StartIdx "+ startIdx + "EndIdx "+ endIdx);
        int randomIndex = (int) Math.floor(Math.random()*(endIdx - startIdx + 1));
        char pivot = string[randomIndex];
        int pivotOrder = order.indexOf(pivot);

        int lIdx = startIdx, rIdx = endIdx;
        while (lIdx < rIdx) {
            int lIdxOrder = order.indexOf(string[lIdx]);
            if(lIdxOrder > pivotOrder) {
                swap(string, lIdx, rIdx);
                rIdx--;
            } else if (lIdxOrder < pivotOrder){
                lIdx++;
            } else {
                lIdx++;
                rIdx--;
            }
        }
        quickSort(string, startIdx, rIdx -1, order);
        quickSort(string, lIdx+1, endIdx, order);
    }                          

    public static void swap(char[] string, int idx1, int idx2) {
        char temp = string[idx2];
        string[idx2] = string[idx1];
        string[idx1] = temp;
    }   
}

- snegi March 25, 2015 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

how about modifying the cmp function in standard sorting routines to achieve the outcome? Something like this --

class Precedences:
	def __init__(self, _prec):
		self.precedences = {}
		for idx, ch in enumerate(_prec):
			self.precedences[ch] = idx;
	def cmp(self, ch):
		if ch in self.precedences.keys():
			return self.precedences[ch]
		return len(self.precendeces)+1

if __name__ == '__main__':
	prec = "729354618"
	inp = "876570"
	precendeces = Precedences(prec)
	out = sorted(inp, key=precedences.cmp)
	print(prec)
	print(inp)
	print(out)

- code_worrier March 30, 2015 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

how about modifying the cmp function in standard sorting routines to achieve the outcome? Something like this --

class Precedences:
	def __init__(self, _prec):
		self.precedences = {}
		for idx, ch in enumerate(_prec):
			self.precedences[ch] = idx;
	def cmp(self, ch):
		if ch in self.precedences.keys():
			return self.precedences[ch]
		return len(self.precendeces)+1

if __name__ == '__main__':
	prec = "729354618"
	inp = "876570"
	precendeces = Precedences(prec)
	out = sorted(inp, key=precedences.cmp)
	print(prec)
	print(inp)
	print(out)

- code_worrier March 30, 2015 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

Good Question, here is my answer.

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.HashMap;

public class CustomSorter {

	public static String sortString(String input, String alphabetSource) {
		
		Map<Character, Integer> alphabetMap = new HashMap<Character, Integer>();
		Map<Integer, Character> alphabetMapRev = new HashMap<Integer, Character>();
		
		char[] alphabetSourceChars = alphabetSource.toCharArray();
		
		for (int i = 0; i < alphabetSourceChars.length; ++i) {
			alphabetMap.put(alphabetSourceChars[i], i);
			alphabetMapRev.put(i, alphabetSourceChars[i]);
		}
		
		char[] inputChars = input.toCharArray();
		List<Integer> inputCharIndexs = new ArrayList<Integer>();
		int missingIndex = -1;
		
		for (int i = 0; i < inputChars.length; ++i) {
			Integer charIndex = alphabetMap.get(inputChars[i]);
			
			if (charIndex == null) {
				inputCharIndexs.add(missingIndex);
				alphabetMap.put(inputChars[i], missingIndex);
				alphabetMapRev.put(missingIndex, inputChars[i]);
				--missingIndex;
			} else {
				inputCharIndexs.add(charIndex);
			}
		}
		
		Collections.sort(inputCharIndexs);
		String sortedString = "";
		
		for (Integer index : inputCharIndexs) {
			sortedString += alphabetMapRev.get(index) + "";
		}
		
		return sortedString;
	}
	
	
	public static void main(String[] args) {
		System.out.println(sortString("ababcdddaab", "dcba"));
		System.out.println(sortString("ababcdzxxzddaab", "dcba"));		
	}
}

- Good Maker May 07, 2015 | Flag Reply


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