Amazon Interview Question for SDE1s


Country: United States




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

This is the "Rank of a permutation" algorithm. It is discussed here:
rosettacode.org/wiki/Permutations/Rank_of_a_permutation

- ashot madatyan July 07, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
1
of 1 vote

BigInteger[] fact;
	
	BigInteger getRank(String word) {
		int n = word.length();
		computeFact(n - 1);
 
		char[] letterArray = word.toCharArray();
		Arrays.sort(letterArray);
		ArrayList<Character> letterList = new ArrayList<Character>();
		
		for (int i = 0; i < n; i++){
			char c = letterArray[i];
			letterList.add(c);
		}
		 
		BigInteger rank = BigInteger.ONE;
		
		for (int i = 0; i < n - 1; i++){
			Character c = word.charAt(i);
			int index = letterList.indexOf(c);

			BigInteger rawDiv = BigInteger.ONE;
			int repeat = 1;
			for (int j = 1; j < letterList.size(); j++){
				if (letterList.get(j).equals(letterList.get(j - 1))){
					repeat++;
				}
				else{
					rawDiv = rawDiv.multiply(fact[repeat]);
					repeat = 1;
				}
			}
			rawDiv = rawDiv.multiply(fact[repeat]);
			
			BigInteger count = BigInteger.ZERO;
			repeat = 1;
			for (int j = 1; j <= index; j++){
				if (letterList.get(j).equals(letterList.get(j - 1))){
					repeat++;
				}
				else{
					if (repeat == 1){
						count = count.add(fact[n - 1 - i].divide(rawDiv));
					}
					else{
						count = count.add(fact[n - 1 - i].multiply(BigInteger.valueOf(repeat)).divide(rawDiv));
					}
					repeat = 1;
				}
			}
			
			//System.out.println(i + " " + count);
			rank = rank.add(count);
			letterList.remove(index);
		}

	    return rank;
	}

	void computeFact(int n) {
	    
		fact = new BigInteger[n + 1];
		fact[0] = BigInteger.ONE;
	    for (int i = 1; i <= n; i++)
	        fact[i] = fact[i - 1].multiply(BigInteger.valueOf(i));

	}

- eastflag163 November 05, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

Here's my code for rank of string with all distinct characters..
Description:
freq(char *str, int len, int* count/*assumed to be of len=26*/): counts the frequency of each char present in the string. As per my assumption each char count must be 1.
factorial(int n): finds factorial of given n.
int countLessThan(char c, int *freq) : counts number of characters which are less than char c
ull findRank(char *str, int len, int pos, int* count): actually finds the rank of given word.
ull wordRank(char *str, int len): wrapper around findRank(). Just to supply the count[] array
void wordRankDriver(): main driver function.

