Facebook Interview Question for Java Developers


Country: United States




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

@Raphael: The approach is good, I think the code has an issue: when moving the "slow" pointer shouldn't we decrement the element count that leaves the window (not only the one that has been seen more than k times)

while (s.charAt(slow) != c) {
	seen[s.charAt(slow)]--;
	slow++;
}

e.g.
1,2,3,2,2,1,1,5,6,7,8, k = 2 --> 3,2,2,1,1,5,6,7,8

- Chris November 27, 2017 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

My interpretation of the question is that we are asked to find a substring with at most k characters that may appear more than once (as opposed to any one character appearing more than k times). Is that not the case?

- Anonymous November 27, 2017 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Thanks @majia168 for clarifying the question!

- Anonymous November 28, 2017 | Flag
Comment hidden because of low score. Click to expand.
1
of 1 vote

Hi @ChrisK, Thank you for your comment. I think you're totally right! So a proper solution should be:

var longestSubstring = function(s, k) {

  var seen = {};

  var slow = 0, fast = 0;
  var max = 0;

  while (fast < s.length) {

    var c = s.charAt(fast);

    if (c in seen) {
    
      if (seen[c] == k) {
        while (s.charAt(slow) != c) {
          seen[s.charAt(slow)]--;
          slow++;
        }
        slow++;
      } else {
        seen[c]++;
      }
      
    } else {
      seen[c] = 1;
    }
    
    fast++;
    if (fast - slow > max)
      max = fast - slow;
  }
  
  return max;
}

- Raphael November 27, 2017 | Flag Reply
Comment hidden because of low score. Click to expand.
1
of 1 vote

I assume repeating characters may be different. E.g.
"abcdc" - 1 repeating char.
"abcdcb" - 2 repeating chars, no matter the repeating chars a different.
"abcdcbb" - 3 repeating chars.

#include <iostream>
#include <unordered_map>

using namespace std;

pair<int, int> LongestSubstring(string const &s, int k)
{
	pair<int, int> out(-1, -1);

	if (k >= s.size()) {
		if (!s.empty()) {
			out = pair<int, int>(0, s.size() - 1);
		}
		return out;
	}

	if (k > 0) {
		int start = 0;
		int max_size = 0;
		unordered_map<char, int> seen;
		int repeted_chars_count = 0;
		for (int i = 0; i < s.size(); ++i) {
			if (++seen[s[i]] > 1) {
				++repeted_chars_count;
				while (repeted_chars_count > k) {
					if (--seen[s[start++]] != 0) {
						--repeted_chars_count;
					}
				}
			}
			int size = i - start + 1;
			if (size > max_size) {
				max_size = size;
				out = pair<int, int>(start, i);
			}
		}
	}

	return out;
}

int main() {

	auto out = LongestSubstring("alblabljln", 2);
	cout << out.first << " - " << out.second << "\n";
}

- Alex November 27, 2017 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

Here is my Javascript solution in O(n) time using O(n) space (n being the length of s):

var longestSubstring = function(s, k) {

  var seen = {};

  var slow = 0, fast = 0;
  var max = 0;

  while (fast < s.length) {

    var c = s.charAt(fast);

    if (c in seen) {
    
      if (seen[c] == k) {
        while (s.charAt(slow) != c) {
          slow++;
        }
        slow++;
      } else {
        seen[c]++;
      }
      
    } else {
      seen[c] = 1;
    }
    
    fast++;
    if (fast - slow > max)
      max = fast - slow;
  }
  
  return max;
}

- Raphael November 27, 2017 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

Here is my O(n) time and O(n) space Javascript solution, using a fast and slow pointer:

var longestSubstring = function(s, k) {

  var seen = {};

  var slow = 0, fast = 0;
  var max = 0;

  while (fast < s.length) {

    var c = s.charAt(fast);

    if (c in seen) {
    
      if (seen[c] == k) {
        while (s.charAt(slow) != c) {
          slow++;
        }
        slow++;
      } else {
        seen[c]++;
      }
      
    } else {
      seen[c] = 1;
    }
    
    fast++;
    if (fast - slow > max)
      max = fast - slow;
  }
  
  return max;

}

