Cracking the Coding Interview

Cracking the Coding Interview

1.1实现一个算法判断一个字符串是否存在重复字符。如果不能利用另外的数据结构又该如何实现?

My solution:

?
/**
*利用类似一个hash table的计数
*然后检查这个hash table计数,时间复杂度(n)
*/
int  unique_string1( char  *array, int  length)
{
     int  CARRAY[26] = {0};
     int  i;
     if (length > 26)
         return  0;
     for  (i = 0;i < length;i++)
         CARRAY[array[i]- 'a' ]++;
     for  (i = 0;i < 26;i++)
         if  (CARRAY[i] > 1)
             return  0;
     return  1;
}

  

?
/**
*直接双重循环检查,时间复杂度O(n^2)
*/
int  unique_string2( char  *array, int  length)
{
     int  i,j;
     if (length > 26)
         return  0;
     for  (i = 0;i < length;i++)
         for (j = i+1;j < length;j++)
             if  (array[i] == array[j])
                 return  0;
     return  1;
}

 The Solution that the book advice:

1.思路类似于我第一种实现的方法,但是其中是一个存放boolean值的hashtable,遇到一个字符将其位置设置为true,检查每次遇到的字符hashtable的位置boolean值是否被设置,时间复杂度O(n),但是略优于我的实现。

2.不能利用额外的数据结构,但是仍然不增加时间复杂度的另外一种方法,利用bit vector,即每一位记录当做一个boolean值对待,这样如果仅仅26个字符,则一个整形int即可,其占32位。

3.另外还有一些其他的思路,比如排序。时间复杂度为O(nlgn)

1.2实现一个逆序C-String字符串的方法。

My Solution:

?
void  swap( char  &a, char  &b)
{
     char  temp;
     temp = a;
     a = b;
     b = temp;
     return ;
}
void  reverse_Cstring( char  *array, int  length)
{
     if (length == 0)
         return ;
     int  i;
     for  (i = 0;i < length/2;i++)
     {
         swap(array[i],array[length-1-i]);
     }
     return ;
}

The Solution that the book advice:

其实思路是类似的,但是可能C-String不能得到length这个值,所以解决办法是检查直到遇到C-String的结尾字符。'\0'

1.3设计一个移除String中重复字符的算法并且不能够利用额外的buffer。

My Solution:

?
int  remove_dupchar( char  *array, int  length)
{
     int  i,j,k;
     for (i = 0;i < length;i++)
         for  (j = i+1;j < length;j++)
             if  (array[i] == array[j])
             {
                 for  (k = j+1;k < length;k++)
                     array[k-1] = array[k];
                 length --;
                 j --;
             }
     array[length] = '\0' ;
     return  length;
}

  The Solution that the book advice:

1. step1,for each character,check if it is a duplicate of already found characters. step2,skip duplicate characters and update the non duplicate characters.

code:

 

?
public  static  void  removeDuplicates( char [] str) {
     if (str == null ) return ;
     int  len = str.length();
     if (len < 2 ) return ;
     int  i,j;
     int  tail = 1 ;
     for (i = 1 ;i < len;i++) {
         for (j = 0 ;j < i;j++) {
             if (str[i] == str[j]) break ;
         }
         if (j == tail) {
             str[tail++]=str[i];
         }
     }
     str[tail]= 0 ;
}

  

2.利用常量长度的额外内存。

code:

 

?
public  static  void  removeDuplicatesEff( char [] str) {
     if  (str == null ) return ;
     int  len = str.length();
     if (len < 2 ) return ;
     boolean [] hashtablesign = new  boolean [ 256 ];
     int  i;
     for (i = 0 ;i < len;i++) {
         hashtablesign[i]= false ;
     }
     hashtablesign[str[ 0 ]] = true ;
     int  tail = 1 ;
     for (i = 1 ;i < len;i++) {
         if (!hashtablesign[str[i]]) {
             str[tail++] = str[i];
             hashtablesign[str[i]] = true ;
         }
         str[tail]= 0 ;
     }

  

1.4实现一个判断两个字符串是否回文的方法。(回文:两个字符串由相同的字符组成,顺序可以不同)

My Solution:

 

?
int  is_anagram( char  *a, char  *b, int  length)
{
     int  CARRAY[26]={0};
     int  i;
     for  (i = 0;i < length;i ++)
     {
         CARRAY[a[i]- 'a' ]++;
         CARRAY[b[i]- 'a' ]--;
     }
     for  (i = 0;i < 26;i++)
     {
         if  (CARRAY[i] != 0)
         {
             return  0;
         }
     }
     return  1;
}

  

1.5实现一个方法,将一个字符串中的空格替换为"%20"

My Solution:

 

?
char * replace_space( char  *array, int  length)
{
     int  i;
     int  s_count = 0;
     for  (i = 0;i < length;i++)
     {
         if  (array[i] == ' ' )
         {
             s_count++;
         }
     }
     int  j = 0;
     int  new_length = (length-s_count)+3*s_count;
     char  *new_array = new  char [new_length];
     for  (i = 0;i < length;i++)
     {
         if  (array[i] == ' ' )
         {
             new_array[j++] = '%' ;
             new_array[j++] = '2' ;
             new_array[j++] = '0' ;
         }
         else
         {
             new_array[j++]=array[i];
         }
     }
     return  new_array;
}

 

1.6给出一个N*N的矩阵。每个像素点4bytes,实现一个方法将该矩阵旋转90度。可以不利用额外的存储空间实现吗?

My Solution:

 不利用额外的存储空间有一句叫in place,快速排序也可以成为原地排序。

?
public  static  void  rotate( int  [][] matrix, int  n) {
     for ( int  layer = 0 ;layer < n/ 2 ;layer++) {
         int  first = layer;
         int  last = n- 1 -layer;
         for ( int  i = first;i<last;i++) {
             int  offset = i - first;
             int  top = matrix[first][i];
             matrix[first][i]=matrix[last-offset][first];
             matrix[last-offset][first]=matrix[last][last-offset];
             matrix[last][last-offset]=matrix[i][last];
             matrix[i][last]=top;
         }
     }
}

  

1.7实现如下方法,如果一个M*N的矩阵中存在0元素,则将其行和列均设置为0。

My Solution:

 这个题目容易犯错的地方在于如果是碰到一个0元素就将其行列置为0肯定最终得不到正确的结果,所以首先第一轮要保存0元素出现的位置,第二轮在设置行列为0.

 

1.8假设你现在已经实现了一个方法isSubString来检查一个字符串是否为另一个字符串的子串。现在给出两个字符串s1,s2,实现方法判断s2是否为s1的轮换通过只调用isSubString一次。

My Solution:

 这个问题真的没有想到解决方案,但是看到答案之后发现题目真的很easy的。

The Solution that the book advice:

 思路就是,将s2重新复制一遍然后连接起来,检查s1是否为s2的字串即可。

例如:s2=“cdab”,s1=“abcd”,首先s2扩展为 “cdabcdab”,检查s1是否为s2的子串即可。

?
public  static  void  check(String str1 , String str2) {
     int  len = str1.length();
     if (len == str2.length() && len > 0 ) {
         String str1str1 = str1+str1;
         return  isSubString(str1str1,str2);
     }
     return  false ;
}

  

你可能感兴趣的:(interview)