IDEA: The idea is to calculate the rank of given word, find the number of permutations which are rank wise smaller than current word. To do so, permutation is calculated recursively.
1. Take all the chars which are smaller than char at position: pos=0. Now each of smaller char can be placed at pos 0 and rest (total # of chars -1) can be arranged among themselves in factorial((total # of chars -1) ways.
2. Once this is calculated for current position: pos, increment pos by 1 and calculate recursively # of permutations for next pos, that is pos.

Hope this description makes it somewhat clear. Appologies if not able to describe the procedure clearly.

BIG ASSUMPTION: All characters in the word are unique with no repeated chars.

#include<iostream>
#include<cstring>

using namespace std;

typedef unsigned long long ull;

void freq(char *str, int len, int* count/*assumed to be of len=26*/)
{
	memset(count, 0x00, 26*sizeof(int));
	if(!str || len == 0)
		return ;
	for(int i=0; (str[i]!= '\0') && (i < len); i++)
		count[tolower(str[i])-'a']++;
	return ;
}

ull factorial(int n)
{
	ull fact = 1;
	for(int i=2; i <= n; i++)
		fact *= i;
	return fact;
}

int countLessThan(char c, int *freq)
{
	int count=0;
	for(int i =0; i<c-'a'; i++)
		count += freq[i];
	
	return count;
}

//ASSUMPTION: All characters in the word are unique with no repeated chars.
ull findRank(char *str, int len, int pos, int* count)
{
	if(!str || len == 0)
		return 0;
	if(pos == len-1)
		return 1;
	int rank = countLessThan(str[pos], count);
	rank = rank*factorial(len-pos-1);
	count[tolower(str[pos])-'a']--;
	return rank + findRank(str, len, pos+1, count);
}

ull wordRank(char *str, int len)
{
	int count[26] = {0,};
	freq(str, len, count);
	return findRank(str, strlen(str), 0, count);
}

void wordRankDriver()
{
	ull rank = wordRank("question", strlen("question"));
	cout << "Rank of word question  = " << rank << endl;

	rank = wordRank("einoqstu", strlen("question"));
	cout << "Rank of word einoqstu  = " << rank << endl;

	rank = wordRank("education", strlen("education"));
	cout << "Rank of word education  = " << rank << endl;
}

- pavi.8081 July 08, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
-1
of 1 vote

Here's a solution in Java that can handle words with repeated characters. The real solution should use BigInteger instead of int to accommodate factorials over 12!.

int rank(String word) {
    List<Character> chars = new ArrayList<>();
    Map<Character, Integer> freqs = new HashMap<>();

    for (char c : word.toCharArray())
        chars.add(c);

    Collections.sort(chars);

    for (Character c : chars)
        if (freqs.containsKey(c))
            freqs.put(c, freqs.get(c) + 1);
        else
            freqs.put(c, 1);

    int rank = 1;
    
    for (int i = 0; i < word.length(); i++) {
        char c = word.charAt(i);
        int sortPos = Collections.binarySearch(chars, c);
        int wordLength = chars.size();
        rank += sortPos * possibilities(wordLength, freqs) / wordLength;
        chars.remove(sortPos);
        freqs.put(c, freqs.get(c) - 1);
    }

    return rank;
}

int possibilities(int wordLength, Map<Character, Integer> freqs) {
    int possibilities = fact(wordLength);
    for (Map.Entry<Character, Integer> entry : freqs.entrySet())
        possibilities /= fact(entry.getValue());
    return possibilities;
}

int fact(int n) {
    int fact = 1;

    for (int i = 2; i <= n; i++)
        fact *= i;

    return fact;
}

- Mihkel Müür August 26, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
-2
of 2 vote

import java.math.BigInteger;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
import java.util.TreeMap;


public class AnagramCount {
static Map<Integer, BigInteger> factMap = new TreeMap<Integer, BigInteger>();
static BigInteger count = BigInteger.ZERO;

/**
* @param args
* Performs
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println("Enter the input");
Scanner sc = new Scanner(System.in);
String inputString = sc.next();
long startTime = System.currentTimeMillis();
findPermutations(inputString);
long endTime = System.currentTimeMillis();
long totalTime = endTime - startTime;
System.out.println("Run Time (in milliseconds) : " + totalTime);
}

/*
* Modification of Bell's Algorithm for permutation. But does not form words at every step
* Calculates the number of words that could be formed until the required permutation of words is reached
* Worst Case RunTime Complexity : O(n * n) - Performs n iterations for fixing each character that could match the input String
* Worst Case Space Complexity : O(n) -linear with n - to track factorial values and duplicates
* where 'n' is the length of the input String
*/

public static void findPermutations(String inputString){
char[] word = inputString.toCharArray();
Arrays.sort(word);
int i = 0;
int j = 0;
while(i<word.length){
if(word[i] != inputString.charAt(j)){
count = count.add(countPermutations(word, i));
for(int k=i; k<word.length; k++){
if((int)word[k] > (int)word[i]){
char temp = word[i];
word[i] = word[k];
word[k] = temp;
break;
}
}
}
else if(word[i] == inputString.charAt(j)){
i += 1;
j += 1;
}
}
System.out.println("Index of the word " + inputString + " : " + count.add(BigInteger.ONE).toString());
}

/*
* Gets the word array which contains individual characters and the current position of the string which is fixed
* Finds the possible PERMUTATION OF WORDS WITH THE CHARACTER 'x'(any character) at the start position
*/

public static BigInteger countPermutations(char[] word, int startPosition){
Map<Character, Integer> duplicateCountMap = new HashMap<Character, Integer>();
for(int i = startPosition + 1; i<word.length; i++){
if(duplicateCountMap.get(word[i]) == null){
duplicateCountMap.put(word[i], 1);
}
else{
duplicateCountMap.put(word[i], duplicateCountMap.get(word[i]) + 1);
}
}
BigInteger numerator = factorial(word.length - startPosition - 1);
BigInteger denominator = BigInteger.ONE;
for(Integer value : duplicateCountMap.values()){
denominator = factorial(value).multiply(denominator);
}
return numerator.divide(denominator);
}


/*
* FACTORIAL CALCULATION WITH MEMOIZATION
* Gets the number as input and returns its Factorial value
*/

public static BigInteger factorial(int number){
if(number <= 1)
return BigInteger.ONE;
if(factMap.get(number) == null){
factMap.put(number, BigInteger.valueOf(number).multiply(factorial(number - 1)));
}
return factMap.get(number);
}
}

- Anonymous July 08, 2013 | 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