- Raphael November 27, 2017 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

Here is my approach O(n) time complexity and O(1) space:

1. Set two pointers (A and B) point at the beginning of the string.

2. Pointer A walks through the string and record the frequency of each character in count[26].

3. If the current character that pointer A points to appears more than K, save the substring between B (inclusive) and A (exclusive) if it is the longest substring so far.

4. Move the pointer B and subtract the pointing character from count[26] until we get the frequencies of all characters in count[26] no more than K.

5. Repeat the process from step 2 until it reaches the end of the string.

//Assume given string is all low case between [a-z]
public String longestSubstring(String str, int K)
{
	int A = 0;
	int B = 0;
	int[] count = new int[26];
	int longestLen = 0;
	String result;
	for(;A<str.length();A++)
	{
		if(++count[str.charAt(A)-'a'] > K)
		{
			if(longestLen < A-B)
			{
				result = str.substring(B,A);
			}
			for(;B<A;B++)
			{
				if(--count[str.charAt(B)-'a'] == K)
				{
					B++;
					break;
				}
			}
		}
		
	}
	//indicates none of the characters in given string appears more than K
	if(result == null) return str;
	return result;
}

- jiahuang November 30, 2017 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

Here's my implementation in C.

Walking the string from left to right, you compute the length of the longest substring ending at each character. You then simply pick the substring ending at the character with the biggest substring length. Compiled and tested at interviewing.io

Sample output:
aacdbbeb, k = 2. Output = aacdbbeb
alblabljln, k = 1. Output = ablj
alblabljln, k = 2. Output = alblab

#include <stdio.h>
#include <string.h>

void LongestSubstringWorker (char *string, unsigned int factor,
                             unsigned int *maxlen,
                             unsigned int *maxindex,
                             unsigned int currindex) {
  unsigned int count[256];
  unsigned int len[strlen(string)];
  unsigned int i,j;
  
  for (i = 0; i < 256; i++) {
    count[i] = 0;
  }
  
  for (i = 0; i < strlen(string); i++) {
    len[i] = 1;
  }
  
  count[(unsigned char)string[0]] = 1;
  
  for (i = 1; i < strlen(string); i++) {
    count[(unsigned char)string[i]]++;
    if (count[(unsigned char)string[i]] <= factor) {
      len[i] = len[i - 1] + 1;
      
      if (len[i] > *maxlen) {
        *maxlen = len[i];
        *maxindex = i + currindex;
      }
    } else {
      for (j = 0; j < i; j++) {
        if (string[j] == string[i]) {
          LongestSubstringWorker (&string[j + 1], factor,
                                  maxlen, maxindex, j + 1 + currindex);
          return;
        }
      }
    }
  }
}

void LongestSubstring (char *string, unsigned int factor) {
  unsigned int maxlen;
  unsigned int maxindex;
  unsigned int i;
  
  if (string == NULL) {
    return;
  }

  maxlen = 1;
  maxindex = 0;
  
  LongestSubstringWorker(string, factor, &maxlen, &maxindex, 0);
  
  for (i = maxindex - (maxlen - 1); i <= maxindex; i++) {
    printf("%c", string[i]);
  }
  
  printf("\n");
}

int main() {
  LongestSubstring("alblabljln", 1);
  return 0;
}

- ranechabria December 02, 2017 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

def longestSubstringRepeating(string,k):

	if not string or k==0:
		return 0 

	max_len, start = 0, 0
	dic= dict()

	for idx, char in enumerate(string):
		dic[char] = dic.get(char,0) + 1
		while dic[char]>k:
			dic[string[start]] = dic[string[start]]-1
			start = start+1
		max_len = max(max_len, idx-start+1)
	return max_len

- DyingLizard December 19, 2017 | 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