Adobe Interview Question
Software Engineer / Developersi think the dynamic approach will work here
if we take L[n] array and n is the length of tyhe string here
now just intialed each L[i] with 1
now traverse the string
and if you found s[i]=s[i-1]+1
then just increase L[i]as L[i-1]+1;
now at the last scan the L array where u fiond the max is going to be the number of contiguous character in string at max
now if u want to print them just start printing string from s[i-L[i]]to s[i]
What a crappy stupid approach! Dare to challenge? Show how to solve for these examples:
example 1 : eacdzxygfde
example 2 : eacdbxygfde
A simpler approach to solve this problem:
1. start with beginIdx = 0, move the endIdx as long as there is no duplicate in a window.
2. In a window, with no duplicate; keep track of minChar and maxChar corresponding to characters in window(i,j). If there is no duplicate, and if maxChar-minChar == j-i, it implies range(i,j) contains consecutive chars.
3. Keep update of max window found.
4. Move beginIdx to 1, 2,....
There are O(n^2) ranges in total. Maintaining a hash to keep track of chars in a window, time complexity is O(n^2).
Cool algo suggested by buried.shopno. Here is a basic C implementation of same(tested):
void findConsecChars(char arr[], int* start, int *length)
{
int hash[256];
int j,k,begIdx;
int min,max,len;
len=strlen(arr);
for(begIdx=0; begIdx<len-1; begIdx++)
{
//initialise hashTable
for(k=0; k<256; k++)
hash[k]=0;
//set min/max char for curWindow
min=arr[begIdx];
max=arr[begIdx];
hash[begIdx]=1;
for(j=begIdx+1; j<len; j++)
{
if (hash[arr[j]])//reset window
break;
hash[arr[j]]=1;
if(arr[j]>max)
max=arr[j];
if(arr[j]<min)
min=arr[j];
if( ((j-begIdx) == (max-min)) && ((max-min) > (*length)) ){
*start=begIdx;
*length = (max-min)+1;
}
}
}
}
Take start = 0
Take maxlength = 0
while start+1 != end of the list
begin = start
end = start+1
while( char(begin)+1 == char(end) && end<end of list)
begin++, end++
if maxlength < (begin - start)
maxlength = (begin - start)
if start<begin
start = begin
else
start++
finally the max length gives the answer.
void find_max_consecutive(char *a,int n)
{
int max=1,q=1;
char str[100];
for(int i=1;i<n;i++)
{
if(a[i-1]==a[i]+1)
{q++;}
elseif(q>1)
{
if(max<q)
{
max=q;
strncpy(str,a[i-q],q)
q=1;
}
}
printf("\n%s",str);
}
O(n)
Your assumption makes the problem too simple. I doubt if Adobe really asked what you meant.
Your approach doesn't work for a variation where a substring could be permuted to get consecutive chars.
For example,
eacdzxygfde => gfde is the solution (i.e. defg)
eacdbxygfde => eacdb is the solution (i.e. abcde)
public static void findLargestString(String input){
if(input == null)
return;
if(input.length()==1)
System.out.println(input);
int localStart=0;
int globalStart=0;
int localEnd=0;
int globalEnd=0;
int localMax=0;
int globalMax=0;
char temp = input.charAt(0);
localMax=1;
for(int i=1; i<input.length(); i++){
if(input.charAt(i) == temp+1){
localEnd++;
localMax++;
} else {
if (localMax > globalMax) {
globalEnd = localEnd;
globalStart = localStart;
globalMax = localMax;
}
localStart = i;
localEnd = i;
localMax = 1;
}
temp = input.charAt(i);
}
if(localMax > globalMax){
globalEnd = localEnd;
globalStart = localStart;
globalMax = localMax;
}
System.out.println(input.substring(globalStart, globalEnd+1));
}
char * FindLongestSubString(const char * pszInput)
{
if(!pszInput) return NULL;
int length = strlen(pszInput);
int max_val =0;
if(length == 1)
return (char *)pszInput[0];
char * pszReturnString = NULL;
const char *start, *end;
start = pszInput;
end = start+1;
while(*end)
{
if(*end == *(end-1)+1)
{
start = end-1;
while(*end == *(end-1)+1)
end +=1;
end--;
if(end-start > max_val)
{
max_val = end-start;
pszReturnString = substr(pszInput,int(start-pszInput),int(end-pszInput));
}
}
end++;
}
return pszReturnString;
}
#include<iostream.h>
#include<stdlib.h>
#include<conio.h>
void main()
{
clrscr();
char *ch="abcdejihgfedcba";
int i,j,N=0,i1,j1;
while(ch[N++]!='\0');
N--;
i=j=0;
i1=i;
j1=j;
while(j<=N)
{
if(abs(j-i)>abs(j1-i1))
{
i1=i;
j1=j;
}
i=j;
while(abs(ch[j]-ch[i])==abs(j-i))
{
j++;
}
}
while(i1!=j1)
{
cout<<ch[i1];
i1++;
}
getch();
}
<pre lang="" line="1" title="CodeMonkey48324" class="run-this"># include "stdio.h"
# include "string.h"
int main()
{
char *InputStr = malloc(sizeof(char)*100);
int len,i,inconsstr = 1;
char *tempbuffer = malloc(sizeof(char)*100);
char *reusltbuffer = malloc(sizeof(char)*100);
memcpy(InputStr, "chinguchaABCDEghuEFGHIJKLMNOPQRST",34);
memset(tempbuffer,0,100);
memset(reusltbuffer,0,100);
len = strlen(InputStr);
for(i = 1; i < len +1 ; i++)
{
if(inconsstr)
{
if(InputStr[i] == InputStr[i -1] + 1)
{
if(!strlen(tempbuffer))
{
tempbuffer[strlen(tempbuffer)] = InputStr[i -1];
}
else
{
tempbuffer[strlen(tempbuffer) - 1] = InputStr[i -1];
}
tempbuffer[strlen(tempbuffer)] = InputStr[i];
inconsstr = 1;
}
else
{
if(strlen(tempbuffer) > strlen(reusltbuffer))
{
strcpy(reusltbuffer,tempbuffer);
}
memset(tempbuffer,0,100);
inconsstr = 0;
}
}
else if(InputStr[i] == InputStr[i -1] + 1)
{
if(!strlen(tempbuffer))
{
tempbuffer[strlen(tempbuffer)] = InputStr[i -1];
}
else
{
tempbuffer[strlen(tempbuffer) - 1] = InputStr[i -1];
}
tempbuffer[strlen(tempbuffer)] = InputStr[i];
inconsstr = 1;
}
}
printf("\nLargest consecutive string %s\n",reusltbuffer);
}
</pre><pre title="CodeMonkey48324" input="yes">
</pre>
<pre lang="" line="1" title="CodeMonkey54357" class="run-this">/* The class name doesn't have to be Main, as long as the class is not public. */
class Main
{
public static void main (String[] args) throws java.lang.Exception
{
java.io.BufferedReader r = new java.io.BufferedReader (new java.io.InputStreamReader (System.in));
String s;
while (!(s=r.readLine()).startsWith("42")) System.out.println(s);
}
}
</pre><pre title="CodeMonkey54357" input="yes">void ConsecutiveCharacters(char*& str)
{
int max = 1;
int i = 0;
int presentcount = 1;
int min_idx = 0;
int max_idx = 0;
char* consecutive_string = (char*)malloc(strlen(str)*sizeof(char));
memset(consecutive_string, '0', strlen(str));
while(str[i] != NULL)
{
if(str[i] + 1 == str[i+1])
{
i++;
presentcount++;
}
else
{
if(presentcount > max)
{
min_idx = i - presentcount + 1;
max = presentcount;
max_idx = presentcount + min_idx;
}
else
{
//Do Nothing
}
presentcount = 1;
i++;
}
}
memcpy((char*)consecutive_string, (char*)str + min_idx, max_idx - min_idx);
memset((char*)consecutive_string + max_idx - min_idx, NULL, 1);
}
</pre>
public static void main(String[] args)
{
String s = "abcdeabcababcdefgh";
int strp = 0;
int strl = 0;
int tstrp = 0;
int tstrl = 1;
int preve = 0;
int curre = 1;
int endofstr = 0;
while(curre < s.length())
{
if(s.charAt(curre) - s.charAt(preve) == 1)
{
// consecutive elements continue
tstrl += 1;
}
else
{
// end of internal string
endofstr = 1;
}
// new string found by end of internal string or end of whole string.
if(endofstr == 1 || curre == s.length() - 1)
{
if(tstrl > strl)
{
// update strings
strl = tstrl;
strp = tstrp;
}
// update temporary elements
tstrl = 1;
tstrp = curre;
endofstr = 0;
}
// pass to next element
preve = curre;
curre += 1;
}
System.out.println("start point = " + strp + "\n" + "string lenght = " + strl + "\n" + "string = " + s.substring(strp, strp+strl));
Space: O(1) (No extra space used)
Time: O(n)
#include <stdio.h>
int main(int argc, char *argv[])
{
int i,size = 0, maxSize = 0;
char *maxPtr = argv[1], *ptr = argv[1];
for(; *ptr != '\0'; ptr++) {
if(*ptr == (*(ptr+1) -1))
size++;
else {
if(size > maxSize) {
maxSize = 1 + size;
maxPtr = ptr - size;
}
size = 0;
}
}
printf("Size = %d String starts from %s\n",maxSize,maxPtr);
return (0);
}
allocate a new array arr[1.. strlen(str)]
arr[0] = 1
for ( i =1; i < strlen(str) ; i++)
{
if(str[i -1 ] and str[i] are consecutive) { arr[i] = 0 }
else arr[i] =1;
}
find longest substring with maximum number of 0's O(n) ( have two ptrs i and j to point to start and end of largest block of 0's in arr)
output the substring which has largest number of 0's
eedeesawe
100001111
output chars matching position 10000
that is eedee
Any suggestions?
Cool algo suggested by buried.shopno. Here is a basic C implementation of same(tested):
void findConsecChars(char arr[], int* start, int *length)
{
int hash[256];
int j,k,begIdx;
int min,max,len;
len=strlen(arr);
for(begIdx=0; begIdx<len-1; begIdx++)
{
//initialise hashTable
for(k=0; k<256; k++)
hash[k]=0;
//set min/max char for curWindow
min=arr[begIdx];
max=arr[begIdx];
hash[begIdx]=1;
for(j=begIdx+1; j<len; j++)
{
if (hash[arr[j]])//reset window
break;
hash[arr[j]]=1;
if(arr[j]>max)
max=arr[j];
if(arr[j]<min)
min=arr[j];
if( ((j-begIdx) == (max-min)) && ((max-min) > (*length)) ){
*start=begIdx;
*length = (max-min)+1;
}
}
}
}
# include<stdio.h>
# include<conio.h>
int max;
int count;
int index;
main()
{
int i,j;
char str[45];
printf("enter the string::\n");
gets(str);
i=0;
while(str[i]!='\0')
{
j=i+1;
if(str[j]==str[i])
{
while(str[j]==str[i])
{
max++;
j++;
}
}
if(count<max)
{
index=i;
count=max;
max=0;
}
i=j;
}
printf("longest string is::");
j=index;
while(str[j]==str[index])
{
putch(str[j]);
j++;
}
getch();
}
Here is Java code
class LongestConsecutive{
public static void main(String args[])
{
String st = "abbcccdddd";
StringBuffer sbf = new StringBuffer(st);
int max = 1,len=st.length(),count=1,index=0,startIndex=0;
for(int i=1;i<len;i++)
{
if(sbf.charAt(i)==sbf.charAt(index))
{
count++;
}
else{
if(count>max)
{
max = count;
startIndex = index;
}
index = i;
count = 1;
}
}
if(count>max)
{
max = count;
startIndex=len-max;
}
System.out.println(sbf.substring(startIndex,startIndex+max).toString()+" "+max);
}
}
- Psycho October 01, 2012