Facebook Interview Question
Software Engineer / DevelopersDude...Do u understand the meaning of extra memory?? writer and reader are just pointers pointing to memory location of "str". Even if you don't understand just used integers for indexing rather than using pointers
XYZ is correct...Anonymous, how else are you supposed to work with the data if not with pointers or integers identifying indices??
No extra memory simply means don't try to copy the string into a new string..do everything in-place is all.
#include <stdio.h>
char* removeSlash (char *str) {
int rindex = 0, windex = 0 ;
char lchar = ' ' ;
while ( str[rindex] != '\0' ) {
if ( str[rindex] == '/' ) {
if ( lchar != '/' )
str[windex++] = str[rindex] ;
} else { str[windex++] = str[rindex] ; }
lchar = str[rindex++] ;
}
str[windex] = '\0' ;
return str ;
}
int main () {
char str[] = "/root//foo/bar" ;
printf ( "\n%s\n", removeSlash (str) ) ;
return 0 ;
}
this has to be solved by scripting instead of writing a program. just use a grep and pipeline it to convert it to the desired string.
If you rewrite below code using c-strings you could make space complexity O(1).
/**
* Time: O(N)
* Space: O(1)
*/
public String removeDuplicateSlashes(String str){
if( str == null ){
throw new IllegalArgumentException("NULL str passed");
}
int copyIndexOffset = 0;
// Space: O(N) make array copy
final char[] arr = str.toCharArray();
boolean previouslySlashFound = false;
for( int i = 0; i < arr.length; i++ ){
if( arr[i] == '/' ){
if( previouslySlashFound ){
continue;
}
previouslySlashFound = true;
}
else {
previouslySlashFound = false;
}
arr[copyIndexOffset++] = arr[i];
}
// Space: O(N) allocate new array
return new String(arr, 0, copyIndexOffset);
}
what about this
public static String shift(String s, int start, int count) {
StringBuffer sb = new StringBuffer(s);
int shiftStartIndex = start + count;
if (shiftStartIndex >= sb.length()) {
return s;
}
while (shiftStartIndex < sb.length()) {
sb.setCharAt(start, sb.charAt(shiftStartIndex));
++start;
++shiftStartIndex;
}
sb.setLength(start);
return sb.toString();
}
public static String removeSlash(String s) {
if (s == null || s.length() == 0) {
return s;
}
int i = 0;
while ( i < s.length()) {
char c = s.charAt(i);
if (c == '/') {
int slashIndex = i;
++i;
if (i == s.length()) {
return s;
}
while ((c = s.charAt(i)) == '/') {
++i;
}
int numShift = i - slashIndex - 1;
if (numShift != 0) {
s = shift(s, slashIndex+1, numShift);
i = slashIndex + 1;
}
} else {
++i;
}
}
return s;
}
Keep two pointers
One to move forward in Input-String characters and another to rewrite the Input-String. we rewrite only if current read char is not slash, if it's slash then check for previous char's being slash.
Keep a variable to maintain state, possible states - last-char-slash, last-char-not-slash.
Actually according to the question, only minimum no. of elements need to be moved. But the algorithms mentioned above always move the elements to the right of the current duplicate slash, that is wrong.
For ex: /foo//baaaaaaaaaaaar. Here when we encounter the duplicate slash we are moving the string "baaaaaaaaaaaar" to its left, and that is not minimum. Ideally, the string "/foo/" needs to be moved to its right.
Here is an algorithm.
1. First count the total number of non-duplicate elements (non-de-count)
2. Now iterate through the array, whenever we encounter a sequence of duplicate slashes i.e. one or more slashes, calculate the non-duplicate elements to its left and non-duplicate elements to its right. How?
the current index will give the no. of non-duplicate elements to its left and non-de-count-current will give the non-duplicate elements to its right.
3. if(non-de-left <= non-de-right){
shift left characters to the right;
}else{
call removeDuplicates(str, currentStart,end);
shift right characters to the left;
}
here is a very simple O(n) algorithm using O(1) space
void rem_dup(char *a)
{
int n=strlen(a);
int s=0,e=0;
for(int i=0;i<n;++i)
{
if(a[i]=='/')
{
s=i;
while(a[i]=='/' && i<n) ++i;
e=i;
for(int j=s+1;j<e;++j) a[j]='\0';
}
}
int pos=0;
for(int i=0;i<n;++i)
{
if(a[i]!='\0')
{
a[pos]=a[i];
pos+=1;
}
}
a[pos]='\0';
}
here is a very simple O(n) algorithm using O(1) space
void rem_dup(char *a)
{
int n=strlen(a);
int s=0,e=0;
for(int i=0;i<n;++i)
{
if(a[i]=='/')
{
s=i;
while(a[i]=='/' && i<n) ++i;
e=i;
for(int j=s+1;j<e;++j) a[j]='\0';
}
}
int pos=0;
for(int i=0;i<n;++i)
{
if(a[i]!='\0')
{
a[pos]=a[i];
pos+=1;
}
}
a[pos]='\0';
}
- XYZ March 29, 2011